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 #define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__; 11 12 #include "ios" 13 #include "streambuf" 14 #include "istream" 15 #include "string" 16 #include "__locale" 17 #include "algorithm" 18 #include "memory" 19 #include "new" 20 #include "limits" 21 #include <stdlib.h> 22 23 _LIBCPP_BEGIN_NAMESPACE_STD 24 25 template class basic_ios<char>; 26 template class basic_ios<wchar_t>; 27 28 template class basic_streambuf<char>; 29 template class basic_streambuf<wchar_t>; 30 31 template class basic_istream<char>; 32 template class basic_istream<wchar_t>; 33 34 template class basic_ostream<char>; 35 template class basic_ostream<wchar_t>; 36 37 template class basic_iostream<char>; 38 39 class _LIBCPP_HIDDEN __iostream_category 40 : public __do_message 41 { 42 public: 43 virtual const char* name() const _NOEXCEPT; 44 virtual string message(int ev) const; 45 }; 46 47 const char* 48 __iostream_category::name() const _NOEXCEPT 49 { 50 return "iostream"; 51 } 52 53 string 54 __iostream_category::message(int ev) const 55 { 56 if (ev != static_cast<int>(io_errc::stream) 57 #ifdef ELAST 58 && ev <= ELAST 59 #endif 60 ) 61 return __do_message::message(ev); 62 return string("unspecified iostream_category error"); 63 } 64 65 const error_category& 66 iostream_category() 67 { 68 static __iostream_category s; 69 return s; 70 } 71 72 // ios_base::failure 73 74 ios_base::failure::failure(const string& msg, const error_code& ec) 75 : system_error(ec, msg) 76 { 77 } 78 79 ios_base::failure::failure(const char* msg, const error_code& ec) 80 : system_error(ec, msg) 81 { 82 } 83 84 ios_base::failure::~failure() throw() 85 { 86 } 87 88 // ios_base locale 89 90 const ios_base::fmtflags ios_base::boolalpha; 91 const ios_base::fmtflags ios_base::dec; 92 const ios_base::fmtflags ios_base::fixed; 93 const ios_base::fmtflags ios_base::hex; 94 const ios_base::fmtflags ios_base::internal; 95 const ios_base::fmtflags ios_base::left; 96 const ios_base::fmtflags ios_base::oct; 97 const ios_base::fmtflags ios_base::right; 98 const ios_base::fmtflags ios_base::scientific; 99 const ios_base::fmtflags ios_base::showbase; 100 const ios_base::fmtflags ios_base::showpoint; 101 const ios_base::fmtflags ios_base::showpos; 102 const ios_base::fmtflags ios_base::skipws; 103 const ios_base::fmtflags ios_base::unitbuf; 104 const ios_base::fmtflags ios_base::uppercase; 105 const ios_base::fmtflags ios_base::adjustfield; 106 const ios_base::fmtflags ios_base::basefield; 107 const ios_base::fmtflags ios_base::floatfield; 108 109 const ios_base::iostate ios_base::badbit; 110 const ios_base::iostate ios_base::eofbit; 111 const ios_base::iostate ios_base::failbit; 112 const ios_base::iostate ios_base::goodbit; 113 114 const ios_base::openmode ios_base::app; 115 const ios_base::openmode ios_base::ate; 116 const ios_base::openmode ios_base::binary; 117 const ios_base::openmode ios_base::in; 118 const ios_base::openmode ios_base::out; 119 const ios_base::openmode ios_base::trunc; 120 121 void 122 ios_base::__call_callbacks(event ev) 123 { 124 for (size_t i = __event_size_; i;) 125 { 126 --i; 127 __fn_[i](ev, *this, __index_[i]); 128 } 129 } 130 131 // locale 132 133 locale 134 ios_base::imbue(const locale& newloc) 135 { 136 static_assert(sizeof(locale) == sizeof(__loc_), ""); 137 locale& loc_storage = *(locale*)&__loc_; 138 locale oldloc = loc_storage; 139 loc_storage = newloc; 140 __call_callbacks(imbue_event); 141 return oldloc; 142 } 143 144 locale 145 ios_base::getloc() const 146 { 147 const locale& loc_storage = *(locale*)&__loc_; 148 return loc_storage; 149 } 150 151 // xalloc 152 153 int ios_base::__xindex_ = 0; 154 155 int 156 ios_base::xalloc() 157 { 158 return __xindex_++; 159 } 160 161 long& 162 ios_base::iword(int index) 163 { 164 size_t req_size = static_cast<size_t>(index)+1; 165 if (req_size > __iarray_cap_) 166 { 167 size_t newcap; 168 const size_t mx = std::numeric_limits<size_t>::max(); 169 if (req_size < mx/2) 170 newcap = _VSTD::max(2 * __iarray_cap_, req_size); 171 else 172 newcap = mx; 173 long* iarray = (long*)realloc(__iarray_, newcap * sizeof(long)); 174 if (iarray == 0) 175 { 176 setstate(badbit); 177 static long error; 178 error = 0; 179 return error; 180 } 181 __iarray_ = iarray; 182 for (long* p = __iarray_ + __iarray_size_; __iarray_cap_ < newcap; ++__iarray_cap_, ++p) 183 *p = 0; 184 } 185 __iarray_size_ = max<size_t>(__iarray_size_, req_size); 186 return __iarray_[index]; 187 } 188 189 void*& 190 ios_base::pword(int index) 191 { 192 size_t req_size = static_cast<size_t>(index)+1; 193 if (req_size > __parray_cap_) 194 { 195 size_t newcap; 196 const size_t mx = std::numeric_limits<size_t>::max(); 197 if (req_size < mx/2) 198 newcap = _VSTD::max(2 * __parray_cap_, req_size); 199 else 200 newcap = mx; 201 void** parray = (void**)realloc(__parray_, newcap * sizeof(void*)); 202 if (parray == 0) 203 { 204 setstate(badbit); 205 static void* error; 206 error = 0; 207 return error; 208 } 209 __parray_ = parray; 210 for (void** p = __parray_ + __parray_size_; __parray_cap_ < newcap; ++__parray_cap_, ++p) 211 *p = 0; 212 } 213 __parray_size_ = max<size_t>(__parray_size_, req_size); 214 return __parray_[index]; 215 } 216 217 // register_callback 218 219 void 220 ios_base::register_callback(event_callback fn, int index) 221 { 222 size_t req_size = __event_size_ + 1; 223 if (req_size > __event_cap_) 224 { 225 size_t newcap; 226 const size_t mx = std::numeric_limits<size_t>::max(); 227 if (req_size < mx/2) 228 newcap = _VSTD::max(2 * __event_cap_, req_size); 229 else 230 newcap = mx; 231 event_callback* fns = (event_callback*)realloc(__fn_, newcap * sizeof(event_callback)); 232 if (fns == 0) 233 setstate(badbit); 234 __fn_ = fns; 235 int* indxs = (int*)realloc(__index_, newcap * sizeof(int)); 236 if (indxs == 0) 237 setstate(badbit); 238 __index_ = indxs; 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 = *(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 aquired 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 new_callbacks.reset((event_callback*)malloc(sizeof(event_callback) * rhs.__event_size_)); 307 #ifndef _LIBCPP_NO_EXCEPTIONS 308 if (!new_callbacks) 309 throw bad_alloc(); 310 #endif // _LIBCPP_NO_EXCEPTIONS 311 new_ints.reset((int*)malloc(sizeof(int) * rhs.__event_size_)); 312 #ifndef _LIBCPP_NO_EXCEPTIONS 313 if (!new_ints) 314 throw bad_alloc(); 315 #endif // _LIBCPP_NO_EXCEPTIONS 316 } 317 if (__iarray_cap_ < rhs.__iarray_size_) 318 { 319 new_longs.reset((long*)malloc(sizeof(long) * rhs.__iarray_size_)); 320 #ifndef _LIBCPP_NO_EXCEPTIONS 321 if (!new_longs) 322 throw bad_alloc(); 323 #endif // _LIBCPP_NO_EXCEPTIONS 324 } 325 if (__parray_cap_ < rhs.__parray_size_) 326 { 327 new_pointers.reset((void**)malloc(sizeof(void*) * rhs.__parray_size_)); 328 #ifndef _LIBCPP_NO_EXCEPTIONS 329 if (!new_pointers) 330 throw bad_alloc(); 331 #endif // _LIBCPP_NO_EXCEPTIONS 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 = *(locale*)&__loc_; 338 locale& rhs_loc = *(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 = *(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 = *(locale*)&__loc_; 414 locale& rhs_loc = *(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