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