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 template <typename _Tp> 158 static 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 167 int 168 ios_base::xalloc() 169 { 170 return __xindex_++; 171 } 172 173 long& 174 ios_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 197 void*& 198 ios_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 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 = __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 245 ios_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 258 void 259 ios_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 273 void 274 ios_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 295 void 296 ios_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 376 void 377 ios_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 410 void 411 ios_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 433 void 434 ios_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 443 void 444 ios_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 453 bool 454 ios_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