OSDN Git Service

2005-01-03 Paolo Carlini <pcarlini@suse.de>
[pf3gnuchains/gcc-fork.git] / 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
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)
112     {
113       if (__n == 1)
114         return ignore();
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 int_type __eof = traits_type::eof();
124               __streambuf_type* __sb = this->rdbuf();
125               int_type __c = __sb->sgetc();
126               
127               while (true)
128                 {
129                   while (_M_gcount < __n
130                          && !traits_type::eq_int_type(__c, __eof))
131                     {
132                       streamsize __size = std::min(streamsize(__sb->egptr()
133                                                               - __sb->gptr()),
134                                                    streamsize(__n - _M_gcount));
135                       if (__size > 1)
136                         {
137                           __sb->gbump(__size);
138                           _M_gcount += __size;
139                           __c = __sb->sgetc();
140                         }
141                       else
142                         {
143                           ++_M_gcount;
144                           __c = __sb->snextc();
145                         } 
146                     }
147                   if (__n == numeric_limits<streamsize>::max()
148                       && !traits_type::eq_int_type(__c, __eof))
149                     _M_gcount = numeric_limits<streamsize>::min();
150                   else
151                     break;
152                 }
153
154               if (traits_type::eq_int_type(__c, __eof))
155                 __err |= ios_base::eofbit;
156             }
157           catch(...)
158             { this->_M_setstate(ios_base::badbit); }
159           if (__err)
160             this->setstate(__err);
161         }
162       return *this;
163     }
164
165   template<>
166     basic_istream<char>&
167     basic_istream<char>::
168     ignore(streamsize __n, int_type __delim)
169     {
170       if (traits_type::eq_int_type(__delim, traits_type::eof()))
171         return ignore(__n);
172
173       _M_gcount = 0;
174       sentry __cerb(*this, true);
175       if (__cerb && __n > 0)
176         {
177           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
178           try
179             {
180               const char_type __cdelim = traits_type::to_char_type(__delim);          
181               const int_type __eof = traits_type::eof();
182               __streambuf_type* __sb = this->rdbuf();
183               int_type __c = __sb->sgetc();
184
185               while (true)
186                 {
187                   while (_M_gcount < __n
188                          && !traits_type::eq_int_type(__c, __eof)
189                          && !traits_type::eq_int_type(__c, __delim))
190                     {
191                       streamsize __size = std::min(streamsize(__sb->egptr()
192                                                               - __sb->gptr()),
193                                                    streamsize(__n - _M_gcount));
194                       if (__size > 1)
195                         {
196                           const char_type* __p = traits_type::find(__sb->gptr(),
197                                                                    __size,
198                                                                    __cdelim);
199                           if (__p)
200                             __size = __p - __sb->gptr();
201                           __sb->gbump(__size);
202                           _M_gcount += __size;
203                           __c = __sb->sgetc();
204                         }
205                       else
206                         {
207                           ++_M_gcount;
208                           __c = __sb->snextc();
209                         }
210                     }
211                   if (__n == numeric_limits<streamsize>::max()
212                       && !traits_type::eq_int_type(__c, __eof)
213                       && !traits_type::eq_int_type(__c, __delim))
214                     _M_gcount = numeric_limits<streamsize>::min();
215                   else
216                     break;
217                 }
218
219               if (traits_type::eq_int_type(__c, __eof))
220                 __err |= ios_base::eofbit;
221               else if (traits_type::eq_int_type(__c, __delim))
222                 {
223                   ++_M_gcount;
224                   __sb->sbumpc();
225                 }
226             }
227           catch(...)
228             { this->_M_setstate(ios_base::badbit); }
229           if (__err)
230             this->setstate(__err);
231         }
232       return *this;
233     }
234
235   template<>
236     basic_istream<char>&
237     getline(basic_istream<char>& __in, basic_string<char>& __str,
238             char __delim)
239     {
240       typedef basic_istream<char>               __istream_type;
241       typedef __istream_type::int_type          __int_type;
242       typedef __istream_type::char_type         __char_type;
243       typedef __istream_type::traits_type       __traits_type;
244       typedef __istream_type::__streambuf_type  __streambuf_type;
245       typedef __istream_type::__ctype_type      __ctype_type;
246       typedef basic_string<char>                __string_type;
247       typedef __string_type::size_type          __size_type;
248
249       __size_type __extracted = 0;
250       const __size_type __n = __str.max_size();
251       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
252       __istream_type::sentry __cerb(__in, true);
253       if (__cerb)
254         {
255           try
256             {
257               __str.erase();
258               const __int_type __idelim = __traits_type::to_int_type(__delim);
259               const __int_type __eof = __traits_type::eof();
260               __streambuf_type* __sb = __in.rdbuf();
261               __int_type __c = __sb->sgetc();
262
263               while (__extracted < __n
264                      && !__traits_type::eq_int_type(__c, __eof)
265                      && !__traits_type::eq_int_type(__c, __idelim))
266                 {
267                   streamsize __size = std::min(streamsize(__sb->egptr()
268                                                           - __sb->gptr()),
269                                                streamsize(__n - __extracted));
270                   if (__size > 1)
271                     {
272                       const __char_type* __p = __traits_type::find(__sb->gptr(),
273                                                                    __size,
274                                                                    __delim);
275                       if (__p)
276                         __size = __p - __sb->gptr();
277                       __str.append(__sb->gptr(), __size);
278                       __sb->gbump(__size);
279                       __extracted += __size;
280                       __c = __sb->sgetc();
281                     }
282                   else
283                     {
284                       __str += __traits_type::to_char_type(__c);
285                       ++__extracted;
286                       __c = __sb->snextc();
287                     }             
288                 }
289
290               if (__traits_type::eq_int_type(__c, __eof))
291                 __err |= ios_base::eofbit;
292               else if (__traits_type::eq_int_type(__c, __idelim))
293                 {
294                   ++__extracted;
295                   __sb->sbumpc();
296                 }
297               else
298                 __err |= ios_base::failbit;
299             }
300           catch(...)
301             {
302               // _GLIBCXX_RESOLVE_LIB_DEFECTS
303               // 91. Description of operator>> and getline() for string<>
304               // might cause endless loop
305               __in._M_setstate(ios_base::badbit);
306             }
307         }
308       if (!__extracted)
309         __err |= ios_base::failbit;
310       if (__err)
311         __in.setstate(__err);
312       return __in;
313     }
314
315 #ifdef _GLIBCXX_USE_WCHAR_T
316   template<>
317     basic_istream<wchar_t>&
318     basic_istream<wchar_t>::
319     getline(char_type* __s, streamsize __n, char_type __delim)
320     {
321       _M_gcount = 0;
322       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
323       sentry __cerb(*this, true);
324       if (__cerb)
325         {
326           try
327             {
328               const int_type __idelim = traits_type::to_int_type(__delim);
329               const int_type __eof = traits_type::eof();
330               __streambuf_type* __sb = this->rdbuf();
331               int_type __c = __sb->sgetc();
332               
333               while (_M_gcount + 1 < __n
334                      && !traits_type::eq_int_type(__c, __eof)
335                      && !traits_type::eq_int_type(__c, __idelim))
336                 {
337                   streamsize __size = std::min(streamsize(__sb->egptr()
338                                                           - __sb->gptr()),
339                                                streamsize(__n - _M_gcount
340                                                           - 1));
341                   if (__size > 1)
342                     {
343                       const char_type* __p = traits_type::find(__sb->gptr(),
344                                                                __size,
345                                                                __delim);
346                       if (__p)
347                         __size = __p - __sb->gptr();
348                       traits_type::copy(__s, __sb->gptr(), __size);
349                       __s += __size;
350                       __sb->gbump(__size);
351                       _M_gcount += __size;
352                       __c = __sb->sgetc();
353                     }
354                   else
355                     {
356                       *__s++ = traits_type::to_char_type(__c);
357                       ++_M_gcount;
358                       __c = __sb->snextc();
359                     }
360                 }
361
362               if (traits_type::eq_int_type(__c, __eof))
363                 __err |= ios_base::eofbit;
364               else if (traits_type::eq_int_type(__c, __idelim))
365                 {
366                   ++_M_gcount;            
367                   __sb->sbumpc();
368                 }
369               else
370                 __err |= ios_base::failbit;
371             }
372           catch(...)
373             { this->_M_setstate(ios_base::badbit); }
374         }
375       // _GLIBCXX_RESOLVE_LIB_DEFECTS
376       // 243. get and getline when sentry reports failure.
377       if (__n > 0)
378         *__s = char_type();
379       if (!_M_gcount)
380         __err |= ios_base::failbit;
381       if (__err)
382         this->setstate(__err);
383       return *this;
384     }
385
386   template<>
387     basic_istream<wchar_t>&
388     basic_istream<wchar_t>::
389     ignore(streamsize __n)
390     {
391       if (__n == 1)
392         return ignore();
393       
394       _M_gcount = 0;
395       sentry __cerb(*this, true);
396       if (__cerb && __n > 0)
397         {
398           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
399           try
400             {
401               const int_type __eof = traits_type::eof();
402               __streambuf_type* __sb = this->rdbuf();
403               int_type __c = __sb->sgetc();
404
405               while (true)
406                 {
407                   while (_M_gcount < __n
408                          && !traits_type::eq_int_type(__c, __eof))
409                     {
410                       streamsize __size = std::min(streamsize(__sb->egptr()
411                                                               - __sb->gptr()),
412                                                    streamsize(__n - _M_gcount));
413                       if (__size > 1)
414                         {
415                           __sb->gbump(__size);
416                           _M_gcount += __size;
417                           __c = __sb->sgetc();
418                         }
419                       else
420                         {
421                           ++_M_gcount;
422                           __c = __sb->snextc();
423                         }
424                     }
425                   if (__n == numeric_limits<streamsize>::max()
426                       && !traits_type::eq_int_type(__c, __eof))
427                     _M_gcount = numeric_limits<streamsize>::min();
428                   else
429                     break;
430                 }
431
432               if (traits_type::eq_int_type(__c, __eof))
433                 __err |= ios_base::eofbit;
434             }
435           catch(...)
436             { this->_M_setstate(ios_base::badbit); }
437           if (__err)
438             this->setstate(__err);
439         }
440       return *this;
441     }
442
443   template<>
444     basic_istream<wchar_t>&
445     basic_istream<wchar_t>::
446     ignore(streamsize __n, int_type __delim)
447     {
448       if (traits_type::eq_int_type(__delim, traits_type::eof()))
449         return ignore(__n);
450
451       _M_gcount = 0;
452       sentry __cerb(*this, true);
453       if (__cerb && __n > 0)
454         {
455           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
456           try
457             {
458               const char_type __cdelim = traits_type::to_char_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 (true)
464                 {
465                   while (_M_gcount < __n
466                          && !traits_type::eq_int_type(__c, __eof)
467                          && !traits_type::eq_int_type(__c, __delim))
468                     {
469                       streamsize __size = std::min(streamsize(__sb->egptr()
470                                                               - __sb->gptr()),
471                                                    streamsize(__n - _M_gcount));
472                       if (__size > 1)
473                         {
474                           const char_type* __p = traits_type::find(__sb->gptr(),
475                                                                    __size,
476                                                                    __cdelim);
477                           if (__p)
478                             __size = __p - __sb->gptr();
479                           __sb->gbump(__size);
480                           _M_gcount += __size;
481                           __c = __sb->sgetc();
482                         }
483                       else
484                         {
485                           ++_M_gcount;
486                           __c = __sb->snextc();
487                         }
488                     }
489                   if (__n == numeric_limits<streamsize>::max()
490                       && !traits_type::eq_int_type(__c, __eof)
491                       && !traits_type::eq_int_type(__c, __delim))
492                     _M_gcount = numeric_limits<streamsize>::min();
493                   else
494                     break;
495                 }
496
497               if (traits_type::eq_int_type(__c, __eof))
498                 __err |= ios_base::eofbit;
499               else if (traits_type::eq_int_type(__c, __delim))
500                 {
501                   ++_M_gcount;
502                   __sb->sbumpc();
503                 }
504             }
505           catch(...)
506             { this->_M_setstate(ios_base::badbit); }
507           if (__err)
508             this->setstate(__err);
509         }
510       return *this;
511     }
512
513   template<>
514     basic_istream<wchar_t>&
515     getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str,
516             wchar_t __delim)
517     {
518       typedef basic_istream<wchar_t>            __istream_type;
519       typedef __istream_type::int_type          __int_type;
520       typedef __istream_type::char_type         __char_type;
521       typedef __istream_type::traits_type       __traits_type;
522       typedef __istream_type::__streambuf_type  __streambuf_type;
523       typedef __istream_type::__ctype_type      __ctype_type;
524       typedef basic_string<wchar_t>             __string_type;
525       typedef __string_type::size_type          __size_type;
526
527       __size_type __extracted = 0;
528       const __size_type __n = __str.max_size();
529       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
530       __istream_type::sentry __cerb(__in, true);
531       if (__cerb)
532         {
533           try
534             {
535               __str.erase();
536               const __int_type __idelim = __traits_type::to_int_type(__delim);
537               const __int_type __eof = __traits_type::eof();
538               __streambuf_type* __sb = __in.rdbuf();
539               __int_type __c = __sb->sgetc();
540
541               while (__extracted < __n
542                      && !__traits_type::eq_int_type(__c, __eof)
543                      && !__traits_type::eq_int_type(__c, __idelim))
544                 {
545                   streamsize __size = std::min(streamsize(__sb->egptr()
546                                                           - __sb->gptr()),
547                                                streamsize(__n - __extracted));
548                   if (__size > 1)
549                     {
550                       const __char_type* __p = __traits_type::find(__sb->gptr(),
551                                                                    __size,
552                                                                    __delim);
553                       if (__p)
554                         __size = __p - __sb->gptr();
555                       __str.append(__sb->gptr(), __size);
556                       __sb->gbump(__size);
557                       __extracted += __size;
558                       __c = __sb->sgetc();
559                     }
560                   else
561                     {
562                       __str += __traits_type::to_char_type(__c);
563                       ++__extracted;
564                       __c = __sb->snextc();
565                     }             
566                 }
567
568               if (__traits_type::eq_int_type(__c, __eof))
569                 __err |= ios_base::eofbit;
570               else if (__traits_type::eq_int_type(__c, __idelim))
571                 {
572                   ++__extracted;
573                   __sb->sbumpc();
574                 }
575               else
576                 __err |= ios_base::failbit;
577             }
578           catch(...)
579             {
580               // _GLIBCXX_RESOLVE_LIB_DEFECTS
581               // 91. Description of operator>> and getline() for string<>
582               // might cause endless loop
583               __in._M_setstate(ios_base::badbit);
584             }
585         }
586       if (!__extracted)
587         __err |= ios_base::failbit;
588       if (__err)
589         __in.setstate(__err);
590       return __in;
591     }
592 #endif
593 } // namespace std