_istream.c

来自「stl的源码」· C语言 代码 · 共 1,430 行 · 第 1/4 页

C
1,430
字号
      }    } // Close the while loop.  }  _STLP_CATCH_ALL {    __that->_M_handle_exception(ios_base::badbit);    return __n;  }  if (__at_eof)    __that->setstate(__set_failbit ? ios_base::eofbit | ios_base::failbit                                   : ios_base::eofbit);  if (__done)    return __n;  // If execution has reached this point, then we have an empty buffer but  // we have not reached eof.  What that means is that the streambuf has  // decided to switch from buffered to unbuffered input.  We switch to  // to _M_ignore_unbuffered.  return __n + _M_ignore_unbuffered(__that,  __buf, _Num, __max_chars,                                    __is_delim, __extract_delim, __set_failbit);}template <class _CharT, class _Traits>basic_istream<_CharT, _Traits>&basic_istream<_CharT, _Traits>::ignore(streamsize __n) {  sentry __sentry(*this, _No_Skip_WS());  this->_M_gcount = 0;  if (__sentry) {    basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();    typedef _STLP_PRIV _Constant_unary_fun<bool, int_type> _Const_bool;    typedef _STLP_PRIV _Constant_binary_fun<streamsize, streamsize, streamsize> _Const_streamsize;    const streamsize __maxss = (numeric_limits<streamsize>::max)();    if (__n == (numeric_limits<int>::max)()) {      if (__buf->gptr() != __buf->egptr())        _M_gcount = _M_ignore_buffered(this,  __buf,                                       __maxss, _Const_streamsize(__maxss),                                       _Const_bool(false),                                       _STLP_PRIV _Project2nd<const _CharT*, const _CharT*>(),                                       false, false);      else        _M_gcount = _M_ignore_unbuffered(this,  __buf,                                         __maxss, _Const_streamsize(__maxss),                                         _Const_bool(false), false, false);    }    else {      if (__buf->gptr() != __buf->egptr())        _M_gcount = _M_ignore_buffered(this,  __buf,                                       __n, minus<streamsize>(),                                       _Const_bool(false),                                       _STLP_PRIV _Project2nd<const _CharT*, const _CharT*>(),                                       false, false);      else        _M_gcount = _M_ignore_unbuffered(this,  __buf, __n, minus<streamsize>(),                                         _Const_bool(false), false, false);    }  }  return *this;}template <class _CharT, class _Traits>basic_istream<_CharT, _Traits>&basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __delim) {  sentry __sentry(*this, _No_Skip_WS());  this->_M_gcount = 0;  if (__sentry) {    basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();    typedef _STLP_PRIV _Constant_unary_fun<bool, int_type> _Const_bool;    typedef _STLP_PRIV _Constant_binary_fun<streamsize, streamsize, streamsize>      _Const_streamsize;    const streamsize __maxss = (numeric_limits<streamsize>::max)();    if (__n == (numeric_limits<int>::max)()) {      if (__buf->gptr() != __buf->egptr())        _M_gcount = _M_ignore_buffered(this,  __buf,                                       __maxss, _Const_streamsize(__maxss),                                       _STLP_PRIV _Eq_int_bound<_Traits>(__delim),                                       _STLP_PRIV _Scan_for_int_val<_Traits>(__delim),                                       true, false);      else        _M_gcount = _M_ignore_unbuffered(this,  __buf,                                         __maxss, _Const_streamsize(__maxss),                                         _STLP_PRIV _Eq_int_bound<_Traits>(__delim),                                         true, false);    }    else {      if (__buf->gptr() != __buf->egptr())        _M_gcount = _M_ignore_buffered(this,  __buf,                                       __n, minus<streamsize>(),                                       _STLP_PRIV _Eq_int_bound<_Traits>(__delim),                                       _STLP_PRIV _Scan_for_int_val<_Traits>(__delim),                                       true, false);      else        _M_gcount = _M_ignore_unbuffered(this,  __buf, __n, minus<streamsize>(),                                         _STLP_PRIV _Eq_int_bound<_Traits>(__delim),                                         true, false);    }  }  return *this;}// This member function does not construct a sentry object, because// it is called from sentry's constructor.template <class _CharT, class _Traits>void basic_istream<_CharT, _Traits>::_M_skip_whitespace(bool __set_failbit) {  basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();  if (!__buf)    this->setstate(ios_base::badbit);  else if (__buf->gptr() != __buf->egptr())    _M_ignore_buffered(this,  __buf,                       _STLP_PRIV _Is_not_wspace<_Traits>(this->_M_ctype_facet()),                       _STLP_PRIV _Scan_for_not_wspace<_Traits>(this->_M_ctype_facet()),                       false, __set_failbit);  else    _M_ignore_unbuffered(this,  __buf,                         _STLP_PRIV _Is_not_wspace<_Traits>(this->_M_ctype_facet()),                         false, __set_failbit);}// This is a very simple loop that reads characters from __src and puts// them into __dest.  It looks complicated because of the (standard-// mandated) exception handling policy.//// We stop when we get an exception, when we fail to insert into the// output streambuf, or when __is_delim is true._STLP_MOVE_TO_PRIV_NAMESPACEtemplate < class _CharT, class _Traits, class _Is_Delim>streamsize _STLP_CALL__copy_unbuffered(basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __src,                  basic_streambuf<_CharT, _Traits>* __dest,                  _Is_Delim __is_delim,                  bool __extract_delim, bool __rethrow) {  streamsize __extracted = 0;  ios_base::iostate __status = 0;  typedef typename basic_istream<_CharT, _Traits>::int_type int_type;  int_type __c;  _STLP_TRY {    for (;;) {      // Get a character. If there's an exception, catch and (maybe) rethrow it.      __c = __src->sbumpc();      // If we failed to get a character, then quit.      if (__that->_S_eof(__c)) {        __status |= ios_base::eofbit;        break;      }      // If it's the delimiter, then quit.      else if (__is_delim(_Traits::to_char_type(__c))) {        if (!__extract_delim && !__pushback(__src, _Traits::to_char_type(__c)))          __status |= ios_base::failbit;        break;      }      else {        // Try to put the character in the output streambuf.        bool __failed = false;        _STLP_TRY {          if (!__that->_S_eof(__dest->sputc(_Traits::to_char_type(__c))))            ++__extracted;          else            __failed = true;        }        _STLP_CATCH_ALL {          __failed = true;        }        // If we failed to put the character in the output streambuf, then        // try to push it back to the input streambuf.        if (__failed && !__pushback(__src, _Traits::to_char_type(__c)))          __status |= ios_base::failbit;        // fbp : avoiding infinite loop in io-27-6-1-2-3.exp        if (__failed)          break;      }    } /* for (;;) */  }  // fbp : this try/catch moved here in reasonable assumption  // __is_delim never throw (__pushback is guaranteed not to)  _STLP_CATCH_ALL {    // See 27.6.1.2.3, paragraph 13.    if (__rethrow && __extracted == 0)      __that->_M_handle_exception(ios_base::failbit);  }  __that->setstate(__status);  return __extracted;}// Buffered copying from one streambuf to another.  We copy the characters// in chunks, rather than one at a time.  We still have to worry about all// of the error conditions we checked in __copy_unbuffered, plus one more:// the streambuf might decide to switch from a buffered to an unbuffered mode.template < class _CharT, class _Traits, class _Is_Delim, class _Scan_Delim>streamsize _STLP_CALL__copy_buffered(basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __src,                basic_streambuf<_CharT, _Traits>* __dest,                _Scan_Delim __scan_delim, _Is_Delim __is_delim,                bool __extract_delim, bool __rethrow) {  streamsize __extracted = 0;  ios_base::iostate __status = 0;  typedef typename basic_istream<_CharT, _Traits>::int_type int_type;  //Borland compiler generates a warning if assignment because value is never used:  int_type __c /*= _Traits::eof()*/;  _CharT* __first = __src->_M_gptr();  ptrdiff_t __avail = __src->_M_egptr() - __first;  // fbp : introduced to move catch/try blocks out of the loop  bool __do_handle_exceptions = false;  _STLP_TRY {    for (;;) {      const _CharT* __last = __scan_delim(__first, __src->_M_egptr());      // Try to copy the entire input buffer to the output buffer.      streamsize __n = __dest->sputn(__first, __extract_delim && __last != __src->_M_egptr()                                     ? (__last - __first) + 1                                     : (__last - __first));      __src->_M_gbump((int)__n);      __extracted += __n;      // from this on, catch() will call _M_handle_exceptions()      __do_handle_exceptions = true;      if (__n < __avail)          // We found the delimiter, or else failed to        break;                    // copy some characters.      __c = __src->sgetc();      // Three possibilities: we succeeded in refilling the buffer, or      // we got EOF, or the streambuf has switched to unbuffered mode.      __first = __src->_M_gptr();      __avail = __src->_M_egptr() - __first;      if (__avail > 0)        {}  // dwa 1/16/00 -- suppress a Metrowerks warning      else if (__that->_S_eof(__c)) {        __status |= ios_base::eofbit;        break;      }      else {        return __extracted + __copy_unbuffered(__that,  __src, __dest, __is_delim,                                                __extract_delim, __rethrow);      }      __do_handle_exceptions = false;    }  }  _STLP_CATCH_ALL {    // See 27.6.1.2.3, paragraph 13.    if (__rethrow && __do_handle_exceptions &&  __extracted == 0)      __that->_M_handle_exception(ios_base::failbit);  }  if (__status)    __that->setstate(__status);   // This might throw.  return __extracted;}_STLP_MOVE_TO_STD_NAMESPACEtemplate <class _CharT, class _Traits>basic_istream<_CharT, _Traits>&basic_istream<_CharT, _Traits>  ::get(basic_streambuf<_CharT, _Traits>& __dest, _CharT __delim) {  sentry __sentry(*this, _No_Skip_WS());  this->_M_gcount = 0;  if (__sentry) {    basic_streambuf<_CharT, _Traits>* __src = this->rdbuf();    if (__src)      this->_M_gcount = __src->egptr() != __src->gptr()        ? _STLP_PRIV __copy_buffered(this,  __src, &__dest,                                     _STLP_PRIV _Scan_for_char_val<_Traits>(__delim),                                     _STLP_PRIV _Eq_char_bound<_Traits>(__delim),                                     false, false)        : _STLP_PRIV __copy_unbuffered(this,  __src, &__dest,                                       _STLP_PRIV _Eq_char_bound<_Traits>(__delim),                                       false, false);  }  if (this->_M_gcount == 0)    this->setstate(ios_base::failbit);  return *this;}// Copying characters into a streambuf.template <class _CharT, class _Traits>basic_istream<_CharT, _Traits>&basic_istream<_CharT, _Traits>  ::operator>>(basic_streambuf<_CharT, _Traits>* __dest) {  streamsize __n = 0;  typedef typename basic_istream<_CharT, _Traits>::sentry _Sentry;  _Sentry __sentry(*this);  if (__sentry) {    basic_streambuf<_CharT, _Traits>* __src = this->rdbuf();    if (__src && __dest)      __n = __src->egptr() != __src->gptr()        ? _STLP_PRIV __copy_buffered(this,  __src, __dest,                                     _STLP_PRIV _Project2nd<const _CharT*, const _CharT*>(),                                     _STLP_PRIV _Constant_unary_fun<bool, int_type>(false),                                     false, true)        : _STLP_PRIV __copy_unbuffered(this,  __src, __dest,                                       _STLP_PRIV _Constant_unary_fun<bool, int_type>(false),                                       false, true);  }  if (__n == 0)    this->setstate(ios_base::failbit);  return *this;}// ----------------------------------------------------------------// basic_iostream<> class// ----------------------------------------------------------------template <class _CharT, class _Traits>basic_iostream<_CharT, _Traits>  ::basic_iostream(basic_streambuf<_CharT, _Traits>* __buf)    : basic_ios<_CharT, _Traits>(),      basic_istream<_CharT, _Traits>(__buf),      basic_ostream<_CharT, _Traits>(__buf) {  this->init(__buf);}template <class _CharT, class _Traits>basic_iostream<_CharT, _Traits>::~basic_iostream(){}_STLP_END_NAMESPACE#undef __BIS_int_type__#undef __BIS_pos_type__#undef __BIS_off_type__#endif /* _STLP_ISTREAM_C */// Local Variables:// mode:C++// End:

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?