ios.cpp revision 278724
1//===-------------------------- ios.cpp -----------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is dual licensed under the MIT and the University of Illinois Open 6// Source Licenses. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "__config" 11#include "ios" 12#include "streambuf" 13#include "istream" 14#include "string" 15#include "__locale" 16#include "algorithm" 17#include "memory" 18#include "new" 19#include "limits" 20#include <stdlib.h> 21 22_LIBCPP_BEGIN_NAMESPACE_STD 23 24template class basic_ios<char>; 25template class basic_ios<wchar_t>; 26 27template class basic_streambuf<char>; 28template class basic_streambuf<wchar_t>; 29 30template class basic_istream<char>; 31template class basic_istream<wchar_t>; 32 33template class basic_ostream<char>; 34template class basic_ostream<wchar_t>; 35 36template class basic_iostream<char>; 37 38class _LIBCPP_HIDDEN __iostream_category 39 : public __do_message 40{ 41public: 42 virtual const char* name() const _NOEXCEPT; 43 virtual string message(int ev) const; 44}; 45 46const char* 47__iostream_category::name() const _NOEXCEPT 48{ 49 return "iostream"; 50} 51 52string 53__iostream_category::message(int ev) const 54{ 55 if (ev != static_cast<int>(io_errc::stream) 56#ifdef _LIBCPP_ELAST 57 && ev <= _LIBCPP_ELAST 58#endif // _LIBCPP_ELAST 59 ) 60 return __do_message::message(ev); 61 return string("unspecified iostream_category error"); 62} 63 64const error_category& 65iostream_category() _NOEXCEPT 66{ 67 static __iostream_category s; 68 return s; 69} 70 71// ios_base::failure 72 73ios_base::failure::failure(const string& msg, const error_code& ec) 74 : system_error(ec, msg) 75{ 76} 77 78ios_base::failure::failure(const char* msg, const error_code& ec) 79 : system_error(ec, msg) 80{ 81} 82 83ios_base::failure::~failure() throw() 84{ 85} 86 87// ios_base locale 88 89const ios_base::fmtflags ios_base::boolalpha; 90const ios_base::fmtflags ios_base::dec; 91const ios_base::fmtflags ios_base::fixed; 92const ios_base::fmtflags ios_base::hex; 93const ios_base::fmtflags ios_base::internal; 94const ios_base::fmtflags ios_base::left; 95const ios_base::fmtflags ios_base::oct; 96const ios_base::fmtflags ios_base::right; 97const ios_base::fmtflags ios_base::scientific; 98const ios_base::fmtflags ios_base::showbase; 99const ios_base::fmtflags ios_base::showpoint; 100const ios_base::fmtflags ios_base::showpos; 101const ios_base::fmtflags ios_base::skipws; 102const ios_base::fmtflags ios_base::unitbuf; 103const ios_base::fmtflags ios_base::uppercase; 104const ios_base::fmtflags ios_base::adjustfield; 105const ios_base::fmtflags ios_base::basefield; 106const ios_base::fmtflags ios_base::floatfield; 107 108const ios_base::iostate ios_base::badbit; 109const ios_base::iostate ios_base::eofbit; 110const ios_base::iostate ios_base::failbit; 111const ios_base::iostate ios_base::goodbit; 112 113const ios_base::openmode ios_base::app; 114const ios_base::openmode ios_base::ate; 115const ios_base::openmode ios_base::binary; 116const ios_base::openmode ios_base::in; 117const ios_base::openmode ios_base::out; 118const ios_base::openmode ios_base::trunc; 119 120void 121ios_base::__call_callbacks(event ev) 122{ 123 for (size_t i = __event_size_; i;) 124 { 125 --i; 126 __fn_[i](ev, *this, __index_[i]); 127 } 128} 129 130// locale 131 132locale 133ios_base::imbue(const locale& newloc) 134{ 135 static_assert(sizeof(locale) == sizeof(__loc_), ""); 136 locale& loc_storage = *reinterpret_cast<locale*>(&__loc_); 137 locale oldloc = loc_storage; 138 loc_storage = newloc; 139 __call_callbacks(imbue_event); 140 return oldloc; 141} 142 143locale 144ios_base::getloc() const 145{ 146 const locale& loc_storage = *reinterpret_cast<const locale*>(&__loc_); 147 return loc_storage; 148} 149 150// xalloc 151#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS) 152atomic<int> ios_base::__xindex_ = ATOMIC_VAR_INIT(0); 153#else 154int ios_base::__xindex_ = 0; 155#endif 156 157template <typename _Tp> 158static size_t __ios_new_cap(size_t __req_size, size_t __current_cap) 159{ // Precondition: __req_size > __current_cap 160 const size_t mx = std::numeric_limits<size_t>::max() / sizeof(_Tp); 161 if (__req_size < mx/2) 162 return _VSTD::max(2 * __current_cap, __req_size); 163 else 164 return mx; 165} 166 167int 168ios_base::xalloc() 169{ 170 return __xindex_++; 171} 172 173long& 174ios_base::iword(int index) 175{ 176 size_t req_size = static_cast<size_t>(index)+1; 177 if (req_size > __iarray_cap_) 178 { 179 size_t newcap = __ios_new_cap<long>(req_size, __iarray_cap_); 180 long* iarray = static_cast<long*>(realloc(__iarray_, newcap * sizeof(long))); 181 if (iarray == 0) 182 { 183 setstate(badbit); 184 static long error; 185 error = 0; 186 return error; 187 } 188 __iarray_ = iarray; 189 for (long* p = __iarray_ + __iarray_size_; p < __iarray_ + newcap; ++p) 190 *p = 0; 191 __iarray_cap_ = newcap; 192 } 193 __iarray_size_ = max<size_t>(__iarray_size_, req_size); 194 return __iarray_[index]; 195} 196 197void*& 198ios_base::pword(int index) 199{ 200 size_t req_size = static_cast<size_t>(index)+1; 201 if (req_size > __parray_cap_) 202 { 203 size_t newcap = __ios_new_cap<void *>(req_size, __iarray_cap_); 204 void** parray = static_cast<void**>(realloc(__parray_, newcap * sizeof(void *))); 205 if (parray == 0) 206 { 207 setstate(badbit); 208 static void* error; 209 error = 0; 210 return error; 211 } 212 __parray_ = parray; 213 for (void** p = __parray_ + __parray_size_; p < __parray_ + newcap; ++p) 214 *p = 0; 215 __parray_cap_ = newcap; 216 } 217 __parray_size_ = max<size_t>(__parray_size_, req_size); 218 return __parray_[index]; 219} 220 221// register_callback 222 223void 224ios_base::register_callback(event_callback fn, int index) 225{ 226 size_t req_size = __event_size_ + 1; 227 if (req_size > __event_cap_) 228 { 229 size_t newcap = __ios_new_cap<event_callback>(req_size, __event_cap_); 230 event_callback* fns = static_cast<event_callback*>(realloc(__fn_, newcap * sizeof(event_callback))); 231 if (fns == 0) 232 setstate(badbit); 233 __fn_ = fns; 234 int* indxs = static_cast<int *>(realloc(__index_, newcap * sizeof(int))); 235 if (indxs == 0) 236 setstate(badbit); 237 __index_ = indxs; 238 __event_cap_ = newcap; 239 } 240 __fn_[__event_size_] = fn; 241 __index_[__event_size_] = index; 242 ++__event_size_; 243} 244 245ios_base::~ios_base() 246{ 247 __call_callbacks(erase_event); 248 locale& loc_storage = *reinterpret_cast<locale*>(&__loc_); 249 loc_storage.~locale(); 250 free(__fn_); 251 free(__index_); 252 free(__iarray_); 253 free(__parray_); 254} 255 256// iostate 257 258void 259ios_base::clear(iostate state) 260{ 261 if (__rdbuf_) 262 __rdstate_ = state; 263 else 264 __rdstate_ = state | badbit; 265#ifndef _LIBCPP_NO_EXCEPTIONS 266 if (((state | (__rdbuf_ ? goodbit : badbit)) & __exceptions_) != 0) 267 throw failure("ios_base::clear"); 268#endif // _LIBCPP_NO_EXCEPTIONS 269} 270 271// init 272 273void 274ios_base::init(void* sb) 275{ 276 __rdbuf_ = sb; 277 __rdstate_ = __rdbuf_ ? goodbit : badbit; 278 __exceptions_ = goodbit; 279 __fmtflags_ = skipws | dec; 280 __width_ = 0; 281 __precision_ = 6; 282 __fn_ = 0; 283 __index_ = 0; 284 __event_size_ = 0; 285 __event_cap_ = 0; 286 __iarray_ = 0; 287 __iarray_size_ = 0; 288 __iarray_cap_ = 0; 289 __parray_ = 0; 290 __parray_size_ = 0; 291 __parray_cap_ = 0; 292 ::new(&__loc_) locale; 293} 294 295void 296ios_base::copyfmt(const ios_base& rhs) 297{ 298 // If we can't acquire the needed resources, throw bad_alloc (can't set badbit) 299 // Don't alter *this until all needed resources are acquired 300 unique_ptr<event_callback, void (*)(void*)> new_callbacks(0, free); 301 unique_ptr<int, void (*)(void*)> new_ints(0, free); 302 unique_ptr<long, void (*)(void*)> new_longs(0, free); 303 unique_ptr<void*, void (*)(void*)> new_pointers(0, free); 304 if (__event_cap_ < rhs.__event_size_) 305 { 306 size_t newesize = sizeof(event_callback) * rhs.__event_size_; 307 new_callbacks.reset(static_cast<event_callback*>(malloc(newesize))); 308#ifndef _LIBCPP_NO_EXCEPTIONS 309 if (!new_callbacks) 310 throw bad_alloc(); 311#endif // _LIBCPP_NO_EXCEPTIONS 312 313 size_t newisize = sizeof(int) * rhs.__event_size_; 314 new_ints.reset(static_cast<int *>(malloc(newisize))); 315#ifndef _LIBCPP_NO_EXCEPTIONS 316 if (!new_ints) 317 throw bad_alloc(); 318#endif // _LIBCPP_NO_EXCEPTIONS 319 } 320 if (__iarray_cap_ < rhs.__iarray_size_) 321 { 322 size_t newsize = sizeof(long) * rhs.__iarray_size_; 323 new_longs.reset(static_cast<long*>(malloc(newsize))); 324#ifndef _LIBCPP_NO_EXCEPTIONS 325 if (!new_longs) 326 throw bad_alloc(); 327#endif // _LIBCPP_NO_EXCEPTIONS 328 } 329 if (__parray_cap_ < rhs.__parray_size_) 330 { 331 size_t newsize = sizeof(void*) * rhs.__parray_size_; 332 new_pointers.reset(static_cast<void**>(malloc(newsize))); 333#ifndef _LIBCPP_NO_EXCEPTIONS 334 if (!new_pointers) 335 throw bad_alloc(); 336#endif // _LIBCPP_NO_EXCEPTIONS 337 } 338 // Got everything we need. Copy everything but __rdstate_, __rdbuf_ and __exceptions_ 339 __fmtflags_ = rhs.__fmtflags_; 340 __precision_ = rhs.__precision_; 341 __width_ = rhs.__width_; 342 locale& lhs_loc = *reinterpret_cast<locale*>(&__loc_); 343 const locale& rhs_loc = *reinterpret_cast<const locale*>(&rhs.__loc_); 344 lhs_loc = rhs_loc; 345 if (__event_cap_ < rhs.__event_size_) 346 { 347 free(__fn_); 348 __fn_ = new_callbacks.release(); 349 free(__index_); 350 __index_ = new_ints.release(); 351 __event_cap_ = rhs.__event_size_; 352 } 353 for (__event_size_ = 0; __event_size_ < rhs.__event_size_; ++__event_size_) 354 { 355 __fn_[__event_size_] = rhs.__fn_[__event_size_]; 356 __index_[__event_size_] = rhs.__index_[__event_size_]; 357 } 358 if (__iarray_cap_ < rhs.__iarray_size_) 359 { 360 free(__iarray_); 361 __iarray_ = new_longs.release(); 362 __iarray_cap_ = rhs.__iarray_size_; 363 } 364 for (__iarray_size_ = 0; __iarray_size_ < rhs.__iarray_size_; ++__iarray_size_) 365 __iarray_[__iarray_size_] = rhs.__iarray_[__iarray_size_]; 366 if (__parray_cap_ < rhs.__parray_size_) 367 { 368 free(__parray_); 369 __parray_ = new_pointers.release(); 370 __parray_cap_ = rhs.__parray_size_; 371 } 372 for (__parray_size_ = 0; __parray_size_ < rhs.__parray_size_; ++__parray_size_) 373 __parray_[__parray_size_] = rhs.__parray_[__parray_size_]; 374} 375 376void 377ios_base::move(ios_base& rhs) 378{ 379 // *this is uninitialized 380 __fmtflags_ = rhs.__fmtflags_; 381 __precision_ = rhs.__precision_; 382 __width_ = rhs.__width_; 383 __rdstate_ = rhs.__rdstate_; 384 __exceptions_ = rhs.__exceptions_; 385 __rdbuf_ = 0; 386 locale& rhs_loc = *reinterpret_cast<locale*>(&rhs.__loc_); 387 ::new(&__loc_) locale(rhs_loc); 388 __fn_ = rhs.__fn_; 389 rhs.__fn_ = 0; 390 __index_ = rhs.__index_; 391 rhs.__index_ = 0; 392 __event_size_ = rhs.__event_size_; 393 rhs.__event_size_ = 0; 394 __event_cap_ = rhs.__event_cap_; 395 rhs.__event_cap_ = 0; 396 __iarray_ = rhs.__iarray_; 397 rhs.__iarray_ = 0; 398 __iarray_size_ = rhs.__iarray_size_; 399 rhs.__iarray_size_ = 0; 400 __iarray_cap_ = rhs.__iarray_cap_; 401 rhs.__iarray_cap_ = 0; 402 __parray_ = rhs.__parray_; 403 rhs.__parray_ = 0; 404 __parray_size_ = rhs.__parray_size_; 405 rhs.__parray_size_ = 0; 406 __parray_cap_ = rhs.__parray_cap_; 407 rhs.__parray_cap_ = 0; 408} 409 410void 411ios_base::swap(ios_base& rhs) _NOEXCEPT 412{ 413 _VSTD::swap(__fmtflags_, rhs.__fmtflags_); 414 _VSTD::swap(__precision_, rhs.__precision_); 415 _VSTD::swap(__width_, rhs.__width_); 416 _VSTD::swap(__rdstate_, rhs.__rdstate_); 417 _VSTD::swap(__exceptions_, rhs.__exceptions_); 418 locale& lhs_loc = *reinterpret_cast<locale*>(&__loc_); 419 locale& rhs_loc = *reinterpret_cast<locale*>(&rhs.__loc_); 420 _VSTD::swap(lhs_loc, rhs_loc); 421 _VSTD::swap(__fn_, rhs.__fn_); 422 _VSTD::swap(__index_, rhs.__index_); 423 _VSTD::swap(__event_size_, rhs.__event_size_); 424 _VSTD::swap(__event_cap_, rhs.__event_cap_); 425 _VSTD::swap(__iarray_, rhs.__iarray_); 426 _VSTD::swap(__iarray_size_, rhs.__iarray_size_); 427 _VSTD::swap(__iarray_cap_, rhs.__iarray_cap_); 428 _VSTD::swap(__parray_, rhs.__parray_); 429 _VSTD::swap(__parray_size_, rhs.__parray_size_); 430 _VSTD::swap(__parray_cap_, rhs.__parray_cap_); 431} 432 433void 434ios_base::__set_badbit_and_consider_rethrow() 435{ 436 __rdstate_ |= badbit; 437#ifndef _LIBCPP_NO_EXCEPTIONS 438 if (__exceptions_ & badbit) 439 throw; 440#endif // _LIBCPP_NO_EXCEPTIONS 441} 442 443void 444ios_base::__set_failbit_and_consider_rethrow() 445{ 446 __rdstate_ |= failbit; 447#ifndef _LIBCPP_NO_EXCEPTIONS 448 if (__exceptions_ & failbit) 449 throw; 450#endif // _LIBCPP_NO_EXCEPTIONS 451} 452 453bool 454ios_base::sync_with_stdio(bool sync) 455{ 456 static bool previous_state = true; 457 bool r = previous_state; 458 previous_state = sync; 459 return r; 460} 461 462_LIBCPP_END_NAMESPACE_STD 463