1/* 2 * Copyright (c) 1999 3 * Silicon Graphics Computer Systems, Inc. 4 * 5 * Copyright (c) 1999 6 * Boris Fomitchev 7 * 8 * This material is provided "as is", with absolutely no warranty expressed 9 * or implied. Any use is at your own risk. 10 * 11 * Permission to use or copy this software for any purpose is hereby granted 12 * without fee, provided the above notices are retained on all copies. 13 * Permission to modify the code and to distribute modified code is granted, 14 * provided the above notices are retained, and a notice that the code was 15 * modified is included with the above copyright notice. 16 * 17 */ 18 19#include "stlport_prefix.h" 20 21#include <algorithm> 22#include <ios> 23#include <locale> 24#include <ostream> // for __get_ostreambuf definition 25 26#include "aligned_buffer.h" 27 28_STLP_BEGIN_NAMESPACE 29 30//---------------------------------------------------------------------- 31// ios_base members 32 33// class ios_base::failure, a subclass of exception. It's used solely 34// for reporting errors. 35 36ios_base::failure::failure(const string& s) 37 : __Named_exception(s) 38{} 39 40ios_base::failure::~failure() _STLP_NOTHROW_INHERENTLY {} 41 42#if !defined (_STLP_STATIC_CONST_INIT_BUG) && !defined (_STLP_NO_STATIC_CONST_DEFINITION) 43// Definitions of ios_base's formatting flags. 44const ios_base::fmtflags ios_base::left; 45const ios_base::fmtflags ios_base::right; 46const ios_base::fmtflags ios_base::internal; 47const ios_base::fmtflags ios_base::dec; 48const ios_base::fmtflags ios_base::hex; 49const ios_base::fmtflags ios_base::oct; 50const ios_base::fmtflags ios_base::fixed; 51const ios_base::fmtflags ios_base::scientific; 52const ios_base::fmtflags ios_base::boolalpha; 53const ios_base::fmtflags ios_base::showbase; 54const ios_base::fmtflags ios_base::showpoint; 55const ios_base::fmtflags ios_base::showpos; 56const ios_base::fmtflags ios_base::skipws; 57const ios_base::fmtflags ios_base::unitbuf; 58const ios_base::fmtflags ios_base::uppercase; 59const ios_base::fmtflags ios_base::adjustfield; 60const ios_base::fmtflags ios_base::basefield; 61const ios_base::fmtflags ios_base::floatfield; 62 63// Definitions of ios_base's state flags. 64const ios_base::iostate ios_base::goodbit; 65const ios_base::iostate ios_base::badbit; 66const ios_base::iostate ios_base::eofbit; 67const ios_base::iostate ios_base::failbit; 68 69// Definitions of ios_base's openmode flags. 70const ios_base::openmode ios_base::app; 71const ios_base::openmode ios_base::ate; 72const ios_base::openmode ios_base::binary; 73const ios_base::openmode ios_base::in; 74const ios_base::openmode ios_base::out; 75const ios_base::openmode ios_base::trunc; 76 77// Definitions of ios_base's seekdir flags. 78const ios_base::seekdir ios_base::beg; 79const ios_base::seekdir ios_base::cur; 80const ios_base::seekdir ios_base::end; 81 82#endif 83 84// Internal functions used for managing exponentially-growing arrays of 85// POD types. 86 87// array is a pointer to N elements of type PODType. Expands the array, 88// if necessary, so that array[index] is meaningful. All new elements are 89// initialized to zero. Returns a pointer to the new array, and the new 90// size. 91 92template <class PODType> 93static pair<PODType*, size_t> 94_Stl_expand_array(PODType* __array, size_t N, int index) { 95 if ((int)N < index + 1) { 96 size_t new_N = (max)(2 * N, size_t(index + 1)); 97 PODType* new_array 98 = __STATIC_CAST(PODType*,realloc(__array, new_N * sizeof(PODType))); 99 if (new_array) { 100 fill(new_array + N, new_array + new_N, PODType()); 101 return pair<PODType*, size_t>(new_array, new_N); 102 } 103 else 104 return pair<PODType*, size_t>(__STATIC_CAST(PODType*,0), 0); 105 } 106 else 107 return pair<PODType*, size_t>(__array, N); 108} 109 110// array is a pointer to N elements of type PODType. Allocate a new 111// array of N elements, copying the values from the old array to the new. 112// Return a pointer to the new array. It is assumed that array is non-null 113// and N is nonzero. 114template <class PODType> 115static PODType* _Stl_copy_array(const PODType* __array, size_t N) { 116 PODType* result = __STATIC_CAST(PODType*,malloc(N * sizeof(PODType))); 117 if (result) 118 copy(__array, __array + N, result); 119 return result; 120} 121 122locale ios_base::imbue(const locale& loc) { 123 if (loc != _M_locale) { 124 locale previous = _M_locale; 125 _M_locale = loc; 126 _M_invoke_callbacks(imbue_event); 127 return previous; 128 } 129 else { 130 _M_invoke_callbacks(imbue_event); 131 return _M_locale; 132 } 133} 134 135int _STLP_CALL ios_base::xalloc() { 136#if defined (_STLP_THREADS) && \ 137 defined (_STLP_WIN32THREADS) && defined (_STLP_NEW_PLATFORM_SDK) 138 static volatile __stl_atomic_t _S_index = 0; 139 return _STLP_ATOMIC_INCREMENT(&_S_index); 140#else 141 static int _S_index = 0; 142 static _STLP_STATIC_MUTEX __lock _STLP_MUTEX_INITIALIZER; 143 _STLP_auto_lock sentry(__lock); 144 return _S_index++; 145#endif 146} 147 148long& ios_base::iword(int index) { 149 static long dummy = 0; 150 151 pair<long*, size_t> tmp = _Stl_expand_array(_M_iwords, _M_num_iwords, index); 152 if (tmp.first) { // The allocation, if any, succeeded. 153 _M_iwords = tmp.first; 154 _M_num_iwords = tmp.second; 155 return _M_iwords[index]; 156 } 157 else { 158 _M_setstate_nothrow(badbit); 159 _M_check_exception_mask(); 160 return dummy; 161 } 162} 163 164 165void*& ios_base::pword(int index) { 166 static void* dummy = 0; 167 168 pair<void**, size_t> tmp = _Stl_expand_array(_M_pwords, _M_num_pwords, index); 169 if (tmp.first) { // The allocation, if any, succeeded. 170 _M_pwords = tmp.first; 171 _M_num_pwords = tmp.second; 172 return _M_pwords[index]; 173 } 174 else { 175 _M_setstate_nothrow(badbit); 176 _M_check_exception_mask(); 177 return dummy; 178 } 179} 180 181void ios_base::register_callback(event_callback __fn, int index) { 182 pair<pair<event_callback, int>*, size_t> tmp 183 = _Stl_expand_array(_M_callbacks, _M_num_callbacks, (int)_M_callback_index /* fbp: index ??? */ ); 184 if (tmp.first) { 185 _M_callbacks = tmp.first; 186 _M_num_callbacks = tmp.second; 187 _M_callbacks[_M_callback_index++] = make_pair(__fn, index); 188 } 189 else { 190 _M_setstate_nothrow(badbit); 191 _M_check_exception_mask(); 192 } 193} 194 195// Invokes all currently registered callbacks for a particular event. 196// Behaves correctly even if one of the callbacks adds a new callback. 197void ios_base::_M_invoke_callbacks(event E) { 198 for (size_t i = _M_callback_index; i > 0; --i) { 199 event_callback f = _M_callbacks[i-1].first; 200 int n = _M_callbacks[i-1].second; 201 f(E, *this, n); 202 } 203} 204 205// This function is called if the state, rdstate(), has a bit set 206// that is also set in the exception mask exceptions(). 207void ios_base::_M_throw_failure() { 208 const char* arg ; 209# if 0 210 char buffer[256]; 211 char* ptr; 212 strcpy(buffer, "ios failure: rdstate = 0x"); 213 ptr = __write_integer(buffer+strlen(buffer), ios_base::hex, __STATIC_CAST(unsigned long,_M_iostate)); 214 strcpy(ptr, " mask = 0x"); 215 ptr = __write_integer(buffer+strlen(buffer), ios_base::hex, __STATIC_CAST(unsigned long,_M_exception_mask)); 216 *ptr = 0; 217 arg = buffer; 218# else 219 arg = "ios failure"; 220# endif 221 222# ifndef _STLP_USE_EXCEPTIONS 223 fputs(arg, stderr); 224# else 225 throw failure(arg); 226# endif 227} 228 229// Copy x's state to *this. This member function is used in the 230// implementation of basic_ios::copyfmt. Does not copy _M_exception_mask 231// or _M_iostate. 232void ios_base::_M_copy_state(const ios_base& x) { 233 _M_fmtflags = x._M_fmtflags; // Copy the flags, except for _M_iostate 234 _M_openmode = x._M_openmode; // and _M_exception_mask. 235 _M_seekdir = x._M_seekdir; 236 _M_precision = x._M_precision; 237 _M_width = x._M_width; 238 _M_locale = x._M_locale; 239 240 if (x._M_callbacks) { 241 pair<event_callback, int>* tmp = _Stl_copy_array(x._M_callbacks, x._M_callback_index); 242 if (tmp) { 243 free(_M_callbacks); 244 _M_callbacks = tmp; 245 _M_num_callbacks = _M_callback_index = x._M_callback_index; 246 } 247 else { 248 _M_setstate_nothrow(badbit); 249 _M_check_exception_mask(); 250 } 251 } 252 253 if (x._M_iwords) { 254 long* tmp = _Stl_copy_array(x._M_iwords, x._M_num_iwords); 255 if (tmp) { 256 free(_M_iwords); 257 _M_iwords = tmp; 258 _M_num_iwords = x._M_num_iwords; 259 } 260 else { 261 _M_setstate_nothrow(badbit); 262 _M_check_exception_mask(); 263 } 264 } 265 266 if (x._M_pwords) { 267 void** tmp = _Stl_copy_array(x._M_pwords, x._M_num_pwords); 268 if (tmp) { 269 free(_M_pwords); 270 _M_pwords = tmp; 271 _M_num_pwords = x._M_num_pwords; 272 } 273 else { 274 _M_setstate_nothrow(badbit); 275 _M_check_exception_mask(); 276 } 277 } 278} 279 280// ios's (protected) default constructor. The standard says that all 281// fields have indeterminate values; we initialize them to zero for 282// simplicity. The only thing that really matters is that the arrays 283// are all initially null pointers, and the array element counts are all 284// initially zero. 285ios_base::ios_base() 286 : _M_fmtflags(0), _M_iostate(0), _M_openmode(0), _M_seekdir(0), 287 _M_exception_mask(0), 288 _M_precision(0), _M_width(0), 289 _M_locale(), 290 _M_callbacks(0), _M_num_callbacks(0), _M_callback_index(0), 291 _M_iwords(0), _M_num_iwords(0), 292 _M_pwords(0), 293 _M_num_pwords(0) 294{} 295 296// ios's destructor. 297ios_base::~ios_base() { 298 _M_invoke_callbacks(erase_event); 299 free(_M_callbacks); 300 free(_M_iwords); 301 free(_M_pwords); 302} 303 304//---------------------------------------------------------------------- 305// Force instantiation of basic_ios 306// For DLL exports, they are already instantiated. 307#if !defined(_STLP_NO_FORCE_INSTANTIATE) 308template class _STLP_CLASS_DECLSPEC basic_ios<char, char_traits<char> >; 309# if !defined (_STLP_NO_WCHAR_T) 310template class _STLP_CLASS_DECLSPEC basic_ios<wchar_t, char_traits<wchar_t> >; 311# endif /* _STLP_NO_WCHAR_T */ 312#endif 313 314_STLP_END_NAMESPACE 315 316// Local Variables: 317// mode:C++ 318// End: 319