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