OSDN Git Service

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