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