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