• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 1999
3  * Silicon Graphics Computer Systems, Inc.
4  *
5  * Copyright (c) 1999
6  * Boris Fomitchev
7  *
8  * This material is provided "as is", with absolutely no warranty expressed
9  * or implied. Any use is at your own risk.
10  *
11  * Permission to use or copy this software for any purpose is hereby granted
12  * without fee, provided the above notices are retained on all copies.
13  * Permission to modify the code and to distribute modified code is granted,
14  * provided the above notices are retained, and a notice that the code was
15  * modified is included with the above copyright notice.
16  *
17  */
18 #ifndef _STLP_ISTREAM_C
19 #define _STLP_ISTREAM_C
20 
21 #ifndef _STLP_INTERNAL_ISTREAM
22 #  include <stl/_istream.h>
23 #endif
24 
25 #ifndef _STLP_INTERNAL_LIMITS
26 #  include <stl/_limits.h>
27 #endif
28 
29 #ifndef _STLP_INTERNAL_NUM_GET_H
30 #  include <stl/_num_get.h>
31 #endif
32 
33 #if defined ( _STLP_NESTED_TYPE_PARAM_BUG )
34 // no wchar_t is supported for this mode
35 #  define __BIS_int_type__ int
36 #  define __BIS_pos_type__ streampos
37 #  define __BIS_off_type__ streamoff
38 #else
39 #  define __BIS_int_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_istream<_CharT, _Traits>::int_type
40 #  define __BIS_pos_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_istream<_CharT, _Traits>::pos_type
41 #  define __BIS_off_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_istream<_CharT, _Traits>::off_type
42 #endif
43 
44 _STLP_BEGIN_NAMESPACE
45 
46 //----------------------------------------------------------------------
47 // Function object structs used by some member functions.
48 
49 _STLP_MOVE_TO_PRIV_NAMESPACE
50 
51 template <class _Traits>
52 struct _Is_not_wspace {
53   typedef typename _Traits::char_type argument_type;
54   typedef bool                        result_type;
55 
56   const ctype<argument_type>* _M_ctype;
57 
_Is_not_wspace_Is_not_wspace58   _Is_not_wspace(const ctype<argument_type>* __c_type) : _M_ctype(__c_type) {}
operator_Is_not_wspace59   bool operator()(argument_type __c) const
60     { return !_M_ctype->is(ctype_base::space, __c); }
61 };
62 
63 template <class _Traits>
64 struct _Is_wspace_null {
65   typedef typename _Traits::char_type argument_type;
66   typedef bool                        result_type;
67 
68   const ctype<argument_type>* _M_ctype;
69 
_Is_wspace_null_Is_wspace_null70   _Is_wspace_null(const ctype<argument_type>* __c_type) : _M_ctype(__c_type) {}
operator_Is_wspace_null71   bool operator()(argument_type __c) const {
72     return _Traits::eq(__c, argument_type()) ||
73            _M_ctype->is(ctype_base::space, __c);
74   }
75 };
76 
77 template <class _Traits>
78 struct _Scan_for_wspace {
79   typedef typename _Traits::char_type  char_type;
80   typedef char_type*                   first_argument_type;
81   typedef char_type*                   second_argument_type;
82   typedef char_type*                   result_type;
83 
84   const ctype<char_type>* _M_ctype;
85 
_Scan_for_wspace_Scan_for_wspace86   _Scan_for_wspace(const ctype<char_type>* __ctype) : _M_ctype(__ctype) {}
87   const char_type*
operator_Scan_for_wspace88   operator()(const char_type* __first, const char_type* __last) const {
89     return _M_ctype->scan_is(ctype_base::space, __first, __last);
90   }
91 };
92 
93 template <class _Traits>
94 struct _Scan_wspace_null {
95   typedef typename _Traits::char_type  char_type;
96   typedef char_type*                   first_argument_type;
97   typedef char_type*                   second_argument_type;
98   typedef char_type*                   result_type;
99 
100   const ctype<char_type>* _M_ctype;
101 
_Scan_wspace_null_Scan_wspace_null102   _Scan_wspace_null(const ctype<char_type>* __c_type) : _M_ctype(__c_type) {}
103   const char_type*
operator_Scan_wspace_null104   operator()(const char_type* __first, const char_type* __last) const {
105     __last = find_if(__first, __last,
106                      _Eq_char_bound<_Traits>(char_type()));
107     return _M_ctype->scan_is(ctype_base::space, __first, __last);
108   }
109 };
110 
111 template <class _Traits>
112 struct _Scan_for_not_wspace {
113   typedef typename _Traits::char_type  char_type;
114   typedef char_type*                   first_argument_type;
115   typedef char_type*                   second_argument_type;
116   typedef char_type*                   result_type;
117 
118   const ctype<char_type>* _M_ctype;
119 
_Scan_for_not_wspace_Scan_for_not_wspace120   _Scan_for_not_wspace(const ctype<char_type>* __c_type) : _M_ctype(__c_type) {}
121   const char_type*
operator_Scan_for_not_wspace122   operator()(const char_type* __first, const char_type* __last) const {
123     return _M_ctype->scan_not(ctype_base::space, __first, __last);
124   }
125 };
126 
127 template <class _Traits>
128 struct _Scan_for_char_val {
129   typedef typename _Traits::char_type char_type;
130   typedef char_type*                  first_argument_type;
131   typedef char_type*                  second_argument_type;
132   typedef char_type*                  result_type;
133 
134   char_type _M_val;
135 
_Scan_for_char_val_Scan_for_char_val136   _Scan_for_char_val(char_type __val) : _M_val(__val) {}
137 
138   const char_type*
operator_Scan_for_char_val139   operator()(const char_type* __first, const char_type* __last) const {
140     return find_if(__first, __last, _Eq_char_bound<_Traits>(_M_val));
141   }
142 };
143 
144 template <class _Traits>
145 struct _Scan_for_int_val {
146   typedef typename _Traits::char_type char_type;
147   typedef typename _Traits::int_type  int_type;
148   typedef char_type*                  first_argument_type;
149   typedef char_type*                  second_argument_type;
150   typedef char_type*                  result_type;
151 
152   int_type _M_val;
153 
_Scan_for_int_val_Scan_for_int_val154   _Scan_for_int_val(int_type __val) : _M_val(__val) {}
155 
156   const char_type*
operator_Scan_for_int_val157   operator()(const char_type* __first, const char_type* __last) const {
158     return find_if(__first, __last,
159                    _Eq_int_bound<_Traits>(_M_val));
160   }
161 };
162 
163 // Helper function: try to push back a character to a streambuf,
164 // return true if the pushback succeeded.  Does not throw.
165 
166 template <class _CharT, class _Traits>
167 bool _STLP_CALL
__pushback(basic_streambuf<_CharT,_Traits> * __buf,_CharT __c)168 __pushback(basic_streambuf<_CharT, _Traits>* __buf, _CharT __c) {
169   bool ret;
170   _STLP_TRY {
171     const typename _Traits::int_type __eof = _Traits::eof();
172     ret = !_Traits::eq_int_type(__buf->sputbackc(__c), __eof);
173   }
174   _STLP_CATCH_ALL {
175     ret = false;
176   }
177   return ret;
178 }
179 
180 //----------------------------------------------------------------------
181 // Definitions of basic_istream<>'s noninline member functions.
182 
183 // Helper function for formatted input of numbers.
184 template <class _CharT, class _Traits, class _Number>
185 ios_base::iostate _STLP_CALL
__get_num(basic_istream<_CharT,_Traits> & __that,_Number & __val)186 __get_num(basic_istream<_CharT, _Traits>& __that, _Number& __val) {
187   typedef typename basic_istream<_CharT, _Traits>::sentry _Sentry;
188   ios_base::iostate __err = 0;
189   _Sentry __sentry( __that );     // Skip whitespace.
190   if (__sentry) {
191     typedef num_get<_CharT, istreambuf_iterator<_CharT, _Traits> > _Num_get;
192     _STLP_TRY {
193       // Do not remove additional parenthesis around use_facet instanciation, some compilers (VC6)
194       // require it when building the library.
195       (use_facet<_Num_get>(__that.getloc())).get(istreambuf_iterator<_CharT, _Traits>(__that.rdbuf()),
196                                                0, __that, __err, __val);
197     }
198     _STLP_CATCH_ALL {
199       __that._M_handle_exception(ios_base::badbit);
200     }
201     if (__err) __that.setstate(__err);
202   }
203   return __err;
204 }
205 
206 _STLP_MOVE_TO_STD_NAMESPACE
207 
208 template <class _CharT, class _Traits>
209 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (short& __val) {
210 #if 0 // This breaks __get_integer for short.
211 // BEGIN Android-removed.
212   long __lval;
213   _STLP_PRIV __get_num(*this, __lval);
214   if ( this->fail() ) {
215     return *this;
216   }
217   short __tmp = __STATIC_CAST(short, __lval);
218   unsigned short __uval = __STATIC_CAST(unsigned short, __lval);
219   // check if we lose digits
220   //    if ((__val != __lval) && ((unsigned short)__val != __lval))
221   if ((__tmp != __lval) && ((long)__uval != __lval))
222     this->setstate(ios_base::failbit);
223   else
224     __val = __tmp;
225   return *this;
226 // END Android-removed.
227 #else
228   _STLP_PRIV __get_num(*this, __val);
229   return *this;
230 #endif
231 }
232 
233 template <class _CharT, class _Traits>
234 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (int& __val) {
235 #if 0 // This seems to work, but there doesn't seem to be any reason for it.
236 // BEGIN Android-removed.
237   long __lval;
238   _STLP_PRIV __get_num(*this, __lval);
239   if ( this->fail() ) {
240     return *this;
241   }
242   int __tmp = __lval;
243   unsigned int __uval = __lval;
244   // check if we lose digits
245   //    if ((__val != __lval) && ((unsigned int)__val != __lval))
246   if ((__tmp != __lval) && ((long)__uval != __lval))
247     this->setstate(ios_base::failbit);
248   else
249     __val = __tmp;
250   return *this;
251 // END Android-removed.
252 #else
253   _STLP_PRIV __get_num(*this, __val);
254   return *this;
255 #endif
256 }
257 
258 template <class _CharT, class _Traits>
259 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (unsigned short& __val) {
260   _STLP_PRIV __get_num(*this, __val);
261   return *this;
262 }
263 
264 template <class _CharT, class _Traits>
265 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (unsigned int& __val) {
266   _STLP_PRIV __get_num(*this, __val);
267   return *this;
268 }
269 
270 template <class _CharT, class _Traits>
271 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (long& __val) {
272   _STLP_PRIV __get_num(*this, __val);
273   return *this;
274 }
275 
276 template <class _CharT, class _Traits>
277 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (unsigned long& __val) {
278   _STLP_PRIV __get_num(*this, __val);
279   return *this;
280 }
281 
282 #if defined (_STLP_LONG_LONG)
283 template <class _CharT, class _Traits>
284 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (_STLP_LONG_LONG& __val) {
285   _STLP_PRIV __get_num(*this, __val);
286   return *this;
287 }
288 
289 template <class _CharT, class _Traits>
290 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (unsigned _STLP_LONG_LONG& __val) {
291   _STLP_PRIV __get_num(*this, __val);
292   return *this;
293 }
294 #endif
295 template <class _CharT, class _Traits>
296 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (float& __val) {
297   _STLP_PRIV __get_num(*this, __val);
298   return *this;
299 }
300 template <class _CharT, class _Traits>
301 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (double& __val) {
302   _STLP_PRIV __get_num(*this, __val);
303   return *this;
304 }
305 #if !defined (_STLP_NO_LONG_DOUBLE)
306 template <class _CharT, class _Traits>
307 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (long double& __val) {
308   _STLP_PRIV __get_num(*this, __val);
309   return *this;
310 }
311 #endif
312 #if !defined (_STLP_NO_BOOL)
313 template <class _CharT, class _Traits>
314 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (bool& __val) {
315   _STLP_PRIV __get_num(*this, __val);
316   return *this;
317 }
318 #endif
319 
320 template <class _CharT, class _Traits>
321 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (void*& __val) {
322   _STLP_PRIV __get_num(*this, __val);
323   return *this;
324 }
325 
326 // Unformatted input
327 
328 template <class _CharT, class _Traits>
329 __BIS_int_type__
peek()330 basic_istream<_CharT, _Traits>::peek() {
331   typename _Traits::int_type __tmp = _Traits::eof();
332 
333   this->_M_gcount = 0;
334   sentry __sentry(*this, _No_Skip_WS());
335 
336   if (__sentry) {
337     _STLP_TRY {
338       __tmp = this->rdbuf()->sgetc();
339     }
340     _STLP_CATCH_ALL {
341       this->_M_handle_exception(ios_base::badbit);
342     }
343     if (this->_S_eof(__tmp))
344       this->setstate(ios_base::eofbit);
345   }
346 
347   return __tmp;
348 }
349 
350 
351 template <class _CharT, class _Traits>
352 __BIS_int_type__
get()353 basic_istream<_CharT, _Traits>::get() {
354   typename _Traits::int_type __tmp = _Traits::eof();
355   sentry __sentry(*this, _No_Skip_WS());
356   this->_M_gcount = 0;
357 
358   if (__sentry) {
359     _STLP_TRY {
360       __tmp = this->rdbuf()->sbumpc();
361     }
362     _STLP_CATCH_ALL {
363       this->_M_handle_exception(ios_base::badbit);
364     }
365 
366     if (!this->_S_eof(__tmp))
367       this->_M_gcount = 1;
368   }
369 
370   if (_M_gcount == 0)
371     this->setstate(ios_base::eofbit | ios_base::failbit);
372 
373   return __tmp;
374 }
375 
376 template <class _CharT, class _Traits>
377 basic_istream<_CharT, _Traits>&
get(_CharT & __c)378 basic_istream<_CharT, _Traits>::get(_CharT& __c) {
379   sentry __sentry(*this, _No_Skip_WS());
380   this->_M_gcount = 0;
381 
382   if (__sentry) {
383     typename _Traits::int_type __tmp = _Traits::eof();
384     _STLP_TRY {
385       __tmp = this->rdbuf()->sbumpc();
386     }
387     _STLP_CATCH_ALL {
388       this->_M_handle_exception(ios_base::badbit);
389     }
390 
391     if (!this->_S_eof(__tmp)) {
392       this->_M_gcount = 1;
393       __c = _Traits::to_char_type(__tmp);
394     }
395   }
396 
397   if (this->_M_gcount == 0)
398     this->setstate(ios_base::eofbit | ios_base::failbit);
399 
400   return *this;
401 }
402 
403 
404 // Read characters and discard them.  The standard specifies a single
405 // function with two arguments, each with a default.  We instead use
406 // three overloded functions, because it's possible to implement the
407 // first two more efficiently than the fully general third version.
408 template <class _CharT, class _Traits>
ignore()409 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::ignore() {
410   sentry __sentry(*this, _No_Skip_WS());
411   this->_M_gcount = 0;
412 
413   if (__sentry) {
414     int_type __c;
415     _STLP_TRY {
416       __c = this->rdbuf()->sbumpc();
417     }
418     _STLP_CATCH_ALL {
419       this->_M_handle_exception(ios_base::badbit);
420       return *this;
421     }
422 
423     if (!this->_S_eof(__c))
424       this->_M_gcount = 1;
425     else
426       this->setstate(ios_base::eofbit);
427   }
428 
429   return *this;
430 }
431 
432 // Putback
433 
434 template <class _CharT, class _Traits>
435 basic_istream<_CharT, _Traits>&
putback(_CharT __c)436 basic_istream<_CharT, _Traits>::putback(_CharT __c) {
437   this->_M_gcount = 0;
438   sentry __sentry(*this, _No_Skip_WS());
439 
440   if (__sentry) {
441     typename _Traits::int_type __tmp = _Traits::eof();
442     basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();
443 //    if (!__buf || this->_S_eof(__buf->sputbackc(__c)))
444     if (__buf) {
445       _STLP_TRY {
446         __tmp = __buf->sputbackc(__c);
447       }
448       _STLP_CATCH_ALL {
449         this->_M_handle_exception(ios_base::badbit);
450       }
451     }
452     if (this->_S_eof(__tmp))
453       this->setstate(ios_base::badbit);
454   }
455   else
456     this->setstate(ios_base::failbit);
457 
458   return *this;
459 }
460 
461 template <class _CharT, class _Traits>
unget()462 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::unget() {
463   this->_M_gcount = 0;
464 
465   sentry __sentry(*this, _No_Skip_WS());
466 
467   if (__sentry) {
468     basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();
469     //     if (!__buf || _Traits::eq_int_type(__buf->sungetc(), _Traits::eof()))
470     if (__buf) {
471       _STLP_TRY {
472         if (this->_S_eof(__buf->sungetc()))
473           this->setstate(ios_base::badbit);
474       }
475       _STLP_CATCH_ALL {
476         this->_M_handle_exception(ios_base::badbit);
477       }
478     } else
479       this->setstate(ios_base::badbit);
480   }
481   else
482     this->setstate(ios_base::failbit);
483 
484   return *this;
485 }
486 
487 // Positioning and buffer control.
488 
489 template <class _CharT, class _Traits>
sync()490 int basic_istream<_CharT, _Traits>::sync() {
491   sentry __sentry(*this, _No_Skip_WS());
492 
493   basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();
494   if (__buf) {
495     if (__buf->pubsync() == -1) {
496       this->setstate(ios_base::badbit);
497       return -1;
498     }
499     else
500       return 0;
501   }
502   else
503     return -1;
504 }
505 
506 template <class _CharT, class _Traits>
507 __BIS_pos_type__
tellg()508 basic_istream<_CharT, _Traits>::tellg() {
509   sentry __sentry(*this, _No_Skip_WS());
510 
511   basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();
512   return (__buf && !this->fail()) ? __buf->pubseekoff(0, ios_base::cur, ios_base::in)
513     : pos_type(-1);
514 }
515 
516 template <class _CharT, class _Traits>
517 basic_istream<_CharT, _Traits>&
seekg(pos_type __pos)518 basic_istream<_CharT, _Traits>::seekg(pos_type __pos) {
519   sentry __sentry(*this, _No_Skip_WS());
520 
521   basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();
522   if (!this->fail() && __buf) {
523     if (__buf->pubseekpos(__pos, ios_base::in) == pos_type(-1)) {
524       this->setstate(ios_base::failbit);
525     }
526   }
527   return *this;
528 }
529 
530 template <class _CharT, class _Traits>
531 basic_istream<_CharT, _Traits>&
seekg(off_type __off,ios_base::seekdir __dir)532 basic_istream<_CharT, _Traits>::seekg(off_type __off, ios_base::seekdir __dir) {
533   sentry __sentry(*this, _No_Skip_WS());
534 
535   basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();
536   if (!this->fail() && __buf)
537     __buf->pubseekoff(__off, __dir, ios_base::in);
538   return *this;
539 }
540 
541 // Formatted input of characters and character arrays.
542 
543 template <class _CharT, class _Traits>
_M_formatted_get(_CharT & __c)544 void basic_istream<_CharT, _Traits>::_M_formatted_get(_CharT& __c) {
545 //  typename _Traits::int_type __tmp = _Traits::eof();
546 
547   sentry __sentry(*this); // Skip whitespace.
548 
549   if (__sentry) {
550     typename _Traits::int_type __tmp;// = _Traits::eof();
551 
552     _STLP_TRY {
553       __tmp = this->rdbuf()->sbumpc();
554     }
555     _STLP_CATCH_ALL {
556       this->_M_handle_exception(ios_base::badbit);
557       return;
558     }
559 
560     if (!this->_S_eof(__tmp))
561       __c = _Traits::to_char_type(__tmp);
562     else
563       this->setstate(ios_base::eofbit | ios_base::failbit);
564   }
565 }
566 
567 
568 //---------------------------------------------------------------------------
569 // istream's helper functions.
570 
571 // A generic function for unbuffered input.  We stop when we reach EOF,
572 // or when we have extracted _Num characters, or when the function object
573 // __is_delim return true.  In the last case, it extracts the character
574 // for which __is_delim is true, if and only if __extract_delim is true.
575 // It appends a null character to the end of the string; this means that
576 // it may store up to _Num + 1 characters.
577 //
578 // __is_getline governs two corner cases: reading _Num characters without
579 // encountering delim or eof (in which case failbit is set if __is_getline
580 // is true); and reading _Num characters where the _Num+1'st character is
581 // eof (in which case eofbit is set if __is_getline is true).
582 //
583 // It is assumed that __is_delim never throws.
584 //
585 // Return value is the number of characters extracted, including the
586 // delimiter if it is extracted.  Note that the number of characaters
587 // extracted isn't necessarily the same as the number stored.
588 
589 _STLP_MOVE_TO_PRIV_NAMESPACE
590 
591 template < class _CharT, class _Traits, class _Is_Delim>
592 streamsize _STLP_CALL
__read_unbuffered(basic_istream<_CharT,_Traits> * __that,basic_streambuf<_CharT,_Traits> * __buf,streamsize _Num,_CharT * __s,_Is_Delim __is_delim,bool __extract_delim,bool __append_null,bool __is_getline)593 __read_unbuffered(basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __buf,
594                   streamsize _Num, _CharT* __s,
595                   _Is_Delim __is_delim,
596                   bool __extract_delim, bool __append_null,
597                   bool __is_getline)
598 {
599   streamsize __n = 0;
600   ios_base::iostate __status = 0;
601 
602   typedef typename basic_istream<_CharT, _Traits>::int_type int_type;
603   // The operations that can potentially throw are sbumpc, snextc, and sgetc.
604   _STLP_TRY {
605     for (;;) {
606       if (__n == _Num) {
607         if (__is_getline) // didn't find delimiter as one of the _Num chars
608           __status |= ios_base::failbit;
609         break;
610       }
611       int_type __c = __buf->sbumpc(); // sschwarz
612 
613       if (__that->_S_eof(__c)) {
614         if (__n < _Num || __is_getline)
615           __status |= ios_base::eofbit;
616         break;
617       } else if (__is_delim(_Traits::to_char_type(__c))) {
618         if (__extract_delim) { // Extract and discard current character.
619           ++__n;
620         } else if ( !__pushback(__buf, _Traits::to_char_type(__c)) ) { // leave delimiter
621           __status |= ios_base::failbit;
622         }
623         break;
624       }
625       // regular character
626       *__s++ = _Traits::to_char_type(__c);
627       ++__n;
628     }
629   }
630   _STLP_CATCH_ALL {
631     __that->_M_handle_exception(ios_base::badbit);
632     *__s = _STLP_DEFAULT_CONSTRUCTED(_CharT);
633     return __n;
634   }
635 
636   if (__append_null)
637     *__s =  _STLP_DEFAULT_CONSTRUCTED(_CharT);
638   if (__status)
639     __that->setstate(__status);    // This might throw.
640   return __n;
641 }
642 
643 // Much like __read_unbuffered, but with one additional function object:
644 // __scan_delim(first, last) returns the first pointer p in [first, last)
645 // such that __is_delim(p) is true.
646 
647 template < class _CharT, class _Traits, class _Is_Delim, class _Scan_Delim>
648 streamsize _STLP_CALL
__read_buffered(basic_istream<_CharT,_Traits> * __that,basic_streambuf<_CharT,_Traits> * __buf,streamsize _Num,_CharT * __s,_Is_Delim __is_delim,_Scan_Delim __scan_delim,bool __extract_delim,bool __append_null,bool __is_getline)649 __read_buffered(basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __buf,
650                  streamsize _Num, _CharT* __s,
651                  _Is_Delim __is_delim, _Scan_Delim __scan_delim,
652                  bool __extract_delim, bool __append_null,
653                  bool __is_getline) {
654   streamsize __n = 0;
655   ios_base::iostate __status = 0;
656   bool __done    = false;
657 
658   _STLP_TRY {
659     while (__buf->_M_egptr() != __buf->_M_gptr() && !__done) {
660       const _CharT* __first = __buf->_M_gptr();
661       const _CharT* __last  = __buf->_M_egptr();
662       //casting numeric_limits<ptrdiff_t>::max to streamsize only works is ptrdiff_t is signed or streamsize representation
663       //is larger than ptrdiff_t one.
664       _STLP_STATIC_ASSERT((sizeof(streamsize) > sizeof(ptrdiff_t)) ||
665                           ((sizeof(streamsize) == sizeof(ptrdiff_t)) && numeric_limits<ptrdiff_t>::is_signed))
666       ptrdiff_t __request = __STATIC_CAST(ptrdiff_t, (min) (__STATIC_CAST(streamsize, (numeric_limits<ptrdiff_t>::max)()), _Num - __n));
667 
668       const _CharT* __p  = __scan_delim(__first, __last);
669       ptrdiff_t __chunk = (min) (ptrdiff_t(__p - __first), __request);
670       _Traits::copy(__s, __first, __chunk);
671       __s += __chunk;
672       __n += __chunk;
673       __buf->_M_gbump((int)__chunk);
674 
675       // We terminated by finding delim.
676       if (__p != __last && __p - __first <= __request) {
677         if (__extract_delim) {
678           __n += 1;
679           __buf->_M_gbump(1);
680         }
681         __done = true;
682       }
683 
684       // We terminated by reading all the characters we were asked for.
685       else if (__n == _Num) {
686 
687         // Find out if we have reached eof.  This matters for getline.
688         if (__is_getline) {
689           if (__chunk == __last - __first) {
690             if (__that->_S_eof(__buf->sgetc()))
691               __status |= ios_base::eofbit;
692           }
693           else
694             __status |= ios_base::failbit;
695         }
696         __done   = true;
697       }
698 
699       // The buffer contained fewer than _Num - __n characters.  Either we're
700       // at eof, or we should refill the buffer and try again.
701       else {
702         if (__that->_S_eof(__buf->sgetc())) {
703           __status |= ios_base::eofbit;
704           __done = true;
705         }
706       }
707     } // Close the while loop.
708   }
709   _STLP_CATCH_ALL {
710     __that->_M_handle_exception(ios_base::badbit);
711     __done = true;
712   }
713 
714   if (__done) {
715     if (__append_null)
716         *__s =  _STLP_DEFAULT_CONSTRUCTED(_CharT);
717     if (__status != 0)
718       __that->setstate(__status);   // This might throw.
719     return __n;
720   }
721 
722   // If execution has reached this point, then we have an empty buffer but
723   // we have not reached eof.  What that means is that the streambuf has
724   // decided to switch from buffered to unbuffered input.  We switch to
725   // to __read_unbuffered.
726 
727   return __n + __read_unbuffered(__that,  __buf, _Num - __n, __s, __is_delim,
728                                  __extract_delim,__append_null,__is_getline);
729 }
730 
731 _STLP_MOVE_TO_STD_NAMESPACE
732 
733 template <class _CharT, class _Traits>
734 basic_istream<_CharT, _Traits>&
get(_CharT * __s,streamsize __n,_CharT __delim)735 basic_istream<_CharT, _Traits>::get(_CharT* __s, streamsize __n,
736                                     _CharT __delim) {
737   sentry __sentry(*this, _No_Skip_WS());
738   this->_M_gcount = 0;
739 
740   if (__sentry) {
741     if (__n > 0) {
742       basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();
743 
744       if (__buf->egptr() != __buf->gptr())
745         this->_M_gcount =
746           _STLP_PRIV __read_buffered(this,  __buf, __n - 1, __s,
747                                      _STLP_PRIV _Eq_char_bound<_Traits>(__delim),
748                                      _STLP_PRIV _Scan_for_char_val<_Traits>(__delim),
749                                      false, true, false);
750       else
751         this->_M_gcount =
752           _STLP_PRIV __read_unbuffered(this,  __buf, __n - 1, __s,
753                                        _STLP_PRIV _Eq_char_bound<_Traits>(__delim),
754                                        false, true, false);
755     }
756   }
757 
758   if (this->_M_gcount == 0)
759     this->setstate(ios_base::failbit);
760 
761   return *this;
762 }
763 
764 // Getline is essentially identical to get, except that it extracts
765 // the delimiter.
766 template <class _CharT, class _Traits>
767 basic_istream<_CharT, _Traits>&
getline(_CharT * __s,streamsize __n,_CharT __delim)768 basic_istream<_CharT, _Traits>::getline(_CharT* __s, streamsize __n,
769                                         _CharT __delim) {
770   sentry __sentry(*this, _No_Skip_WS());
771   this->_M_gcount = 0;
772 
773   if (__sentry) {
774     if (__n > 0) {
775       basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();
776       this->_M_gcount = __buf->egptr() != __buf->gptr()
777         ? _STLP_PRIV __read_buffered(this,  __buf, __n - 1, __s,
778                                      _STLP_PRIV _Eq_char_bound<_Traits>(__delim),
779                                      _STLP_PRIV _Scan_for_char_val<_Traits>(__delim),
780                                      true, true, true)
781         : _STLP_PRIV __read_unbuffered(this,  __buf, __n - 1, __s,
782                                        _STLP_PRIV _Eq_char_bound<_Traits>(__delim),
783                                        true, true, true);
784     }
785   }
786 
787   if (this->_M_gcount == 0)
788     this->setstate(ios_base::failbit);
789 
790   return *this;
791 }
792 
793 // Read n characters.  We don't look for any delimiter, and we don't
794 // put in a terminating null character.
795 template <class _CharT, class _Traits>
796 basic_istream<_CharT, _Traits>&
read(char_type * __s,streamsize __n)797 basic_istream<_CharT, _Traits>::read(char_type* __s, streamsize __n) {
798   sentry __sentry(*this, _No_Skip_WS());
799   this->_M_gcount = 0;
800 
801   if (__sentry && !this->eof()) {
802     basic_streambuf<_CharT, _Traits>*__buf = this->rdbuf();
803     if (__buf->gptr() != __buf->egptr())
804       _M_gcount
805         = _STLP_PRIV __read_buffered(this,  __buf, __n, __s,
806                                      _STLP_PRIV _Constant_unary_fun<bool, int_type>(false),
807                                      _STLP_PRIV _Project2nd<const _CharT*, const _CharT*>(),
808                                      false, false, false);
809     else
810       _M_gcount
811         = _STLP_PRIV __read_unbuffered(this,  __buf, __n, __s,
812                                        _STLP_PRIV _Constant_unary_fun<bool, int_type>(false),
813                                        false, false, false);
814   }
815   else
816     this->setstate(ios_base::failbit);
817 
818   if (this->eof())
819     this->setstate(ios_base::eofbit | ios_base::failbit);
820 
821   return *this;
822 }
823 
824 
825 // Read n or fewer characters.  We don't look for any delimiter, and
826 // we don't put in a terminating null character.
827 template <class _CharT, class _Traits>
828 streamsize
readsome(char_type * __s,streamsize __nmax)829 basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __nmax) {
830   sentry __sentry(*this, _No_Skip_WS());
831   this->_M_gcount = 0;
832 
833   if (__sentry && !this->eof() && __nmax >= 0) {
834 
835     basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();
836     streamsize __avail = __buf->in_avail();
837 
838     // fbp : isn't full-blown setstate required here ?
839     if (__avail == -1)
840       this->_M_setstate_nothrow(ios_base::eofbit);
841 
842     else if (__avail != 0) {
843 
844       if (__buf->gptr() != __buf->egptr())
845         _M_gcount
846           = _STLP_PRIV __read_buffered(this,  __buf, (min) (__avail, __nmax), __s,
847                                        _STLP_PRIV _Constant_unary_fun<bool, int_type>(false),
848                                        _STLP_PRIV _Project2nd<const _CharT*, const _CharT*>(),
849                                        false, false, false);
850       else
851         _M_gcount
852           = _STLP_PRIV __read_unbuffered(this,  __buf, (min) (__avail, __nmax), __s,
853                                          _STLP_PRIV _Constant_unary_fun<bool, int_type>(false),
854                                          false, false, false);
855     }
856   }
857   else {
858     // fbp : changed so that failbit is set only there, to pass Dietmar's test
859     if (this->eof())
860       this->setstate(ios_base::eofbit | ios_base::failbit);
861     else
862       this->setstate(ios_base::failbit);
863   }
864 
865   //  if (this->eof())
866   //    this->setstate(ios_base::eofbit | ios_base::failbit);
867 
868   return _M_gcount;
869 }
870 
871 template <class _CharT, class _Traits>
_M_formatted_get(_CharT * __s)872 void basic_istream<_CharT, _Traits>::_M_formatted_get(_CharT* __s) {
873   sentry __sentry(*this); // Skip whitespace.
874 
875   if (__sentry) {
876     basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();
877     streamsize __nmax = this->width() > 0
878       ? this->width() - 1
879       : ((numeric_limits<streamsize>::max)() / sizeof(_CharT)) - 1;
880 
881     streamsize __n = __buf->gptr() != __buf->egptr()
882       ? _STLP_PRIV __read_buffered(this,  __buf, __nmax, __s,
883                                    _STLP_PRIV _Is_wspace_null<_Traits>(this->_M_ctype_facet()),
884                                    _STLP_PRIV _Scan_wspace_null<_Traits>(this->_M_ctype_facet()),
885                                    false, true, false)
886       : _STLP_PRIV __read_unbuffered(this,  __buf, __nmax, __s,
887                                      _STLP_PRIV _Is_wspace_null<_Traits>(this->_M_ctype_facet()),
888                                      false, true, false);
889     if (__n == 0)
890       this->setstate(ios_base::failbit);
891   }
892   this->width(0);
893 }
894 
895 // A generic unbuffered function for ignoring characters.  We stop
896 // when we reach EOF, or when the function object __is_delim returns
897 // true.  In the last case, it extracts the character for which
898 // __is_delim is true, if and only if __extract_delim is true.
899 
900 template < class _CharT, class _Traits, class _Is_Delim>
901 void _STLP_CALL
_M_ignore_unbuffered(basic_istream<_CharT,_Traits> * __that,basic_streambuf<_CharT,_Traits> * __buf,_Is_Delim __is_delim,bool __extract_delim,bool __set_failbit)902 _M_ignore_unbuffered(basic_istream<_CharT, _Traits>* __that,
903                      basic_streambuf<_CharT, _Traits>* __buf,
904                      _Is_Delim __is_delim,
905                      bool __extract_delim, bool __set_failbit) {
906   bool __done = false;
907   ios_base::iostate __status = 0;
908   typedef typename basic_istream<_CharT, _Traits>::int_type int_type;
909 
910   _STLP_TRY {
911     while (!__done) {
912       int_type __c = __buf->sbumpc();
913 
914       if (__that->_S_eof(__c)) {
915         __done = true;
916         __status |= __set_failbit ? ios_base::eofbit | ios_base::failbit
917                                   : ios_base::eofbit;
918       }
919 
920       else if (__is_delim(_Traits::to_char_type(__c))) {
921         __done = true;
922         if (!__extract_delim)
923           if (__that->_S_eof(__buf->sputbackc(_Traits::to_char_type(__c))))
924             __status |= ios_base::failbit;
925       }
926     }
927   }
928   _STLP_CATCH_ALL {
929     __that->_M_handle_exception(ios_base::badbit);
930   }
931 
932   __that->setstate(__status);
933 }
934 
935 // A generic buffered function for ignoring characters.  Much like
936 // _M_ignore_unbuffered, but with one additional function object:
937 // __scan_delim(first, last) returns the first pointer p in [first,
938 // last) such that __is_delim(p) is true.
939 
940 template < class _CharT, class _Traits, class _Is_Delim, class _Scan_Delim>
941 void _STLP_CALL
_M_ignore_buffered(basic_istream<_CharT,_Traits> * __that,basic_streambuf<_CharT,_Traits> * __buf,_Is_Delim __is_delim,_Scan_Delim __scan_delim,bool __extract_delim,bool __set_failbit)942 _M_ignore_buffered(basic_istream<_CharT, _Traits>* __that,
943                    basic_streambuf<_CharT, _Traits>* __buf,
944                    _Is_Delim __is_delim, _Scan_Delim __scan_delim,
945                    bool __extract_delim, bool __set_failbit) {
946   bool __at_eof      = false;
947   bool __found_delim = false;
948 
949   _STLP_TRY {
950     while (__buf->_M_egptr() != __buf->_M_gptr() && !__at_eof && !__found_delim) {
951       const _CharT* __p = __scan_delim(__buf->_M_gptr(), __buf->_M_egptr());
952       __buf->_M_gbump((int)(__p - __buf->_M_gptr()));
953 
954       if (__p != __buf->_M_egptr()) { // We found delim, so we're done.
955         if (__extract_delim)
956           __buf->_M_gbump(1);
957         __found_delim = true;
958       }
959 
960       else                         // No delim.  Try to refil the buffer.
961         __at_eof = __that->_S_eof(__buf->sgetc());
962     }                              // Close the while loop.
963   }
964   _STLP_CATCH_ALL {
965     __that->_M_handle_exception(ios_base::badbit);
966     return;
967   }
968 
969   if (__at_eof) {
970     __that->setstate(__set_failbit ? ios_base::eofbit | ios_base::failbit
971                                    : ios_base::eofbit);
972     return;
973   }
974   if (__found_delim)
975     return;
976 
977   // If execution has reached this point, then we have an empty buffer but
978   // we have not reached eof.  What that means is that the streambuf has
979   // decided to switch from a buffered to an unbuffered mode.  We switch
980   // to _M_ignore_unbuffered.
981   _M_ignore_unbuffered(__that,  __buf, __is_delim, __extract_delim, __set_failbit);
982 }
983 
984 // Overloaded versions of _M_ignore_unbuffered and _M_ignore_unbuffered
985 // with an explicit count _Num.  Return value is the number of
986 // characters extracted.
987 //
988 // The function object __max_chars takes two arguments, _Num and __n
989 // (the latter being the number of characters we have already read),
990 // and returns the maximum number of characters to read from the buffer.
991 // We parameterize _M_ignore_buffered so that we can use it for both
992 // bounded and unbounded input; for the former the function object should
993 // be minus<>, and for the latter it should return a constant maximum value.
994 
995 template < class _CharT, class _Traits, class _Max_Chars, class _Is_Delim>
996 streamsize _STLP_CALL
_M_ignore_unbuffered(basic_istream<_CharT,_Traits> * __that,basic_streambuf<_CharT,_Traits> * __buf,streamsize _Num,_Max_Chars __max_chars,_Is_Delim __is_delim,bool __extract_delim,bool __set_failbit)997 _M_ignore_unbuffered(basic_istream<_CharT, _Traits>* __that,
998                      basic_streambuf<_CharT, _Traits>* __buf,
999                      streamsize _Num, _Max_Chars __max_chars,
1000                      _Is_Delim __is_delim,
1001                      bool __extract_delim, bool __set_failbit) {
1002   streamsize __n = 0;
1003   ios_base::iostate __status = 0;
1004   typedef typename basic_istream<_CharT, _Traits>::int_type int_type;
1005 
1006   _STLP_TRY {
1007     while (__max_chars(_Num, __n) > 0) {
1008       int_type __c = __buf->sbumpc();
1009 
1010       if (__that->_S_eof(__c)) {
1011         __status |= __set_failbit ? ios_base::eofbit | ios_base::failbit
1012                                   : ios_base::eofbit;
1013         break;
1014       }
1015 
1016       else if (__is_delim(_Traits::to_char_type(__c))) {
1017         if (__extract_delim)
1018           ++__n;
1019         else if (__that->_S_eof(__buf->sputbackc(_Traits::to_char_type(__c))))
1020           __status |= ios_base::failbit;
1021 
1022         break;
1023       }
1024       // fbp : added counter increment to pass Dietmar's test
1025       ++__n;
1026     }
1027   }
1028   _STLP_CATCH_ALL {
1029     __that->_M_handle_exception(ios_base::badbit);
1030   }
1031 
1032   if (__status)
1033     __that->setstate(__status);   // This might throw.
1034   return __n;
1035 }
1036 
1037 template < class _CharT, class _Traits, class _Max_Chars, class _Is_Delim, class _Scan_Delim>
1038 streamsize _STLP_CALL
_M_ignore_buffered(basic_istream<_CharT,_Traits> * __that,basic_streambuf<_CharT,_Traits> * __buf,streamsize _Num,_Max_Chars __max_chars,_Is_Delim __is_delim,_Scan_Delim __scan_delim,bool __extract_delim,bool __set_failbit)1039 _M_ignore_buffered(basic_istream<_CharT, _Traits>* __that,
1040                    basic_streambuf<_CharT, _Traits>* __buf,
1041                    streamsize _Num,
1042                    _Max_Chars __max_chars,
1043                    _Is_Delim __is_delim, _Scan_Delim __scan_delim,
1044                    bool __extract_delim, bool __set_failbit) {
1045   streamsize __n = 0;
1046   bool __at_eof = false;
1047   bool __done   = false;
1048 
1049   _STLP_TRY {
1050     while (__buf->_M_egptr() != __buf->_M_gptr() && !__done) {
1051       ptrdiff_t __avail = __buf->_M_egptr() - __buf->_M_gptr();
1052       streamsize __m = __max_chars(_Num, __n);
1053 
1054       if (__avail >= __m) {       // We have more characters than we need.
1055         const _CharT* __last = __buf->_M_gptr() + __STATIC_CAST(ptrdiff_t, __m);
1056         const _CharT* __p = __scan_delim(__buf->_M_gptr(), __last);
1057         ptrdiff_t __chunk = __p - __buf->_M_gptr();
1058         __n += __chunk;
1059         __buf->_M_gbump((int)__chunk);
1060 
1061         if (__extract_delim && __p != __last) {
1062           __n += 1;
1063           __buf->_M_gbump(1);
1064         }
1065 
1066         __done = true;
1067       }
1068 
1069       else {
1070         const _CharT* __p = __scan_delim(__buf->_M_gptr(), __buf->_M_egptr());
1071         ptrdiff_t __chunk = __p - __buf->_M_gptr();
1072         __n += __chunk;
1073         __buf->_M_gbump((int)__chunk);
1074 
1075         if (__p != __buf->_M_egptr()) { // We found delim.
1076           if (__extract_delim) {
1077             __n += 1;
1078             __buf->_M_gbump(1);
1079           }
1080 
1081           __done = true;
1082         }
1083 
1084         // We didn't find delim.  Try to refill the buffer.
1085         else if (__that->_S_eof(__buf->sgetc())) {
1086           __done   = true;
1087           __at_eof = true;
1088         }
1089       }
1090     } // Close the while loop.
1091   }
1092   _STLP_CATCH_ALL {
1093     __that->_M_handle_exception(ios_base::badbit);
1094     return __n;
1095   }
1096 
1097   if (__at_eof)
1098     __that->setstate(__set_failbit ? ios_base::eofbit | ios_base::failbit
1099                                    : ios_base::eofbit);
1100 
1101   if (__done)
1102     return __n;
1103 
1104   // If execution has reached this point, then we have an empty buffer but
1105   // we have not reached eof.  What that means is that the streambuf has
1106   // decided to switch from buffered to unbuffered input.  We switch to
1107   // to _M_ignore_unbuffered.
1108 
1109   return __n + _M_ignore_unbuffered(__that,  __buf, _Num, __max_chars,
1110                                     __is_delim, __extract_delim, __set_failbit);
1111 }
1112 
1113 
1114 template <class _CharT, class _Traits>
1115 basic_istream<_CharT, _Traits>&
ignore(streamsize __n)1116 basic_istream<_CharT, _Traits>::ignore(streamsize __n) {
1117   sentry __sentry(*this, _No_Skip_WS());
1118   this->_M_gcount = 0;
1119 
1120   if (__sentry) {
1121     basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();
1122     typedef _STLP_PRIV _Constant_unary_fun<bool, int_type> _Const_bool;
1123     typedef _STLP_PRIV _Constant_binary_fun<streamsize, streamsize, streamsize> _Const_streamsize;
1124     const streamsize __maxss = (numeric_limits<streamsize>::max)();
1125 
1126     if (__n == (numeric_limits<int>::max)()) {
1127       if (__buf->gptr() != __buf->egptr())
1128         _M_gcount = _M_ignore_buffered(this,  __buf,
1129                                        __maxss, _Const_streamsize(__maxss),
1130                                        _Const_bool(false),
1131                                        _STLP_PRIV _Project2nd<const _CharT*, const _CharT*>(),
1132                                        false, false);
1133       else
1134         _M_gcount = _M_ignore_unbuffered(this,  __buf,
1135                                          __maxss, _Const_streamsize(__maxss),
1136                                          _Const_bool(false), false, false);
1137     }
1138     else {
1139       if (__buf->gptr() != __buf->egptr())
1140         _M_gcount = _M_ignore_buffered(this,  __buf,
1141                                        __n, minus<streamsize>(),
1142                                        _Const_bool(false),
1143                                        _STLP_PRIV _Project2nd<const _CharT*, const _CharT*>(),
1144                                        false, false);
1145       else
1146         _M_gcount = _M_ignore_unbuffered(this,  __buf, __n, minus<streamsize>(),
1147                                          _Const_bool(false), false, false);
1148     }
1149   }
1150 
1151   return *this;
1152 }
1153 
1154 template <class _CharT, class _Traits>
1155 basic_istream<_CharT, _Traits>&
ignore(streamsize __n,int_type __delim)1156 basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __delim) {
1157   sentry __sentry(*this, _No_Skip_WS());
1158   this->_M_gcount = 0;
1159 
1160   if (__sentry) {
1161     basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();
1162     typedef _STLP_PRIV _Constant_binary_fun<streamsize, streamsize, streamsize>
1163       _Const_streamsize;
1164     const streamsize __maxss = (numeric_limits<streamsize>::max)();
1165 
1166     if (__n == (numeric_limits<int>::max)()) {
1167       if (__buf->gptr() != __buf->egptr())
1168         _M_gcount = _M_ignore_buffered(this,  __buf,
1169                                        __maxss, _Const_streamsize(__maxss),
1170                                        _STLP_PRIV _Eq_int_bound<_Traits>(__delim),
1171                                        _STLP_PRIV _Scan_for_int_val<_Traits>(__delim),
1172                                        true, false);
1173       else
1174         _M_gcount = _M_ignore_unbuffered(this,  __buf,
1175                                          __maxss, _Const_streamsize(__maxss),
1176                                          _STLP_PRIV _Eq_int_bound<_Traits>(__delim),
1177                                          true, false);
1178     }
1179     else {
1180       if (__buf->gptr() != __buf->egptr())
1181         _M_gcount = _M_ignore_buffered(this,  __buf,
1182                                        __n, minus<streamsize>(),
1183                                        _STLP_PRIV _Eq_int_bound<_Traits>(__delim),
1184                                        _STLP_PRIV _Scan_for_int_val<_Traits>(__delim),
1185                                        true, false);
1186       else
1187         _M_gcount = _M_ignore_unbuffered(this,  __buf, __n, minus<streamsize>(),
1188                                          _STLP_PRIV _Eq_int_bound<_Traits>(__delim),
1189                                          true, false);
1190     }
1191   }
1192 
1193   return *this;
1194 }
1195 
1196 // This member function does not construct a sentry object, because
1197 // it is called from sentry's constructor.
1198 template <class _CharT, class _Traits>
_M_skip_whitespace(bool __set_failbit)1199 void basic_istream<_CharT, _Traits>::_M_skip_whitespace(bool __set_failbit) {
1200   basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();
1201   if (!__buf)
1202     this->setstate(ios_base::badbit);
1203   else if (__buf->gptr() != __buf->egptr())
1204     _M_ignore_buffered(this,  __buf,
1205                        _STLP_PRIV _Is_not_wspace<_Traits>(this->_M_ctype_facet()),
1206                        _STLP_PRIV _Scan_for_not_wspace<_Traits>(this->_M_ctype_facet()),
1207                        false, __set_failbit);
1208   else
1209     _M_ignore_unbuffered(this,  __buf,
1210                          _STLP_PRIV _Is_not_wspace<_Traits>(this->_M_ctype_facet()),
1211                          false, __set_failbit);
1212 }
1213 
1214 
1215 // This is a very simple loop that reads characters from __src and puts
1216 // them into __dest.  It looks complicated because of the (standard-
1217 // mandated) exception handling policy.
1218 //
1219 // We stop when we get an exception, when we fail to insert into the
1220 // output streambuf, or when __is_delim is true.
1221 
1222 _STLP_MOVE_TO_PRIV_NAMESPACE
1223 
1224 template < class _CharT, class _Traits, class _Is_Delim>
1225 streamsize _STLP_CALL
__copy_unbuffered(basic_istream<_CharT,_Traits> * __that,basic_streambuf<_CharT,_Traits> * __src,basic_streambuf<_CharT,_Traits> * __dest,_Is_Delim __is_delim,bool __extract_delim,bool __rethrow)1226 __copy_unbuffered(basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __src,
1227                   basic_streambuf<_CharT, _Traits>* __dest,
1228                   _Is_Delim __is_delim,
1229                   bool __extract_delim, bool __rethrow) {
1230   streamsize __extracted = 0;
1231   ios_base::iostate __status = 0;
1232   typedef typename basic_istream<_CharT, _Traits>::int_type int_type;
1233   int_type __c;
1234 
1235   _STLP_TRY {
1236     for (;;) {
1237       // Get a character. If there's an exception, catch and (maybe) rethrow it.
1238       __c = __src->sbumpc();
1239 
1240       // If we failed to get a character, then quit.
1241       if (__that->_S_eof(__c)) {
1242         __status |= ios_base::eofbit;
1243         break;
1244       }
1245       // If it's the delimiter, then quit.
1246       else if (__is_delim(_Traits::to_char_type(__c))) {
1247         if (!__extract_delim && !__pushback(__src, _Traits::to_char_type(__c)))
1248           __status |= ios_base::failbit;
1249         break;
1250       }
1251       else {
1252         // Try to put the character in the output streambuf.
1253         bool __failed = false;
1254         _STLP_TRY {
1255           if (!__that->_S_eof(__dest->sputc(_Traits::to_char_type(__c))))
1256             ++__extracted;
1257           else
1258             __failed = true;
1259         }
1260         _STLP_CATCH_ALL {
1261           __failed = true;
1262         }
1263 
1264         // If we failed to put the character in the output streambuf, then
1265         // try to push it back to the input streambuf.
1266         if (__failed && !__pushback(__src, _Traits::to_char_type(__c)))
1267           __status |= ios_base::failbit;
1268 
1269         // fbp : avoiding infinite loop in io-27-6-1-2-3.exp
1270         if (__failed)
1271           break;
1272       }
1273 
1274     } /* for (;;) */
1275 
1276   }
1277   // fbp : this try/catch moved here in reasonable assumption
1278   // __is_delim never throw (__pushback is guaranteed not to)
1279   _STLP_CATCH_ALL {
1280     // See 27.6.1.2.3, paragraph 13.
1281     if (__rethrow && __extracted == 0)
1282       __that->_M_handle_exception(ios_base::failbit);
1283   }
1284   __that->setstate(__status);
1285   return __extracted;
1286 }
1287 
1288 // Buffered copying from one streambuf to another.  We copy the characters
1289 // in chunks, rather than one at a time.  We still have to worry about all
1290 // of the error conditions we checked in __copy_unbuffered, plus one more:
1291 // the streambuf might decide to switch from a buffered to an unbuffered mode.
1292 
1293 template < class _CharT, class _Traits, class _Is_Delim, class _Scan_Delim>
1294 streamsize _STLP_CALL
__copy_buffered(basic_istream<_CharT,_Traits> * __that,basic_streambuf<_CharT,_Traits> * __src,basic_streambuf<_CharT,_Traits> * __dest,_Scan_Delim __scan_delim,_Is_Delim __is_delim,bool __extract_delim,bool __rethrow)1295 __copy_buffered(basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __src,
1296                 basic_streambuf<_CharT, _Traits>* __dest,
1297                 _Scan_Delim __scan_delim, _Is_Delim __is_delim,
1298                 bool __extract_delim, bool __rethrow) {
1299   streamsize __extracted = 0;
1300   ios_base::iostate __status = 0;
1301   typedef typename basic_istream<_CharT, _Traits>::int_type int_type;
1302   //Borland compiler generates a warning if assignment because value is never used:
1303   int_type __c /*= _Traits::eof()*/;
1304   _CharT* __first = __src->_M_gptr();
1305   ptrdiff_t __avail = __src->_M_egptr() - __first;
1306   // fbp : introduced to move catch/try blocks out of the loop
1307   bool __do_handle_exceptions = false;
1308 
1309   _STLP_TRY {
1310     for (;;) {
1311       const _CharT* __last = __scan_delim(__first, __src->_M_egptr());
1312 
1313       // Try to copy the entire input buffer to the output buffer.
1314       streamsize __n = __dest->sputn(__first, __extract_delim && __last != __src->_M_egptr()
1315                                      ? (__last - __first) + 1
1316                                      : (__last - __first));
1317       __src->_M_gbump((int)__n);
1318       __extracted += __n;
1319 
1320       // from this on, catch() will call _M_handle_exceptions()
1321       __do_handle_exceptions = true;
1322 
1323       if (__n < __avail)          // We found the delimiter, or else failed to
1324         break;                    // copy some characters.
1325 
1326       __c = __src->sgetc();
1327 
1328       // Three possibilities: we succeeded in refilling the buffer, or
1329       // we got EOF, or the streambuf has switched to unbuffered mode.
1330       __first = __src->_M_gptr();
1331       __avail = __src->_M_egptr() - __first;
1332 
1333       if (__avail > 0)
1334         {}  // dwa 1/16/00 -- suppress a Metrowerks warning
1335       else if (__that->_S_eof(__c)) {
1336         __status |= ios_base::eofbit;
1337         break;
1338       }
1339       else {
1340         return __extracted + __copy_unbuffered(__that,  __src, __dest, __is_delim,
1341                                                 __extract_delim, __rethrow);
1342       }
1343 
1344       __do_handle_exceptions = false;
1345     }
1346   }
1347 
1348   _STLP_CATCH_ALL {
1349     // See 27.6.1.2.3, paragraph 13.
1350     if (__rethrow && __do_handle_exceptions &&  __extracted == 0)
1351       __that->_M_handle_exception(ios_base::failbit);
1352   }
1353 
1354   if (__status)
1355     __that->setstate(__status);   // This might throw.
1356   return __extracted;
1357 }
1358 
1359 _STLP_MOVE_TO_STD_NAMESPACE
1360 
1361 template <class _CharT, class _Traits>
1362 basic_istream<_CharT, _Traits>&
1363 basic_istream<_CharT, _Traits>
get(basic_streambuf<_CharT,_Traits> & __dest,_CharT __delim)1364   ::get(basic_streambuf<_CharT, _Traits>& __dest, _CharT __delim) {
1365   sentry __sentry(*this, _No_Skip_WS());
1366   this->_M_gcount = 0;
1367 
1368   if (__sentry) {
1369     basic_streambuf<_CharT, _Traits>* __src = this->rdbuf();
1370 
1371     if (__src)
1372       this->_M_gcount = __src->egptr() != __src->gptr()
1373         ? _STLP_PRIV __copy_buffered(this,  __src, &__dest,
1374                                      _STLP_PRIV _Scan_for_char_val<_Traits>(__delim),
1375                                      _STLP_PRIV _Eq_char_bound<_Traits>(__delim),
1376                                      false, false)
1377         : _STLP_PRIV __copy_unbuffered(this,  __src, &__dest,
1378                                        _STLP_PRIV _Eq_char_bound<_Traits>(__delim),
1379                                        false, false);
1380   }
1381 
1382   if (this->_M_gcount == 0)
1383     this->setstate(ios_base::failbit);
1384 
1385   return *this;
1386 }
1387 
1388 // Copying characters into a streambuf.
1389 template <class _CharT, class _Traits>
1390 basic_istream<_CharT, _Traits>&
1391 basic_istream<_CharT, _Traits>
1392   ::operator>>(basic_streambuf<_CharT, _Traits>* __dest) {
1393   streamsize __n = 0;
1394   typedef typename basic_istream<_CharT, _Traits>::sentry _Sentry;
1395   _Sentry __sentry(*this);
1396   if (__sentry) {
1397     basic_streambuf<_CharT, _Traits>* __src = this->rdbuf();
1398     if (__src && __dest)
1399       __n = __src->egptr() != __src->gptr()
1400         ? _STLP_PRIV __copy_buffered(this,  __src, __dest,
1401                                      _STLP_PRIV _Project2nd<const _CharT*, const _CharT*>(),
1402                                      _STLP_PRIV _Constant_unary_fun<bool, int_type>(false),
1403                                      false, true)
1404         : _STLP_PRIV __copy_unbuffered(this,  __src, __dest,
1405                                        _STLP_PRIV _Constant_unary_fun<bool, int_type>(false),
1406                                        false, true);
1407   }
1408 
1409   if (__n == 0)
1410     this->setstate(ios_base::failbit);
1411 
1412   return *this;
1413 }
1414 
1415 // ----------------------------------------------------------------
1416 // basic_iostream<> class
1417 // ----------------------------------------------------------------
1418 
1419 template <class _CharT, class _Traits>
1420 basic_iostream<_CharT, _Traits>
basic_iostream(basic_streambuf<_CharT,_Traits> * __buf)1421   ::basic_iostream(basic_streambuf<_CharT, _Traits>* __buf)
1422     : basic_ios<_CharT, _Traits>(),
1423       basic_istream<_CharT, _Traits>(__buf),
1424       basic_ostream<_CharT, _Traits>(__buf) {
1425   this->init(__buf);
1426 }
1427 
1428 template <class _CharT, class _Traits>
~basic_iostream()1429 basic_iostream<_CharT, _Traits>::~basic_iostream()
1430 {}
1431 
1432 _STLP_END_NAMESPACE
1433 
1434 #undef __BIS_int_type__
1435 #undef __BIS_pos_type__
1436 #undef __BIS_off_type__
1437 
1438 #endif /* _STLP_ISTREAM_C */
1439 
1440 // Local Variables:
1441 // mode:C++
1442 // End:
1443