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