blob: 4d1261e3854a23656d7e76dbbff1f69995116266 [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001//===-------------------------- ios.cpp -----------------------------------===//
2//
Howard Hinnantc566dc32010-05-11 21:36:01 +00003// The LLVM Compiler Infrastructure
Howard Hinnantc51e1022010-05-11 19:42:16 +00004//
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{
Howard Hinnant155c2af2010-05-24 17:49:41 +0000109 if (ev != static_cast<int>(io_errc::stream)
110#ifdef ELAST
111 && ev <= ELAST
112#endif
113 )
Howard Hinnantc51e1022010-05-11 19:42:16 +0000114 return __do_message::message(ev);
115 return string("unspecified iostream_category error");
116}
117
118const error_category&
119iostream_category()
120{
121 static __iostream_category s;
122 return s;
123}
124
125// ios_base::failure
126
127ios_base::failure::failure(const string& msg, const error_code& ec)
128 : system_error(ec, msg)
129{
130}
131
132ios_base::failure::failure(const char* msg, const error_code& ec)
133 : system_error(ec, msg)
134{
135}
136
137ios_base::failure::~failure() throw()
138{
139}
140
141// ios_base locale
142
143const ios_base::fmtflags ios_base::boolalpha;
144const ios_base::fmtflags ios_base::dec;
145const ios_base::fmtflags ios_base::fixed;
146const ios_base::fmtflags ios_base::hex;
147const ios_base::fmtflags ios_base::internal;
148const ios_base::fmtflags ios_base::left;
149const ios_base::fmtflags ios_base::oct;
150const ios_base::fmtflags ios_base::right;
151const ios_base::fmtflags ios_base::scientific;
152const ios_base::fmtflags ios_base::showbase;
153const ios_base::fmtflags ios_base::showpoint;
154const ios_base::fmtflags ios_base::showpos;
155const ios_base::fmtflags ios_base::skipws;
156const ios_base::fmtflags ios_base::unitbuf;
157const ios_base::fmtflags ios_base::uppercase;
158const ios_base::fmtflags ios_base::adjustfield;
159const ios_base::fmtflags ios_base::basefield;
160const ios_base::fmtflags ios_base::floatfield;
161
162const ios_base::iostate ios_base::badbit;
163const ios_base::iostate ios_base::eofbit;
164const ios_base::iostate ios_base::failbit;
165const ios_base::iostate ios_base::goodbit;
166
167const ios_base::openmode ios_base::app;
168const ios_base::openmode ios_base::ate;
169const ios_base::openmode ios_base::binary;
170const ios_base::openmode ios_base::in;
171const ios_base::openmode ios_base::out;
172const ios_base::openmode ios_base::trunc;
173
174void
175ios_base::__call_callbacks(event ev)
176{
177 for (size_t i = __event_size_; i;)
178 {
179 --i;
180 __fn_[i](ev, *this, __index_[i]);
181 }
182}
183
184// locale
185
186locale
187ios_base::imbue(const locale& newloc)
188{
189 static_assert(sizeof(locale) == sizeof(__loc_), "");
190 locale& loc_storage = *(locale*)&__loc_;
191 locale oldloc = loc_storage;
192 loc_storage = newloc;
193 __call_callbacks(imbue_event);
194 return oldloc;
195}
196
197locale
198ios_base::getloc() const
199{
200 const locale& loc_storage = *(locale*)&__loc_;
201 return loc_storage;
202}
203
204// xalloc
205
206int ios_base::__xindex_ = 0;
207
208int
209ios_base::xalloc()
210{
211 return __xindex_++;
212}
213
214long&
215ios_base::iword(int index)
216{
217 size_t req_size = static_cast<size_t>(index)+1;
218 if (req_size > __iarray_cap_)
219 {
220 size_t newcap;
221 const size_t mx = std::numeric_limits<size_t>::max();
222 if (req_size < mx/2)
223 newcap = max(2 * __iarray_cap_, req_size);
224 else
225 newcap = mx;
226 long* iarray = (long*)realloc(__iarray_, newcap * sizeof(long));
227 if (iarray == 0)
228 {
229 setstate(badbit);
230 static long error;
231 error = 0;
232 return error;
233 }
234 __iarray_ = iarray;
235 for (long* p = __iarray_ + __iarray_size_; __iarray_cap_ < newcap; ++__iarray_cap_, ++p)
236 *p = 0;
237 }
238 __iarray_size_ = max<size_t>(__iarray_size_, req_size);
239 return __iarray_[index];
240}
241
242void*&
243ios_base::pword(int index)
244{
245 size_t req_size = static_cast<size_t>(index)+1;
246 if (req_size > __parray_cap_)
247 {
248 size_t newcap;
249 const size_t mx = std::numeric_limits<size_t>::max();
250 if (req_size < mx/2)
251 newcap = max(2 * __parray_cap_, req_size);
252 else
253 newcap = mx;
254 void** parray = (void**)realloc(__parray_, newcap * sizeof(void*));
255 if (parray == 0)
256 {
257 setstate(badbit);
258 static void* error;
259 error = 0;
260 return error;
261 }
262 __parray_ = parray;
263 for (void** p = __parray_ + __parray_size_; __parray_cap_ < newcap; ++__parray_cap_, ++p)
264 *p = 0;
265 }
266 __parray_size_ = max<size_t>(__parray_size_, req_size);
267 return __parray_[index];
268}
269
270// register_callback
271
272void
273ios_base::register_callback(event_callback fn, int index)
274{
275 size_t req_size = __event_size_ + 1;
276 if (req_size > __event_cap_)
277 {
278 size_t newcap;
279 const size_t mx = std::numeric_limits<size_t>::max();
280 if (req_size < mx/2)
281 newcap = max(2 * __event_cap_, req_size);
282 else
283 newcap = mx;
284 event_callback* fns = (event_callback*)realloc(__fn_, newcap * sizeof(event_callback));
285 if (fns == 0)
286 setstate(badbit);
287 __fn_ = fns;
288 int* indxs = (int*)realloc(__index_, newcap * sizeof(int));
289 if (indxs == 0)
290 setstate(badbit);
291 __index_ = indxs;
292 }
293 __fn_[__event_size_] = fn;
294 __index_[__event_size_] = index;
295 ++__event_size_;
296}
297
298ios_base::~ios_base()
299{
300 __call_callbacks(erase_event);
301 locale& loc_storage = *(locale*)&__loc_;
302 loc_storage.~locale();
303 free(__fn_);
304 free(__index_);
305 free(__iarray_);
306 free(__parray_);
307}
308
309// iostate
310
311void
312ios_base::clear(iostate state)
313{
314 if (__rdbuf_)
315 __rdstate_ = state;
316 else
317 __rdstate_ = state | badbit;
318 if (((state | (__rdbuf_ ? goodbit : badbit)) & __exceptions_) != 0)
319 throw failure("ios_base::clear");
320}
321
322// init
323
324void
325ios_base::init(void* sb)
326{
327 __rdbuf_ = sb;
328 __rdstate_ = __rdbuf_ ? goodbit : badbit;
329 __exceptions_ = goodbit;
330 __fmtflags_ = skipws | dec;
331 __width_ = 0;
332 __precision_ = 6;
333 __fn_ = 0;
334 __index_ = 0;
335 __event_size_ = 0;
336 __event_cap_ = 0;
337 __iarray_ = 0;
338 __iarray_size_ = 0;
339 __iarray_cap_ = 0;
340 __parray_ = 0;
341 __parray_size_ = 0;
342 __parray_cap_ = 0;
343 ::new(&__loc_) locale;
344}
345
346void
347ios_base::copyfmt(const ios_base& rhs)
348{
349 // If we can't acquire the needed resources, throw bad_alloc (can't set badbit)
350 // Don't alter *this until all needed resources are aquired
351 unique_ptr<event_callback, void (*)(void*)> new_callbacks(0, free);
352 unique_ptr<int, void (*)(void*)> new_ints(0, free);
353 unique_ptr<long, void (*)(void*)> new_longs(0, free);
354 unique_ptr<void*, void (*)(void*)> new_pointers(0, free);
355 if (__event_cap_ < rhs.__event_size_)
356 {
357 new_callbacks.reset((event_callback*)malloc(sizeof(event_callback) * rhs.__event_size_));
358 if (!new_callbacks)
359 throw bad_alloc();
360 new_ints.reset((int*)malloc(sizeof(int) * rhs.__event_size_));
361 if (!new_ints)
362 throw bad_alloc();
363 }
364 if (__iarray_cap_ < rhs.__iarray_size_)
365 {
366 new_longs.reset((long*)malloc(sizeof(long) * rhs.__iarray_size_));
367 if (!new_longs)
368 throw bad_alloc();
369 }
370 if (__parray_cap_ < rhs.__parray_size_)
371 {
372 new_pointers.reset((void**)malloc(sizeof(void*) * rhs.__parray_size_));
373 if (!new_pointers)
374 throw bad_alloc();
375 }
376 // Got everything we need. Copy everything but __rdstate_, __rdbuf_ and __exceptions_
377 __fmtflags_ = rhs.__fmtflags_;
378 __precision_ = rhs.__precision_;
379 __width_ = rhs.__width_;
380 locale& lhs_loc = *(locale*)&__loc_;
381 locale& rhs_loc = *(locale*)&rhs.__loc_;
382 lhs_loc = rhs_loc;
383 if (__event_cap_ < rhs.__event_size_)
384 {
385 free(__fn_);
386 __fn_ = new_callbacks.release();
387 free(__index_);
388 __index_ = new_ints.release();
389 __event_cap_ = rhs.__event_size_;
390 }
391 for (__event_size_ = 0; __event_size_ < rhs.__event_size_; ++__event_size_)
392 {
393 __fn_[__event_size_] = rhs.__fn_[__event_size_];
394 __index_[__event_size_] = rhs.__index_[__event_size_];
395 }
396 if (__iarray_cap_ < rhs.__iarray_size_)
397 {
398 free(__iarray_);
399 __iarray_ = new_longs.release();
400 __iarray_cap_ = rhs.__iarray_size_;
401 }
402 for (__iarray_size_ = 0; __iarray_size_ < rhs.__iarray_size_; ++__iarray_size_)
403 __iarray_[__iarray_size_] = rhs.__iarray_[__iarray_size_];
404 if (__parray_cap_ < rhs.__parray_size_)
405 {
406 free(__parray_);
407 __parray_ = new_pointers.release();
408 __parray_cap_ = rhs.__parray_size_;
409 }
410 for (__parray_size_ = 0; __parray_size_ < rhs.__parray_size_; ++__parray_size_)
411 __parray_[__parray_size_] = rhs.__parray_[__parray_size_];
412}
413
414void
415ios_base::move(ios_base& rhs)
416{
417 // *this is uninitialized
418 __fmtflags_ = rhs.__fmtflags_;
419 __precision_ = rhs.__precision_;
420 __width_ = rhs.__width_;
421 __rdstate_ = rhs.__rdstate_;
422 __exceptions_ = rhs.__exceptions_;
423 __rdbuf_ = 0;
424 locale& rhs_loc = *(locale*)&rhs.__loc_;
425 ::new(&__loc_) locale(rhs_loc);
426 __fn_ = rhs.__fn_;
427 rhs.__fn_ = 0;
428 __index_ = rhs.__index_;
429 rhs.__index_ = 0;
430 __event_size_ = rhs.__event_size_;
431 rhs.__event_size_ = 0;
432 __event_cap_ = rhs.__event_cap_;
433 rhs.__event_cap_ = 0;
434 __iarray_ = rhs.__iarray_;
435 rhs.__iarray_ = 0;
436 __iarray_size_ = rhs.__iarray_size_;
437 rhs.__iarray_size_ = 0;
438 __iarray_cap_ = rhs.__iarray_cap_;
439 rhs.__iarray_cap_ = 0;
440 __parray_ = rhs.__parray_;
441 rhs.__parray_ = 0;
442 __parray_size_ = rhs.__parray_size_;
443 rhs.__parray_size_ = 0;
444 __parray_cap_ = rhs.__parray_cap_;
445 rhs.__parray_cap_ = 0;
446}
447
448void
449ios_base::swap(ios_base& rhs)
450{
451 _STD::swap(__fmtflags_, rhs.__fmtflags_);
452 _STD::swap(__precision_, rhs.__precision_);
453 _STD::swap(__width_, rhs.__width_);
454 _STD::swap(__rdstate_, rhs.__rdstate_);
455 _STD::swap(__exceptions_, rhs.__exceptions_);
456 locale& lhs_loc = *(locale*)&__loc_;
457 locale& rhs_loc = *(locale*)&rhs.__loc_;
458 _STD::swap(lhs_loc, rhs_loc);
459 _STD::swap(__fn_, rhs.__fn_);
460 _STD::swap(__index_, rhs.__index_);
461 _STD::swap(__event_size_, rhs.__event_size_);
462 _STD::swap(__event_cap_, rhs.__event_cap_);
463 _STD::swap(__iarray_, rhs.__iarray_);
464 _STD::swap(__iarray_size_, rhs.__iarray_size_);
465 _STD::swap(__iarray_cap_, rhs.__iarray_cap_);
466 _STD::swap(__parray_, rhs.__parray_);
467 _STD::swap(__parray_size_, rhs.__parray_size_);
468 _STD::swap(__parray_cap_, rhs.__parray_cap_);
469}
470
471void
472ios_base::__set_badbit_and_consider_rethrow()
473{
474 __rdstate_ |= badbit;
475 if (__exceptions_ & badbit)
476 throw;
477}
478
479void
480ios_base::__set_failbit_and_consider_rethrow()
481{
482 __rdstate_ |= failbit;
483 if (__exceptions_ & failbit)
484 throw;
485}
486
487bool
488ios_base::sync_with_stdio(bool sync)
489{
490 static bool previous_state = true;
491 bool r = previous_state;
492 previous_state = sync;
493 return r;
494}
495
496_LIBCPP_END_NAMESPACE_STD