_istream.c
来自「stl的源码」· C语言 代码 · 共 1,430 行 · 第 1/4 页
C
1,430 行
_STLP_MOVE_TO_STD_NAMESPACEtemplate <class _CharT, class _Traits>basic_istream<_CharT, _Traits>&basic_istream<_CharT, _Traits>::get(_CharT* __s, streamsize __n, _CharT __delim) { sentry __sentry(*this, _No_Skip_WS()); this->_M_gcount = 0; if (__sentry) { if (__n > 0) { basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); if (__buf->egptr() != __buf->gptr()) this->_M_gcount = _STLP_PRIV __read_buffered(this, __buf, __n - 1, __s, _STLP_PRIV _Eq_char_bound<_Traits>(__delim), _STLP_PRIV _Scan_for_char_val<_Traits>(__delim), false, true, false); else this->_M_gcount = _STLP_PRIV __read_unbuffered(this, __buf, __n - 1, __s, _STLP_PRIV _Eq_char_bound<_Traits>(__delim), false, true, false); } } if (this->_M_gcount == 0) this->setstate(ios_base::failbit); return *this;}// Getline is essentially identical to get, except that it extracts// the delimiter.template <class _CharT, class _Traits>basic_istream<_CharT, _Traits>&basic_istream<_CharT, _Traits>::getline(_CharT* __s, streamsize __n, _CharT __delim) { sentry __sentry(*this, _No_Skip_WS()); this->_M_gcount = 0; if (__sentry) { if (__n > 0) { basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); this->_M_gcount = __buf->egptr() != __buf->gptr() ? _STLP_PRIV __read_buffered(this, __buf, __n - 1, __s, _STLP_PRIV _Eq_char_bound<_Traits>(__delim), _STLP_PRIV _Scan_for_char_val<_Traits>(__delim), true, true, true) : _STLP_PRIV __read_unbuffered(this, __buf, __n - 1, __s, _STLP_PRIV _Eq_char_bound<_Traits>(__delim), true, true, true); } } if (this->_M_gcount == 0) this->setstate(ios_base::failbit); return *this;}// Read n characters. We don't look for any delimiter, and we don't// put in a terminating null character.template <class _CharT, class _Traits>basic_istream<_CharT, _Traits>&basic_istream<_CharT, _Traits>::read(char_type* __s, streamsize __n) { sentry __sentry(*this, _No_Skip_WS()); this->_M_gcount = 0; if (__sentry && !this->eof()) { basic_streambuf<_CharT, _Traits>*__buf = this->rdbuf(); if (__buf->gptr() != __buf->egptr()) _M_gcount = _STLP_PRIV __read_buffered(this, __buf, __n, __s, _STLP_PRIV _Constant_unary_fun<bool, int_type>(false), _STLP_PRIV _Project2nd<const _CharT*, const _CharT*>(), false, false, false); else _M_gcount = _STLP_PRIV __read_unbuffered(this, __buf, __n, __s, _STLP_PRIV _Constant_unary_fun<bool, int_type>(false), false, false, false); } else this->setstate(ios_base::failbit); if (this->eof()) this->setstate(ios_base::eofbit | ios_base::failbit); return *this;}// Read n or fewer characters. We don't look for any delimiter, and// we don't put in a terminating null character.template <class _CharT, class _Traits>streamsizebasic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __nmax) { sentry __sentry(*this, _No_Skip_WS()); this->_M_gcount = 0; if (__sentry && !this->eof() && __nmax >= 0) { basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); streamsize __avail = __buf->in_avail(); // fbp : isn't full-blown setstate required here ? if (__avail == -1) this->_M_setstate_nothrow(ios_base::eofbit); else if (__avail != 0) { if (__buf->gptr() != __buf->egptr()) _M_gcount = _STLP_PRIV __read_buffered(this, __buf, (min) (__avail, __nmax), __s, _STLP_PRIV _Constant_unary_fun<bool, int_type>(false), _STLP_PRIV _Project2nd<const _CharT*, const _CharT*>(), false, false, false); else _M_gcount = _STLP_PRIV __read_unbuffered(this, __buf, (min) (__avail, __nmax), __s, _STLP_PRIV _Constant_unary_fun<bool, int_type>(false), false, false, false); } } else { // fbp : changed so that failbit is set only there, to pass Dietmar's test if (this->eof()) this->setstate(ios_base::eofbit | ios_base::failbit); else this->setstate(ios_base::failbit); } // if (this->eof()) // this->setstate(ios_base::eofbit | ios_base::failbit); return _M_gcount;}template <class _CharT, class _Traits>void basic_istream<_CharT, _Traits>::_M_formatted_get(_CharT* __s) { sentry __sentry(*this); // Skip whitespace. if (__sentry) { basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); streamsize __nmax = this->width() > 0 ? this->width() - 1 : ((numeric_limits<streamsize>::max)() / sizeof(_CharT)) - 1; streamsize __n = __buf->gptr() != __buf->egptr() ? _STLP_PRIV __read_buffered(this, __buf, __nmax, __s, _STLP_PRIV _Is_wspace_null<_Traits>(this->_M_ctype_facet()), _STLP_PRIV _Scan_wspace_null<_Traits>(this->_M_ctype_facet()), false, true, false) : _STLP_PRIV __read_unbuffered(this, __buf, __nmax, __s, _STLP_PRIV _Is_wspace_null<_Traits>(this->_M_ctype_facet()), false, true, false); if (__n == 0) this->setstate(ios_base::failbit); } this->width(0);}// A generic unbuffered function for ignoring characters. We stop// when we reach EOF, or when the function object __is_delim returns// true. In the last case, it extracts the character for which// __is_delim is true, if and only if __extract_delim is true.template < class _CharT, class _Traits, class _Is_Delim>void _STLP_CALL_M_ignore_unbuffered(basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __buf, _Is_Delim __is_delim, bool __extract_delim, bool __set_failbit) { bool __done = false; ios_base::iostate __status = 0; typedef typename basic_istream<_CharT, _Traits>::int_type int_type; _STLP_TRY { while (!__done) { int_type __c = __buf->sbumpc(); if (__that->_S_eof(__c)) { __done = true; __status |= __set_failbit ? ios_base::eofbit | ios_base::failbit : ios_base::eofbit; } else if (__is_delim(_Traits::to_char_type(__c))) { __done = true; if (!__extract_delim) if (__that->_S_eof(__buf->sputbackc(_Traits::to_char_type(__c)))) __status |= ios_base::failbit; } } } _STLP_CATCH_ALL { __that->_M_handle_exception(ios_base::badbit); } __that->setstate(__status);}// A generic buffered function for ignoring characters. Much like// _M_ignore_unbuffered, but with one additional function object:// __scan_delim(first, last) returns the first pointer p in [first,// last) such that __is_delim(p) is true.template < class _CharT, class _Traits, class _Is_Delim, class _Scan_Delim>void _STLP_CALL_M_ignore_buffered(basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __buf, _Is_Delim __is_delim, _Scan_Delim __scan_delim, bool __extract_delim, bool __set_failbit) { bool __at_eof = false; bool __found_delim = false; _STLP_TRY { while (__buf->_M_egptr() != __buf->_M_gptr() && !__at_eof && !__found_delim) { const _CharT* __p = __scan_delim(__buf->_M_gptr(), __buf->_M_egptr()); __buf->_M_gbump((int)(__p - __buf->_M_gptr())); if (__p != __buf->_M_egptr()) { // We found delim, so we're done. if (__extract_delim) __buf->_M_gbump(1); __found_delim = true; } else // No delim. Try to refil the buffer. __at_eof = __that->_S_eof(__buf->sgetc()); } // Close the while loop. } _STLP_CATCH_ALL { __that->_M_handle_exception(ios_base::badbit); return; } if (__at_eof) { __that->setstate(__set_failbit ? ios_base::eofbit | ios_base::failbit : ios_base::eofbit); return; } if (__found_delim) return; // 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 a buffered to an unbuffered mode. We switch // to _M_ignore_unbuffered. _M_ignore_unbuffered(__that, __buf, __is_delim, __extract_delim, __set_failbit);}// Overloaded versions of _M_ignore_unbuffered and _M_ignore_unbuffered// with an explicit count _Num. Return value is the number of// characters extracted.//// The function object __max_chars takes two arguments, _Num and __n// (the latter being the number of characters we have already read),// and returns the maximum number of characters to read from the buffer.// We parameterize _M_ignore_buffered so that we can use it for both// bounded and unbounded input; for the former the function object should// be minus<>, and for the latter it should return a constant maximum value.template < class _CharT, class _Traits, class _Max_Chars, class _Is_Delim>streamsize _STLP_CALL_M_ignore_unbuffered(basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __buf, streamsize _Num, _Max_Chars __max_chars, _Is_Delim __is_delim, bool __extract_delim, bool __set_failbit) { streamsize __n = 0; ios_base::iostate __status = 0; typedef typename basic_istream<_CharT, _Traits>::int_type int_type; _STLP_TRY { while (__max_chars(_Num, __n) > 0) { int_type __c = __buf->sbumpc(); if (__that->_S_eof(__c)) { __status |= __set_failbit ? ios_base::eofbit | ios_base::failbit : ios_base::eofbit; break; } else if (__is_delim(_Traits::to_char_type(__c))) { if (__extract_delim) ++__n; else if (__that->_S_eof(__buf->sputbackc(_Traits::to_char_type(__c)))) __status |= ios_base::failbit; break; } // fbp : added counter increment to pass Dietmar's test ++__n; } } _STLP_CATCH_ALL { __that->_M_handle_exception(ios_base::badbit); } if (__status) __that->setstate(__status); // This might throw. return __n;}template < class _CharT, class _Traits, class _Max_Chars, class _Is_Delim, class _Scan_Delim>streamsize _STLP_CALL_M_ignore_buffered(basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __buf, streamsize _Num, _Max_Chars __max_chars, _Is_Delim __is_delim, _Scan_Delim __scan_delim, bool __extract_delim, bool __set_failbit) { streamsize __n = 0; bool __at_eof = false; bool __done = false; _STLP_TRY { while (__buf->_M_egptr() != __buf->_M_gptr() && !__done) { ptrdiff_t __avail = __buf->_M_egptr() - __buf->_M_gptr(); streamsize __m = __max_chars(_Num, __n); if (__avail >= __m) { // We have more characters than we need. const _CharT* __last = __buf->_M_gptr() + __STATIC_CAST(ptrdiff_t, __m); const _CharT* __p = __scan_delim(__buf->_M_gptr(), __last); ptrdiff_t __chunk = __p - __buf->_M_gptr(); __n += __chunk; __buf->_M_gbump((int)__chunk); if (__extract_delim && __p != __last) { __n += 1; __buf->_M_gbump(1); } __done = true; } else { const _CharT* __p = __scan_delim(__buf->_M_gptr(), __buf->_M_egptr()); ptrdiff_t __chunk = __p - __buf->_M_gptr(); __n += __chunk; __buf->_M_gbump((int)__chunk); if (__p != __buf->_M_egptr()) { // We found delim. if (__extract_delim) { __n += 1; __buf->_M_gbump(1); } __done = true; } // We didn't find delim. Try to refill the buffer. else if (__that->_S_eof(__buf->sgetc())) { __done = true; __at_eof = true; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?