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