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