Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/c++/src/ios.cpp
12346 views
1
//===-------------------------- ios.cpp -----------------------------------===//
2
//
3
// The LLVM Compiler Infrastructure
4
//
5
// This file is dual licensed under the MIT and the University of Illinois Open
6
// Source Licenses. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
10
#include "__config"
11
12
#include "ios"
13
14
#include <stdlib.h>
15
16
#include "__locale"
17
#include "algorithm"
18
#include "include/config_elast.h"
19
#include "istream"
20
#include "limits"
21
#include "memory"
22
#include "new"
23
#include "streambuf"
24
#include "string"
25
#include "__undef_macros"
26
27
_LIBCPP_BEGIN_NAMESPACE_STD
28
29
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ios<char>;
30
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ios<wchar_t>;
31
32
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_streambuf<char>;
33
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_streambuf<wchar_t>;
34
35
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_istream<char>;
36
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_istream<wchar_t>;
37
38
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostream<char>;
39
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostream<wchar_t>;
40
41
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_iostream<char>;
42
43
class _LIBCPP_HIDDEN __iostream_category
44
: public __do_message
45
{
46
public:
47
virtual const char* name() const _NOEXCEPT;
48
virtual string message(int ev) const;
49
};
50
51
const char*
52
__iostream_category::name() const _NOEXCEPT
53
{
54
return "iostream";
55
}
56
57
string
58
__iostream_category::message(int ev) const
59
{
60
if (ev != static_cast<int>(io_errc::stream)
61
#ifdef _LIBCPP_ELAST
62
&& ev <= _LIBCPP_ELAST
63
#endif // _LIBCPP_ELAST
64
)
65
return __do_message::message(ev);
66
return string("unspecified iostream_category error");
67
}
68
69
const error_category&
70
iostream_category() _NOEXCEPT
71
{
72
static __iostream_category s;
73
return s;
74
}
75
76
// ios_base::failure
77
78
ios_base::failure::failure(const string& msg, const error_code& ec)
79
: system_error(ec, msg)
80
{
81
}
82
83
ios_base::failure::failure(const char* msg, const error_code& ec)
84
: system_error(ec, msg)
85
{
86
}
87
88
ios_base::failure::~failure() throw()
89
{
90
}
91
92
// ios_base locale
93
94
const ios_base::fmtflags ios_base::boolalpha;
95
const ios_base::fmtflags ios_base::dec;
96
const ios_base::fmtflags ios_base::fixed;
97
const ios_base::fmtflags ios_base::hex;
98
const ios_base::fmtflags ios_base::internal;
99
const ios_base::fmtflags ios_base::left;
100
const ios_base::fmtflags ios_base::oct;
101
const ios_base::fmtflags ios_base::right;
102
const ios_base::fmtflags ios_base::scientific;
103
const ios_base::fmtflags ios_base::showbase;
104
const ios_base::fmtflags ios_base::showpoint;
105
const ios_base::fmtflags ios_base::showpos;
106
const ios_base::fmtflags ios_base::skipws;
107
const ios_base::fmtflags ios_base::unitbuf;
108
const ios_base::fmtflags ios_base::uppercase;
109
const ios_base::fmtflags ios_base::adjustfield;
110
const ios_base::fmtflags ios_base::basefield;
111
const ios_base::fmtflags ios_base::floatfield;
112
113
const ios_base::iostate ios_base::badbit;
114
const ios_base::iostate ios_base::eofbit;
115
const ios_base::iostate ios_base::failbit;
116
const ios_base::iostate ios_base::goodbit;
117
118
const ios_base::openmode ios_base::app;
119
const ios_base::openmode ios_base::ate;
120
const ios_base::openmode ios_base::binary;
121
const ios_base::openmode ios_base::in;
122
const ios_base::openmode ios_base::out;
123
const ios_base::openmode ios_base::trunc;
124
125
void
126
ios_base::__call_callbacks(event ev)
127
{
128
for (size_t i = __event_size_; i;)
129
{
130
--i;
131
__fn_[i](ev, *this, __index_[i]);
132
}
133
}
134
135
// locale
136
137
locale
138
ios_base::imbue(const locale& newloc)
139
{
140
static_assert(sizeof(locale) == sizeof(__loc_), "");
141
locale& loc_storage = *reinterpret_cast<locale*>(&__loc_);
142
locale oldloc = loc_storage;
143
loc_storage = newloc;
144
__call_callbacks(imbue_event);
145
return oldloc;
146
}
147
148
locale
149
ios_base::getloc() const
150
{
151
const locale& loc_storage = *reinterpret_cast<const locale*>(&__loc_);
152
return loc_storage;
153
}
154
155
// xalloc
156
#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS)
157
atomic<int> ios_base::__xindex_ = ATOMIC_VAR_INIT(0);
158
#else
159
int ios_base::__xindex_ = 0;
160
#endif
161
162
template <typename _Tp>
163
static size_t __ios_new_cap(size_t __req_size, size_t __current_cap)
164
{ // Precondition: __req_size > __current_cap
165
const size_t mx = std::numeric_limits<size_t>::max() / sizeof(_Tp);
166
if (__req_size < mx/2)
167
return _VSTD::max(2 * __current_cap, __req_size);
168
else
169
return mx;
170
}
171
172
int
173
ios_base::xalloc()
174
{
175
return __xindex_++;
176
}
177
178
long&
179
ios_base::iword(int index)
180
{
181
size_t req_size = static_cast<size_t>(index)+1;
182
if (req_size > __iarray_cap_)
183
{
184
size_t newcap = __ios_new_cap<long>(req_size, __iarray_cap_);
185
long* iarray = static_cast<long*>(realloc(__iarray_, newcap * sizeof(long)));
186
if (iarray == 0)
187
{
188
setstate(badbit);
189
static long error;
190
error = 0;
191
return error;
192
}
193
__iarray_ = iarray;
194
for (long* p = __iarray_ + __iarray_size_; p < __iarray_ + newcap; ++p)
195
*p = 0;
196
__iarray_cap_ = newcap;
197
}
198
__iarray_size_ = max<size_t>(__iarray_size_, req_size);
199
return __iarray_[index];
200
}
201
202
void*&
203
ios_base::pword(int index)
204
{
205
size_t req_size = static_cast<size_t>(index)+1;
206
if (req_size > __parray_cap_)
207
{
208
size_t newcap = __ios_new_cap<void *>(req_size, __iarray_cap_);
209
void** parray = static_cast<void**>(realloc(__parray_, newcap * sizeof(void *)));
210
if (parray == 0)
211
{
212
setstate(badbit);
213
static void* error;
214
error = 0;
215
return error;
216
}
217
__parray_ = parray;
218
for (void** p = __parray_ + __parray_size_; p < __parray_ + newcap; ++p)
219
*p = 0;
220
__parray_cap_ = newcap;
221
}
222
__parray_size_ = max<size_t>(__parray_size_, req_size);
223
return __parray_[index];
224
}
225
226
// register_callback
227
228
void
229
ios_base::register_callback(event_callback fn, int index)
230
{
231
size_t req_size = __event_size_ + 1;
232
if (req_size > __event_cap_)
233
{
234
size_t newcap = __ios_new_cap<event_callback>(req_size, __event_cap_);
235
event_callback* fns = static_cast<event_callback*>(realloc(__fn_, newcap * sizeof(event_callback)));
236
if (fns == 0)
237
setstate(badbit);
238
__fn_ = fns;
239
int* indxs = static_cast<int *>(realloc(__index_, newcap * sizeof(int)));
240
if (indxs == 0)
241
setstate(badbit);
242
__index_ = indxs;
243
__event_cap_ = newcap;
244
}
245
__fn_[__event_size_] = fn;
246
__index_[__event_size_] = index;
247
++__event_size_;
248
}
249
250
ios_base::~ios_base()
251
{
252
__call_callbacks(erase_event);
253
locale& loc_storage = *reinterpret_cast<locale*>(&__loc_);
254
loc_storage.~locale();
255
free(__fn_);
256
free(__index_);
257
free(__iarray_);
258
free(__parray_);
259
}
260
261
// iostate
262
263
void
264
ios_base::clear(iostate state)
265
{
266
if (__rdbuf_)
267
__rdstate_ = state;
268
else
269
__rdstate_ = state | badbit;
270
#ifndef _LIBCPP_NO_EXCEPTIONS
271
if (((state | (__rdbuf_ ? goodbit : badbit)) & __exceptions_) != 0)
272
throw failure("ios_base::clear");
273
#endif // _LIBCPP_NO_EXCEPTIONS
274
}
275
276
// init
277
278
void
279
ios_base::init(void* sb)
280
{
281
__rdbuf_ = sb;
282
__rdstate_ = __rdbuf_ ? goodbit : badbit;
283
__exceptions_ = goodbit;
284
__fmtflags_ = skipws | dec;
285
__width_ = 0;
286
__precision_ = 6;
287
__fn_ = 0;
288
__index_ = 0;
289
__event_size_ = 0;
290
__event_cap_ = 0;
291
__iarray_ = 0;
292
__iarray_size_ = 0;
293
__iarray_cap_ = 0;
294
__parray_ = 0;
295
__parray_size_ = 0;
296
__parray_cap_ = 0;
297
::new(&__loc_) locale;
298
}
299
300
void
301
ios_base::copyfmt(const ios_base& rhs)
302
{
303
// If we can't acquire the needed resources, throw bad_alloc (can't set badbit)
304
// Don't alter *this until all needed resources are acquired
305
unique_ptr<event_callback, void (*)(void*)> new_callbacks(0, free);
306
unique_ptr<int, void (*)(void*)> new_ints(0, free);
307
unique_ptr<long, void (*)(void*)> new_longs(0, free);
308
unique_ptr<void*, void (*)(void*)> new_pointers(0, free);
309
if (__event_cap_ < rhs.__event_size_)
310
{
311
size_t newesize = sizeof(event_callback) * rhs.__event_size_;
312
new_callbacks.reset(static_cast<event_callback*>(malloc(newesize)));
313
#ifndef _LIBCPP_NO_EXCEPTIONS
314
if (!new_callbacks)
315
throw bad_alloc();
316
#endif // _LIBCPP_NO_EXCEPTIONS
317
318
size_t newisize = sizeof(int) * rhs.__event_size_;
319
new_ints.reset(static_cast<int *>(malloc(newisize)));
320
#ifndef _LIBCPP_NO_EXCEPTIONS
321
if (!new_ints)
322
throw bad_alloc();
323
#endif // _LIBCPP_NO_EXCEPTIONS
324
}
325
if (__iarray_cap_ < rhs.__iarray_size_)
326
{
327
size_t newsize = sizeof(long) * rhs.__iarray_size_;
328
new_longs.reset(static_cast<long*>(malloc(newsize)));
329
#ifndef _LIBCPP_NO_EXCEPTIONS
330
if (!new_longs)
331
throw bad_alloc();
332
#endif // _LIBCPP_NO_EXCEPTIONS
333
}
334
if (__parray_cap_ < rhs.__parray_size_)
335
{
336
size_t newsize = sizeof(void*) * rhs.__parray_size_;
337
new_pointers.reset(static_cast<void**>(malloc(newsize)));
338
#ifndef _LIBCPP_NO_EXCEPTIONS
339
if (!new_pointers)
340
throw bad_alloc();
341
#endif // _LIBCPP_NO_EXCEPTIONS
342
}
343
// Got everything we need. Copy everything but __rdstate_, __rdbuf_ and __exceptions_
344
__fmtflags_ = rhs.__fmtflags_;
345
__precision_ = rhs.__precision_;
346
__width_ = rhs.__width_;
347
locale& lhs_loc = *reinterpret_cast<locale*>(&__loc_);
348
const locale& rhs_loc = *reinterpret_cast<const locale*>(&rhs.__loc_);
349
lhs_loc = rhs_loc;
350
if (__event_cap_ < rhs.__event_size_)
351
{
352
free(__fn_);
353
__fn_ = new_callbacks.release();
354
free(__index_);
355
__index_ = new_ints.release();
356
__event_cap_ = rhs.__event_size_;
357
}
358
for (__event_size_ = 0; __event_size_ < rhs.__event_size_; ++__event_size_)
359
{
360
__fn_[__event_size_] = rhs.__fn_[__event_size_];
361
__index_[__event_size_] = rhs.__index_[__event_size_];
362
}
363
if (__iarray_cap_ < rhs.__iarray_size_)
364
{
365
free(__iarray_);
366
__iarray_ = new_longs.release();
367
__iarray_cap_ = rhs.__iarray_size_;
368
}
369
for (__iarray_size_ = 0; __iarray_size_ < rhs.__iarray_size_; ++__iarray_size_)
370
__iarray_[__iarray_size_] = rhs.__iarray_[__iarray_size_];
371
if (__parray_cap_ < rhs.__parray_size_)
372
{
373
free(__parray_);
374
__parray_ = new_pointers.release();
375
__parray_cap_ = rhs.__parray_size_;
376
}
377
for (__parray_size_ = 0; __parray_size_ < rhs.__parray_size_; ++__parray_size_)
378
__parray_[__parray_size_] = rhs.__parray_[__parray_size_];
379
}
380
381
void
382
ios_base::move(ios_base& rhs)
383
{
384
// *this is uninitialized
385
__fmtflags_ = rhs.__fmtflags_;
386
__precision_ = rhs.__precision_;
387
__width_ = rhs.__width_;
388
__rdstate_ = rhs.__rdstate_;
389
__exceptions_ = rhs.__exceptions_;
390
__rdbuf_ = 0;
391
locale& rhs_loc = *reinterpret_cast<locale*>(&rhs.__loc_);
392
::new(&__loc_) locale(rhs_loc);
393
__fn_ = rhs.__fn_;
394
rhs.__fn_ = 0;
395
__index_ = rhs.__index_;
396
rhs.__index_ = 0;
397
__event_size_ = rhs.__event_size_;
398
rhs.__event_size_ = 0;
399
__event_cap_ = rhs.__event_cap_;
400
rhs.__event_cap_ = 0;
401
__iarray_ = rhs.__iarray_;
402
rhs.__iarray_ = 0;
403
__iarray_size_ = rhs.__iarray_size_;
404
rhs.__iarray_size_ = 0;
405
__iarray_cap_ = rhs.__iarray_cap_;
406
rhs.__iarray_cap_ = 0;
407
__parray_ = rhs.__parray_;
408
rhs.__parray_ = 0;
409
__parray_size_ = rhs.__parray_size_;
410
rhs.__parray_size_ = 0;
411
__parray_cap_ = rhs.__parray_cap_;
412
rhs.__parray_cap_ = 0;
413
}
414
415
void
416
ios_base::swap(ios_base& rhs) _NOEXCEPT
417
{
418
_VSTD::swap(__fmtflags_, rhs.__fmtflags_);
419
_VSTD::swap(__precision_, rhs.__precision_);
420
_VSTD::swap(__width_, rhs.__width_);
421
_VSTD::swap(__rdstate_, rhs.__rdstate_);
422
_VSTD::swap(__exceptions_, rhs.__exceptions_);
423
locale& lhs_loc = *reinterpret_cast<locale*>(&__loc_);
424
locale& rhs_loc = *reinterpret_cast<locale*>(&rhs.__loc_);
425
_VSTD::swap(lhs_loc, rhs_loc);
426
_VSTD::swap(__fn_, rhs.__fn_);
427
_VSTD::swap(__index_, rhs.__index_);
428
_VSTD::swap(__event_size_, rhs.__event_size_);
429
_VSTD::swap(__event_cap_, rhs.__event_cap_);
430
_VSTD::swap(__iarray_, rhs.__iarray_);
431
_VSTD::swap(__iarray_size_, rhs.__iarray_size_);
432
_VSTD::swap(__iarray_cap_, rhs.__iarray_cap_);
433
_VSTD::swap(__parray_, rhs.__parray_);
434
_VSTD::swap(__parray_size_, rhs.__parray_size_);
435
_VSTD::swap(__parray_cap_, rhs.__parray_cap_);
436
}
437
438
void
439
ios_base::__set_badbit_and_consider_rethrow()
440
{
441
__rdstate_ |= badbit;
442
#ifndef _LIBCPP_NO_EXCEPTIONS
443
if (__exceptions_ & badbit)
444
throw;
445
#endif // _LIBCPP_NO_EXCEPTIONS
446
}
447
448
void
449
ios_base::__set_failbit_and_consider_rethrow()
450
{
451
__rdstate_ |= failbit;
452
#ifndef _LIBCPP_NO_EXCEPTIONS
453
if (__exceptions_ & failbit)
454
throw;
455
#endif // _LIBCPP_NO_EXCEPTIONS
456
}
457
458
bool
459
ios_base::sync_with_stdio(bool sync)
460
{
461
static bool previous_state = true;
462
bool r = previous_state;
463
previous_state = sync;
464
return r;
465
}
466
467
_LIBCPP_END_NAMESPACE_STD
468
469