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