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#endif 60 ) 61 return __do_message::message(ev); 62 return string("unspecified iostream_category error"); 63} 64 65const error_category& 66iostream_category() _NOEXCEPT 67{ 68 static __iostream_category s; 69 return s; 70} 71 72// ios_base::failure 73 74ios_base::failure::failure(const string& msg, const error_code& ec) 75 : system_error(ec, msg) 76{ 77} 78 79ios_base::failure::failure(const char* msg, const error_code& ec) 80 : system_error(ec, msg) 81{ 82} 83 84ios_base::failure::~failure() throw() 85{ 86} 87 88// ios_base locale 89 90const ios_base::fmtflags ios_base::boolalpha; 91const ios_base::fmtflags ios_base::dec; 92const ios_base::fmtflags ios_base::fixed; 93const ios_base::fmtflags ios_base::hex; 94const ios_base::fmtflags ios_base::internal; 95const ios_base::fmtflags ios_base::left; 96const ios_base::fmtflags ios_base::oct; 97const ios_base::fmtflags ios_base::right; 98const ios_base::fmtflags ios_base::scientific; 99const ios_base::fmtflags ios_base::showbase; 100const ios_base::fmtflags ios_base::showpoint; 101const ios_base::fmtflags ios_base::showpos; 102const ios_base::fmtflags ios_base::skipws; 103const ios_base::fmtflags ios_base::unitbuf; 104const ios_base::fmtflags ios_base::uppercase; 105const ios_base::fmtflags ios_base::adjustfield; 106const ios_base::fmtflags ios_base::basefield; 107const ios_base::fmtflags ios_base::floatfield; 108 109const ios_base::iostate ios_base::badbit; 110const ios_base::iostate ios_base::eofbit; 111const ios_base::iostate ios_base::failbit; 112const ios_base::iostate ios_base::goodbit; 113 114const ios_base::openmode ios_base::app; 115const ios_base::openmode ios_base::ate; 116const ios_base::openmode ios_base::binary; 117const ios_base::openmode ios_base::in; 118const ios_base::openmode ios_base::out; 119const ios_base::openmode ios_base::trunc; 120 121void 122ios_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 133locale 134ios_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 144locale 145ios_base::getloc() const 146{ 147 const locale& loc_storage = *(locale*)&__loc_; 148 return loc_storage; 149} 150 151// xalloc 152#if __has_feature(cxx_atomic) 153atomic<int> ios_base::__xindex_ = ATOMIC_VAR_INIT(0); 154#else 155int ios_base::__xindex_ = 0; 156#endif 157 158int 159ios_base::xalloc() 160{ 161 return __xindex_++; 162} 163 164long& 165ios_base::iword(int index) 166{ 167 size_t req_size = static_cast<size_t>(index)+1; 168 if (req_size > __iarray_cap_) 169 { 170 size_t newcap; 171 const size_t mx = std::numeric_limits<size_t>::max(); 172 if (req_size < mx/2) 173 newcap = _VSTD::max(2 * __iarray_cap_, req_size); 174 else 175 newcap = mx; 176 long* iarray = (long*)realloc(__iarray_, newcap * sizeof(long)); 177 if (iarray == 0) 178 { 179 setstate(badbit); 180 static long error; 181 error = 0; 182 return error; 183 } 184 __iarray_ = iarray; 185 for (long* p = __iarray_ + __iarray_size_; __iarray_cap_ < newcap; ++__iarray_cap_, ++p) 186 *p = 0; 187 } 188 __iarray_size_ = max<size_t>(__iarray_size_, req_size); 189 return __iarray_[index]; 190} 191 192void*& 193ios_base::pword(int index) 194{ 195 size_t req_size = static_cast<size_t>(index)+1; 196 if (req_size > __parray_cap_) 197 { 198 size_t newcap; 199 const size_t mx = std::numeric_limits<size_t>::max(); 200 if (req_size < mx/2) 201 newcap = _VSTD::max(2 * __parray_cap_, req_size); 202 else 203 newcap = mx; 204 void** parray = (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_; __parray_cap_ < newcap; ++__parray_cap_, ++p) 214 *p = 0; 215 } 216 __parray_size_ = max<size_t>(__parray_size_, req_size); 217 return __parray_[index]; 218} 219 220// register_callback 221 222void 223ios_base::register_callback(event_callback fn, int index) 224{ 225 size_t req_size = __event_size_ + 1; 226 if (req_size > __event_cap_) 227 { 228 size_t newcap; 229 const size_t mx = std::numeric_limits<size_t>::max(); 230 if (req_size < mx/2) 231 newcap = _VSTD::max(2 * __event_cap_, req_size); 232 else 233 newcap = mx; 234 event_callback* fns = (event_callback*)realloc(__fn_, newcap * sizeof(event_callback)); 235 if (fns == 0) 236 setstate(badbit); 237 __fn_ = fns; 238 int* indxs = (int*)realloc(__index_, newcap * sizeof(int)); 239 if (indxs == 0) 240 setstate(badbit); 241 __index_ = indxs; 242 } 243 __fn_[__event_size_] = fn; 244 __index_[__event_size_] = index; 245 ++__event_size_; 246} 247 248ios_base::~ios_base() 249{ 250 __call_callbacks(erase_event); 251 locale& loc_storage = *(locale*)&__loc_; 252 loc_storage.~locale(); 253 free(__fn_); 254 free(__index_); 255 free(__iarray_); 256 free(__parray_); 257} 258 259// iostate 260 261void 262ios_base::clear(iostate state) 263{ 264 if (__rdbuf_) 265 __rdstate_ = state; 266 else 267 __rdstate_ = state | badbit; 268#ifndef _LIBCPP_NO_EXCEPTIONS 269 if (((state | (__rdbuf_ ? goodbit : badbit)) & __exceptions_) != 0) 270 throw failure("ios_base::clear"); 271#endif // _LIBCPP_NO_EXCEPTIONS 272} 273 274// init 275 276void 277ios_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 298void 299ios_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 aquired 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 new_callbacks.reset((event_callback*)malloc(sizeof(event_callback) * rhs.__event_size_)); 310#ifndef _LIBCPP_NO_EXCEPTIONS 311 if (!new_callbacks) 312 throw bad_alloc(); 313#endif // _LIBCPP_NO_EXCEPTIONS 314 new_ints.reset((int*)malloc(sizeof(int) * rhs.__event_size_)); 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 new_longs.reset((long*)malloc(sizeof(long) * rhs.__iarray_size_)); 323#ifndef _LIBCPP_NO_EXCEPTIONS 324 if (!new_longs) 325 throw bad_alloc(); 326#endif // _LIBCPP_NO_EXCEPTIONS 327 } 328 if (__parray_cap_ < rhs.__parray_size_) 329 { 330 new_pointers.reset((void**)malloc(sizeof(void*) * rhs.__parray_size_)); 331#ifndef _LIBCPP_NO_EXCEPTIONS 332 if (!new_pointers) 333 throw bad_alloc(); 334#endif // _LIBCPP_NO_EXCEPTIONS 335 } 336 // Got everything we need. Copy everything but __rdstate_, __rdbuf_ and __exceptions_ 337 __fmtflags_ = rhs.__fmtflags_; 338 __precision_ = rhs.__precision_; 339 __width_ = rhs.__width_; 340 locale& lhs_loc = *(locale*)&__loc_; 341 locale& rhs_loc = *(locale*)&rhs.__loc_; 342 lhs_loc = rhs_loc; 343 if (__event_cap_ < rhs.__event_size_) 344 { 345 free(__fn_); 346 __fn_ = new_callbacks.release(); 347 free(__index_); 348 __index_ = new_ints.release(); 349 __event_cap_ = rhs.__event_size_; 350 } 351 for (__event_size_ = 0; __event_size_ < rhs.__event_size_; ++__event_size_) 352 { 353 __fn_[__event_size_] = rhs.__fn_[__event_size_]; 354 __index_[__event_size_] = rhs.__index_[__event_size_]; 355 } 356 if (__iarray_cap_ < rhs.__iarray_size_) 357 { 358 free(__iarray_); 359 __iarray_ = new_longs.release(); 360 __iarray_cap_ = rhs.__iarray_size_; 361 } 362 for (__iarray_size_ = 0; __iarray_size_ < rhs.__iarray_size_; ++__iarray_size_) 363 __iarray_[__iarray_size_] = rhs.__iarray_[__iarray_size_]; 364 if (__parray_cap_ < rhs.__parray_size_) 365 { 366 free(__parray_); 367 __parray_ = new_pointers.release(); 368 __parray_cap_ = rhs.__parray_size_; 369 } 370 for (__parray_size_ = 0; __parray_size_ < rhs.__parray_size_; ++__parray_size_) 371 __parray_[__parray_size_] = rhs.__parray_[__parray_size_]; 372} 373 374void 375ios_base::move(ios_base& rhs) 376{ 377 // *this is uninitialized 378 __fmtflags_ = rhs.__fmtflags_; 379 __precision_ = rhs.__precision_; 380 __width_ = rhs.__width_; 381 __rdstate_ = rhs.__rdstate_; 382 __exceptions_ = rhs.__exceptions_; 383 __rdbuf_ = 0; 384 locale& rhs_loc = *(locale*)&rhs.__loc_; 385 ::new(&__loc_) locale(rhs_loc); 386 __fn_ = rhs.__fn_; 387 rhs.__fn_ = 0; 388 __index_ = rhs.__index_; 389 rhs.__index_ = 0; 390 __event_size_ = rhs.__event_size_; 391 rhs.__event_size_ = 0; 392 __event_cap_ = rhs.__event_cap_; 393 rhs.__event_cap_ = 0; 394 __iarray_ = rhs.__iarray_; 395 rhs.__iarray_ = 0; 396 __iarray_size_ = rhs.__iarray_size_; 397 rhs.__iarray_size_ = 0; 398 __iarray_cap_ = rhs.__iarray_cap_; 399 rhs.__iarray_cap_ = 0; 400 __parray_ = rhs.__parray_; 401 rhs.__parray_ = 0; 402 __parray_size_ = rhs.__parray_size_; 403 rhs.__parray_size_ = 0; 404 __parray_cap_ = rhs.__parray_cap_; 405 rhs.__parray_cap_ = 0; 406} 407 408void 409ios_base::swap(ios_base& rhs) _NOEXCEPT 410{ 411 _VSTD::swap(__fmtflags_, rhs.__fmtflags_); 412 _VSTD::swap(__precision_, rhs.__precision_); 413 _VSTD::swap(__width_, rhs.__width_); 414 _VSTD::swap(__rdstate_, rhs.__rdstate_); 415 _VSTD::swap(__exceptions_, rhs.__exceptions_); 416 locale& lhs_loc = *(locale*)&__loc_; 417 locale& rhs_loc = *(locale*)&rhs.__loc_; 418 _VSTD::swap(lhs_loc, rhs_loc); 419 _VSTD::swap(__fn_, rhs.__fn_); 420 _VSTD::swap(__index_, rhs.__index_); 421 _VSTD::swap(__event_size_, rhs.__event_size_); 422 _VSTD::swap(__event_cap_, rhs.__event_cap_); 423 _VSTD::swap(__iarray_, rhs.__iarray_); 424 _VSTD::swap(__iarray_size_, rhs.__iarray_size_); 425 _VSTD::swap(__iarray_cap_, rhs.__iarray_cap_); 426 _VSTD::swap(__parray_, rhs.__parray_); 427 _VSTD::swap(__parray_size_, rhs.__parray_size_); 428 _VSTD::swap(__parray_cap_, rhs.__parray_cap_); 429} 430 431void 432ios_base::__set_badbit_and_consider_rethrow() 433{ 434 __rdstate_ |= badbit; 435#ifndef _LIBCPP_NO_EXCEPTIONS 436 if (__exceptions_ & badbit) 437 throw; 438#endif // _LIBCPP_NO_EXCEPTIONS 439} 440 441void 442ios_base::__set_failbit_and_consider_rethrow() 443{ 444 __rdstate_ |= failbit; 445#ifndef _LIBCPP_NO_EXCEPTIONS 446 if (__exceptions_ & failbit) 447 throw; 448#endif // _LIBCPP_NO_EXCEPTIONS 449} 450 451bool 452ios_base::sync_with_stdio(bool sync) 453{ 454 static bool previous_state = true; 455 bool r = previous_state; 456 previous_state = sync; 457 return r; 458} 459 460_LIBCPP_END_NAMESPACE_STD 461