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