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