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