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
_GLIBCXX_BEGIN_NAMESPACE(std)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(...)
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>::
ignore(streamsize __n,int_type __delim)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>&
operator >>(basic_istream<char> & __in,char * __s)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>&
operator >>(basic_istream<char> & __in,basic_string<char> & __str)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>&
getline(basic_istream<char> & __in,basic_string<char> & __str,char __delim)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>::
getline(char_type * __s,streamsize __n,char_type __delim)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>::
ignore(streamsize __n,int_type __delim)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>&
getline(basic_istream<wchar_t> & __in,basic_string<wchar_t> & __str,wchar_t __delim)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
647 _GLIBCXX_END_NAMESPACE
648