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