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