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