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