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