ios.cpp revision 227983
1254885Sdumbbell//===-------------------------- ios.cpp -----------------------------------===// 2254885Sdumbbell// 3254885Sdumbbell// The LLVM Compiler Infrastructure 4254885Sdumbbell// 5254885Sdumbbell// This file is dual licensed under the MIT and the University of Illinois Open 6254885Sdumbbell// Source Licenses. See LICENSE.TXT for details. 7254885Sdumbbell// 8254885Sdumbbell//===----------------------------------------------------------------------===// 9254885Sdumbbell 10254885Sdumbbell#include "ios" 11254885Sdumbbell#include "streambuf" 12254885Sdumbbell#include "istream" 13254885Sdumbbell#include "string" 14254885Sdumbbell#include "__locale" 15254885Sdumbbell#include "algorithm" 16254885Sdumbbell#include "memory" 17254885Sdumbbell#include "new" 18254885Sdumbbell#include "limits" 19254885Sdumbbell#include <stdlib.h> 20254885Sdumbbell 21254885Sdumbbell_LIBCPP_BEGIN_NAMESPACE_STD 22254885Sdumbbell 23254885Sdumbbelltemplate class basic_ios<char>; 24254885Sdumbbelltemplate class basic_ios<wchar_t>; 25254885Sdumbbell 26254885Sdumbbelltemplate class basic_streambuf<char>; 27254885Sdumbbelltemplate class basic_streambuf<wchar_t>; 28254885Sdumbbell 29254885Sdumbbelltemplate class basic_istream<char>; 30254885Sdumbbelltemplate class basic_istream<wchar_t>; 31254885Sdumbbell 32254885Sdumbbelltemplate class basic_ostream<char>; 33254885Sdumbbelltemplate class basic_ostream<wchar_t>; 34254885Sdumbbell 35254885Sdumbbelltemplate class basic_iostream<char>; 36254885Sdumbbell 37254885Sdumbbellclass _LIBCPP_HIDDEN __iostream_category 38254885Sdumbbell : public __do_message 39254885Sdumbbell{ 40254885Sdumbbellpublic: 41254885Sdumbbell virtual const char* name() const _NOEXCEPT; 42254885Sdumbbell virtual string message(int ev) const; 43254885Sdumbbell}; 44254885Sdumbbell 45254885Sdumbbellconst char* 46254885Sdumbbell__iostream_category::name() const _NOEXCEPT 47254885Sdumbbell{ 48254885Sdumbbell return "iostream"; 49254885Sdumbbell} 50254885Sdumbbell 51254885Sdumbbellstring 52254885Sdumbbell__iostream_category::message(int ev) const 53254885Sdumbbell{ 54254885Sdumbbell if (ev != static_cast<int>(io_errc::stream) 55254885Sdumbbell#ifdef ELAST 56254885Sdumbbell && ev <= ELAST 57254885Sdumbbell#endif 58254885Sdumbbell ) 59254885Sdumbbell return __do_message::message(ev); 60254885Sdumbbell return string("unspecified iostream_category error"); 61254885Sdumbbell} 62254885Sdumbbell 63254885Sdumbbellconst error_category& 64254885Sdumbbelliostream_category() 65254885Sdumbbell{ 66254885Sdumbbell static __iostream_category s; 67254885Sdumbbell return s; 68254885Sdumbbell} 69254885Sdumbbell 70254885Sdumbbell// ios_base::failure 71254885Sdumbbell 72254885Sdumbbellios_base::failure::failure(const string& msg, const error_code& ec) 73254885Sdumbbell : system_error(ec, msg) 74254885Sdumbbell{ 75254885Sdumbbell} 76254885Sdumbbell 77254885Sdumbbellios_base::failure::failure(const char* msg, const error_code& ec) 78254885Sdumbbell : system_error(ec, msg) 79254885Sdumbbell{ 80254885Sdumbbell} 81254885Sdumbbell 82254885Sdumbbellios_base::failure::~failure() throw() 83254885Sdumbbell{ 84254885Sdumbbell} 85254885Sdumbbell 86254885Sdumbbell// ios_base locale 87254885Sdumbbell 88254885Sdumbbellconst ios_base::fmtflags ios_base::boolalpha; 89254885Sdumbbellconst ios_base::fmtflags ios_base::dec; 90254885Sdumbbellconst ios_base::fmtflags ios_base::fixed; 91254885Sdumbbellconst ios_base::fmtflags ios_base::hex; 92254885Sdumbbellconst ios_base::fmtflags ios_base::internal; 93254885Sdumbbellconst ios_base::fmtflags ios_base::left; 94254885Sdumbbellconst ios_base::fmtflags ios_base::oct; 95254885Sdumbbellconst ios_base::fmtflags ios_base::right; 96254885Sdumbbellconst ios_base::fmtflags ios_base::scientific; 97254885Sdumbbellconst ios_base::fmtflags ios_base::showbase; 98254885Sdumbbellconst ios_base::fmtflags ios_base::showpoint; 99254885Sdumbbellconst ios_base::fmtflags ios_base::showpos; 100254885Sdumbbellconst ios_base::fmtflags ios_base::skipws; 101254885Sdumbbellconst ios_base::fmtflags ios_base::unitbuf; 102254885Sdumbbellconst ios_base::fmtflags ios_base::uppercase; 103254885Sdumbbellconst ios_base::fmtflags ios_base::adjustfield; 104254885Sdumbbellconst ios_base::fmtflags ios_base::basefield; 105254885Sdumbbellconst ios_base::fmtflags ios_base::floatfield; 106254885Sdumbbell 107254885Sdumbbellconst ios_base::iostate ios_base::badbit; 108254885Sdumbbellconst ios_base::iostate ios_base::eofbit; 109254885Sdumbbellconst ios_base::iostate ios_base::failbit; 110254885Sdumbbellconst ios_base::iostate ios_base::goodbit; 111254885Sdumbbell 112254885Sdumbbellconst ios_base::openmode ios_base::app; 113254885Sdumbbellconst ios_base::openmode ios_base::ate; 114254885Sdumbbellconst ios_base::openmode ios_base::binary; 115254885Sdumbbellconst ios_base::openmode ios_base::in; 116254885Sdumbbellconst ios_base::openmode ios_base::out; 117254885Sdumbbellconst ios_base::openmode ios_base::trunc; 118254885Sdumbbell 119254885Sdumbbellvoid 120254885Sdumbbellios_base::__call_callbacks(event ev) 121254885Sdumbbell{ 122254885Sdumbbell for (size_t i = __event_size_; i;) 123254885Sdumbbell { 124254885Sdumbbell --i; 125254885Sdumbbell __fn_[i](ev, *this, __index_[i]); 126254885Sdumbbell } 127254885Sdumbbell} 128254885Sdumbbell 129254885Sdumbbell// locale 130254885Sdumbbell 131254885Sdumbbelllocale 132254885Sdumbbellios_base::imbue(const locale& newloc) 133254885Sdumbbell{ 134254885Sdumbbell static_assert(sizeof(locale) == sizeof(__loc_), ""); 135254885Sdumbbell locale& loc_storage = *(locale*)&__loc_; 136254885Sdumbbell locale oldloc = loc_storage; 137254885Sdumbbell loc_storage = newloc; 138254885Sdumbbell __call_callbacks(imbue_event); 139254885Sdumbbell return oldloc; 140254885Sdumbbell} 141254885Sdumbbell 142254885Sdumbbelllocale 143254885Sdumbbellios_base::getloc() const 144254885Sdumbbell{ 145254885Sdumbbell const locale& loc_storage = *(locale*)&__loc_; 146254885Sdumbbell return loc_storage; 147254885Sdumbbell} 148254885Sdumbbell 149254885Sdumbbell// xalloc 150254885Sdumbbell 151254885Sdumbbellint ios_base::__xindex_ = 0; 152254885Sdumbbell 153254885Sdumbbellint 154254885Sdumbbellios_base::xalloc() 155254885Sdumbbell{ 156254885Sdumbbell return __xindex_++; 157254885Sdumbbell} 158254885Sdumbbell 159254885Sdumbbelllong& 160254885Sdumbbellios_base::iword(int index) 161254885Sdumbbell{ 162254885Sdumbbell size_t req_size = static_cast<size_t>(index)+1; 163254885Sdumbbell if (req_size > __iarray_cap_) 164254885Sdumbbell { 165254885Sdumbbell size_t newcap; 166254885Sdumbbell const size_t mx = std::numeric_limits<size_t>::max(); 167254885Sdumbbell if (req_size < mx/2) 168254885Sdumbbell newcap = _VSTD::max(2 * __iarray_cap_, req_size); 169254885Sdumbbell else 170254885Sdumbbell newcap = mx; 171254885Sdumbbell long* iarray = (long*)realloc(__iarray_, newcap * sizeof(long)); 172254885Sdumbbell if (iarray == 0) 173254885Sdumbbell { 174254885Sdumbbell setstate(badbit); 175254885Sdumbbell static long error; 176254885Sdumbbell error = 0; 177254885Sdumbbell return error; 178254885Sdumbbell } 179254885Sdumbbell __iarray_ = iarray; 180254885Sdumbbell for (long* p = __iarray_ + __iarray_size_; __iarray_cap_ < newcap; ++__iarray_cap_, ++p) 181254885Sdumbbell *p = 0; 182254885Sdumbbell } 183254885Sdumbbell __iarray_size_ = max<size_t>(__iarray_size_, req_size); 184254885Sdumbbell return __iarray_[index]; 185254885Sdumbbell} 186254885Sdumbbell 187254885Sdumbbellvoid*& 188254885Sdumbbellios_base::pword(int index) 189254885Sdumbbell{ 190254885Sdumbbell size_t req_size = static_cast<size_t>(index)+1; 191254885Sdumbbell if (req_size > __parray_cap_) 192254885Sdumbbell { 193254885Sdumbbell size_t newcap; 194254885Sdumbbell const size_t mx = std::numeric_limits<size_t>::max(); 195254885Sdumbbell if (req_size < mx/2) 196254885Sdumbbell newcap = _VSTD::max(2 * __parray_cap_, req_size); 197254885Sdumbbell else 198254885Sdumbbell newcap = mx; 199254885Sdumbbell void** parray = (void**)realloc(__parray_, newcap * sizeof(void*)); 200254885Sdumbbell if (parray == 0) 201254885Sdumbbell { 202254885Sdumbbell setstate(badbit); 203254885Sdumbbell static void* error; 204254885Sdumbbell error = 0; 205254885Sdumbbell return error; 206254885Sdumbbell } 207254885Sdumbbell __parray_ = parray; 208254885Sdumbbell for (void** p = __parray_ + __parray_size_; __parray_cap_ < newcap; ++__parray_cap_, ++p) 209254885Sdumbbell *p = 0; 210254885Sdumbbell } 211254885Sdumbbell __parray_size_ = max<size_t>(__parray_size_, req_size); 212254885Sdumbbell return __parray_[index]; 213254885Sdumbbell} 214254885Sdumbbell 215254885Sdumbbell// register_callback 216254885Sdumbbell 217254885Sdumbbellvoid 218ios_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 243ios_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 256void 257ios_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 271void 272ios_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 293void 294ios_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 369void 370ios_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 403void 404ios_base::swap(ios_base& rhs) 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 426void 427ios_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 436void 437ios_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 446bool 447ios_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