OSDN Git Service

e550306a0e69d7f45b2bd00561e275a56d9b95bd
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / src / 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->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->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->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::char_type         __char_type;
284       typedef __istream_type::traits_type       __traits_type;
285       typedef __istream_type::__streambuf_type  __streambuf_type;
286       typedef __istream_type::__ctype_type      __ctype_type;
287       typedef basic_string<char>                __string_type;
288       typedef __string_type::size_type          __size_type;
289
290       __size_type __extracted = 0;
291       ios_base::iostate __err = ios_base::goodbit;
292       __istream_type::sentry __cerb(__in, false);
293       if (__cerb)
294         {
295           __try
296             {
297               __str.erase();
298               const streamsize __w = __in.width();
299               const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
300                                               : __str.max_size();
301               const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
302               const __int_type __eof = __traits_type::eof();
303               __streambuf_type* __sb = __in.rdbuf();
304               __int_type __c = __sb->sgetc();
305
306               while (__extracted < __n
307                      && !__traits_type::eq_int_type(__c, __eof)
308                      && !__ct.is(ctype_base::space,
309                                  __traits_type::to_char_type(__c)))
310                 {
311                   streamsize __size = std::min(streamsize(__sb->egptr()
312                                                           - __sb->gptr()),
313                                                streamsize(__n - __extracted));
314                   if (__size > 1)
315                     {
316                       __size = (__ct.scan_is(ctype_base::space,
317                                              __sb->gptr() + 1,
318                                              __sb->gptr() + __size)
319                                 - __sb->gptr());
320                       __str.append(__sb->gptr(), __size);
321                       __sb->gbump(__size);
322                       __extracted += __size;
323                       __c = __sb->sgetc();
324                     }
325                   else
326                     {
327                       __str += __traits_type::to_char_type(__c);
328                       ++__extracted;
329                       __c = __sb->snextc();
330                     }             
331                 }
332
333               if (__traits_type::eq_int_type(__c, __eof))
334                 __err |= ios_base::eofbit;
335               __in.width(0);
336             }
337           __catch(__cxxabiv1::__forced_unwind&)
338             {
339               __in._M_setstate(ios_base::badbit);
340               __throw_exception_again;
341             }
342           __catch(...)
343             {
344               // _GLIBCXX_RESOLVE_LIB_DEFECTS
345               // 91. Description of operator>> and getline() for string<>
346               // might cause endless loop
347               __in._M_setstate(ios_base::badbit);
348             }
349         }
350       if (!__extracted)
351         __err |= ios_base::failbit;
352       if (__err)
353         __in.setstate(__err);
354       return __in;
355     }
356
357   template<>
358     basic_istream<char>&
359     getline(basic_istream<char>& __in, basic_string<char>& __str,
360             char __delim)
361     {
362       typedef basic_istream<char>               __istream_type;
363       typedef __istream_type::int_type          __int_type;
364       typedef __istream_type::char_type         __char_type;
365       typedef __istream_type::traits_type       __traits_type;
366       typedef __istream_type::__streambuf_type  __streambuf_type;
367       typedef __istream_type::__ctype_type      __ctype_type;
368       typedef basic_string<char>                __string_type;
369       typedef __string_type::size_type          __size_type;
370
371       __size_type __extracted = 0;
372       const __size_type __n = __str.max_size();
373       ios_base::iostate __err = ios_base::goodbit;
374       __istream_type::sentry __cerb(__in, true);
375       if (__cerb)
376         {
377           __try
378             {
379               __str.erase();
380               const __int_type __idelim = __traits_type::to_int_type(__delim);
381               const __int_type __eof = __traits_type::eof();
382               __streambuf_type* __sb = __in.rdbuf();
383               __int_type __c = __sb->sgetc();
384
385               while (__extracted < __n
386                      && !__traits_type::eq_int_type(__c, __eof)
387                      && !__traits_type::eq_int_type(__c, __idelim))
388                 {
389                   streamsize __size = std::min(streamsize(__sb->egptr()
390                                                           - __sb->gptr()),
391                                                streamsize(__n - __extracted));
392                   if (__size > 1)
393                     {
394                       const __char_type* __p = __traits_type::find(__sb->gptr(),
395                                                                    __size,
396                                                                    __delim);
397                       if (__p)
398                         __size = __p - __sb->gptr();
399                       __str.append(__sb->gptr(), __size);
400                       __sb->gbump(__size);
401                       __extracted += __size;
402                       __c = __sb->sgetc();
403                     }
404                   else
405                     {
406                       __str += __traits_type::to_char_type(__c);
407                       ++__extracted;
408                       __c = __sb->snextc();
409                     }             
410                 }
411
412               if (__traits_type::eq_int_type(__c, __eof))
413                 __err |= ios_base::eofbit;
414               else if (__traits_type::eq_int_type(__c, __idelim))
415                 {
416                   ++__extracted;
417                   __sb->sbumpc();
418                 }
419               else
420                 __err |= ios_base::failbit;
421             }
422           __catch(__cxxabiv1::__forced_unwind&)
423             {
424               __in._M_setstate(ios_base::badbit);
425               __throw_exception_again;
426             }
427           __catch(...)
428             {
429               // _GLIBCXX_RESOLVE_LIB_DEFECTS
430               // 91. Description of operator>> and getline() for string<>
431               // might cause endless loop
432               __in._M_setstate(ios_base::badbit);
433             }
434         }
435       if (!__extracted)
436         __err |= ios_base::failbit;
437       if (__err)
438         __in.setstate(__err);
439       return __in;
440     }
441
442 #ifdef _GLIBCXX_USE_WCHAR_T
443   template<>
444     basic_istream<wchar_t>&
445     basic_istream<wchar_t>::
446     getline(char_type* __s, streamsize __n, char_type __delim)
447     {
448       _M_gcount = 0;
449       ios_base::iostate __err = ios_base::goodbit;
450       sentry __cerb(*this, true);
451       if (__cerb)
452         {
453           __try
454             {
455               const int_type __idelim = traits_type::to_int_type(__delim);
456               const int_type __eof = traits_type::eof();
457               __streambuf_type* __sb = this->rdbuf();
458               int_type __c = __sb->sgetc();
459               
460               while (_M_gcount + 1 < __n
461                      && !traits_type::eq_int_type(__c, __eof)
462                      && !traits_type::eq_int_type(__c, __idelim))
463                 {
464                   streamsize __size = std::min(streamsize(__sb->egptr()
465                                                           - __sb->gptr()),
466                                                streamsize(__n - _M_gcount
467                                                           - 1));
468                   if (__size > 1)
469                     {
470                       const char_type* __p = traits_type::find(__sb->gptr(),
471                                                                __size,
472                                                                __delim);
473                       if (__p)
474                         __size = __p - __sb->gptr();
475                       traits_type::copy(__s, __sb->gptr(), __size);
476                       __s += __size;
477                       __sb->gbump(__size);
478                       _M_gcount += __size;
479                       __c = __sb->sgetc();
480                     }
481                   else
482                     {
483                       *__s++ = traits_type::to_char_type(__c);
484                       ++_M_gcount;
485                       __c = __sb->snextc();
486                     }
487                 }
488
489               if (traits_type::eq_int_type(__c, __eof))
490                 __err |= ios_base::eofbit;
491               else if (traits_type::eq_int_type(__c, __idelim))
492                 {
493                   ++_M_gcount;            
494                   __sb->sbumpc();
495                 }
496               else
497                 __err |= ios_base::failbit;
498             }
499           __catch(__cxxabiv1::__forced_unwind&)
500             {
501               this->_M_setstate(ios_base::badbit);
502               __throw_exception_again;
503             }
504           __catch(...)
505             { this->_M_setstate(ios_base::badbit); }
506         }
507       // _GLIBCXX_RESOLVE_LIB_DEFECTS
508       // 243. get and getline when sentry reports failure.
509       if (__n > 0)
510         *__s = char_type();
511       if (!_M_gcount)
512         __err |= ios_base::failbit;
513       if (__err)
514         this->setstate(__err);
515       return *this;
516     }
517
518   template<>
519     basic_istream<wchar_t>&
520     basic_istream<wchar_t>::
521     ignore(streamsize __n, int_type __delim)
522     {
523       if (traits_type::eq_int_type(__delim, traits_type::eof()))
524         return ignore(__n);
525
526       _M_gcount = 0;
527       sentry __cerb(*this, true);
528       if (__n > 0 && __cerb)
529         {
530           ios_base::iostate __err = ios_base::goodbit;
531           __try
532             {
533               const char_type __cdelim = traits_type::to_char_type(__delim);
534               const int_type __eof = traits_type::eof();
535               __streambuf_type* __sb = this->rdbuf();
536               int_type __c = __sb->sgetc();
537
538               bool __large_ignore = false;
539               while (true)
540                 {
541                   while (_M_gcount < __n
542                          && !traits_type::eq_int_type(__c, __eof)
543                          && !traits_type::eq_int_type(__c, __delim))
544                     {
545                       streamsize __size = std::min(streamsize(__sb->egptr()
546                                                               - __sb->gptr()),
547                                                    streamsize(__n - _M_gcount));
548                       if (__size > 1)
549                         {
550                           const char_type* __p = traits_type::find(__sb->gptr(),
551                                                                    __size,
552                                                                    __cdelim);
553                           if (__p)
554                             __size = __p - __sb->gptr();
555                           __sb->gbump(__size);
556                           _M_gcount += __size;
557                           __c = __sb->sgetc();
558                         }
559                       else
560                         {
561                           ++_M_gcount;
562                           __c = __sb->snextc();
563                         }
564                     }
565                   if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max
566                       && !traits_type::eq_int_type(__c, __eof)
567                       && !traits_type::eq_int_type(__c, __delim))
568                     {
569                       _M_gcount =
570                         __gnu_cxx::__numeric_traits<streamsize>::__min;
571                       __large_ignore = true;
572                     }
573                   else
574                     break;
575                 }
576
577               if (__large_ignore)
578                 _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max;
579
580               if (traits_type::eq_int_type(__c, __eof))
581                 __err |= ios_base::eofbit;
582               else if (traits_type::eq_int_type(__c, __delim))
583                 {
584                   if (_M_gcount
585                       < __gnu_cxx::__numeric_traits<streamsize>::__max)
586                     ++_M_gcount;
587                   __sb->sbumpc();
588                 }
589             }
590           __catch(__cxxabiv1::__forced_unwind&)
591             {
592               this->_M_setstate(ios_base::badbit);
593               __throw_exception_again;
594             }
595           __catch(...)
596             { this->_M_setstate(ios_base::badbit); }
597           if (__err)
598             this->setstate(__err);
599         }
600       return *this;
601     }
602
603   template<>
604     basic_istream<wchar_t>&
605     getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str,
606             wchar_t __delim)
607     {
608       typedef basic_istream<wchar_t>            __istream_type;
609       typedef __istream_type::int_type          __int_type;
610       typedef __istream_type::char_type         __char_type;
611       typedef __istream_type::traits_type       __traits_type;
612       typedef __istream_type::__streambuf_type  __streambuf_type;
613       typedef __istream_type::__ctype_type      __ctype_type;
614       typedef basic_string<wchar_t>             __string_type;
615       typedef __string_type::size_type          __size_type;
616
617       __size_type __extracted = 0;
618       const __size_type __n = __str.max_size();
619       ios_base::iostate __err = ios_base::goodbit;
620       __istream_type::sentry __cerb(__in, true);
621       if (__cerb)
622         {
623           __try
624             {
625               __str.erase();
626               const __int_type __idelim = __traits_type::to_int_type(__delim);
627               const __int_type __eof = __traits_type::eof();
628               __streambuf_type* __sb = __in.rdbuf();
629               __int_type __c = __sb->sgetc();
630
631               while (__extracted < __n
632                      && !__traits_type::eq_int_type(__c, __eof)
633                      && !__traits_type::eq_int_type(__c, __idelim))
634                 {
635                   streamsize __size = std::min(streamsize(__sb->egptr()
636                                                           - __sb->gptr()),
637                                                streamsize(__n - __extracted));
638                   if (__size > 1)
639                     {
640                       const __char_type* __p = __traits_type::find(__sb->gptr(),
641                                                                    __size,
642                                                                    __delim);
643                       if (__p)
644                         __size = __p - __sb->gptr();
645                       __str.append(__sb->gptr(), __size);
646                       __sb->gbump(__size);
647                       __extracted += __size;
648                       __c = __sb->sgetc();
649                     }
650                   else
651                     {
652                       __str += __traits_type::to_char_type(__c);
653                       ++__extracted;
654                       __c = __sb->snextc();
655                     }             
656                 }
657
658               if (__traits_type::eq_int_type(__c, __eof))
659                 __err |= ios_base::eofbit;
660               else if (__traits_type::eq_int_type(__c, __idelim))
661                 {
662                   ++__extracted;
663                   __sb->sbumpc();
664                 }
665               else
666                 __err |= ios_base::failbit;
667             }
668           __catch(__cxxabiv1::__forced_unwind&)
669             {
670               __in._M_setstate(ios_base::badbit);
671               __throw_exception_again;
672             }
673           __catch(...)
674             {
675               // _GLIBCXX_RESOLVE_LIB_DEFECTS
676               // 91. Description of operator>> and getline() for string<>
677               // might cause endless loop
678               __in._M_setstate(ios_base::badbit);
679             }
680         }
681       if (!__extracted)
682         __err |= ios_base::failbit;
683       if (__err)
684         __in.setstate(__err);
685       return __in;
686     }
687 #endif
688
689 _GLIBCXX_END_NAMESPACE_VERSION
690 } // namespace