/* * Copyright (c) 1999 * Silicon Graphics Computer Systems, Inc. * * Copyright (c) 1999 * Boris Fomitchev * * This material is provided "as is", with absolutely no warranty expressed * or implied. Any use is at your own risk. * * Permission to use or copy this software for any purpose is hereby granted * without fee, provided the above notices are retained on all copies. * Permission to modify the code and to distribute modified code is granted, * provided the above notices are retained, and a notice that the code was * modified is included with the above copyright notice. * */ #include "stlport_prefix.h" #include <algorithm> #include <ios> #include <locale> #include <ostream> // for __get_ostreambuf definition #include "aligned_buffer.h" _STLP_BEGIN_NAMESPACE //---------------------------------------------------------------------- // ios_base members #ifdef _STLP_USE_EXCEPTIONS // class ios_base::failure, a subclass of exception. It's used solely // for reporting errors. ios_base::failure::failure(const string& s) : __Named_exception(s) {} ios_base::failure::~failure() _STLP_NOTHROW_INHERENTLY {} #endif #if !defined (_STLP_STATIC_CONST_INIT_BUG) && !defined (_STLP_NO_STATIC_CONST_DEFINITION) // Definitions of ios_base's formatting flags. const ios_base::fmtflags ios_base::left; const ios_base::fmtflags ios_base::right; const ios_base::fmtflags ios_base::internal; const ios_base::fmtflags ios_base::dec; const ios_base::fmtflags ios_base::hex; const ios_base::fmtflags ios_base::oct; const ios_base::fmtflags ios_base::fixed; const ios_base::fmtflags ios_base::scientific; const ios_base::fmtflags ios_base::boolalpha; const ios_base::fmtflags ios_base::showbase; const ios_base::fmtflags ios_base::showpoint; const ios_base::fmtflags ios_base::showpos; const ios_base::fmtflags ios_base::skipws; const ios_base::fmtflags ios_base::unitbuf; const ios_base::fmtflags ios_base::uppercase; const ios_base::fmtflags ios_base::adjustfield; const ios_base::fmtflags ios_base::basefield; const ios_base::fmtflags ios_base::floatfield; // Definitions of ios_base's state flags. const ios_base::iostate ios_base::goodbit; const ios_base::iostate ios_base::badbit; const ios_base::iostate ios_base::eofbit; const ios_base::iostate ios_base::failbit; // Definitions of ios_base's openmode flags. const ios_base::openmode ios_base::app; const ios_base::openmode ios_base::ate; const ios_base::openmode ios_base::binary; const ios_base::openmode ios_base::in; const ios_base::openmode ios_base::out; const ios_base::openmode ios_base::trunc; // Definitions of ios_base's seekdir flags. const ios_base::seekdir ios_base::beg; const ios_base::seekdir ios_base::cur; const ios_base::seekdir ios_base::end; #endif // Internal functions used for managing exponentially-growing arrays of // POD types. // array is a pointer to N elements of type PODType. Expands the array, // if necessary, so that array[index] is meaningful. All new elements are // initialized to zero. Returns a pointer to the new array, and the new // size. template <class PODType> static pair<PODType*, size_t> _Stl_expand_array(PODType* __array, size_t N, int index) { if ((int)N < index + 1) { size_t new_N = (max)(2 * N, size_t(index + 1)); PODType* new_array = __STATIC_CAST(PODType*,realloc(__array, new_N * sizeof(PODType))); if (new_array) { fill(new_array + N, new_array + new_N, PODType()); return pair<PODType*, size_t>(new_array, new_N); } else return pair<PODType*, size_t>(__STATIC_CAST(PODType*,0), 0); } else return pair<PODType*, size_t>(__array, N); } // array is a pointer to N elements of type PODType. Allocate a new // array of N elements, copying the values from the old array to the new. // Return a pointer to the new array. It is assumed that array is non-null // and N is nonzero. template <class PODType> static PODType* _Stl_copy_array(const PODType* __array, size_t N) { PODType* result = __STATIC_CAST(PODType*,malloc(N * sizeof(PODType))); if (result) copy(__array, __array + N, result); return result; } locale ios_base::imbue(const locale& loc) { if (loc != _M_locale) { locale previous = _M_locale; _M_locale = loc; _M_invoke_callbacks(imbue_event); return previous; } else { _M_invoke_callbacks(imbue_event); return _M_locale; } } int _STLP_CALL ios_base::xalloc() { #if defined (_STLP_THREADS) && \ defined (_STLP_WIN32THREADS) && defined (_STLP_NEW_PLATFORM_SDK) static volatile __stl_atomic_t _S_index = 0; return _STLP_ATOMIC_INCREMENT(&_S_index); #else static int _S_index = 0; static _STLP_STATIC_MUTEX __lock _STLP_MUTEX_INITIALIZER; _STLP_auto_lock sentry(__lock); return _S_index++; #endif } long& ios_base::iword(int index) { static long dummy = 0; pair<long*, size_t> tmp = _Stl_expand_array(_M_iwords, _M_num_iwords, index); if (tmp.first) { // The allocation, if any, succeeded. _M_iwords = tmp.first; _M_num_iwords = tmp.second; return _M_iwords[index]; } else { _M_setstate_nothrow(badbit); _M_check_exception_mask(); return dummy; } } void*& ios_base::pword(int index) { static void* dummy = 0; pair<void**, size_t> tmp = _Stl_expand_array(_M_pwords, _M_num_pwords, index); if (tmp.first) { // The allocation, if any, succeeded. _M_pwords = tmp.first; _M_num_pwords = tmp.second; return _M_pwords[index]; } else { _M_setstate_nothrow(badbit); _M_check_exception_mask(); return dummy; } } void ios_base::register_callback(event_callback __fn, int index) { pair<pair<event_callback, int>*, size_t> tmp = _Stl_expand_array(_M_callbacks, _M_num_callbacks, (int)_M_callback_index /* fbp: index ??? */ ); if (tmp.first) { _M_callbacks = tmp.first; _M_num_callbacks = tmp.second; _M_callbacks[_M_callback_index++] = make_pair(__fn, index); } else { _M_setstate_nothrow(badbit); _M_check_exception_mask(); } } // Invokes all currently registered callbacks for a particular event. // Behaves correctly even if one of the callbacks adds a new callback. void ios_base::_M_invoke_callbacks(event E) { for (size_t i = _M_callback_index; i > 0; --i) { event_callback f = _M_callbacks[i-1].first; int n = _M_callbacks[i-1].second; f(E, *this, n); } } // This function is called if the state, rdstate(), has a bit set // that is also set in the exception mask exceptions(). void ios_base::_M_throw_failure() { const char* arg ; # if 0 char buffer[256]; char* ptr; strcpy(buffer, "ios failure: rdstate = 0x"); ptr = __write_integer(buffer+strlen(buffer), ios_base::hex, __STATIC_CAST(unsigned long,_M_iostate)); strcpy(ptr, " mask = 0x"); ptr = __write_integer(buffer+strlen(buffer), ios_base::hex, __STATIC_CAST(unsigned long,_M_exception_mask)); *ptr = 0; arg = buffer; # else arg = "ios failure"; # endif # ifndef _STLP_USE_EXCEPTIONS fputs(arg, stderr); # else throw failure(arg); # endif } // Copy x's state to *this. This member function is used in the // implementation of basic_ios::copyfmt. Does not copy _M_exception_mask // or _M_iostate. void ios_base::_M_copy_state(const ios_base& x) { _M_fmtflags = x._M_fmtflags; // Copy the flags, except for _M_iostate _M_openmode = x._M_openmode; // and _M_exception_mask. _M_seekdir = x._M_seekdir; _M_precision = x._M_precision; _M_width = x._M_width; _M_locale = x._M_locale; if (x._M_callbacks) { pair<event_callback, int>* tmp = _Stl_copy_array(x._M_callbacks, x._M_callback_index); if (tmp) { free(_M_callbacks); _M_callbacks = tmp; _M_num_callbacks = _M_callback_index = x._M_callback_index; } else { _M_setstate_nothrow(badbit); _M_check_exception_mask(); } } if (x._M_iwords) { long* tmp = _Stl_copy_array(x._M_iwords, x._M_num_iwords); if (tmp) { free(_M_iwords); _M_iwords = tmp; _M_num_iwords = x._M_num_iwords; } else { _M_setstate_nothrow(badbit); _M_check_exception_mask(); } } if (x._M_pwords) { void** tmp = _Stl_copy_array(x._M_pwords, x._M_num_pwords); if (tmp) { free(_M_pwords); _M_pwords = tmp; _M_num_pwords = x._M_num_pwords; } else { _M_setstate_nothrow(badbit); _M_check_exception_mask(); } } } // ios's (protected) default constructor. The standard says that all // fields have indeterminate values; we initialize them to zero for // simplicity. The only thing that really matters is that the arrays // are all initially null pointers, and the array element counts are all // initially zero. ios_base::ios_base() : _M_fmtflags(0), _M_iostate(0), _M_openmode(0), _M_seekdir(0), _M_exception_mask(0), _M_precision(0), _M_width(0), _M_locale(), _M_callbacks(0), _M_num_callbacks(0), _M_callback_index(0), _M_iwords(0), _M_num_iwords(0), _M_pwords(0), _M_num_pwords(0) {} // ios's destructor. ios_base::~ios_base() { _M_invoke_callbacks(erase_event); free(_M_callbacks); free(_M_iwords); free(_M_pwords); } //---------------------------------------------------------------------- // Force instantiation of basic_ios // For DLL exports, they are already instantiated. #if !defined(_STLP_NO_FORCE_INSTANTIATE) template class _STLP_CLASS_DECLSPEC basic_ios<char, char_traits<char> >; # if !defined (_STLP_NO_WCHAR_T) template class _STLP_CLASS_DECLSPEC basic_ios<wchar_t, char_traits<wchar_t> >; # endif /* _STLP_NO_WCHAR_T */ #endif _STLP_END_NAMESPACE // Local Variables: // mode:C++ // End: