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 51template <class _Traits> 52struct _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 58 _Is_not_wspace(const ctype<argument_type>* __c_type) : _M_ctype(__c_type) {} 59 bool operator()(argument_type __c) const 60 { return !_M_ctype->is(ctype_base::space, __c); } 61}; 62 63template <class _Traits> 64struct _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 70 _Is_wspace_null(const ctype<argument_type>* __c_type) : _M_ctype(__c_type) {} 71 bool operator()(argument_type __c) const { 72 return _Traits::eq(__c, argument_type()) || 73 _M_ctype->is(ctype_base::space, __c); 74 } 75}; 76 77template <class _Traits> 78struct _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 86 _Scan_for_wspace(const ctype<char_type>* __ctype) : _M_ctype(__ctype) {} 87 const char_type* 88 operator()(const char_type* __first, const char_type* __last) const { 89 return _M_ctype->scan_is(ctype_base::space, __first, __last); 90 } 91}; 92 93template <class _Traits> 94struct _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 102 _Scan_wspace_null(const ctype<char_type>* __c_type) : _M_ctype(__c_type) {} 103 const char_type* 104 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 111template <class _Traits> 112struct _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 120 _Scan_for_not_wspace(const ctype<char_type>* __c_type) : _M_ctype(__c_type) {} 121 const char_type* 122 operator()(const char_type* __first, const char_type* __last) const { 123 return _M_ctype->scan_not(ctype_base::space, __first, __last); 124 } 125}; 126 127template <class _Traits> 128struct _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 136 _Scan_for_char_val(char_type __val) : _M_val(__val) {} 137 138 const char_type* 139 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 144template <class _Traits> 145struct _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 154 _Scan_for_int_val(int_type __val) : _M_val(__val) {} 155 156 const char_type* 157 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 166template <class _CharT, class _Traits> 167bool _STLP_CALL 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. 184template <class _CharT, class _Traits, class _Number> 185ios_base::iostate _STLP_CALL 186__get_num(basic_istream<_CharT, _Traits>& __that, _Number& __val) { 187 typedef typename basic_istream<_CharT, _Traits>::sentry _Sentry; 188 ios_base::iostate __err = 0; 189 _Sentry __sentry( __that ); // Skip whitespace. 190 if (__sentry) { 191 typedef num_get<_CharT, istreambuf_iterator<_CharT, _Traits> > _Num_get; 192 _STLP_TRY { 193 // Do not remove additional parenthesis around use_facet instanciation, some compilers (VC6) 194 // require it when building the library. 195 (use_facet<_Num_get>(__that.getloc())).get(istreambuf_iterator<_CharT, _Traits>(__that.rdbuf()), 196 0, __that, __err, __val); 197 } 198 _STLP_CATCH_ALL { 199 __that._M_handle_exception(ios_base::badbit); 200 } 201 if (__err) __that.setstate(__err); 202 } 203 return __err; 204} 205 206_STLP_MOVE_TO_STD_NAMESPACE 207 208template <class _CharT, class _Traits> 209basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (short& __val) { 210 long __lval; 211 _STLP_PRIV __get_num(*this, __lval); 212 if ( this->fail() ) { 213 return *this; 214 } 215 short __tmp = __STATIC_CAST(short, __lval); 216 unsigned short __uval = __STATIC_CAST(unsigned short, __lval); 217 // check if we lose digits 218 // if ((__val != __lval) && ((unsigned short)__val != __lval)) 219 if ((__tmp != __lval) && ((long)__uval != __lval)) 220 this->setstate(ios_base::failbit); 221 else 222 __val = __tmp; 223 return *this; 224} 225 226template <class _CharT, class _Traits> 227basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (int& __val) { 228 long __lval; 229 _STLP_PRIV __get_num(*this, __lval); 230 if ( this->fail() ) { 231 return *this; 232 } 233 int __tmp = __lval; 234 unsigned int __uval = __lval; 235 // check if we lose digits 236 // if ((__val != __lval) && ((unsigned int)__val != __lval)) 237 if ((__tmp != __lval) && ((long)__uval != __lval)) 238 this->setstate(ios_base::failbit); 239 else 240 __val = __tmp; 241 return *this; 242} 243 244template <class _CharT, class _Traits> 245basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (unsigned short& __val) { 246 _STLP_PRIV __get_num(*this, __val); 247 return *this; 248} 249 250template <class _CharT, class _Traits> 251basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (unsigned int& __val) { 252 _STLP_PRIV __get_num(*this, __val); 253 return *this; 254} 255 256template <class _CharT, class _Traits> 257basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (long& __val) { 258 _STLP_PRIV __get_num(*this, __val); 259 return *this; 260} 261 262template <class _CharT, class _Traits> 263basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (unsigned long& __val) { 264 _STLP_PRIV __get_num(*this, __val); 265 return *this; 266} 267 268#if defined (_STLP_LONG_LONG) 269template <class _CharT, class _Traits> 270basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (_STLP_LONG_LONG& __val) { 271 _STLP_PRIV __get_num(*this, __val); 272 return *this; 273} 274 275template <class _CharT, class _Traits> 276basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (unsigned _STLP_LONG_LONG& __val) { 277 _STLP_PRIV __get_num(*this, __val); 278 return *this; 279} 280#endif 281template <class _CharT, class _Traits> 282basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (float& __val) { 283 _STLP_PRIV __get_num(*this, __val); 284 return *this; 285} 286template <class _CharT, class _Traits> 287basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (double& __val) { 288 _STLP_PRIV __get_num(*this, __val); 289 return *this; 290} 291#if !defined (_STLP_NO_LONG_DOUBLE) 292template <class _CharT, class _Traits> 293basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (long double& __val) { 294 _STLP_PRIV __get_num(*this, __val); 295 return *this; 296} 297#endif 298#if !defined (_STLP_NO_BOOL) 299template <class _CharT, class _Traits> 300basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (bool& __val) { 301 _STLP_PRIV __get_num(*this, __val); 302 return *this; 303} 304#endif 305 306template <class _CharT, class _Traits> 307basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (void*& __val) { 308 _STLP_PRIV __get_num(*this, __val); 309 return *this; 310} 311 312// Unformatted input 313 314template <class _CharT, class _Traits> 315__BIS_int_type__ 316basic_istream<_CharT, _Traits>::peek() { 317 typename _Traits::int_type __tmp = _Traits::eof(); 318 319 this->_M_gcount = 0; 320 sentry __sentry(*this, _No_Skip_WS()); 321 322 if (__sentry) { 323 _STLP_TRY { 324 __tmp = this->rdbuf()->sgetc(); 325 } 326 _STLP_CATCH_ALL { 327 this->_M_handle_exception(ios_base::badbit); 328 } 329 if (this->_S_eof(__tmp)) 330 this->setstate(ios_base::eofbit); 331 } 332 333 return __tmp; 334} 335 336 337template <class _CharT, class _Traits> 338__BIS_int_type__ 339basic_istream<_CharT, _Traits>::get() { 340 typename _Traits::int_type __tmp = _Traits::eof(); 341 sentry __sentry(*this, _No_Skip_WS()); 342 this->_M_gcount = 0; 343 344 if (__sentry) { 345 _STLP_TRY { 346 __tmp = this->rdbuf()->sbumpc(); 347 } 348 _STLP_CATCH_ALL { 349 this->_M_handle_exception(ios_base::badbit); 350 } 351 352 if (!this->_S_eof(__tmp)) 353 this->_M_gcount = 1; 354 } 355 356 if (_M_gcount == 0) 357 this->setstate(ios_base::eofbit | ios_base::failbit); 358 359 return __tmp; 360} 361 362template <class _CharT, class _Traits> 363basic_istream<_CharT, _Traits>& 364basic_istream<_CharT, _Traits>::get(_CharT& __c) { 365 sentry __sentry(*this, _No_Skip_WS()); 366 this->_M_gcount = 0; 367 368 if (__sentry) { 369 typename _Traits::int_type __tmp = _Traits::eof(); 370 _STLP_TRY { 371 __tmp = this->rdbuf()->sbumpc(); 372 } 373 _STLP_CATCH_ALL { 374 this->_M_handle_exception(ios_base::badbit); 375 } 376 377 if (!this->_S_eof(__tmp)) { 378 this->_M_gcount = 1; 379 __c = _Traits::to_char_type(__tmp); 380 } 381 } 382 383 if (this->_M_gcount == 0) 384 this->setstate(ios_base::eofbit | ios_base::failbit); 385 386 return *this; 387} 388 389 390// Read characters and discard them. The standard specifies a single 391// function with two arguments, each with a default. We instead use 392// three overloded functions, because it's possible to implement the 393// first two more efficiently than the fully general third version. 394template <class _CharT, class _Traits> 395basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::ignore() { 396 sentry __sentry(*this, _No_Skip_WS()); 397 this->_M_gcount = 0; 398 399 if (__sentry) { 400 int_type __c; 401 _STLP_TRY { 402 __c = this->rdbuf()->sbumpc(); 403 } 404 _STLP_CATCH_ALL { 405 this->_M_handle_exception(ios_base::badbit); 406 return *this; 407 } 408 409 if (!this->_S_eof(__c)) 410 this->_M_gcount = 1; 411 else 412 this->setstate(ios_base::eofbit); 413 } 414 415 return *this; 416} 417 418// Putback 419 420template <class _CharT, class _Traits> 421basic_istream<_CharT, _Traits>& 422basic_istream<_CharT, _Traits>::putback(_CharT __c) { 423 this->_M_gcount = 0; 424 sentry __sentry(*this, _No_Skip_WS()); 425 426 if (__sentry) { 427 typename _Traits::int_type __tmp = _Traits::eof(); 428 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 429// if (!__buf || this->_S_eof(__buf->sputbackc(__c))) 430 if (__buf) { 431 _STLP_TRY { 432 __tmp = __buf->sputbackc(__c); 433 } 434 _STLP_CATCH_ALL { 435 this->_M_handle_exception(ios_base::badbit); 436 } 437 } 438 if (this->_S_eof(__tmp)) 439 this->setstate(ios_base::badbit); 440 } 441 else 442 this->setstate(ios_base::failbit); 443 444 return *this; 445} 446 447template <class _CharT, class _Traits> 448basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::unget() { 449 this->_M_gcount = 0; 450 451 sentry __sentry(*this, _No_Skip_WS()); 452 453 if (__sentry) { 454 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 455 // if (!__buf || _Traits::eq_int_type(__buf->sungetc(), _Traits::eof())) 456 if (__buf) { 457 _STLP_TRY { 458 if (this->_S_eof(__buf->sungetc())) 459 this->setstate(ios_base::badbit); 460 } 461 _STLP_CATCH_ALL { 462 this->_M_handle_exception(ios_base::badbit); 463 } 464 } else 465 this->setstate(ios_base::badbit); 466 } 467 else 468 this->setstate(ios_base::failbit); 469 470 return *this; 471} 472 473// Positioning and buffer control. 474 475template <class _CharT, class _Traits> 476int basic_istream<_CharT, _Traits>::sync() { 477 sentry __sentry(*this, _No_Skip_WS()); 478 479 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 480 if (__buf) { 481 if (__buf->pubsync() == -1) { 482 this->setstate(ios_base::badbit); 483 return -1; 484 } 485 else 486 return 0; 487 } 488 else 489 return -1; 490} 491 492template <class _CharT, class _Traits> 493__BIS_pos_type__ 494basic_istream<_CharT, _Traits>::tellg() { 495 sentry __sentry(*this, _No_Skip_WS()); 496 497 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 498 return (__buf && !this->fail()) ? __buf->pubseekoff(0, ios_base::cur, ios_base::in) 499 : pos_type(-1); 500} 501 502template <class _CharT, class _Traits> 503basic_istream<_CharT, _Traits>& 504basic_istream<_CharT, _Traits>::seekg(pos_type __pos) { 505 sentry __sentry(*this, _No_Skip_WS()); 506 507 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 508 if (!this->fail() && __buf) { 509 if (__buf->pubseekpos(__pos, ios_base::in) == pos_type(-1)) { 510 this->setstate(ios_base::failbit); 511 } 512 } 513 return *this; 514} 515 516template <class _CharT, class _Traits> 517basic_istream<_CharT, _Traits>& 518basic_istream<_CharT, _Traits>::seekg(off_type __off, ios_base::seekdir __dir) { 519 sentry __sentry(*this, _No_Skip_WS()); 520 521 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 522 if (!this->fail() && __buf) 523 __buf->pubseekoff(__off, __dir, ios_base::in); 524 return *this; 525} 526 527// Formatted input of characters and character arrays. 528 529template <class _CharT, class _Traits> 530void basic_istream<_CharT, _Traits>::_M_formatted_get(_CharT& __c) { 531// typename _Traits::int_type __tmp = _Traits::eof(); 532 533 sentry __sentry(*this); // Skip whitespace. 534 535 if (__sentry) { 536 typename _Traits::int_type __tmp;// = _Traits::eof(); 537 538 _STLP_TRY { 539 __tmp = this->rdbuf()->sbumpc(); 540 } 541 _STLP_CATCH_ALL { 542 this->_M_handle_exception(ios_base::badbit); 543 return; 544 } 545 546 if (!this->_S_eof(__tmp)) 547 __c = _Traits::to_char_type(__tmp); 548 else 549 this->setstate(ios_base::eofbit | ios_base::failbit); 550 } 551} 552 553 554//--------------------------------------------------------------------------- 555// istream's helper functions. 556 557// A generic function for unbuffered input. We stop when we reach EOF, 558// or when we have extracted _Num characters, or when the function object 559// __is_delim return true. In the last case, it extracts the character 560// for which __is_delim is true, if and only if __extract_delim is true. 561// It appends a null character to the end of the string; this means that 562// it may store up to _Num + 1 characters. 563// 564// __is_getline governs two corner cases: reading _Num characters without 565// encountering delim or eof (in which case failbit is set if __is_getline 566// is true); and reading _Num characters where the _Num+1'st character is 567// eof (in which case eofbit is set if __is_getline is true). 568// 569// It is assumed that __is_delim never throws. 570// 571// Return value is the number of characters extracted, including the 572// delimiter if it is extracted. Note that the number of characaters 573// extracted isn't necessarily the same as the number stored. 574 575_STLP_MOVE_TO_PRIV_NAMESPACE 576 577template < class _CharT, class _Traits, class _Is_Delim> 578streamsize _STLP_CALL 579__read_unbuffered(basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __buf, 580 streamsize _Num, _CharT* __s, 581 _Is_Delim __is_delim, 582 bool __extract_delim, bool __append_null, 583 bool __is_getline) 584{ 585 streamsize __n = 0; 586 ios_base::iostate __status = 0; 587 588 typedef typename basic_istream<_CharT, _Traits>::int_type int_type; 589 // The operations that can potentially throw are sbumpc, snextc, and sgetc. 590 _STLP_TRY { 591 for (;;) { 592 if (__n == _Num) { 593 if (__is_getline) // didn't find delimiter as one of the _Num chars 594 __status |= ios_base::failbit; 595 break; 596 } 597 int_type __c = __buf->sbumpc(); // sschwarz 598 599 if (__that->_S_eof(__c)) { 600 if (__n < _Num || __is_getline) 601 __status |= ios_base::eofbit; 602 break; 603 } else if (__is_delim(_Traits::to_char_type(__c))) { 604 if (__extract_delim) { // Extract and discard current character. 605 ++__n; 606 } else if ( !__pushback(__buf, _Traits::to_char_type(__c)) ) { // leave delimiter 607 __status |= ios_base::failbit; 608 } 609 break; 610 } 611 // regular character 612 *__s++ = _Traits::to_char_type(__c); 613 ++__n; 614 } 615 } 616 _STLP_CATCH_ALL { 617 __that->_M_handle_exception(ios_base::badbit); 618 *__s = _STLP_DEFAULT_CONSTRUCTED(_CharT); 619 return __n; 620 } 621 622 if (__append_null) 623 *__s = _STLP_DEFAULT_CONSTRUCTED(_CharT); 624 if (__status) 625 __that->setstate(__status); // This might throw. 626 return __n; 627} 628 629// Much like __read_unbuffered, but with one additional function object: 630// __scan_delim(first, last) returns the first pointer p in [first, last) 631// such that __is_delim(p) is true. 632 633template < class _CharT, class _Traits, class _Is_Delim, class _Scan_Delim> 634streamsize _STLP_CALL 635__read_buffered(basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __buf, 636 streamsize _Num, _CharT* __s, 637 _Is_Delim __is_delim, _Scan_Delim __scan_delim, 638 bool __extract_delim, bool __append_null, 639 bool __is_getline) { 640 streamsize __n = 0; 641 ios_base::iostate __status = 0; 642 bool __done = false; 643 644 _STLP_TRY { 645 while (__buf->_M_egptr() != __buf->_M_gptr() && !__done) { 646 const _CharT* __first = __buf->_M_gptr(); 647 const _CharT* __last = __buf->_M_egptr(); 648 //casting numeric_limits<ptrdiff_t>::max to streamsize only works is ptrdiff_t is signed or streamsize representation 649 //is larger than ptrdiff_t one. 650 _STLP_STATIC_ASSERT((sizeof(streamsize) > sizeof(ptrdiff_t)) || 651 ((sizeof(streamsize) == sizeof(ptrdiff_t)) && numeric_limits<ptrdiff_t>::is_signed)) 652 ptrdiff_t __request = __STATIC_CAST(ptrdiff_t, (min) (__STATIC_CAST(streamsize, (numeric_limits<ptrdiff_t>::max)()), _Num - __n)); 653 654 const _CharT* __p = __scan_delim(__first, __last); 655 ptrdiff_t __chunk = (min) (ptrdiff_t(__p - __first), __request); 656 _Traits::copy(__s, __first, __chunk); 657 __s += __chunk; 658 __n += __chunk; 659 __buf->_M_gbump((int)__chunk); 660 661 // We terminated by finding delim. 662 if (__p != __last && __p - __first <= __request) { 663 if (__extract_delim) { 664 __n += 1; 665 __buf->_M_gbump(1); 666 } 667 __done = true; 668 } 669 670 // We terminated by reading all the characters we were asked for. 671 else if (__n == _Num) { 672 673 // Find out if we have reached eof. This matters for getline. 674 if (__is_getline) { 675 if (__chunk == __last - __first) { 676 if (__that->_S_eof(__buf->sgetc())) 677 __status |= ios_base::eofbit; 678 } 679 else 680 __status |= ios_base::failbit; 681 } 682 __done = true; 683 } 684 685 // The buffer contained fewer than _Num - __n characters. Either we're 686 // at eof, or we should refill the buffer and try again. 687 else { 688 if (__that->_S_eof(__buf->sgetc())) { 689 __status |= ios_base::eofbit; 690 __done = true; 691 } 692 } 693 } // Close the while loop. 694 } 695 _STLP_CATCH_ALL { 696 __that->_M_handle_exception(ios_base::badbit); 697 __done = true; 698 } 699 700 if (__done) { 701 if (__append_null) 702 *__s = _STLP_DEFAULT_CONSTRUCTED(_CharT); 703 if (__status != 0) 704 __that->setstate(__status); // This might throw. 705 return __n; 706 } 707 708 // If execution has reached this point, then we have an empty buffer but 709 // we have not reached eof. What that means is that the streambuf has 710 // decided to switch from buffered to unbuffered input. We switch to 711 // to __read_unbuffered. 712 713 return __n + __read_unbuffered(__that, __buf, _Num - __n, __s, __is_delim, 714 __extract_delim,__append_null,__is_getline); 715} 716 717_STLP_MOVE_TO_STD_NAMESPACE 718 719template <class _CharT, class _Traits> 720basic_istream<_CharT, _Traits>& 721basic_istream<_CharT, _Traits>::get(_CharT* __s, streamsize __n, 722 _CharT __delim) { 723 sentry __sentry(*this, _No_Skip_WS()); 724 this->_M_gcount = 0; 725 726 if (__sentry) { 727 if (__n > 0) { 728 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 729 730 if (__buf->egptr() != __buf->gptr()) 731 this->_M_gcount = 732 _STLP_PRIV __read_buffered(this, __buf, __n - 1, __s, 733 _STLP_PRIV _Eq_char_bound<_Traits>(__delim), 734 _STLP_PRIV _Scan_for_char_val<_Traits>(__delim), 735 false, true, false); 736 else 737 this->_M_gcount = 738 _STLP_PRIV __read_unbuffered(this, __buf, __n - 1, __s, 739 _STLP_PRIV _Eq_char_bound<_Traits>(__delim), 740 false, true, false); 741 } 742 } 743 744 if (this->_M_gcount == 0) 745 this->setstate(ios_base::failbit); 746 747 return *this; 748} 749 750// Getline is essentially identical to get, except that it extracts 751// the delimiter. 752template <class _CharT, class _Traits> 753basic_istream<_CharT, _Traits>& 754basic_istream<_CharT, _Traits>::getline(_CharT* __s, streamsize __n, 755 _CharT __delim) { 756 sentry __sentry(*this, _No_Skip_WS()); 757 this->_M_gcount = 0; 758 759 if (__sentry) { 760 if (__n > 0) { 761 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 762 this->_M_gcount = __buf->egptr() != __buf->gptr() 763 ? _STLP_PRIV __read_buffered(this, __buf, __n - 1, __s, 764 _STLP_PRIV _Eq_char_bound<_Traits>(__delim), 765 _STLP_PRIV _Scan_for_char_val<_Traits>(__delim), 766 true, true, true) 767 : _STLP_PRIV __read_unbuffered(this, __buf, __n - 1, __s, 768 _STLP_PRIV _Eq_char_bound<_Traits>(__delim), 769 true, true, true); 770 } 771 } 772 773 if (this->_M_gcount == 0) 774 this->setstate(ios_base::failbit); 775 776 return *this; 777} 778 779// Read n characters. We don't look for any delimiter, and we don't 780// put in a terminating null character. 781template <class _CharT, class _Traits> 782basic_istream<_CharT, _Traits>& 783basic_istream<_CharT, _Traits>::read(char_type* __s, streamsize __n) { 784 sentry __sentry(*this, _No_Skip_WS()); 785 this->_M_gcount = 0; 786 787 if (__sentry && !this->eof()) { 788 basic_streambuf<_CharT, _Traits>*__buf = this->rdbuf(); 789 if (__buf->gptr() != __buf->egptr()) 790 _M_gcount 791 = _STLP_PRIV __read_buffered(this, __buf, __n, __s, 792 _STLP_PRIV _Constant_unary_fun<bool, int_type>(false), 793 _STLP_PRIV _Project2nd<const _CharT*, const _CharT*>(), 794 false, false, false); 795 else 796 _M_gcount 797 = _STLP_PRIV __read_unbuffered(this, __buf, __n, __s, 798 _STLP_PRIV _Constant_unary_fun<bool, int_type>(false), 799 false, false, false); 800 } 801 else 802 this->setstate(ios_base::failbit); 803 804 if (this->eof()) 805 this->setstate(ios_base::eofbit | ios_base::failbit); 806 807 return *this; 808} 809 810 811// Read n or fewer characters. We don't look for any delimiter, and 812// we don't put in a terminating null character. 813template <class _CharT, class _Traits> 814streamsize 815basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __nmax) { 816 sentry __sentry(*this, _No_Skip_WS()); 817 this->_M_gcount = 0; 818 819 if (__sentry && !this->eof() && __nmax >= 0) { 820 821 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 822 streamsize __avail = __buf->in_avail(); 823 824 // fbp : isn't full-blown setstate required here ? 825 if (__avail == -1) 826 this->_M_setstate_nothrow(ios_base::eofbit); 827 828 else if (__avail != 0) { 829 830 if (__buf->gptr() != __buf->egptr()) 831 _M_gcount 832 = _STLP_PRIV __read_buffered(this, __buf, (min) (__avail, __nmax), __s, 833 _STLP_PRIV _Constant_unary_fun<bool, int_type>(false), 834 _STLP_PRIV _Project2nd<const _CharT*, const _CharT*>(), 835 false, false, false); 836 else 837 _M_gcount 838 = _STLP_PRIV __read_unbuffered(this, __buf, (min) (__avail, __nmax), __s, 839 _STLP_PRIV _Constant_unary_fun<bool, int_type>(false), 840 false, false, false); 841 } 842 } 843 else { 844 // fbp : changed so that failbit is set only there, to pass Dietmar's test 845 if (this->eof()) 846 this->setstate(ios_base::eofbit | ios_base::failbit); 847 else 848 this->setstate(ios_base::failbit); 849 } 850 851 // if (this->eof()) 852 // this->setstate(ios_base::eofbit | ios_base::failbit); 853 854 return _M_gcount; 855} 856 857template <class _CharT, class _Traits> 858void basic_istream<_CharT, _Traits>::_M_formatted_get(_CharT* __s) { 859 sentry __sentry(*this); // Skip whitespace. 860 861 if (__sentry) { 862 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 863 streamsize __nmax = this->width() > 0 864 ? this->width() - 1 865 : ((numeric_limits<streamsize>::max)() / sizeof(_CharT)) - 1; 866 867 streamsize __n = __buf->gptr() != __buf->egptr() 868 ? _STLP_PRIV __read_buffered(this, __buf, __nmax, __s, 869 _STLP_PRIV _Is_wspace_null<_Traits>(this->_M_ctype_facet()), 870 _STLP_PRIV _Scan_wspace_null<_Traits>(this->_M_ctype_facet()), 871 false, true, false) 872 : _STLP_PRIV __read_unbuffered(this, __buf, __nmax, __s, 873 _STLP_PRIV _Is_wspace_null<_Traits>(this->_M_ctype_facet()), 874 false, true, false); 875 if (__n == 0) 876 this->setstate(ios_base::failbit); 877 } 878 this->width(0); 879} 880 881// A generic unbuffered function for ignoring characters. We stop 882// when we reach EOF, or when the function object __is_delim returns 883// true. In the last case, it extracts the character for which 884// __is_delim is true, if and only if __extract_delim is true. 885 886template < class _CharT, class _Traits, class _Is_Delim> 887void _STLP_CALL 888_M_ignore_unbuffered(basic_istream<_CharT, _Traits>* __that, 889 basic_streambuf<_CharT, _Traits>* __buf, 890 _Is_Delim __is_delim, 891 bool __extract_delim, bool __set_failbit) { 892 bool __done = false; 893 ios_base::iostate __status = 0; 894 typedef typename basic_istream<_CharT, _Traits>::int_type int_type; 895 896 _STLP_TRY { 897 while (!__done) { 898 int_type __c = __buf->sbumpc(); 899 900 if (__that->_S_eof(__c)) { 901 __done = true; 902 __status |= __set_failbit ? ios_base::eofbit | ios_base::failbit 903 : ios_base::eofbit; 904 } 905 906 else if (__is_delim(_Traits::to_char_type(__c))) { 907 __done = true; 908 if (!__extract_delim) 909 if (__that->_S_eof(__buf->sputbackc(_Traits::to_char_type(__c)))) 910 __status |= ios_base::failbit; 911 } 912 } 913 } 914 _STLP_CATCH_ALL { 915 __that->_M_handle_exception(ios_base::badbit); 916 } 917 918 __that->setstate(__status); 919} 920 921// A generic buffered function for ignoring characters. Much like 922// _M_ignore_unbuffered, but with one additional function object: 923// __scan_delim(first, last) returns the first pointer p in [first, 924// last) such that __is_delim(p) is true. 925 926template < class _CharT, class _Traits, class _Is_Delim, class _Scan_Delim> 927void _STLP_CALL 928_M_ignore_buffered(basic_istream<_CharT, _Traits>* __that, 929 basic_streambuf<_CharT, _Traits>* __buf, 930 _Is_Delim __is_delim, _Scan_Delim __scan_delim, 931 bool __extract_delim, bool __set_failbit) { 932 bool __at_eof = false; 933 bool __found_delim = false; 934 935 _STLP_TRY { 936 while (__buf->_M_egptr() != __buf->_M_gptr() && !__at_eof && !__found_delim) { 937 const _CharT* __p = __scan_delim(__buf->_M_gptr(), __buf->_M_egptr()); 938 __buf->_M_gbump((int)(__p - __buf->_M_gptr())); 939 940 if (__p != __buf->_M_egptr()) { // We found delim, so we're done. 941 if (__extract_delim) 942 __buf->_M_gbump(1); 943 __found_delim = true; 944 } 945 946 else // No delim. Try to refil the buffer. 947 __at_eof = __that->_S_eof(__buf->sgetc()); 948 } // Close the while loop. 949 } 950 _STLP_CATCH_ALL { 951 __that->_M_handle_exception(ios_base::badbit); 952 return; 953 } 954 955 if (__at_eof) { 956 __that->setstate(__set_failbit ? ios_base::eofbit | ios_base::failbit 957 : ios_base::eofbit); 958 return; 959 } 960 if (__found_delim) 961 return; 962 963 // If execution has reached this point, then we have an empty buffer but 964 // we have not reached eof. What that means is that the streambuf has 965 // decided to switch from a buffered to an unbuffered mode. We switch 966 // to _M_ignore_unbuffered. 967 _M_ignore_unbuffered(__that, __buf, __is_delim, __extract_delim, __set_failbit); 968} 969 970// Overloaded versions of _M_ignore_unbuffered and _M_ignore_unbuffered 971// with an explicit count _Num. Return value is the number of 972// characters extracted. 973// 974// The function object __max_chars takes two arguments, _Num and __n 975// (the latter being the number of characters we have already read), 976// and returns the maximum number of characters to read from the buffer. 977// We parameterize _M_ignore_buffered so that we can use it for both 978// bounded and unbounded input; for the former the function object should 979// be minus<>, and for the latter it should return a constant maximum value. 980 981template < class _CharT, class _Traits, class _Max_Chars, class _Is_Delim> 982streamsize _STLP_CALL 983_M_ignore_unbuffered(basic_istream<_CharT, _Traits>* __that, 984 basic_streambuf<_CharT, _Traits>* __buf, 985 streamsize _Num, _Max_Chars __max_chars, 986 _Is_Delim __is_delim, 987 bool __extract_delim, bool __set_failbit) { 988 streamsize __n = 0; 989 ios_base::iostate __status = 0; 990 typedef typename basic_istream<_CharT, _Traits>::int_type int_type; 991 992 _STLP_TRY { 993 while (__max_chars(_Num, __n) > 0) { 994 int_type __c = __buf->sbumpc(); 995 996 if (__that->_S_eof(__c)) { 997 __status |= __set_failbit ? ios_base::eofbit | ios_base::failbit 998 : ios_base::eofbit; 999 break; 1000 } 1001 1002 else if (__is_delim(_Traits::to_char_type(__c))) { 1003 if (__extract_delim) 1004 ++__n; 1005 else if (__that->_S_eof(__buf->sputbackc(_Traits::to_char_type(__c)))) 1006 __status |= ios_base::failbit; 1007 1008 break; 1009 } 1010 // fbp : added counter increment to pass Dietmar's test 1011 ++__n; 1012 } 1013 } 1014 _STLP_CATCH_ALL { 1015 __that->_M_handle_exception(ios_base::badbit); 1016 } 1017 1018 if (__status) 1019 __that->setstate(__status); // This might throw. 1020 return __n; 1021} 1022 1023template < class _CharT, class _Traits, class _Max_Chars, class _Is_Delim, class _Scan_Delim> 1024streamsize _STLP_CALL 1025_M_ignore_buffered(basic_istream<_CharT, _Traits>* __that, 1026 basic_streambuf<_CharT, _Traits>* __buf, 1027 streamsize _Num, 1028 _Max_Chars __max_chars, 1029 _Is_Delim __is_delim, _Scan_Delim __scan_delim, 1030 bool __extract_delim, bool __set_failbit) { 1031 streamsize __n = 0; 1032 bool __at_eof = false; 1033 bool __done = false; 1034 1035 _STLP_TRY { 1036 while (__buf->_M_egptr() != __buf->_M_gptr() && !__done) { 1037 ptrdiff_t __avail = __buf->_M_egptr() - __buf->_M_gptr(); 1038 streamsize __m = __max_chars(_Num, __n); 1039 1040 if (__avail >= __m) { // We have more characters than we need. 1041 const _CharT* __last = __buf->_M_gptr() + __STATIC_CAST(ptrdiff_t, __m); 1042 const _CharT* __p = __scan_delim(__buf->_M_gptr(), __last); 1043 ptrdiff_t __chunk = __p - __buf->_M_gptr(); 1044 __n += __chunk; 1045 __buf->_M_gbump((int)__chunk); 1046 1047 if (__extract_delim && __p != __last) { 1048 __n += 1; 1049 __buf->_M_gbump(1); 1050 } 1051 1052 __done = true; 1053 } 1054 1055 else { 1056 const _CharT* __p = __scan_delim(__buf->_M_gptr(), __buf->_M_egptr()); 1057 ptrdiff_t __chunk = __p - __buf->_M_gptr(); 1058 __n += __chunk; 1059 __buf->_M_gbump((int)__chunk); 1060 1061 if (__p != __buf->_M_egptr()) { // We found delim. 1062 if (__extract_delim) { 1063 __n += 1; 1064 __buf->_M_gbump(1); 1065 } 1066 1067 __done = true; 1068 } 1069 1070 // We didn't find delim. Try to refill the buffer. 1071 else if (__that->_S_eof(__buf->sgetc())) { 1072 __done = true; 1073 __at_eof = true; 1074 } 1075 } 1076 } // Close the while loop. 1077 } 1078 _STLP_CATCH_ALL { 1079 __that->_M_handle_exception(ios_base::badbit); 1080 return __n; 1081 } 1082 1083 if (__at_eof) 1084 __that->setstate(__set_failbit ? ios_base::eofbit | ios_base::failbit 1085 : ios_base::eofbit); 1086 1087 if (__done) 1088 return __n; 1089 1090 // If execution has reached this point, then we have an empty buffer but 1091 // we have not reached eof. What that means is that the streambuf has 1092 // decided to switch from buffered to unbuffered input. We switch to 1093 // to _M_ignore_unbuffered. 1094 1095 return __n + _M_ignore_unbuffered(__that, __buf, _Num, __max_chars, 1096 __is_delim, __extract_delim, __set_failbit); 1097} 1098 1099 1100template <class _CharT, class _Traits> 1101basic_istream<_CharT, _Traits>& 1102basic_istream<_CharT, _Traits>::ignore(streamsize __n) { 1103 sentry __sentry(*this, _No_Skip_WS()); 1104 this->_M_gcount = 0; 1105 1106 if (__sentry) { 1107 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 1108 typedef _STLP_PRIV _Constant_unary_fun<bool, int_type> _Const_bool; 1109 typedef _STLP_PRIV _Constant_binary_fun<streamsize, streamsize, streamsize> _Const_streamsize; 1110 const streamsize __maxss = (numeric_limits<streamsize>::max)(); 1111 1112 if (__n == (numeric_limits<int>::max)()) { 1113 if (__buf->gptr() != __buf->egptr()) 1114 _M_gcount = _M_ignore_buffered(this, __buf, 1115 __maxss, _Const_streamsize(__maxss), 1116 _Const_bool(false), 1117 _STLP_PRIV _Project2nd<const _CharT*, const _CharT*>(), 1118 false, false); 1119 else 1120 _M_gcount = _M_ignore_unbuffered(this, __buf, 1121 __maxss, _Const_streamsize(__maxss), 1122 _Const_bool(false), false, false); 1123 } 1124 else { 1125 if (__buf->gptr() != __buf->egptr()) 1126 _M_gcount = _M_ignore_buffered(this, __buf, 1127 __n, minus<streamsize>(), 1128 _Const_bool(false), 1129 _STLP_PRIV _Project2nd<const _CharT*, const _CharT*>(), 1130 false, false); 1131 else 1132 _M_gcount = _M_ignore_unbuffered(this, __buf, __n, minus<streamsize>(), 1133 _Const_bool(false), false, false); 1134 } 1135 } 1136 1137 return *this; 1138} 1139 1140template <class _CharT, class _Traits> 1141basic_istream<_CharT, _Traits>& 1142basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __delim) { 1143 sentry __sentry(*this, _No_Skip_WS()); 1144 this->_M_gcount = 0; 1145 1146 if (__sentry) { 1147 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 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. 1184template <class _CharT, class _Traits> 1185void 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>(this->_M_ctype_facet()), 1192 _STLP_PRIV _Scan_for_not_wspace<_Traits>(this->_M_ctype_facet()), 1193 false, __set_failbit); 1194 else 1195 _M_ignore_unbuffered(this, __buf, 1196 _STLP_PRIV _Is_not_wspace<_Traits>(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 1210template < class _CharT, class _Traits, class _Is_Delim> 1211streamsize _STLP_CALL 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 1279template < class _CharT, class _Traits, class _Is_Delim, class _Scan_Delim> 1280streamsize _STLP_CALL 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 1347template <class _CharT, class _Traits> 1348basic_istream<_CharT, _Traits>& 1349basic_istream<_CharT, _Traits> 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. 1375template <class _CharT, class _Traits> 1376basic_istream<_CharT, _Traits>& 1377basic_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 1405template <class _CharT, class _Traits> 1406basic_iostream<_CharT, _Traits> 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 1414template <class _CharT, class _Traits> 1415basic_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