]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/src/istream.cc
319202ee4c3af177e8ec9ac0bd4672c5b0166e89
[thirdparty/gcc.git] / libstdc++-v3 / src / istream.cc
1 // Input streams -*- C++ -*-
2
3 // Copyright (C) 2004, 2005 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 // USA.
20
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
29
30 //
31 // ISO C++ 14882: 27.6.1 Input streams
32 //
33
34 #include <istream>
35
36 _GLIBCXX_BEGIN_NAMESPACE(std)
37
38 template<>
39 basic_istream<char>&
40 basic_istream<char>::
41 getline(char_type* __s, streamsize __n, char_type __delim)
42 {
43 _M_gcount = 0;
44 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
45 sentry __cerb(*this, true);
46 if (__cerb)
47 {
48 try
49 {
50 const int_type __idelim = traits_type::to_int_type(__delim);
51 const int_type __eof = traits_type::eof();
52 __streambuf_type* __sb = this->rdbuf();
53 int_type __c = __sb->sgetc();
54
55 while (_M_gcount + 1 < __n
56 && !traits_type::eq_int_type(__c, __eof)
57 && !traits_type::eq_int_type(__c, __idelim))
58 {
59 streamsize __size = std::min(streamsize(__sb->egptr()
60 - __sb->gptr()),
61 streamsize(__n - _M_gcount
62 - 1));
63 if (__size > 1)
64 {
65 const char_type* __p = traits_type::find(__sb->gptr(),
66 __size,
67 __delim);
68 if (__p)
69 __size = __p - __sb->gptr();
70 traits_type::copy(__s, __sb->gptr(), __size);
71 __s += __size;
72 __sb->gbump(__size);
73 _M_gcount += __size;
74 __c = __sb->sgetc();
75 }
76 else
77 {
78 *__s++ = traits_type::to_char_type(__c);
79 ++_M_gcount;
80 __c = __sb->snextc();
81 }
82 }
83
84 if (traits_type::eq_int_type(__c, __eof))
85 __err |= ios_base::eofbit;
86 else if (traits_type::eq_int_type(__c, __idelim))
87 {
88 ++_M_gcount;
89 __sb->sbumpc();
90 }
91 else
92 __err |= ios_base::failbit;
93 }
94 catch(__cxxabiv1::__forced_unwind&)
95 {
96 this->_M_setstate(ios_base::badbit);
97 __throw_exception_again;
98 }
99 catch(...)
100 { this->_M_setstate(ios_base::badbit); }
101 }
102 // _GLIBCXX_RESOLVE_LIB_DEFECTS
103 // 243. get and getline when sentry reports failure.
104 if (__n > 0)
105 *__s = char_type();
106 if (!_M_gcount)
107 __err |= ios_base::failbit;
108 if (__err)
109 this->setstate(__err);
110 return *this;
111 }
112
113 template<>
114 basic_istream<char>&
115 basic_istream<char>::
116 ignore(streamsize __n, int_type __delim)
117 {
118 if (traits_type::eq_int_type(__delim, traits_type::eof()))
119 return ignore(__n);
120
121 _M_gcount = 0;
122 sentry __cerb(*this, true);
123 if (__cerb && __n > 0)
124 {
125 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
126 try
127 {
128 const char_type __cdelim = traits_type::to_char_type(__delim);
129 const int_type __eof = traits_type::eof();
130 __streambuf_type* __sb = this->rdbuf();
131 int_type __c = __sb->sgetc();
132
133 bool __large_ignore = false;
134 while (true)
135 {
136 while (_M_gcount < __n
137 && !traits_type::eq_int_type(__c, __eof)
138 && !traits_type::eq_int_type(__c, __delim))
139 {
140 streamsize __size = std::min(streamsize(__sb->egptr()
141 - __sb->gptr()),
142 streamsize(__n - _M_gcount));
143 if (__size > 1)
144 {
145 const char_type* __p = traits_type::find(__sb->gptr(),
146 __size,
147 __cdelim);
148 if (__p)
149 __size = __p - __sb->gptr();
150 __sb->gbump(__size);
151 _M_gcount += __size;
152 __c = __sb->sgetc();
153 }
154 else
155 {
156 ++_M_gcount;
157 __c = __sb->snextc();
158 }
159 }
160 if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max
161 && !traits_type::eq_int_type(__c, __eof)
162 && !traits_type::eq_int_type(__c, __delim))
163 {
164 _M_gcount =
165 __gnu_cxx::__numeric_traits<streamsize>::__min;
166 __large_ignore = true;
167 }
168 else
169 break;
170 }
171
172 if (__large_ignore)
173 _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max;
174
175 if (traits_type::eq_int_type(__c, __eof))
176 __err |= ios_base::eofbit;
177 else if (traits_type::eq_int_type(__c, __delim))
178 {
179 if (_M_gcount
180 < __gnu_cxx::__numeric_traits<streamsize>::__max)
181 ++_M_gcount;
182 __sb->sbumpc();
183 }
184 }
185 catch(__cxxabiv1::__forced_unwind&)
186 {
187 this->_M_setstate(ios_base::badbit);
188 __throw_exception_again;
189 }
190 catch(...)
191 { this->_M_setstate(ios_base::badbit); }
192 if (__err)
193 this->setstate(__err);
194 }
195 return *this;
196 }
197
198 template<>
199 basic_istream<char>&
200 operator>>(basic_istream<char>& __in, char* __s)
201 {
202 typedef basic_istream<char> __istream_type;
203 typedef __istream_type::int_type __int_type;
204 typedef __istream_type::char_type __char_type;
205 typedef __istream_type::traits_type __traits_type;
206 typedef __istream_type::__streambuf_type __streambuf_type;
207 typedef __istream_type::__ctype_type __ctype_type;
208
209 streamsize __extracted = 0;
210 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
211 __istream_type::sentry __cerb(__in, false);
212 if (__cerb)
213 {
214 try
215 {
216 // Figure out how many characters to extract.
217 streamsize __num = __in.width();
218 if (__num <= 0)
219 __num = __gnu_cxx::__numeric_traits<streamsize>::__max;
220
221 const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
222
223 const __int_type __eof = __traits_type::eof();
224 __streambuf_type* __sb = __in.rdbuf();
225 __int_type __c = __sb->sgetc();
226
227 while (__extracted < __num - 1
228 && !__traits_type::eq_int_type(__c, __eof)
229 && !__ct.is(ctype_base::space,
230 __traits_type::to_char_type(__c)))
231 {
232 streamsize __size = std::min(streamsize(__sb->egptr()
233 - __sb->gptr()),
234 streamsize(__num - __extracted
235 - 1));
236 if (__size > 1)
237 {
238 __size = (__ct.scan_is(ctype_base::space,
239 __sb->gptr() + 1,
240 __sb->gptr() + __size)
241 - __sb->gptr());
242 __traits_type::copy(__s, __sb->gptr(), __size);
243 __s += __size;
244 __sb->gbump(__size);
245 __extracted += __size;
246 __c = __sb->sgetc();
247 }
248 else
249 {
250 *__s++ = __traits_type::to_char_type(__c);
251 ++__extracted;
252 __c = __sb->snextc();
253 }
254 }
255
256 if (__traits_type::eq_int_type(__c, __eof))
257 __err |= ios_base::eofbit;
258
259 // _GLIBCXX_RESOLVE_LIB_DEFECTS
260 // 68. Extractors for char* should store null at end
261 *__s = __char_type();
262 __in.width(0);
263 }
264 catch(__cxxabiv1::__forced_unwind&)
265 {
266 __in._M_setstate(ios_base::badbit);
267 __throw_exception_again;
268 }
269 catch(...)
270 { __in._M_setstate(ios_base::badbit); }
271 }
272 if (!__extracted)
273 __err |= ios_base::failbit;
274 if (__err)
275 __in.setstate(__err);
276 return __in;
277 }
278
279 template<>
280 basic_istream<char>&
281 operator>>(basic_istream<char>& __in, basic_string<char>& __str)
282 {
283 typedef basic_istream<char> __istream_type;
284 typedef __istream_type::int_type __int_type;
285 typedef __istream_type::char_type __char_type;
286 typedef __istream_type::traits_type __traits_type;
287 typedef __istream_type::__streambuf_type __streambuf_type;
288 typedef __istream_type::__ctype_type __ctype_type;
289 typedef basic_string<char> __string_type;
290 typedef __string_type::size_type __size_type;
291
292 __size_type __extracted = 0;
293 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
294 __istream_type::sentry __cerb(__in, false);
295 if (__cerb)
296 {
297 try
298 {
299 __str.erase();
300 const streamsize __w = __in.width();
301 const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
302 : __str.max_size();
303 const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
304 const __int_type __eof = __traits_type::eof();
305 __streambuf_type* __sb = __in.rdbuf();
306 __int_type __c = __sb->sgetc();
307
308 while (__extracted < __n
309 && !__traits_type::eq_int_type(__c, __eof)
310 && !__ct.is(ctype_base::space,
311 __traits_type::to_char_type(__c)))
312 {
313 streamsize __size = std::min(streamsize(__sb->egptr()
314 - __sb->gptr()),
315 streamsize(__n - __extracted));
316 if (__size > 1)
317 {
318 __size = (__ct.scan_is(ctype_base::space,
319 __sb->gptr() + 1,
320 __sb->gptr() + __size)
321 - __sb->gptr());
322 __str.append(__sb->gptr(), __size);
323 __sb->gbump(__size);
324 __extracted += __size;
325 __c = __sb->sgetc();
326 }
327 else
328 {
329 __str += __traits_type::to_char_type(__c);
330 ++__extracted;
331 __c = __sb->snextc();
332 }
333 }
334
335 if (__traits_type::eq_int_type(__c, __eof))
336 __err |= ios_base::eofbit;
337 __in.width(0);
338 }
339 catch(__cxxabiv1::__forced_unwind&)
340 {
341 __in._M_setstate(ios_base::badbit);
342 __throw_exception_again;
343 }
344 catch(...)
345 {
346 // _GLIBCXX_RESOLVE_LIB_DEFECTS
347 // 91. Description of operator>> and getline() for string<>
348 // might cause endless loop
349 __in._M_setstate(ios_base::badbit);
350 }
351 }
352 if (!__extracted)
353 __err |= ios_base::failbit;
354 if (__err)
355 __in.setstate(__err);
356 return __in;
357 }
358
359 template<>
360 basic_istream<char>&
361 getline(basic_istream<char>& __in, basic_string<char>& __str,
362 char __delim)
363 {
364 typedef basic_istream<char> __istream_type;
365 typedef __istream_type::int_type __int_type;
366 typedef __istream_type::char_type __char_type;
367 typedef __istream_type::traits_type __traits_type;
368 typedef __istream_type::__streambuf_type __streambuf_type;
369 typedef __istream_type::__ctype_type __ctype_type;
370 typedef basic_string<char> __string_type;
371 typedef __string_type::size_type __size_type;
372
373 __size_type __extracted = 0;
374 const __size_type __n = __str.max_size();
375 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
376 __istream_type::sentry __cerb(__in, true);
377 if (__cerb)
378 {
379 try
380 {
381 __str.erase();
382 const __int_type __idelim = __traits_type::to_int_type(__delim);
383 const __int_type __eof = __traits_type::eof();
384 __streambuf_type* __sb = __in.rdbuf();
385 __int_type __c = __sb->sgetc();
386
387 while (__extracted < __n
388 && !__traits_type::eq_int_type(__c, __eof)
389 && !__traits_type::eq_int_type(__c, __idelim))
390 {
391 streamsize __size = std::min(streamsize(__sb->egptr()
392 - __sb->gptr()),
393 streamsize(__n - __extracted));
394 if (__size > 1)
395 {
396 const __char_type* __p = __traits_type::find(__sb->gptr(),
397 __size,
398 __delim);
399 if (__p)
400 __size = __p - __sb->gptr();
401 __str.append(__sb->gptr(), __size);
402 __sb->gbump(__size);
403 __extracted += __size;
404 __c = __sb->sgetc();
405 }
406 else
407 {
408 __str += __traits_type::to_char_type(__c);
409 ++__extracted;
410 __c = __sb->snextc();
411 }
412 }
413
414 if (__traits_type::eq_int_type(__c, __eof))
415 __err |= ios_base::eofbit;
416 else if (__traits_type::eq_int_type(__c, __idelim))
417 {
418 ++__extracted;
419 __sb->sbumpc();
420 }
421 else
422 __err |= ios_base::failbit;
423 }
424 catch(__cxxabiv1::__forced_unwind&)
425 {
426 __in._M_setstate(ios_base::badbit);
427 __throw_exception_again;
428 }
429 catch(...)
430 {
431 // _GLIBCXX_RESOLVE_LIB_DEFECTS
432 // 91. Description of operator>> and getline() for string<>
433 // might cause endless loop
434 __in._M_setstate(ios_base::badbit);
435 }
436 }
437 if (!__extracted)
438 __err |= ios_base::failbit;
439 if (__err)
440 __in.setstate(__err);
441 return __in;
442 }
443
444 #ifdef _GLIBCXX_USE_WCHAR_T
445 template<>
446 basic_istream<wchar_t>&
447 basic_istream<wchar_t>::
448 getline(char_type* __s, streamsize __n, char_type __delim)
449 {
450 _M_gcount = 0;
451 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
452 sentry __cerb(*this, true);
453 if (__cerb)
454 {
455 try
456 {
457 const int_type __idelim = traits_type::to_int_type(__delim);
458 const int_type __eof = traits_type::eof();
459 __streambuf_type* __sb = this->rdbuf();
460 int_type __c = __sb->sgetc();
461
462 while (_M_gcount + 1 < __n
463 && !traits_type::eq_int_type(__c, __eof)
464 && !traits_type::eq_int_type(__c, __idelim))
465 {
466 streamsize __size = std::min(streamsize(__sb->egptr()
467 - __sb->gptr()),
468 streamsize(__n - _M_gcount
469 - 1));
470 if (__size > 1)
471 {
472 const char_type* __p = traits_type::find(__sb->gptr(),
473 __size,
474 __delim);
475 if (__p)
476 __size = __p - __sb->gptr();
477 traits_type::copy(__s, __sb->gptr(), __size);
478 __s += __size;
479 __sb->gbump(__size);
480 _M_gcount += __size;
481 __c = __sb->sgetc();
482 }
483 else
484 {
485 *__s++ = traits_type::to_char_type(__c);
486 ++_M_gcount;
487 __c = __sb->snextc();
488 }
489 }
490
491 if (traits_type::eq_int_type(__c, __eof))
492 __err |= ios_base::eofbit;
493 else if (traits_type::eq_int_type(__c, __idelim))
494 {
495 ++_M_gcount;
496 __sb->sbumpc();
497 }
498 else
499 __err |= ios_base::failbit;
500 }
501 catch(__cxxabiv1::__forced_unwind&)
502 {
503 this->_M_setstate(ios_base::badbit);
504 __throw_exception_again;
505 }
506 catch(...)
507 { this->_M_setstate(ios_base::badbit); }
508 }
509 // _GLIBCXX_RESOLVE_LIB_DEFECTS
510 // 243. get and getline when sentry reports failure.
511 if (__n > 0)
512 *__s = char_type();
513 if (!_M_gcount)
514 __err |= ios_base::failbit;
515 if (__err)
516 this->setstate(__err);
517 return *this;
518 }
519
520 template<>
521 basic_istream<wchar_t>&
522 basic_istream<wchar_t>::
523 ignore(streamsize __n, int_type __delim)
524 {
525 if (traits_type::eq_int_type(__delim, traits_type::eof()))
526 return ignore(__n);
527
528 _M_gcount = 0;
529 sentry __cerb(*this, true);
530 if (__cerb && __n > 0)
531 {
532 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
533 try
534 {
535 const char_type __cdelim = traits_type::to_char_type(__delim);
536 const int_type __eof = traits_type::eof();
537 __streambuf_type* __sb = this->rdbuf();
538 int_type __c = __sb->sgetc();
539
540 bool __large_ignore = false;
541 while (true)
542 {
543 while (_M_gcount < __n
544 && !traits_type::eq_int_type(__c, __eof)
545 && !traits_type::eq_int_type(__c, __delim))
546 {
547 streamsize __size = std::min(streamsize(__sb->egptr()
548 - __sb->gptr()),
549 streamsize(__n - _M_gcount));
550 if (__size > 1)
551 {
552 const char_type* __p = traits_type::find(__sb->gptr(),
553 __size,
554 __cdelim);
555 if (__p)
556 __size = __p - __sb->gptr();
557 __sb->gbump(__size);
558 _M_gcount += __size;
559 __c = __sb->sgetc();
560 }
561 else
562 {
563 ++_M_gcount;
564 __c = __sb->snextc();
565 }
566 }
567 if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max
568 && !traits_type::eq_int_type(__c, __eof)
569 && !traits_type::eq_int_type(__c, __delim))
570 {
571 _M_gcount =
572 __gnu_cxx::__numeric_traits<streamsize>::__min;
573 __large_ignore = true;
574 }
575 else
576 break;
577 }
578
579 if (__large_ignore)
580 _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max;
581
582 if (traits_type::eq_int_type(__c, __eof))
583 __err |= ios_base::eofbit;
584 else if (traits_type::eq_int_type(__c, __delim))
585 {
586 if (_M_gcount
587 < __gnu_cxx::__numeric_traits<streamsize>::__max)
588 ++_M_gcount;
589 __sb->sbumpc();
590 }
591 }
592 catch(__cxxabiv1::__forced_unwind&)
593 {
594 this->_M_setstate(ios_base::badbit);
595 __throw_exception_again;
596 }
597 catch(...)
598 { this->_M_setstate(ios_base::badbit); }
599 if (__err)
600 this->setstate(__err);
601 }
602 return *this;
603 }
604
605 template<>
606 basic_istream<wchar_t>&
607 getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str,
608 wchar_t __delim)
609 {
610 typedef basic_istream<wchar_t> __istream_type;
611 typedef __istream_type::int_type __int_type;
612 typedef __istream_type::char_type __char_type;
613 typedef __istream_type::traits_type __traits_type;
614 typedef __istream_type::__streambuf_type __streambuf_type;
615 typedef __istream_type::__ctype_type __ctype_type;
616 typedef basic_string<wchar_t> __string_type;
617 typedef __string_type::size_type __size_type;
618
619 __size_type __extracted = 0;
620 const __size_type __n = __str.max_size();
621 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
622 __istream_type::sentry __cerb(__in, true);
623 if (__cerb)
624 {
625 try
626 {
627 __str.erase();
628 const __int_type __idelim = __traits_type::to_int_type(__delim);
629 const __int_type __eof = __traits_type::eof();
630 __streambuf_type* __sb = __in.rdbuf();
631 __int_type __c = __sb->sgetc();
632
633 while (__extracted < __n
634 && !__traits_type::eq_int_type(__c, __eof)
635 && !__traits_type::eq_int_type(__c, __idelim))
636 {
637 streamsize __size = std::min(streamsize(__sb->egptr()
638 - __sb->gptr()),
639 streamsize(__n - __extracted));
640 if (__size > 1)
641 {
642 const __char_type* __p = __traits_type::find(__sb->gptr(),
643 __size,
644 __delim);
645 if (__p)
646 __size = __p - __sb->gptr();
647 __str.append(__sb->gptr(), __size);
648 __sb->gbump(__size);
649 __extracted += __size;
650 __c = __sb->sgetc();
651 }
652 else
653 {
654 __str += __traits_type::to_char_type(__c);
655 ++__extracted;
656 __c = __sb->snextc();
657 }
658 }
659
660 if (__traits_type::eq_int_type(__c, __eof))
661 __err |= ios_base::eofbit;
662 else if (__traits_type::eq_int_type(__c, __idelim))
663 {
664 ++__extracted;
665 __sb->sbumpc();
666 }
667 else
668 __err |= ios_base::failbit;
669 }
670 catch(__cxxabiv1::__forced_unwind&)
671 {
672 __in._M_setstate(ios_base::badbit);
673 __throw_exception_again;
674 }
675 catch(...)
676 {
677 // _GLIBCXX_RESOLVE_LIB_DEFECTS
678 // 91. Description of operator>> and getline() for string<>
679 // might cause endless loop
680 __in._M_setstate(ios_base::badbit);
681 }
682 }
683 if (!__extracted)
684 __err |= ios_base::failbit;
685 if (__err)
686 __in.setstate(__err);
687 return __in;
688 }
689 #endif
690
691 _GLIBCXX_END_NAMESPACE