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