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) && !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>
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>
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
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
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
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
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
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.
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().
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.
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.
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.
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: