OSDN Git Service

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