/home/ntakagi/work/STLport-5.1.5/src/ios.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1999
00003  * Silicon Graphics Computer Systems, Inc.
00004  *
00005  * Copyright (c) 1999
00006  * Boris Fomitchev
00007  *
00008  * This material is provided "as is", with absolutely no warranty expressed
00009  * or implied. Any use is at your own risk.
00010  *
00011  * Permission to use or copy this software for any purpose is hereby granted
00012  * without fee, provided the above notices are retained on all copies.
00013  * Permission to modify the code and to distribute modified code is granted,
00014  * provided the above notices are retained, and a notice that the code was
00015  * modified is included with the above copyright notice.
00016  *
00017  */
00018 
00019 #include "stlport_prefix.h"
00020 
00021 #include <algorithm>
00022 #include <ios>
00023 #include <locale>
00024 #include <ostream> // for __get_ostreambuf definition
00025 
00026 #include "aligned_buffer.h"
00027 
00028 _STLP_BEGIN_NAMESPACE
00029 
00030 //----------------------------------------------------------------------
00031 // ios_base members
00032 
00033 // class ios_base::failure, a subclass of exception.  It's used solely
00034 // for reporting errors.
00035 
00036 ios_base::failure::failure(const string& s)
00037   : __Named_exception(s)
00038 {}
00039 
00040 ios_base::failure::~failure() _STLP_NOTHROW_INHERENTLY {}
00041 
00042 #if !defined (_STLP_STATIC_CONST_INIT_BUG)
00043 
00044 // Definitions of ios_base's formatting flags.
00045 const ios_base::fmtflags ios_base::left;
00046 const ios_base::fmtflags ios_base::right;
00047 const ios_base::fmtflags ios_base::internal;
00048 const ios_base::fmtflags ios_base::dec;
00049 const ios_base::fmtflags ios_base::hex;
00050 const ios_base::fmtflags ios_base::oct;
00051 const ios_base::fmtflags ios_base::fixed;
00052 const ios_base::fmtflags ios_base::scientific;
00053 const ios_base::fmtflags ios_base::boolalpha;
00054 const ios_base::fmtflags ios_base::showbase;
00055 const ios_base::fmtflags ios_base::showpoint;
00056 const ios_base::fmtflags ios_base::showpos;
00057 const ios_base::fmtflags ios_base::skipws;
00058 const ios_base::fmtflags ios_base::unitbuf;
00059 const ios_base::fmtflags ios_base::uppercase;
00060 const ios_base::fmtflags ios_base::adjustfield;
00061 const ios_base::fmtflags ios_base::basefield;
00062 const ios_base::fmtflags ios_base::floatfield;
00063 
00064 // Definitions of ios_base's state flags.
00065 const ios_base::iostate ios_base::goodbit;
00066 const ios_base::iostate ios_base::badbit;
00067 const ios_base::iostate ios_base::eofbit;
00068 const ios_base::iostate ios_base::failbit;
00069 
00070 // Definitions of ios_base's openmode flags.
00071 const ios_base::openmode ios_base::app;
00072 const ios_base::openmode ios_base::ate;
00073 const ios_base::openmode ios_base::binary;
00074 const ios_base::openmode ios_base::in;
00075 const ios_base::openmode ios_base::out;
00076 const ios_base::openmode ios_base::trunc;
00077 
00078 // Definitions of ios_base's seekdir flags.
00079 const ios_base::seekdir ios_base::beg;
00080 const ios_base::seekdir ios_base::cur;
00081 const ios_base::seekdir ios_base::end;
00082 
00083 #endif /*  _STLP_STATIC_CONST_INIT_BUG */
00084 
00085 // Internal functions used for managing exponentially-growing arrays of
00086 // POD types.
00087 
00088 // array is a pointer to N elements of type PODType.  Expands the array,
00089 // if necessary, so that array[index] is meaningful.  All new elements are
00090 // initialized to zero.  Returns a pointer to the new array, and the new
00091 // size.
00092 
00093 template <class PODType>
00094 static pair<PODType*, size_t>
00095 _Stl_expand_array(PODType* __array, size_t N, int index) {
00096   if ((int)N < index + 1) {
00097     size_t new_N = (max)(2 * N, size_t(index + 1));
00098     PODType* new_array
00099       = __STATIC_CAST(PODType*,realloc(__array, new_N * sizeof(PODType)));
00100     if (new_array) {
00101       fill(new_array + N, new_array + new_N, PODType());
00102       return pair<PODType*, size_t>(new_array, new_N);
00103     }
00104     else
00105       return pair<PODType*, size_t>(__STATIC_CAST(PODType*,0), 0);
00106   }
00107   else
00108     return pair<PODType*, size_t>(__array, N);
00109 }
00110 
00111 // array is a pointer to N elements of type PODType.  Allocate a new
00112 // array of N elements, copying the values from the old array to the new.
00113 // Return a pointer to the new array.  It is assumed that array is non-null
00114 // and N is nonzero.
00115 template <class PODType>
00116 static PODType* _Stl_copy_array(const PODType* __array, size_t N) {
00117   PODType* result = __STATIC_CAST(PODType*,malloc(N * sizeof(PODType)));
00118   if (result)
00119     copy(__array, __array + N, result);
00120   return result;
00121 }
00122 
00123 locale ios_base::imbue(const locale& loc) {
00124   if (loc._M_impl != _M_locale._M_impl) {
00125     locale previous = _M_locale;
00126     _M_locale = loc;
00127     _M_invoke_callbacks(imbue_event);
00128     return previous;
00129   }
00130   else {
00131     _M_invoke_callbacks(imbue_event);
00132     return _M_locale;
00133   }
00134 }
00135 
00136 int _STLP_CALL ios_base::xalloc() {
00137 #if defined (_STLP_THREADS) && \
00138     defined (_STLP_WIN32THREADS) && defined (_STLP_NEW_PLATFORM_SDK)
00139   static volatile __stl_atomic_t _S_index = 0;
00140   return _STLP_ATOMIC_INCREMENT(&_S_index);
00141 #else
00142   static int _S_index = 0;
00143   static _STLP_STATIC_MUTEX __lock _STLP_MUTEX_INITIALIZER;
00144   _STLP_auto_lock sentry(__lock);
00145   return _S_index++;
00146 #endif
00147 }
00148 
00149 long& ios_base::iword(int index) {
00150   static long dummy = 0;
00151 
00152   pair<long*, size_t> tmp = _Stl_expand_array(_M_iwords, _M_num_iwords, index);
00153   if (tmp.first) {              // The allocation, if any, succeeded.
00154     _M_iwords = tmp.first;
00155     _M_num_iwords = tmp.second;
00156     return _M_iwords[index];
00157   }
00158   else {
00159     _M_setstate_nothrow(badbit);
00160     _M_check_exception_mask();
00161     return dummy;
00162   }
00163 }
00164 
00165 
00166 void*& ios_base::pword(int index) {
00167   static void* dummy = 0;
00168 
00169   pair<void**, size_t> tmp = _Stl_expand_array(_M_pwords, _M_num_pwords, index);
00170   if (tmp.first) {              // The allocation, if any, succeeded.
00171     _M_pwords = tmp.first;
00172     _M_num_pwords = tmp.second;
00173     return _M_pwords[index];
00174   }
00175   else {
00176     _M_setstate_nothrow(badbit);
00177     _M_check_exception_mask();
00178     return dummy;
00179   }
00180 }
00181 
00182 void ios_base::register_callback(event_callback __fn, int index) {
00183   pair<pair<event_callback, int>*, size_t> tmp
00184     = _Stl_expand_array(_M_callbacks, _M_num_callbacks, (int)_M_callback_index /* fbp: index ??? */ );
00185   if (tmp.first) {
00186     _M_callbacks = tmp.first;
00187     _M_num_callbacks = tmp.second;
00188     _M_callbacks[_M_callback_index++] = make_pair(__fn, index);
00189   }
00190   else {
00191     _M_setstate_nothrow(badbit);
00192     _M_check_exception_mask();
00193   }
00194 }
00195 
00196 // Invokes all currently registered callbacks for a particular event.
00197 // Behaves correctly even if one of the callbacks adds a new callback.
00198 void ios_base::_M_invoke_callbacks(event E) {
00199   for (size_t i = _M_callback_index; i > 0; --i) {
00200     event_callback f = _M_callbacks[i-1].first;
00201     int n = _M_callbacks[i-1].second;
00202     f(E, *this, n);
00203   }
00204 }
00205 
00206 // This function is called if the state, rdstate(), has a bit set
00207 // that is also set in the exception mask exceptions().
00208 void ios_base::_M_throw_failure() {
00209   const char* arg ;
00210 # if 0
00211   char buffer[256];
00212   char* ptr;
00213   strcpy(buffer, "ios failure: rdstate = 0x");
00214   ptr = __write_integer(buffer+strlen(buffer), ios_base::hex, __STATIC_CAST(unsigned long,_M_iostate));
00215   strcpy(ptr, " mask = 0x");
00216   ptr = __write_integer(buffer+strlen(buffer), ios_base::hex, __STATIC_CAST(unsigned long,_M_exception_mask));
00217   *ptr = 0;
00218   arg = buffer;
00219 # else
00220   arg = "ios failure";
00221 # endif
00222 
00223 # ifndef _STLP_USE_EXCEPTIONS
00224   fputs(arg, stderr);
00225 # else
00226   throw failure(arg);
00227 # endif
00228 }
00229 
00230 // Copy x's state to *this.  This member function is used in the
00231 // implementation of basic_ios::copyfmt.  Does not copy _M_exception_mask
00232 // or _M_iostate.
00233 void ios_base::_M_copy_state(const ios_base& x) {
00234   _M_fmtflags  = x._M_fmtflags; // Copy the flags, except for _M_iostate
00235   _M_openmode  = x._M_openmode; // and _M_exception_mask.
00236   _M_seekdir   = x._M_seekdir;
00237   _M_precision = x._M_precision;
00238   _M_width     = x._M_width;
00239 
00240   if (_M_locale != x._M_locale) {
00241     _M_locale = x._M_locale;
00242     _M_cached_ctype = x._M_cached_ctype;
00243     _M_cached_numpunct = x._M_cached_numpunct;
00244   }
00245 
00246   if (x._M_callbacks) {
00247     pair<event_callback, int>* tmp = _Stl_copy_array(x._M_callbacks, x._M_callback_index);
00248     if (tmp) {
00249       free(_M_callbacks);
00250       _M_callbacks = tmp;
00251       _M_num_callbacks = _M_callback_index = x._M_callback_index;
00252     }
00253     else {
00254       _M_setstate_nothrow(badbit);
00255       _M_check_exception_mask();
00256     }
00257   }
00258 
00259   if (x._M_iwords) {
00260     long* tmp = _Stl_copy_array(x._M_iwords, x._M_num_iwords);
00261     if (tmp) {
00262       free(_M_iwords);
00263       _M_iwords = tmp;
00264       _M_num_iwords = x._M_num_iwords;
00265     }
00266     else {
00267       _M_setstate_nothrow(badbit);
00268       _M_check_exception_mask();
00269     }
00270   }
00271 
00272   if (x._M_pwords) {
00273     void** tmp = _Stl_copy_array(x._M_pwords, x._M_num_pwords);
00274     if (tmp) {
00275       free(_M_pwords);
00276       _M_pwords = tmp;
00277       _M_num_pwords = x._M_num_pwords;
00278     }
00279     else {
00280       _M_setstate_nothrow(badbit);
00281       _M_check_exception_mask();
00282     }
00283   }
00284 }
00285 
00286 // ios's (protected) default constructor.  The standard says that all
00287 // fields have indeterminate values; we initialize them to zero for
00288 // simplicity.  The only thing that really matters is that the arrays
00289 // are all initially null pointers, and the array element counts are all
00290 // initially zero.
00291 ios_base::ios_base()
00292   : _M_fmtflags(0), _M_iostate(0), _M_openmode(0), _M_seekdir(0),
00293     _M_exception_mask(0),
00294     _M_precision(0), _M_width(0),
00295     _M_locale(),
00296     _M_callbacks(0), _M_num_callbacks(0), _M_callback_index(0),
00297     _M_iwords(0), _M_num_iwords(0),
00298     _M_pwords(0),
00299     _M_num_pwords(0) , _M_cached_ctype(0), _M_cached_numpunct(0)
00300 {}
00301 
00302 // ios's destructor.
00303 ios_base::~ios_base() {
00304   _M_invoke_callbacks(erase_event);
00305   free(_M_callbacks);
00306   free(_M_iwords);
00307   free(_M_pwords);
00308 }
00309 
00310 //----------------------------------------------------------------------
00311 // Force instantiation of basic_ios
00312 // For DLL exports, they are already instantiated.
00313 #if !defined(_STLP_NO_FORCE_INSTANTIATE)
00314 template class _STLP_CLASS_DECLSPEC basic_ios<char, char_traits<char> >;
00315 #  if !defined (_STLP_NO_WCHAR_T)
00316 template class _STLP_CLASS_DECLSPEC basic_ios<wchar_t, char_traits<wchar_t> >;
00317 #  endif /* _STLP_NO_WCHAR_T */
00318 #endif
00319 
00320 _STLP_END_NAMESPACE
00321 
00322 // Local Variables:
00323 // mode:C++
00324 // End:



Generated on Mon Mar 10 15:32:16 2008 by  doxygen 1.5.1