• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  
failure(const string & s)36  ios_base::failure::failure(const string& s)
37    : __Named_exception(s)
38  {}
39  
~failure()40  ios_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.
44  const ios_base::fmtflags ios_base::left;
45  const ios_base::fmtflags ios_base::right;
46  const ios_base::fmtflags ios_base::internal;
47  const ios_base::fmtflags ios_base::dec;
48  const ios_base::fmtflags ios_base::hex;
49  const ios_base::fmtflags ios_base::oct;
50  const ios_base::fmtflags ios_base::fixed;
51  const ios_base::fmtflags ios_base::scientific;
52  const ios_base::fmtflags ios_base::boolalpha;
53  const ios_base::fmtflags ios_base::showbase;
54  const ios_base::fmtflags ios_base::showpoint;
55  const ios_base::fmtflags ios_base::showpos;
56  const ios_base::fmtflags ios_base::skipws;
57  const ios_base::fmtflags ios_base::unitbuf;
58  const ios_base::fmtflags ios_base::uppercase;
59  const ios_base::fmtflags ios_base::adjustfield;
60  const ios_base::fmtflags ios_base::basefield;
61  const ios_base::fmtflags ios_base::floatfield;
62  
63  // Definitions of ios_base's state flags.
64  const ios_base::iostate ios_base::goodbit;
65  const ios_base::iostate ios_base::badbit;
66  const ios_base::iostate ios_base::eofbit;
67  const ios_base::iostate ios_base::failbit;
68  
69  // Definitions of ios_base's openmode flags.
70  const ios_base::openmode ios_base::app;
71  const ios_base::openmode ios_base::ate;
72  const ios_base::openmode ios_base::binary;
73  const ios_base::openmode ios_base::in;
74  const ios_base::openmode ios_base::out;
75  const ios_base::openmode ios_base::trunc;
76  
77  // Definitions of ios_base's seekdir flags.
78  const ios_base::seekdir ios_base::beg;
79  const ios_base::seekdir ios_base::cur;
80  const 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  
92  template <class PODType>
93  static pair<PODType*, size_t>
_Stl_expand_array(PODType * __array,size_t N,int index)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.
114  template <class PODType>
_Stl_copy_array(const PODType * __array,size_t N)115  static 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  
imbue(const locale & loc)122  locale 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  
xalloc()135  int _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  
iword(int index)148  long& 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  
pword(int index)165  void*& 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  
register_callback(event_callback __fn,int index)181  void 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.
_M_invoke_callbacks(event E)197  void 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().
_M_throw_failure()207  void 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.
_M_copy_state(const ios_base & x)232  void 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.
ios_base()285  ios_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.
~ios_base()297  ios_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)
308  template class _STLP_CLASS_DECLSPEC basic_ios<char, char_traits<char> >;
309  #  if !defined (_STLP_NO_WCHAR_T)
310  template 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