Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygen_istream.c
Go to the documentation of this file.
00001 /* 00002 * Copyright (c) 1999 00003 * Silicon Graphics Computer Systems, Inc. 00004 * 00005 * Copyright (c) 1999 00006 * Boris Fomitchev 00007 * 00008 * This material is provided "as is", with absolutely no warranty expressed 00009 * or implied. Any use is at your own risk. 00010 * 00011 * Permission to use or copy this software for any purpose is hereby granted 00012 * without fee, provided the above notices are retained on all copies. 00013 * Permission to modify the code and to distribute modified code is granted, 00014 * provided the above notices are retained, and a notice that the code was 00015 * modified is included with the above copyright notice. 00016 * 00017 */ 00018 #ifndef _STLP_ISTREAM_C 00019 #define _STLP_ISTREAM_C 00020 00021 #ifndef _STLP_INTERNAL_ISTREAM 00022 # include <stl/_istream.h> 00023 #endif 00024 00025 #ifndef _STLP_INTERNAL_LIMITS 00026 # include <stl/_limits.h> 00027 #endif 00028 00029 #ifndef _STLP_INTERNAL_NUM_GET_H 00030 # include <stl/_num_get.h> 00031 #endif 00032 00033 #if defined ( _STLP_NESTED_TYPE_PARAM_BUG ) 00034 // no wchar_t is supported for this mode 00035 # define __BIS_int_type__ int 00036 # define __BIS_pos_type__ streampos 00037 # define __BIS_off_type__ streamoff 00038 #else 00039 # define __BIS_int_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_istream<_CharT, _Traits>::int_type 00040 # define __BIS_pos_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_istream<_CharT, _Traits>::pos_type 00041 # define __BIS_off_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_istream<_CharT, _Traits>::off_type 00042 #endif 00043 00044 _STLP_BEGIN_NAMESPACE 00045 00046 //---------------------------------------------------------------------- 00047 // Function object structs used by some member functions. 00048 00049 _STLP_MOVE_TO_PRIV_NAMESPACE 00050 00051 template <class _Traits> 00052 struct _Is_not_wspace { 00053 typedef typename _Traits::char_type argument_type; 00054 typedef bool result_type; 00055 00056 const ctype<argument_type>* _M_ctype; 00057 00058 _Is_not_wspace(const ctype<argument_type>* __c_type) : _M_ctype(__c_type) {} 00059 bool operator()(argument_type __c) const 00060 { return !_M_ctype->is(ctype_base::space, __c); } 00061 }; 00062 00063 template <class _Traits> 00064 struct _Is_wspace_null { 00065 typedef typename _Traits::char_type argument_type; 00066 typedef bool result_type; 00067 00068 const ctype<argument_type>* _M_ctype; 00069 00070 _Is_wspace_null(const ctype<argument_type>* __c_type) : _M_ctype(__c_type) {} 00071 bool operator()(argument_type __c) const { 00072 return _Traits::eq(__c, argument_type()) || 00073 _M_ctype->is(ctype_base::space, __c); 00074 } 00075 }; 00076 00077 template <class _Traits> 00078 struct _Scan_for_wspace { 00079 typedef typename _Traits::char_type char_type; 00080 typedef char_type* first_argument_type; 00081 typedef char_type* second_argument_type; 00082 typedef char_type* result_type; 00083 00084 const ctype<char_type>* _M_ctype; 00085 00086 _Scan_for_wspace(const ctype<char_type>* __ctype) : _M_ctype(__ctype) {} 00087 const char_type* 00088 operator()(const char_type* __first, const char_type* __last) const { 00089 return _M_ctype->scan_is(ctype_base::space, __first, __last); 00090 } 00091 }; 00092 00093 template <class _Traits> 00094 struct _Scan_wspace_null { 00095 typedef typename _Traits::char_type char_type; 00096 typedef char_type* first_argument_type; 00097 typedef char_type* second_argument_type; 00098 typedef char_type* result_type; 00099 00100 const ctype<char_type>* _M_ctype; 00101 00102 _Scan_wspace_null(const ctype<char_type>* __c_type) : _M_ctype(__c_type) {} 00103 const char_type* 00104 operator()(const char_type* __first, const char_type* __last) const { 00105 __last = find_if(__first, __last, 00106 _Eq_char_bound<_Traits>(char_type())); 00107 return _M_ctype->scan_is(ctype_base::space, __first, __last); 00108 } 00109 }; 00110 00111 template <class _Traits> 00112 struct _Scan_for_not_wspace { 00113 typedef typename _Traits::char_type char_type; 00114 typedef char_type* first_argument_type; 00115 typedef char_type* second_argument_type; 00116 typedef char_type* result_type; 00117 00118 const ctype<char_type>* _M_ctype; 00119 00120 _Scan_for_not_wspace(const ctype<char_type>* __c_type) : _M_ctype(__c_type) {} 00121 const char_type* 00122 operator()(const char_type* __first, const char_type* __last) const { 00123 return _M_ctype->scan_not(ctype_base::space, __first, __last); 00124 } 00125 }; 00126 00127 template <class _Traits> 00128 struct _Scan_for_char_val { 00129 typedef typename _Traits::char_type char_type; 00130 typedef char_type* first_argument_type; 00131 typedef char_type* second_argument_type; 00132 typedef char_type* result_type; 00133 00134 char_type _M_val; 00135 00136 _Scan_for_char_val(char_type __val) : _M_val(__val) {} 00137 00138 const char_type* 00139 operator()(const char_type* __first, const char_type* __last) const { 00140 return find_if(__first, __last, _Eq_char_bound<_Traits>(_M_val)); 00141 } 00142 }; 00143 00144 template <class _Traits> 00145 struct _Scan_for_int_val { 00146 typedef typename _Traits::char_type char_type; 00147 typedef typename _Traits::int_type int_type; 00148 typedef char_type* first_argument_type; 00149 typedef char_type* second_argument_type; 00150 typedef char_type* result_type; 00151 00152 int_type _M_val; 00153 00154 _Scan_for_int_val(int_type __val) : _M_val(__val) {} 00155 00156 const char_type* 00157 operator()(const char_type* __first, const char_type* __last) const { 00158 return find_if(__first, __last, 00159 _Eq_int_bound<_Traits>(_M_val)); 00160 } 00161 }; 00162 00163 // Helper function: try to push back a character to a streambuf, 00164 // return true if the pushback succeeded. Does not throw. 00165 00166 template <class _CharT, class _Traits> 00167 bool _STLP_CALL 00168 __pushback(basic_streambuf<_CharT, _Traits>* __buf, _CharT __c) { 00169 bool ret; 00170 _STLP_TRY { 00171 const typename _Traits::int_type __eof = _Traits::eof(); 00172 ret = !_Traits::eq_int_type(__buf->sputbackc(__c), __eof); 00173 } 00174 _STLP_CATCH_ALL { 00175 ret = false; 00176 } 00177 return ret; 00178 } 00179 00180 //---------------------------------------------------------------------- 00181 // Definitions of basic_istream<>'s noninline member functions. 00182 00183 // Helper function for formatted input of numbers. 00184 template <class _CharT, class _Traits, class _Number> 00185 ios_base::iostate _STLP_CALL 00186 __get_num(basic_istream<_CharT, _Traits>& __that, _Number& __val) { 00187 typedef typename basic_istream<_CharT, _Traits>::sentry _Sentry; 00188 ios_base::iostate __err = 0; 00189 _Sentry __sentry( __that ); // Skip whitespace. 00190 if (__sentry) { 00191 typedef num_get<_CharT, istreambuf_iterator<_CharT, _Traits> > _Num_get; 00192 _STLP_TRY { 00193 // Do not remove additional parenthesis around use_facet instanciation, some compilers (VC6) 00194 // require it when building the library. 00195 (use_facet<_Num_get>(__that.getloc())).get(istreambuf_iterator<_CharT, _Traits>(__that.rdbuf()), 00196 0, __that, __err, __val); 00197 } 00198 _STLP_CATCH_ALL { 00199 __that._M_handle_exception(ios_base::badbit); 00200 } 00201 if (__err) __that.setstate(__err); 00202 } 00203 return __err; 00204 } 00205 00206 _STLP_MOVE_TO_STD_NAMESPACE 00207 00208 template <class _CharT, class _Traits> 00209 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (short& __val) { 00210 long __lval; 00211 _STLP_PRIV __get_num(*this, __lval); 00212 if ( this->fail() ) { 00213 return *this; 00214 } 00215 short __tmp = __STATIC_CAST(short, __lval); 00216 unsigned short __uval = __STATIC_CAST(unsigned short, __lval); 00217 // check if we lose digits 00218 // if ((__val != __lval) && ((unsigned short)__val != __lval)) 00219 if ((__tmp != __lval) && ((long)__uval != __lval)) 00220 this->setstate(ios_base::failbit); 00221 else 00222 __val = __tmp; 00223 return *this; 00224 } 00225 00226 template <class _CharT, class _Traits> 00227 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (int& __val) { 00228 long __lval; 00229 _STLP_PRIV __get_num(*this, __lval); 00230 if ( this->fail() ) { 00231 return *this; 00232 } 00233 int __tmp = __lval; 00234 unsigned int __uval = __lval; 00235 // check if we lose digits 00236 // if ((__val != __lval) && ((unsigned int)__val != __lval)) 00237 if ((__tmp != __lval) && ((long)__uval != __lval)) 00238 this->setstate(ios_base::failbit); 00239 else 00240 __val = __tmp; 00241 return *this; 00242 } 00243 00244 template <class _CharT, class _Traits> 00245 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (unsigned short& __val) { 00246 _STLP_PRIV __get_num(*this, __val); 00247 return *this; 00248 } 00249 00250 template <class _CharT, class _Traits> 00251 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (unsigned int& __val) { 00252 _STLP_PRIV __get_num(*this, __val); 00253 return *this; 00254 } 00255 00256 template <class _CharT, class _Traits> 00257 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (long& __val) { 00258 _STLP_PRIV __get_num(*this, __val); 00259 return *this; 00260 } 00261 00262 template <class _CharT, class _Traits> 00263 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (unsigned long& __val) { 00264 _STLP_PRIV __get_num(*this, __val); 00265 return *this; 00266 } 00267 00268 #if defined (_STLP_LONG_LONG) 00269 template <class _CharT, class _Traits> 00270 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (_STLP_LONG_LONG& __val) { 00271 _STLP_PRIV __get_num(*this, __val); 00272 return *this; 00273 } 00274 00275 template <class _CharT, class _Traits> 00276 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (unsigned _STLP_LONG_LONG& __val) { 00277 _STLP_PRIV __get_num(*this, __val); 00278 return *this; 00279 } 00280 #endif 00281 template <class _CharT, class _Traits> 00282 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (float& __val) { 00283 _STLP_PRIV __get_num(*this, __val); 00284 return *this; 00285 } 00286 template <class _CharT, class _Traits> 00287 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (double& __val) { 00288 _STLP_PRIV __get_num(*this, __val); 00289 return *this; 00290 } 00291 #if !defined (_STLP_NO_LONG_DOUBLE) 00292 template <class _CharT, class _Traits> 00293 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (long double& __val) { 00294 _STLP_PRIV __get_num(*this, __val); 00295 return *this; 00296 } 00297 #endif 00298 #if !defined (_STLP_NO_BOOL) 00299 template <class _CharT, class _Traits> 00300 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (bool& __val) { 00301 _STLP_PRIV __get_num(*this, __val); 00302 return *this; 00303 } 00304 #endif 00305 00306 template <class _CharT, class _Traits> 00307 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>> (void*& __val) { 00308 _STLP_PRIV __get_num(*this, __val); 00309 return *this; 00310 } 00311 00312 // Unformatted input 00313 00314 template <class _CharT, class _Traits> 00315 __BIS_int_type__ 00316 basic_istream<_CharT, _Traits>::peek() { 00317 typename _Traits::int_type __tmp = _Traits::eof(); 00318 00319 this->_M_gcount = 0; 00320 sentry __sentry(*this, _No_Skip_WS()); 00321 00322 if (__sentry) { 00323 _STLP_TRY { 00324 __tmp = this->rdbuf()->sgetc(); 00325 } 00326 _STLP_CATCH_ALL { 00327 this->_M_handle_exception(ios_base::badbit); 00328 } 00329 if (this->_S_eof(__tmp)) 00330 this->setstate(ios_base::eofbit); 00331 } 00332 00333 return __tmp; 00334 } 00335 00336 00337 template <class _CharT, class _Traits> 00338 __BIS_int_type__ 00339 basic_istream<_CharT, _Traits>::get() { 00340 typename _Traits::int_type __tmp = _Traits::eof(); 00341 sentry __sentry(*this, _No_Skip_WS()); 00342 this->_M_gcount = 0; 00343 00344 if (__sentry) { 00345 _STLP_TRY { 00346 __tmp = this->rdbuf()->sbumpc(); 00347 } 00348 _STLP_CATCH_ALL { 00349 this->_M_handle_exception(ios_base::badbit); 00350 } 00351 00352 if (!this->_S_eof(__tmp)) 00353 this->_M_gcount = 1; 00354 } 00355 00356 if (_M_gcount == 0) 00357 this->setstate(ios_base::eofbit | ios_base::failbit); 00358 00359 return __tmp; 00360 } 00361 00362 template <class _CharT, class _Traits> 00363 basic_istream<_CharT, _Traits>& 00364 basic_istream<_CharT, _Traits>::get(_CharT& __c) { 00365 sentry __sentry(*this, _No_Skip_WS()); 00366 this->_M_gcount = 0; 00367 00368 if (__sentry) { 00369 typename _Traits::int_type __tmp = _Traits::eof(); 00370 _STLP_TRY { 00371 __tmp = this->rdbuf()->sbumpc(); 00372 } 00373 _STLP_CATCH_ALL { 00374 this->_M_handle_exception(ios_base::badbit); 00375 } 00376 00377 if (!this->_S_eof(__tmp)) { 00378 this->_M_gcount = 1; 00379 __c = _Traits::to_char_type(__tmp); 00380 } 00381 } 00382 00383 if (this->_M_gcount == 0) 00384 this->setstate(ios_base::eofbit | ios_base::failbit); 00385 00386 return *this; 00387 } 00388 00389 00390 // Read characters and discard them. The standard specifies a single 00391 // function with two arguments, each with a default. We instead use 00392 // three overloded functions, because it's possible to implement the 00393 // first two more efficiently than the fully general third version. 00394 template <class _CharT, class _Traits> 00395 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::ignore() { 00396 sentry __sentry(*this, _No_Skip_WS()); 00397 this->_M_gcount = 0; 00398 00399 if (__sentry) { 00400 int_type __c; 00401 _STLP_TRY { 00402 __c = this->rdbuf()->sbumpc(); 00403 } 00404 _STLP_CATCH_ALL { 00405 this->_M_handle_exception(ios_base::badbit); 00406 return *this; 00407 } 00408 00409 if (!this->_S_eof(__c)) 00410 this->_M_gcount = 1; 00411 else 00412 this->setstate(ios_base::eofbit); 00413 } 00414 00415 return *this; 00416 } 00417 00418 // Putback 00419 00420 template <class _CharT, class _Traits> 00421 basic_istream<_CharT, _Traits>& 00422 basic_istream<_CharT, _Traits>::putback(_CharT __c) { 00423 this->_M_gcount = 0; 00424 sentry __sentry(*this, _No_Skip_WS()); 00425 00426 if (__sentry) { 00427 typename _Traits::int_type __tmp = _Traits::eof(); 00428 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 00429 // if (!__buf || this->_S_eof(__buf->sputbackc(__c))) 00430 if (__buf) { 00431 _STLP_TRY { 00432 __tmp = __buf->sputbackc(__c); 00433 } 00434 _STLP_CATCH_ALL { 00435 this->_M_handle_exception(ios_base::badbit); 00436 } 00437 } 00438 if (this->_S_eof(__tmp)) 00439 this->setstate(ios_base::badbit); 00440 } 00441 else 00442 this->setstate(ios_base::failbit); 00443 00444 return *this; 00445 } 00446 00447 template <class _CharT, class _Traits> 00448 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::unget() { 00449 this->_M_gcount = 0; 00450 00451 sentry __sentry(*this, _No_Skip_WS()); 00452 00453 if (__sentry) { 00454 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 00455 // if (!__buf || _Traits::eq_int_type(__buf->sungetc(), _Traits::eof())) 00456 if (__buf) { 00457 _STLP_TRY { 00458 if (this->_S_eof(__buf->sungetc())) 00459 this->setstate(ios_base::badbit); 00460 } 00461 _STLP_CATCH_ALL { 00462 this->_M_handle_exception(ios_base::badbit); 00463 } 00464 } else 00465 this->setstate(ios_base::badbit); 00466 } 00467 else 00468 this->setstate(ios_base::failbit); 00469 00470 return *this; 00471 } 00472 00473 // Positioning and buffer control. 00474 00475 template <class _CharT, class _Traits> 00476 int basic_istream<_CharT, _Traits>::sync() { 00477 sentry __sentry(*this, _No_Skip_WS()); 00478 00479 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 00480 if (__buf) { 00481 if (__buf->pubsync() == -1) { 00482 this->setstate(ios_base::badbit); 00483 return -1; 00484 } 00485 else 00486 return 0; 00487 } 00488 else 00489 return -1; 00490 } 00491 00492 template <class _CharT, class _Traits> 00493 __BIS_pos_type__ 00494 basic_istream<_CharT, _Traits>::tellg() { 00495 sentry __sentry(*this, _No_Skip_WS()); 00496 00497 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 00498 return (__buf && !this->fail()) ? __buf->pubseekoff(0, ios_base::cur, ios_base::in) 00499 : pos_type(-1); 00500 } 00501 00502 template <class _CharT, class _Traits> 00503 basic_istream<_CharT, _Traits>& 00504 basic_istream<_CharT, _Traits>::seekg(pos_type __pos) { 00505 sentry __sentry(*this, _No_Skip_WS()); 00506 00507 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 00508 if (!this->fail() && __buf) { 00509 if (__buf->pubseekpos(__pos, ios_base::in) == pos_type(-1)) { 00510 this->setstate(ios_base::failbit); 00511 } 00512 } 00513 return *this; 00514 } 00515 00516 template <class _CharT, class _Traits> 00517 basic_istream<_CharT, _Traits>& 00518 basic_istream<_CharT, _Traits>::seekg(off_type __off, ios_base::seekdir __dir) { 00519 sentry __sentry(*this, _No_Skip_WS()); 00520 00521 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 00522 if (!this->fail() && __buf) 00523 __buf->pubseekoff(__off, __dir, ios_base::in); 00524 return *this; 00525 } 00526 00527 // Formatted input of characters and character arrays. 00528 00529 template <class _CharT, class _Traits> 00530 void basic_istream<_CharT, _Traits>::_M_formatted_get(_CharT& __c) { 00531 // typename _Traits::int_type __tmp = _Traits::eof(); 00532 00533 sentry __sentry(*this); // Skip whitespace. 00534 00535 if (__sentry) { 00536 typename _Traits::int_type __tmp;// = _Traits::eof(); 00537 00538 _STLP_TRY { 00539 __tmp = this->rdbuf()->sbumpc(); 00540 } 00541 _STLP_CATCH_ALL { 00542 this->_M_handle_exception(ios_base::badbit); 00543 return; 00544 } 00545 00546 if (!this->_S_eof(__tmp)) 00547 __c = _Traits::to_char_type(__tmp); 00548 else 00549 this->setstate(ios_base::eofbit | ios_base::failbit); 00550 } 00551 } 00552 00553 00554 //--------------------------------------------------------------------------- 00555 // istream's helper functions. 00556 00557 // A generic function for unbuffered input. We stop when we reach EOF, 00558 // or when we have extracted _Num characters, or when the function object 00559 // __is_delim return true. In the last case, it extracts the character 00560 // for which __is_delim is true, if and only if __extract_delim is true. 00561 // It appends a null character to the end of the string; this means that 00562 // it may store up to _Num + 1 characters. 00563 // 00564 // __is_getline governs two corner cases: reading _Num characters without 00565 // encountering delim or eof (in which case failbit is set if __is_getline 00566 // is true); and reading _Num characters where the _Num+1'st character is 00567 // eof (in which case eofbit is set if __is_getline is true). 00568 // 00569 // It is assumed that __is_delim never throws. 00570 // 00571 // Return value is the number of characters extracted, including the 00572 // delimiter if it is extracted. Note that the number of characaters 00573 // extracted isn't necessarily the same as the number stored. 00574 00575 _STLP_MOVE_TO_PRIV_NAMESPACE 00576 00577 template < class _CharT, class _Traits, class _Is_Delim> 00578 streamsize _STLP_CALL 00579 __read_unbuffered(basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __buf, 00580 streamsize _Num, _CharT* __s, 00581 _Is_Delim __is_delim, 00582 bool __extract_delim, bool __append_null, 00583 bool __is_getline) 00584 { 00585 streamsize __n = 0; 00586 ios_base::iostate __status = 0; 00587 00588 typedef typename basic_istream<_CharT, _Traits>::int_type int_type; 00589 // The operations that can potentially throw are sbumpc, snextc, and sgetc. 00590 _STLP_TRY { 00591 for (;;) { 00592 if (__n == _Num) { 00593 if (__is_getline) // didn't find delimiter as one of the _Num chars 00594 __status |= ios_base::failbit; 00595 break; 00596 } 00597 int_type __c = __buf->sbumpc(); // sschwarz 00598 00599 if (__that->_S_eof(__c)) { 00600 if (__n < _Num || __is_getline) 00601 __status |= ios_base::eofbit; 00602 break; 00603 } else if (__is_delim(_Traits::to_char_type(__c))) { 00604 if (__extract_delim) { // Extract and discard current character. 00605 ++__n; 00606 } else if ( !__pushback(__buf, _Traits::to_char_type(__c)) ) { // leave delimiter 00607 __status |= ios_base::failbit; 00608 } 00609 break; 00610 } 00611 // regular character 00612 *__s++ = _Traits::to_char_type(__c); 00613 ++__n; 00614 } 00615 } 00616 _STLP_CATCH_ALL { 00617 __that->_M_handle_exception(ios_base::badbit); 00618 *__s = _STLP_DEFAULT_CONSTRUCTED(_CharT); 00619 return __n; 00620 } 00621 00622 if (__append_null) 00623 *__s = _STLP_DEFAULT_CONSTRUCTED(_CharT); 00624 if (__status) 00625 __that->setstate(__status); // This might throw. 00626 return __n; 00627 } 00628 00629 // Much like __read_unbuffered, but with one additional function object: 00630 // __scan_delim(first, last) returns the first pointer p in [first, last) 00631 // such that __is_delim(p) is true. 00632 00633 template < class _CharT, class _Traits, class _Is_Delim, class _Scan_Delim> 00634 streamsize _STLP_CALL 00635 __read_buffered(basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __buf, 00636 streamsize _Num, _CharT* __s, 00637 _Is_Delim __is_delim, _Scan_Delim __scan_delim, 00638 bool __extract_delim, bool __append_null, 00639 bool __is_getline) { 00640 streamsize __n = 0; 00641 ios_base::iostate __status = 0; 00642 bool __done = false; 00643 00644 _STLP_TRY { 00645 while (__buf->_M_egptr() != __buf->_M_gptr() && !__done) { 00646 const _CharT* __first = __buf->_M_gptr(); 00647 const _CharT* __last = __buf->_M_egptr(); 00648 //casting numeric_limits<ptrdiff_t>::max to streamsize only works is ptrdiff_t is signed or streamsize representation 00649 //is larger than ptrdiff_t one. 00650 _STLP_STATIC_ASSERT((sizeof(streamsize) > sizeof(ptrdiff_t)) || 00651 ((sizeof(streamsize) == sizeof(ptrdiff_t)) && numeric_limits<ptrdiff_t>::is_signed)) 00652 ptrdiff_t __request = __STATIC_CAST(ptrdiff_t, (min) (__STATIC_CAST(streamsize, (numeric_limits<ptrdiff_t>::max)()), _Num - __n)); 00653 00654 const _CharT* __p = __scan_delim(__first, __last); 00655 ptrdiff_t __chunk = (min) (ptrdiff_t(__p - __first), __request); 00656 _Traits::copy(__s, __first, __chunk); 00657 __s += __chunk; 00658 __n += __chunk; 00659 __buf->_M_gbump((int)__chunk); 00660 00661 // We terminated by finding delim. 00662 if (__p != __last && __p - __first <= __request) { 00663 if (__extract_delim) { 00664 __n += 1; 00665 __buf->_M_gbump(1); 00666 } 00667 __done = true; 00668 } 00669 00670 // We terminated by reading all the characters we were asked for. 00671 else if (__n == _Num) { 00672 00673 // Find out if we have reached eof. This matters for getline. 00674 if (__is_getline) { 00675 if (__chunk == __last - __first) { 00676 if (__that->_S_eof(__buf->sgetc())) 00677 __status |= ios_base::eofbit; 00678 } 00679 else 00680 __status |= ios_base::failbit; 00681 } 00682 __done = true; 00683 } 00684 00685 // The buffer contained fewer than _Num - __n characters. Either we're 00686 // at eof, or we should refill the buffer and try again. 00687 else { 00688 if (__that->_S_eof(__buf->sgetc())) { 00689 __status |= ios_base::eofbit; 00690 __done = true; 00691 } 00692 } 00693 } // Close the while loop. 00694 } 00695 _STLP_CATCH_ALL { 00696 __that->_M_handle_exception(ios_base::badbit); 00697 __done = true; 00698 } 00699 00700 if (__done) { 00701 if (__append_null) 00702 *__s = _STLP_DEFAULT_CONSTRUCTED(_CharT); 00703 if (__status != 0) 00704 __that->setstate(__status); // This might throw. 00705 return __n; 00706 } 00707 00708 // If execution has reached this point, then we have an empty buffer but 00709 // we have not reached eof. What that means is that the streambuf has 00710 // decided to switch from buffered to unbuffered input. We switch to 00711 // to __read_unbuffered. 00712 00713 return __n + __read_unbuffered(__that, __buf, _Num - __n, __s, __is_delim, 00714 __extract_delim,__append_null,__is_getline); 00715 } 00716 00717 _STLP_MOVE_TO_STD_NAMESPACE 00718 00719 template <class _CharT, class _Traits> 00720 basic_istream<_CharT, _Traits>& 00721 basic_istream<_CharT, _Traits>::get(_CharT* __s, streamsize __n, 00722 _CharT __delim) { 00723 sentry __sentry(*this, _No_Skip_WS()); 00724 this->_M_gcount = 0; 00725 00726 if (__sentry) { 00727 if (__n > 0) { 00728 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 00729 00730 if (__buf->egptr() != __buf->gptr()) 00731 this->_M_gcount = 00732 _STLP_PRIV __read_buffered(this, __buf, __n - 1, __s, 00733 _STLP_PRIV _Eq_char_bound<_Traits>(__delim), 00734 _STLP_PRIV _Scan_for_char_val<_Traits>(__delim), 00735 false, true, false); 00736 else 00737 this->_M_gcount = 00738 _STLP_PRIV __read_unbuffered(this, __buf, __n - 1, __s, 00739 _STLP_PRIV _Eq_char_bound<_Traits>(__delim), 00740 false, true, false); 00741 } 00742 } 00743 00744 if (this->_M_gcount == 0) 00745 this->setstate(ios_base::failbit); 00746 00747 return *this; 00748 } 00749 00750 // Getline is essentially identical to get, except that it extracts 00751 // the delimiter. 00752 template <class _CharT, class _Traits> 00753 basic_istream<_CharT, _Traits>& 00754 basic_istream<_CharT, _Traits>::getline(_CharT* __s, streamsize __n, 00755 _CharT __delim) { 00756 sentry __sentry(*this, _No_Skip_WS()); 00757 this->_M_gcount = 0; 00758 00759 if (__sentry) { 00760 if (__n > 0) { 00761 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 00762 this->_M_gcount = __buf->egptr() != __buf->gptr() 00763 ? _STLP_PRIV __read_buffered(this, __buf, __n - 1, __s, 00764 _STLP_PRIV _Eq_char_bound<_Traits>(__delim), 00765 _STLP_PRIV _Scan_for_char_val<_Traits>(__delim), 00766 true, true, true) 00767 : _STLP_PRIV __read_unbuffered(this, __buf, __n - 1, __s, 00768 _STLP_PRIV _Eq_char_bound<_Traits>(__delim), 00769 true, true, true); 00770 } 00771 } 00772 00773 if (this->_M_gcount == 0) 00774 this->setstate(ios_base::failbit); 00775 00776 return *this; 00777 } 00778 00779 // Read n characters. We don't look for any delimiter, and we don't 00780 // put in a terminating null character. 00781 template <class _CharT, class _Traits> 00782 basic_istream<_CharT, _Traits>& 00783 basic_istream<_CharT, _Traits>::read(char_type* __s, streamsize __n) { 00784 sentry __sentry(*this, _No_Skip_WS()); 00785 this->_M_gcount = 0; 00786 00787 if (__sentry && !this->eof()) { 00788 basic_streambuf<_CharT, _Traits>*__buf = this->rdbuf(); 00789 if (__buf->gptr() != __buf->egptr()) 00790 _M_gcount 00791 = _STLP_PRIV __read_buffered(this, __buf, __n, __s, 00792 _STLP_PRIV _Constant_unary_fun<bool, int_type>(false), 00793 _STLP_PRIV _Project2nd<const _CharT*, const _CharT*>(), 00794 false, false, false); 00795 else 00796 _M_gcount 00797 = _STLP_PRIV __read_unbuffered(this, __buf, __n, __s, 00798 _STLP_PRIV _Constant_unary_fun<bool, int_type>(false), 00799 false, false, false); 00800 } 00801 else 00802 this->setstate(ios_base::failbit); 00803 00804 if (this->eof()) 00805 this->setstate(ios_base::eofbit | ios_base::failbit); 00806 00807 return *this; 00808 } 00809 00810 00811 // Read n or fewer characters. We don't look for any delimiter, and 00812 // we don't put in a terminating null character. 00813 template <class _CharT, class _Traits> 00814 streamsize 00815 basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __nmax) { 00816 sentry __sentry(*this, _No_Skip_WS()); 00817 this->_M_gcount = 0; 00818 00819 if (__sentry && !this->eof() && __nmax >= 0) { 00820 00821 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 00822 streamsize __avail = __buf->in_avail(); 00823 00824 // fbp : isn't full-blown setstate required here ? 00825 if (__avail == -1) 00826 this->_M_setstate_nothrow(ios_base::eofbit); 00827 00828 else if (__avail != 0) { 00829 00830 if (__buf->gptr() != __buf->egptr()) 00831 _M_gcount 00832 = _STLP_PRIV __read_buffered(this, __buf, (min) (__avail, __nmax), __s, 00833 _STLP_PRIV _Constant_unary_fun<bool, int_type>(false), 00834 _STLP_PRIV _Project2nd<const _CharT*, const _CharT*>(), 00835 false, false, false); 00836 else 00837 _M_gcount 00838 = _STLP_PRIV __read_unbuffered(this, __buf, (min) (__avail, __nmax), __s, 00839 _STLP_PRIV _Constant_unary_fun<bool, int_type>(false), 00840 false, false, false); 00841 } 00842 } 00843 else { 00844 // fbp : changed so that failbit is set only there, to pass Dietmar's test 00845 if (this->eof()) 00846 this->setstate(ios_base::eofbit | ios_base::failbit); 00847 else 00848 this->setstate(ios_base::failbit); 00849 } 00850 00851 // if (this->eof()) 00852 // this->setstate(ios_base::eofbit | ios_base::failbit); 00853 00854 return _M_gcount; 00855 } 00856 00857 template <class _CharT, class _Traits> 00858 void basic_istream<_CharT, _Traits>::_M_formatted_get(_CharT* __s) { 00859 sentry __sentry(*this); // Skip whitespace. 00860 00861 if (__sentry) { 00862 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 00863 streamsize __nmax = this->width() > 0 00864 ? this->width() - 1 00865 : ((numeric_limits<streamsize>::max)() / sizeof(_CharT)) - 1; 00866 00867 streamsize __n = __buf->gptr() != __buf->egptr() 00868 ? _STLP_PRIV __read_buffered(this, __buf, __nmax, __s, 00869 _STLP_PRIV _Is_wspace_null<_Traits>(this->_M_ctype_facet()), 00870 _STLP_PRIV _Scan_wspace_null<_Traits>(this->_M_ctype_facet()), 00871 false, true, false) 00872 : _STLP_PRIV __read_unbuffered(this, __buf, __nmax, __s, 00873 _STLP_PRIV _Is_wspace_null<_Traits>(this->_M_ctype_facet()), 00874 false, true, false); 00875 if (__n == 0) 00876 this->setstate(ios_base::failbit); 00877 } 00878 this->width(0); 00879 } 00880 00881 // A generic unbuffered function for ignoring characters. We stop 00882 // when we reach EOF, or when the function object __is_delim returns 00883 // true. In the last case, it extracts the character for which 00884 // __is_delim is true, if and only if __extract_delim is true. 00885 00886 template < class _CharT, class _Traits, class _Is_Delim> 00887 void _STLP_CALL 00888 _M_ignore_unbuffered(basic_istream<_CharT, _Traits>* __that, 00889 basic_streambuf<_CharT, _Traits>* __buf, 00890 _Is_Delim __is_delim, 00891 bool __extract_delim, bool __set_failbit) { 00892 bool __done = false; 00893 ios_base::iostate __status = 0; 00894 typedef typename basic_istream<_CharT, _Traits>::int_type int_type; 00895 00896 _STLP_TRY { 00897 while (!__done) { 00898 int_type __c = __buf->sbumpc(); 00899 00900 if (__that->_S_eof(__c)) { 00901 __done = true; 00902 __status |= __set_failbit ? ios_base::eofbit | ios_base::failbit 00903 : ios_base::eofbit; 00904 } 00905 00906 else if (__is_delim(_Traits::to_char_type(__c))) { 00907 __done = true; 00908 if (!__extract_delim) 00909 if (__that->_S_eof(__buf->sputbackc(_Traits::to_char_type(__c)))) 00910 __status |= ios_base::failbit; 00911 } 00912 } 00913 } 00914 _STLP_CATCH_ALL { 00915 __that->_M_handle_exception(ios_base::badbit); 00916 } 00917 00918 __that->setstate(__status); 00919 } 00920 00921 // A generic buffered function for ignoring characters. Much like 00922 // _M_ignore_unbuffered, but with one additional function object: 00923 // __scan_delim(first, last) returns the first pointer p in [first, 00924 // last) such that __is_delim(p) is true. 00925 00926 template < class _CharT, class _Traits, class _Is_Delim, class _Scan_Delim> 00927 void _STLP_CALL 00928 _M_ignore_buffered(basic_istream<_CharT, _Traits>* __that, 00929 basic_streambuf<_CharT, _Traits>* __buf, 00930 _Is_Delim __is_delim, _Scan_Delim __scan_delim, 00931 bool __extract_delim, bool __set_failbit) { 00932 bool __at_eof = false; 00933 bool __found_delim = false; 00934 00935 _STLP_TRY { 00936 while (__buf->_M_egptr() != __buf->_M_gptr() && !__at_eof && !__found_delim) { 00937 const _CharT* __p = __scan_delim(__buf->_M_gptr(), __buf->_M_egptr()); 00938 __buf->_M_gbump((int)(__p - __buf->_M_gptr())); 00939 00940 if (__p != __buf->_M_egptr()) { // We found delim, so we're done. 00941 if (__extract_delim) 00942 __buf->_M_gbump(1); 00943 __found_delim = true; 00944 } 00945 00946 else // No delim. Try to refil the buffer. 00947 __at_eof = __that->_S_eof(__buf->sgetc()); 00948 } // Close the while loop. 00949 } 00950 _STLP_CATCH_ALL { 00951 __that->_M_handle_exception(ios_base::badbit); 00952 return; 00953 } 00954 00955 if (__at_eof) { 00956 __that->setstate(__set_failbit ? ios_base::eofbit | ios_base::failbit 00957 : ios_base::eofbit); 00958 return; 00959 } 00960 if (__found_delim) 00961 return; 00962 00963 // If execution has reached this point, then we have an empty buffer but 00964 // we have not reached eof. What that means is that the streambuf has 00965 // decided to switch from a buffered to an unbuffered mode. We switch 00966 // to _M_ignore_unbuffered. 00967 _M_ignore_unbuffered(__that, __buf, __is_delim, __extract_delim, __set_failbit); 00968 } 00969 00970 // Overloaded versions of _M_ignore_unbuffered and _M_ignore_unbuffered 00971 // with an explicit count _Num. Return value is the number of 00972 // characters extracted. 00973 // 00974 // The function object __max_chars takes two arguments, _Num and __n 00975 // (the latter being the number of characters we have already read), 00976 // and returns the maximum number of characters to read from the buffer. 00977 // We parameterize _M_ignore_buffered so that we can use it for both 00978 // bounded and unbounded input; for the former the function object should 00979 // be minus<>, and for the latter it should return a constant maximum value. 00980 00981 template < class _CharT, class _Traits, class _Max_Chars, class _Is_Delim> 00982 streamsize _STLP_CALL 00983 _M_ignore_unbuffered(basic_istream<_CharT, _Traits>* __that, 00984 basic_streambuf<_CharT, _Traits>* __buf, 00985 streamsize _Num, _Max_Chars __max_chars, 00986 _Is_Delim __is_delim, 00987 bool __extract_delim, bool __set_failbit) { 00988 streamsize __n = 0; 00989 ios_base::iostate __status = 0; 00990 typedef typename basic_istream<_CharT, _Traits>::int_type int_type; 00991 00992 _STLP_TRY { 00993 while (__max_chars(_Num, __n) > 0) { 00994 int_type __c = __buf->sbumpc(); 00995 00996 if (__that->_S_eof(__c)) { 00997 __status |= __set_failbit ? ios_base::eofbit | ios_base::failbit 00998 : ios_base::eofbit; 00999 break; 01000 } 01001 01002 else if (__is_delim(_Traits::to_char_type(__c))) { 01003 if (__extract_delim) 01004 ++__n; 01005 else if (__that->_S_eof(__buf->sputbackc(_Traits::to_char_type(__c)))) 01006 __status |= ios_base::failbit; 01007 01008 break; 01009 } 01010 // fbp : added counter increment to pass Dietmar's test 01011 ++__n; 01012 } 01013 } 01014 _STLP_CATCH_ALL { 01015 __that->_M_handle_exception(ios_base::badbit); 01016 } 01017 01018 if (__status) 01019 __that->setstate(__status); // This might throw. 01020 return __n; 01021 } 01022 01023 template < class _CharT, class _Traits, class _Max_Chars, class _Is_Delim, class _Scan_Delim> 01024 streamsize _STLP_CALL 01025 _M_ignore_buffered(basic_istream<_CharT, _Traits>* __that, 01026 basic_streambuf<_CharT, _Traits>* __buf, 01027 streamsize _Num, 01028 _Max_Chars __max_chars, 01029 _Is_Delim __is_delim, _Scan_Delim __scan_delim, 01030 bool __extract_delim, bool __set_failbit) { 01031 streamsize __n = 0; 01032 bool __at_eof = false; 01033 bool __done = false; 01034 01035 _STLP_TRY { 01036 while (__buf->_M_egptr() != __buf->_M_gptr() && !__done) { 01037 ptrdiff_t __avail = __buf->_M_egptr() - __buf->_M_gptr(); 01038 streamsize __m = __max_chars(_Num, __n); 01039 01040 if (__avail >= __m) { // We have more characters than we need. 01041 const _CharT* __last = __buf->_M_gptr() + __STATIC_CAST(ptrdiff_t, __m); 01042 const _CharT* __p = __scan_delim(__buf->_M_gptr(), __last); 01043 ptrdiff_t __chunk = __p - __buf->_M_gptr(); 01044 __n += __chunk; 01045 __buf->_M_gbump((int)__chunk); 01046 01047 if (__extract_delim && __p != __last) { 01048 __n += 1; 01049 __buf->_M_gbump(1); 01050 } 01051 01052 __done = true; 01053 } 01054 01055 else { 01056 const _CharT* __p = __scan_delim(__buf->_M_gptr(), __buf->_M_egptr()); 01057 ptrdiff_t __chunk = __p - __buf->_M_gptr(); 01058 __n += __chunk; 01059 __buf->_M_gbump((int)__chunk); 01060 01061 if (__p != __buf->_M_egptr()) { // We found delim. 01062 if (__extract_delim) { 01063 __n += 1; 01064 __buf->_M_gbump(1); 01065 } 01066 01067 __done = true; 01068 } 01069 01070 // We didn't find delim. Try to refill the buffer. 01071 else if (__that->_S_eof(__buf->sgetc())) { 01072 __done = true; 01073 __at_eof = true; 01074 } 01075 } 01076 } // Close the while loop. 01077 } 01078 _STLP_CATCH_ALL { 01079 __that->_M_handle_exception(ios_base::badbit); 01080 return __n; 01081 } 01082 01083 if (__at_eof) 01084 __that->setstate(__set_failbit ? ios_base::eofbit | ios_base::failbit 01085 : ios_base::eofbit); 01086 01087 if (__done) 01088 return __n; 01089 01090 // If execution has reached this point, then we have an empty buffer but 01091 // we have not reached eof. What that means is that the streambuf has 01092 // decided to switch from buffered to unbuffered input. We switch to 01093 // to _M_ignore_unbuffered. 01094 01095 return __n + _M_ignore_unbuffered(__that, __buf, _Num, __max_chars, 01096 __is_delim, __extract_delim, __set_failbit); 01097 } 01098 01099 01100 template <class _CharT, class _Traits> 01101 basic_istream<_CharT, _Traits>& 01102 basic_istream<_CharT, _Traits>::ignore(streamsize __n) { 01103 sentry __sentry(*this, _No_Skip_WS()); 01104 this->_M_gcount = 0; 01105 01106 if (__sentry) { 01107 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 01108 typedef _STLP_PRIV _Constant_unary_fun<bool, int_type> _Const_bool; 01109 typedef _STLP_PRIV _Constant_binary_fun<streamsize, streamsize, streamsize> _Const_streamsize; 01110 const streamsize __maxss = (numeric_limits<streamsize>::max)(); 01111 01112 if (__n == (numeric_limits<int>::max)()) { 01113 if (__buf->gptr() != __buf->egptr()) 01114 _M_gcount = _M_ignore_buffered(this, __buf, 01115 __maxss, _Const_streamsize(__maxss), 01116 _Const_bool(false), 01117 _STLP_PRIV _Project2nd<const _CharT*, const _CharT*>(), 01118 false, false); 01119 else 01120 _M_gcount = _M_ignore_unbuffered(this, __buf, 01121 __maxss, _Const_streamsize(__maxss), 01122 _Const_bool(false), false, false); 01123 } 01124 else { 01125 if (__buf->gptr() != __buf->egptr()) 01126 _M_gcount = _M_ignore_buffered(this, __buf, 01127 __n, minus<streamsize>(), 01128 _Const_bool(false), 01129 _STLP_PRIV _Project2nd<const _CharT*, const _CharT*>(), 01130 false, false); 01131 else 01132 _M_gcount = _M_ignore_unbuffered(this, __buf, __n, minus<streamsize>(), 01133 _Const_bool(false), false, false); 01134 } 01135 } 01136 01137 return *this; 01138 } 01139 01140 template <class _CharT, class _Traits> 01141 basic_istream<_CharT, _Traits>& 01142 basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __delim) { 01143 sentry __sentry(*this, _No_Skip_WS()); 01144 this->_M_gcount = 0; 01145 01146 if (__sentry) { 01147 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 01148 typedef _STLP_PRIV _Constant_unary_fun<bool, int_type> _Const_bool; 01149 typedef _STLP_PRIV _Constant_binary_fun<streamsize, streamsize, streamsize> 01150 _Const_streamsize; 01151 const streamsize __maxss = (numeric_limits<streamsize>::max)(); 01152 01153 if (__n == (numeric_limits<int>::max)()) { 01154 if (__buf->gptr() != __buf->egptr()) 01155 _M_gcount = _M_ignore_buffered(this, __buf, 01156 __maxss, _Const_streamsize(__maxss), 01157 _STLP_PRIV _Eq_int_bound<_Traits>(__delim), 01158 _STLP_PRIV _Scan_for_int_val<_Traits>(__delim), 01159 true, false); 01160 else 01161 _M_gcount = _M_ignore_unbuffered(this, __buf, 01162 __maxss, _Const_streamsize(__maxss), 01163 _STLP_PRIV _Eq_int_bound<_Traits>(__delim), 01164 true, false); 01165 } 01166 else { 01167 if (__buf->gptr() != __buf->egptr()) 01168 _M_gcount = _M_ignore_buffered(this, __buf, 01169 __n, minus<streamsize>(), 01170 _STLP_PRIV _Eq_int_bound<_Traits>(__delim), 01171 _STLP_PRIV _Scan_for_int_val<_Traits>(__delim), 01172 true, false); 01173 else 01174 _M_gcount = _M_ignore_unbuffered(this, __buf, __n, minus<streamsize>(), 01175 _STLP_PRIV _Eq_int_bound<_Traits>(__delim), 01176 true, false); 01177 } 01178 } 01179 01180 return *this; 01181 } 01182 01183 // This member function does not construct a sentry object, because 01184 // it is called from sentry's constructor. 01185 template <class _CharT, class _Traits> 01186 void basic_istream<_CharT, _Traits>::_M_skip_whitespace(bool __set_failbit) { 01187 basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); 01188 if (!__buf) 01189 this->setstate(ios_base::badbit); 01190 else if (__buf->gptr() != __buf->egptr()) 01191 _M_ignore_buffered(this, __buf, 01192 _STLP_PRIV _Is_not_wspace<_Traits>(this->_M_ctype_facet()), 01193 _STLP_PRIV _Scan_for_not_wspace<_Traits>(this->_M_ctype_facet()), 01194 false, __set_failbit); 01195 else 01196 _M_ignore_unbuffered(this, __buf, 01197 _STLP_PRIV _Is_not_wspace<_Traits>(this->_M_ctype_facet()), 01198 false, __set_failbit); 01199 } 01200 01201 01202 // This is a very simple loop that reads characters from __src and puts 01203 // them into __dest. It looks complicated because of the (standard- 01204 // mandated) exception handling policy. 01205 // 01206 // We stop when we get an exception, when we fail to insert into the 01207 // output streambuf, or when __is_delim is true. 01208 01209 _STLP_MOVE_TO_PRIV_NAMESPACE 01210 01211 template < class _CharT, class _Traits, class _Is_Delim> 01212 streamsize _STLP_CALL 01213 __copy_unbuffered(basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __src, 01214 basic_streambuf<_CharT, _Traits>* __dest, 01215 _Is_Delim __is_delim, 01216 bool __extract_delim, bool __rethrow) { 01217 streamsize __extracted = 0; 01218 ios_base::iostate __status = 0; 01219 typedef typename basic_istream<_CharT, _Traits>::int_type int_type; 01220 int_type __c; 01221 01222 _STLP_TRY { 01223 for (;;) { 01224 // Get a character. If there's an exception, catch and (maybe) rethrow it. 01225 __c = __src->sbumpc(); 01226 01227 // If we failed to get a character, then quit. 01228 if (__that->_S_eof(__c)) { 01229 __status |= ios_base::eofbit; 01230 break; 01231 } 01232 // If it's the delimiter, then quit. 01233 else if (__is_delim(_Traits::to_char_type(__c))) { 01234 if (!__extract_delim && !__pushback(__src, _Traits::to_char_type(__c))) 01235 __status |= ios_base::failbit; 01236 break; 01237 } 01238 else { 01239 // Try to put the character in the output streambuf. 01240 bool __failed = false; 01241 _STLP_TRY { 01242 if (!__that->_S_eof(__dest->sputc(_Traits::to_char_type(__c)))) 01243 ++__extracted; 01244 else 01245 __failed = true; 01246 } 01247 _STLP_CATCH_ALL { 01248 __failed = true; 01249 } 01250 01251 // If we failed to put the character in the output streambuf, then 01252 // try to push it back to the input streambuf. 01253 if (__failed && !__pushback(__src, _Traits::to_char_type(__c))) 01254 __status |= ios_base::failbit; 01255 01256 // fbp : avoiding infinite loop in io-27-6-1-2-3.exp 01257 if (__failed) 01258 break; 01259 } 01260 01261 } /* for (;;) */ 01262 01263 } 01264 // fbp : this try/catch moved here in reasonable assumption 01265 // __is_delim never throw (__pushback is guaranteed not to) 01266 _STLP_CATCH_ALL { 01267 // See 27.6.1.2.3, paragraph 13. 01268 if (__rethrow && __extracted == 0) 01269 __that->_M_handle_exception(ios_base::failbit); 01270 } 01271 __that->setstate(__status); 01272 return __extracted; 01273 } 01274 01275 // Buffered copying from one streambuf to another. We copy the characters 01276 // in chunks, rather than one at a time. We still have to worry about all 01277 // of the error conditions we checked in __copy_unbuffered, plus one more: 01278 // the streambuf might decide to switch from a buffered to an unbuffered mode. 01279 01280 template < class _CharT, class _Traits, class _Is_Delim, class _Scan_Delim> 01281 streamsize _STLP_CALL 01282 __copy_buffered(basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __src, 01283 basic_streambuf<_CharT, _Traits>* __dest, 01284 _Scan_Delim __scan_delim, _Is_Delim __is_delim, 01285 bool __extract_delim, bool __rethrow) { 01286 streamsize __extracted = 0; 01287 ios_base::iostate __status = 0; 01288 typedef typename basic_istream<_CharT, _Traits>::int_type int_type; 01289 //Borland compiler generates a warning if assignment because value is never used: 01290 int_type __c /*= _Traits::eof()*/; 01291 _CharT* __first = __src->_M_gptr(); 01292 ptrdiff_t __avail = __src->_M_egptr() - __first; 01293 // fbp : introduced to move catch/try blocks out of the loop 01294 bool __do_handle_exceptions = false; 01295 01296 _STLP_TRY { 01297 for (;;) { 01298 const _CharT* __last = __scan_delim(__first, __src->_M_egptr()); 01299 01300 // Try to copy the entire input buffer to the output buffer. 01301 streamsize __n = __dest->sputn(__first, __extract_delim && __last != __src->_M_egptr() 01302 ? (__last - __first) + 1 01303 : (__last - __first)); 01304 __src->_M_gbump((int)__n); 01305 __extracted += __n; 01306 01307 // from this on, catch() will call _M_handle_exceptions() 01308 __do_handle_exceptions = true; 01309 01310 if (__n < __avail) // We found the delimiter, or else failed to 01311 break; // copy some characters. 01312 01313 __c = __src->sgetc(); 01314 01315 // Three possibilities: we succeeded in refilling the buffer, or 01316 // we got EOF, or the streambuf has switched to unbuffered mode. 01317 __first = __src->_M_gptr(); 01318 __avail = __src->_M_egptr() - __first; 01319 01320 if (__avail > 0) 01321 {} // dwa 1/16/00 -- suppress a Metrowerks warning 01322 else if (__that->_S_eof(__c)) { 01323 __status |= ios_base::eofbit; 01324 break; 01325 } 01326 else { 01327 return __extracted + __copy_unbuffered(__that, __src, __dest, __is_delim, 01328 __extract_delim, __rethrow); 01329 } 01330 01331 __do_handle_exceptions = false; 01332 } 01333 } 01334 01335 _STLP_CATCH_ALL { 01336 // See 27.6.1.2.3, paragraph 13. 01337 if (__rethrow && __do_handle_exceptions && __extracted == 0) 01338 __that->_M_handle_exception(ios_base::failbit); 01339 } 01340 01341 if (__status) 01342 __that->setstate(__status); // This might throw. 01343 return __extracted; 01344 } 01345 01346 _STLP_MOVE_TO_STD_NAMESPACE 01347 01348 template <class _CharT, class _Traits> 01349 basic_istream<_CharT, _Traits>& 01350 basic_istream<_CharT, _Traits> 01351 ::get(basic_streambuf<_CharT, _Traits>& __dest, _CharT __delim) { 01352 sentry __sentry(*this, _No_Skip_WS()); 01353 this->_M_gcount = 0; 01354 01355 if (__sentry) { 01356 basic_streambuf<_CharT, _Traits>* __src = this->rdbuf(); 01357 01358 if (__src) 01359 this->_M_gcount = __src->egptr() != __src->gptr() 01360 ? _STLP_PRIV __copy_buffered(this, __src, &__dest, 01361 _STLP_PRIV _Scan_for_char_val<_Traits>(__delim), 01362 _STLP_PRIV _Eq_char_bound<_Traits>(__delim), 01363 false, false) 01364 : _STLP_PRIV __copy_unbuffered(this, __src, &__dest, 01365 _STLP_PRIV _Eq_char_bound<_Traits>(__delim), 01366 false, false); 01367 } 01368 01369 if (this->_M_gcount == 0) 01370 this->setstate(ios_base::failbit); 01371 01372 return *this; 01373 } 01374 01375 // Copying characters into a streambuf. 01376 template <class _CharT, class _Traits> 01377 basic_istream<_CharT, _Traits>& 01378 basic_istream<_CharT, _Traits> 01379 ::operator>>(basic_streambuf<_CharT, _Traits>* __dest) { 01380 streamsize __n = 0; 01381 typedef typename basic_istream<_CharT, _Traits>::sentry _Sentry; 01382 _Sentry __sentry(*this); 01383 if (__sentry) { 01384 basic_streambuf<_CharT, _Traits>* __src = this->rdbuf(); 01385 if (__src && __dest) 01386 __n = __src->egptr() != __src->gptr() 01387 ? _STLP_PRIV __copy_buffered(this, __src, __dest, 01388 _STLP_PRIV _Project2nd<const _CharT*, const _CharT*>(), 01389 _STLP_PRIV _Constant_unary_fun<bool, int_type>(false), 01390 false, true) 01391 : _STLP_PRIV __copy_unbuffered(this, __src, __dest, 01392 _STLP_PRIV _Constant_unary_fun<bool, int_type>(false), 01393 false, true); 01394 } 01395 01396 if (__n == 0) 01397 this->setstate(ios_base::failbit); 01398 01399 return *this; 01400 } 01401 01402 // ---------------------------------------------------------------- 01403 // basic_iostream<> class 01404 // ---------------------------------------------------------------- 01405 01406 template <class _CharT, class _Traits> 01407 basic_iostream<_CharT, _Traits> 01408 ::basic_iostream(basic_streambuf<_CharT, _Traits>* __buf) 01409 : basic_ios<_CharT, _Traits>(), 01410 basic_istream<_CharT, _Traits>(__buf), 01411 basic_ostream<_CharT, _Traits>(__buf) { 01412 this->init(__buf); 01413 } 01414 01415 template <class _CharT, class _Traits> 01416 basic_iostream<_CharT, _Traits>::~basic_iostream() 01417 {} 01418 01419 _STLP_END_NAMESPACE 01420 01421 #undef __BIS_int_type__ 01422 #undef __BIS_pos_type__ 01423 #undef __BIS_off_type__ 01424 01425 #endif /* _STLP_ISTREAM_C */ 01426 01427 // Local Variables: 01428 // mode:C++ 01429 // End: Generated on Sat May 26 2012 04:27:44 for ReactOS by
1.7.6.1
|