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