williamr@2: /* williamr@2: * © Portions copyright (c) 2006-2007 Nokia Corporation. All rights reserved. williamr@2: * Copyright (c) 1999 williamr@2: * Silicon Graphics Computer Systems, Inc. williamr@2: * williamr@2: * Copyright (c) 1999 williamr@2: * Boris Fomitchev williamr@2: * williamr@2: * This material is provided "as is", with absolutely no warranty expressed williamr@2: * or implied. Any use is at your own risk. williamr@2: * williamr@2: * Permission to use or copy this software for any purpose is hereby granted williamr@2: * without fee, provided the above notices are retained on all copies. williamr@2: * Permission to modify the code and to distribute modified code is granted, williamr@2: * provided the above notices are retained, and a notice that the code was williamr@2: * modified is included with the above copyright notice. williamr@2: * williamr@2: */ williamr@2: #ifndef _STLP_ISTREAM_C williamr@2: #define _STLP_ISTREAM_C williamr@2: williamr@2: #ifndef _STLP_INTERNAL_ISTREAM_H williamr@2: # include williamr@2: #endif williamr@2: williamr@2: # if defined (_STLP_EXPOSE_STREAM_IMPLEMENTATION) williamr@2: williamr@2: #ifndef _STLP_LIMITS_H williamr@2: # include williamr@2: #endif williamr@2: williamr@2: #ifndef _STLP_INTERNAL_NUM_GET_H williamr@2: # include williamr@2: #endif williamr@2: williamr@2: # if defined ( _STLP_NESTED_TYPE_PARAM_BUG ) williamr@2: // no wchar_t is supported for this mode williamr@2: # define __BIS_int_type__ int williamr@2: # define __BIS_pos_type__ streampos williamr@2: # define __BIS_off_type__ streamoff williamr@2: # else williamr@2: # define __BIS_int_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_istream<_CharT, _Traits>::int_type williamr@2: # define __BIS_pos_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_istream<_CharT, _Traits>::pos_type williamr@2: # define __BIS_off_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_istream<_CharT, _Traits>::off_type williamr@2: # endif williamr@2: williamr@2: _STLP_BEGIN_NAMESPACE williamr@2: williamr@2: //---------------------------------------------------------------------- williamr@2: // Function object structs used by some member functions. williamr@2: williamr@2: template williamr@2: struct _Is_not_wspace { williamr@2: typedef typename _Traits::char_type argument_type; williamr@2: typedef bool result_type; williamr@2: williamr@2: const ctype* _M_ctype; williamr@2: williamr@2: _Is_not_wspace(const ctype* __c_type) : _M_ctype(__c_type) {} williamr@2: bool operator()(argument_type __c) const williamr@2: { return !_M_ctype->is(ctype_base::space, __c); } williamr@2: }; williamr@2: williamr@2: template williamr@2: struct _Is_wspace_null { williamr@2: typedef typename _Traits::char_type argument_type; williamr@2: typedef bool result_type; williamr@2: williamr@2: const ctype* _M_ctype; williamr@2: williamr@2: _Is_wspace_null(const ctype* __c_type) : _M_ctype(__c_type) {} williamr@2: bool operator()(argument_type __c) const { williamr@2: return _Traits::eq(__c, argument_type()) || williamr@2: _M_ctype->is(ctype_base::space, __c); williamr@2: } williamr@2: }; williamr@2: williamr@2: template williamr@2: struct _Scan_for_wspace { williamr@2: typedef typename _Traits::char_type char_type; williamr@2: typedef char_type* first_argument_type; williamr@2: typedef char_type* second_argument_type; williamr@2: typedef char_type* result_type; williamr@2: williamr@2: const ctype* _M_ctype; williamr@2: williamr@2: _Scan_for_wspace(const ctype* __ctype) : _M_ctype(__ctype) {} williamr@2: const char_type* williamr@2: operator()(const char_type* __first, const char_type* __last) const { williamr@2: return _M_ctype->scan_is(ctype_base::space, __first, __last); williamr@2: } williamr@2: }; williamr@2: williamr@2: template williamr@2: struct _Scan_wspace_null { williamr@2: typedef typename _Traits::char_type char_type; williamr@2: typedef char_type* first_argument_type; williamr@2: typedef char_type* second_argument_type; williamr@2: typedef char_type* result_type; williamr@2: williamr@2: const ctype* _M_ctype; williamr@2: williamr@2: _Scan_wspace_null(const ctype* __c_type) : _M_ctype(__c_type) {} williamr@2: const char_type* williamr@2: operator()(const char_type* __first, const char_type* __last) const { williamr@2: __last = find_if(__first, __last, williamr@2: _Eq_char_bound<_Traits>(char_type())); williamr@2: return _M_ctype->scan_is(ctype_base::space, __first, __last); williamr@2: } williamr@2: }; williamr@2: williamr@2: template williamr@2: struct _Scan_for_not_wspace { williamr@2: typedef typename _Traits::char_type char_type; williamr@2: typedef char_type* first_argument_type; williamr@2: typedef char_type* second_argument_type; williamr@2: typedef char_type* result_type; williamr@2: williamr@2: const ctype* _M_ctype; williamr@2: williamr@2: _Scan_for_not_wspace(const ctype* __c_type) : _M_ctype(__c_type) {} williamr@2: const char_type* williamr@2: operator()(const char_type* __first, const char_type* __last) const { williamr@2: return _M_ctype->scan_not(ctype_base::space, __first, __last); williamr@2: } williamr@2: }; williamr@2: williamr@2: template williamr@2: struct _Scan_for_char_val williamr@2: { williamr@2: typedef typename _Traits::char_type char_type; williamr@2: typedef char_type* first_argument_type; williamr@2: typedef char_type* second_argument_type; williamr@2: typedef char_type* result_type; williamr@2: williamr@2: char_type _M_val; williamr@2: williamr@2: _Scan_for_char_val(char_type __val) : _M_val(__val) {} williamr@2: williamr@2: const char_type* williamr@2: operator()(const char_type* __first, const char_type* __last) const { williamr@2: return find_if(__first, __last, _Eq_char_bound<_Traits>(_M_val)); williamr@2: } williamr@2: }; williamr@2: williamr@2: template williamr@2: struct _Scan_for_int_val williamr@2: { williamr@2: typedef typename _Traits::char_type char_type; williamr@2: typedef typename _Traits::int_type int_type; williamr@2: typedef char_type* first_argument_type; williamr@2: typedef char_type* second_argument_type; williamr@2: typedef char_type* result_type; williamr@2: williamr@2: int_type _M_val; williamr@2: williamr@2: _Scan_for_int_val(int_type __val) : _M_val(__val) {} williamr@2: williamr@2: const char_type* williamr@2: operator()(const char_type* __first, const char_type* __last) const { williamr@2: return find_if(__first, __last, williamr@2: _Eq_int_bound<_Traits>(_M_val)); williamr@2: } williamr@2: }; williamr@2: williamr@2: // Helper function: try to push back a character to a streambuf, williamr@2: // return true if the pushback succeeded. Does not throw. williamr@2: williamr@2: template williamr@2: bool _STLP_CALL williamr@2: __pushback(basic_streambuf<_CharT, _Traits>* __buf, _CharT __c) williamr@2: { williamr@2: bool ret; williamr@2: _STLP_TRY { williamr@2: const typename _Traits::int_type __eof = _Traits::eof(); williamr@2: ret = !_Traits::eq_int_type(__buf->sputbackc(__c), __eof); williamr@2: } williamr@2: _STLP_CATCH_ALL { williamr@2: ret = false; williamr@2: } williamr@2: return ret; williamr@2: } williamr@2: williamr@2: template williamr@2: basic_istream<_CharT, _Traits>& _STLP_CALL williamr@2: ws(basic_istream<_CharT, _Traits>& __is) williamr@2: { williamr@2: typedef typename basic_istream<_CharT, _Traits>::sentry _Sentry; williamr@2: _Sentry __sentry(__is, _No_Skip_WS()); // Don't skip whitespace. williamr@2: if (__sentry) williamr@2: __is._M_skip_whitespace(false); williamr@2: return __is; williamr@2: } williamr@2: williamr@2: // Helper functions for istream<>::sentry constructor. williamr@2: template williamr@2: bool williamr@2: _M_init_skip(basic_istream<_CharT, _Traits>& __is) { williamr@2: if (__is.good()) { williamr@2: if (__is.tie()) williamr@2: __is.tie()->flush(); williamr@2: williamr@2: __is._M_skip_whitespace(true); williamr@2: } williamr@2: williamr@2: if (!__is.good()) { williamr@2: __is.setstate(ios_base::failbit); williamr@2: return false; williamr@2: } else williamr@2: return true; williamr@2: } williamr@2: williamr@2: template williamr@2: bool williamr@2: _M_init_noskip(basic_istream<_CharT, _Traits>& __is){ williamr@2: if (__is.good()) { williamr@2: if (__is.tie()) williamr@2: __is.tie()->flush(); williamr@2: williamr@2: if (!__is.rdbuf()) williamr@2: __is.setstate(ios_base::badbit); williamr@2: } williamr@2: else williamr@2: __is.setstate(ios_base::failbit); williamr@2: return __is.good(); williamr@2: } williamr@2: williamr@2: //---------------------------------------------------------------------- williamr@2: // Definitions of basic_istream<>'s noninline member functions. williamr@2: williamr@2: // Helper function for formatted input of numbers. williamr@2: template williamr@2: ios_base::iostate _STLP_CALL williamr@2: _M_get_num(basic_istream<_CharT, _Traits>& __that, _Number& __val) williamr@2: { williamr@2: typedef typename basic_istream<_CharT, _Traits>::sentry _Sentry; williamr@2: ios_base::iostate __err = 0; williamr@2: _Sentry __sentry( __that ); // Skip whitespace. williamr@2: if (__sentry) { williamr@2: typedef num_get<_CharT, istreambuf_iterator<_CharT, _Traits> > _Num_get; williamr@2: _STLP_TRY { williamr@2: ((const _Num_get&)use_facet<_Num_get>(__that.getloc())).get(istreambuf_iterator<_CharT, _Traits>(__that.rdbuf()), williamr@2: 0, __that, __err, __val); williamr@2: } williamr@2: _STLP_CATCH_ALL { williamr@2: __that._M_handle_exception(ios_base::badbit); williamr@2: } williamr@2: if (__err) __that.setstate(__err); williamr@2: } williamr@2: return __err; williamr@2: } williamr@2: williamr@2: williamr@2: // Unformatted input williamr@2: williamr@2: template williamr@2: __BIS_int_type__ williamr@2: basic_istream<_CharT, _Traits>::peek() williamr@2: { williamr@2: typename _Traits::int_type __tmp = _Traits::eof(); williamr@2: williamr@2: this->_M_gcount = 0; williamr@2: sentry __sentry(*this, _No_Skip_WS()); williamr@2: williamr@2: if (__sentry) { williamr@2: _STLP_TRY { williamr@2: __tmp = this->rdbuf()->sgetc(); williamr@2: } williamr@2: _STLP_CATCH_ALL { williamr@2: this->_M_handle_exception(ios_base::badbit); williamr@2: } williamr@2: } williamr@2: else williamr@2: { williamr@2: if (this->_S_eof(__tmp)) williamr@2: { williamr@2: this->clear(); williamr@2: this->setstate(ios_base::eofbit); williamr@2: } williamr@2: } williamr@2: return __tmp; williamr@2: } williamr@2: williamr@2: williamr@2: template williamr@2: __BIS_int_type__ williamr@2: basic_istream<_CharT, _Traits>::get() williamr@2: { williamr@2: typename _Traits::int_type __tmp = _Traits::eof(); williamr@2: sentry __sentry(*this, _No_Skip_WS()); williamr@2: this->_M_gcount = 0; williamr@2: williamr@2: if (__sentry) { williamr@2: _STLP_TRY { williamr@2: __tmp = this->rdbuf()->sbumpc(); williamr@2: } williamr@2: _STLP_CATCH_ALL { williamr@2: this->_M_handle_exception(ios_base::badbit); williamr@2: } williamr@2: williamr@2: if (!this->_S_eof(__tmp)) williamr@2: this->_M_gcount = 1; williamr@2: } williamr@2: williamr@2: if (_M_gcount == 0) williamr@2: this->setstate(ios_base::eofbit | ios_base::failbit); williamr@2: williamr@2: return __tmp; williamr@2: } williamr@2: williamr@2: template williamr@2: basic_istream<_CharT, _Traits>& williamr@2: basic_istream<_CharT, _Traits>::get(_CharT& __c) williamr@2: { williamr@2: sentry __sentry(*this, _No_Skip_WS()); williamr@2: this->_M_gcount = 0; williamr@2: williamr@2: if (__sentry) { williamr@2: typename _Traits::int_type __tmp = _Traits::eof(); williamr@2: _STLP_TRY { williamr@2: __tmp = this->rdbuf()->sbumpc(); williamr@2: } williamr@2: _STLP_CATCH_ALL { williamr@2: this->_M_handle_exception(ios_base::badbit); williamr@2: } williamr@2: williamr@2: if (!this->_S_eof(__tmp)) { williamr@2: this->_M_gcount = 1; williamr@2: __c = _Traits::to_char_type(__tmp); williamr@2: } williamr@2: } williamr@2: williamr@2: if (this->_M_gcount == 0) williamr@2: this->setstate(ios_base::eofbit | ios_base::failbit); williamr@2: williamr@2: return *this; williamr@2: } williamr@2: williamr@2: williamr@2: williamr@2: // Read characters and discard them. The standard specifies a single williamr@2: // function with two arguments, each with a default. We instead use williamr@2: // three overloded functions, because it's possible to implement the williamr@2: // first two more efficiently than the fully general third version. williamr@2: template williamr@2: basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::ignore() williamr@2: { williamr@2: sentry __sentry(*this, _No_Skip_WS()); williamr@2: this->_M_gcount = 0; williamr@2: williamr@2: if (__sentry) { williamr@2: int_type __c; williamr@2: _STLP_TRY { williamr@2: __c = this->rdbuf()->sbumpc(); williamr@2: } williamr@2: _STLP_CATCH_ALL { williamr@2: this->_M_handle_exception(ios_base::badbit); williamr@2: return *this; williamr@2: } williamr@2: williamr@2: if (!this->_S_eof(__c)) williamr@2: this->_M_gcount = 1; williamr@2: else williamr@2: this->setstate(ios_base::eofbit); williamr@2: } williamr@2: williamr@2: return *this; williamr@2: } williamr@2: williamr@2: // Putback williamr@2: williamr@2: template williamr@2: basic_istream<_CharT, _Traits>& williamr@2: basic_istream<_CharT, _Traits>::putback(_CharT __c) { williamr@2: this->_M_gcount = 0; williamr@2: sentry __sentry(*this, _No_Skip_WS()); williamr@2: williamr@2: if (__sentry) { williamr@2: typename _Traits::int_type __tmp = _Traits::eof(); williamr@2: basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); williamr@2: // if (!__buf || this->_S_eof(__buf->sputbackc(__c))) williamr@2: if (__buf) { williamr@2: _STLP_TRY { williamr@2: __tmp = __buf->sputbackc(__c); williamr@2: } williamr@2: _STLP_CATCH_ALL { williamr@2: this->_M_handle_exception(ios_base::badbit); williamr@2: } williamr@2: } williamr@2: if (this->_S_eof(__tmp)) williamr@2: this->setstate(ios_base::badbit); williamr@2: } williamr@2: else williamr@2: this->setstate(ios_base::failbit); williamr@2: williamr@2: return *this; williamr@2: } williamr@2: williamr@2: template williamr@2: basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::unget() { williamr@2: this->_M_gcount = 0; williamr@2: williamr@2: sentry __sentry(*this, _No_Skip_WS()); williamr@2: williamr@2: if (__sentry) { williamr@2: basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); williamr@2: // if (!__buf || _Traits::eq_int_type(__buf->sungetc(), _Traits::eof())) williamr@2: if (__buf) { williamr@2: _STLP_TRY { williamr@2: _CharT __tmp; williamr@2: __tmp = __buf->sungetc(); williamr@2: #ifdef __SYMBIAN32__ williamr@2: if (__tmp == (_CharT)-1) //chek for eof williamr@2: #else williamr@2: if (this->_S_eof(__tmp)) williamr@2: #endif williamr@2: this->setstate(ios_base::badbit); williamr@2: } williamr@2: _STLP_CATCH_ALL { williamr@2: this->_M_handle_exception(ios_base::badbit); williamr@2: } williamr@2: } else williamr@2: this->setstate(ios_base::badbit); williamr@2: } williamr@2: else williamr@2: this->setstate(ios_base::failbit); williamr@2: williamr@2: return *this; williamr@2: } williamr@2: williamr@2: // Positioning and buffer control. williamr@2: williamr@2: template williamr@2: int basic_istream<_CharT, _Traits>::sync() { williamr@2: sentry __sentry(*this, _No_Skip_WS()); williamr@2: williamr@2: basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); williamr@2: if (__buf) { williamr@2: if (__buf->pubsync() == -1) { williamr@2: this->setstate(ios_base::badbit); williamr@2: return -1; williamr@2: } williamr@2: else williamr@2: return 0; williamr@2: } williamr@2: else williamr@2: return -1; williamr@2: } williamr@2: williamr@2: template williamr@2: __BIS_pos_type__ williamr@2: basic_istream<_CharT, _Traits>::tellg() { williamr@2: #ifndef __SYMBIAN32__ williamr@2: sentry __sentry(*this, _No_Skip_WS()); williamr@2: #endif williamr@2: basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); williamr@2: return (__buf && !this->fail()) ? __buf->pubseekoff(0, ios_base::cur, ios_base::in) williamr@2: : pos_type(-1); williamr@2: } williamr@2: williamr@2: template williamr@2: basic_istream<_CharT, _Traits>& williamr@2: basic_istream<_CharT, _Traits>::seekg(pos_type __pos) { williamr@2: #ifndef __SYMBIAN32__ williamr@2: sentry __sentry(*this, _No_Skip_WS()); williamr@2: #endif williamr@2: basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); williamr@2: if (!this->fail() && __buf) williamr@2: { williamr@2: pos_type pos = __buf->pubseekpos(__pos, ios_base::in); williamr@2: if(pos == pos_type(off_type(-1))) williamr@2: this->setstate(ios_base::failbit); williamr@2: } williamr@2: return *this; williamr@2: } williamr@2: williamr@2: template williamr@2: basic_istream<_CharT, _Traits>& williamr@2: basic_istream<_CharT, _Traits>::seekg(off_type __off, ios_base::seekdir __dir) williamr@2: { williamr@2: #ifndef __SYMBIAN32__ williamr@2: sentry __sentry(*this, _No_Skip_WS()); williamr@2: #endif williamr@2: basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); williamr@2: if (!this->fail() && __buf) williamr@2: { williamr@2: williamr@2: pos_type pos = __buf->pubseekoff(__off, __dir, ios_base::in); williamr@2: if(pos == pos_type(off_type(-1))) williamr@2: this->setstate(ios_base::failbit); williamr@2: } williamr@2: return *this; williamr@2: } williamr@2: williamr@2: // Formatted input of characters and character arrays. williamr@2: williamr@2: template williamr@2: void basic_istream<_CharT, _Traits>::_M_formatted_get(_CharT& __c) williamr@2: { williamr@2: // typename _Traits::int_type __tmp = _Traits::eof(); williamr@2: williamr@2: sentry __sentry(*this); // Skip whitespace. williamr@2: williamr@2: if (__sentry) { williamr@2: typename _Traits::int_type __tmp = _Traits::eof(); williamr@2: williamr@2: _STLP_TRY { williamr@2: __tmp = this->rdbuf()->sbumpc(); williamr@2: } williamr@2: _STLP_CATCH_ALL { williamr@2: this->_M_handle_exception(ios_base::badbit); williamr@2: return; williamr@2: } williamr@2: williamr@2: if (!this->_S_eof(__tmp)) williamr@2: __c = _Traits::to_char_type(__tmp); williamr@2: else williamr@2: this->setstate(ios_base::eofbit | ios_base::failbit); williamr@2: } williamr@2: } williamr@2: williamr@2: williamr@2: //--------------------------------------------------------------------------- williamr@2: // istream's helper functions. williamr@2: williamr@2: // A generic function for unbuffered input. We stop when we reach EOF, williamr@2: // or when we have extracted _Num characters, or when the function object williamr@2: // __is_delim return true. In the last case, it extracts the character williamr@2: // for which __is_delim is true, if and only if __extract_delim is true. williamr@2: // It appends a null character to the end of the string; this means that williamr@2: // it may store up to _Num + 1 characters. williamr@2: // williamr@2: // __is_getline governs two corner cases: reading _Num characters without williamr@2: // encountering delim or eof (in which case failbit is set if __is_getline williamr@2: // is true); and reading _Num characters where the _Num+1'st character is williamr@2: // eof (in which case eofbit is set if __is_getline is true). williamr@2: // williamr@2: // It is assumed that __is_delim never throws. williamr@2: // williamr@2: // Return value is the number of characters extracted, including the williamr@2: // delimiter if it is extracted. Note that the number of characaters williamr@2: // extracted isn't necessarily the same as the number stored. williamr@2: williamr@2: template < class _CharT, class _Traits, class _Is_Delim> williamr@2: streamsize _STLP_CALL williamr@2: _M_read_unbuffered(basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __buf, williamr@2: streamsize _Num, _CharT* __s, williamr@2: _Is_Delim __is_delim, williamr@2: bool __extract_delim, bool __append_null, williamr@2: bool __is_getline) williamr@2: { williamr@2: streamsize __n = 0; williamr@2: ios_base::iostate __status = 0; williamr@2: williamr@2: typedef typename basic_istream<_CharT, _Traits>::int_type int_type; williamr@2: // The operations that can potentially throw are sbumpc, snextc, and sgetc. williamr@2: _STLP_TRY { williamr@2: # if 0 williamr@2: int_type __c = __buf->sgetc(); williamr@2: while (true) { williamr@2: if (__that->_S_eof(__c)) { williamr@2: if (__n < _Num || __is_getline) williamr@2: __status |= ios_base::eofbit; williamr@2: break; williamr@2: } williamr@2: williamr@2: else if (__is_delim(__c)) { williamr@2: if (__extract_delim) { // Extract and discard current character. williamr@2: __buf->sbumpc(); williamr@2: ++__n; williamr@2: } williamr@2: break; williamr@2: } williamr@2: williamr@2: else if (__n == _Num) { williamr@2: if (__is_getline) williamr@2: __status |= ios_base::failbit; williamr@2: break; williamr@2: } williamr@2: williamr@2: *__s++ = _Traits::to_char_type(__c); williamr@2: ++__n; williamr@2: __c = __buf->snextc(); williamr@2: } williamr@2: # else williamr@2: // int_type __c = __buf->sbumpc(); // __buf->sgetc(); williamr@2: while (true) { williamr@2: williamr@2: int_type __c = __buf->sbumpc(); // sschwarz williamr@2: williamr@2: if (__that->_S_eof(__c)) { williamr@2: if (__n < _Num || __is_getline) williamr@2: __status |= ios_base::eofbit; williamr@2: break; williamr@2: } williamr@2: williamr@2: else if (__is_delim(__c)) { williamr@2: if (__extract_delim) { // Extract and discard current character. williamr@2: // __buf->sbumpc(); williamr@2: ++__n; williamr@2: } williamr@2: break; williamr@2: } williamr@2: williamr@2: else { // regular character williamr@2: williamr@2: *__s++ = _Traits::to_char_type(__c); williamr@2: ++__n; williamr@2: williamr@2: } williamr@2: williamr@2: if (__n == _Num) { williamr@2: if (__is_getline) // didn't find delimiter as one of the _Num chars williamr@2: __status |= ios_base::failbit; williamr@2: break; williamr@2: } williamr@2: williamr@2: // *__s++ = _Traits::to_char_type(__c); williamr@2: // ++__n; williamr@2: williamr@2: } williamr@2: williamr@2: # endif williamr@2: williamr@2: } williamr@2: _STLP_CATCH_ALL { williamr@2: __that->_M_handle_exception(ios_base::badbit); williamr@2: *__s = _STLP_DEFAULT_CONSTRUCTED(_CharT); williamr@2: return __n; williamr@2: } williamr@2: williamr@2: if (__append_null) williamr@2: *__s = _STLP_DEFAULT_CONSTRUCTED(_CharT); williamr@2: if (__status) williamr@2: __that->setstate(__status); // This might throw. williamr@2: return __n; williamr@2: } williamr@2: williamr@2: // Much like _M_read_unbuffered, but with one additional function object: williamr@2: // __scan_delim(first, last) returns the first pointer p in [first, last) williamr@2: // such that __is_delim(p) is true. williamr@2: williamr@2: template < class _CharT, class _Traits, class _Is_Delim, class _Scan_Delim> williamr@2: streamsize _STLP_CALL williamr@2: _M_read_buffered(basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __buf, williamr@2: streamsize _Num, _CharT* __s, williamr@2: _Is_Delim __is_delim, _Scan_Delim __scan_delim, williamr@2: bool __extract_delim, bool __append_null, williamr@2: bool __is_getline) williamr@2: { williamr@2: streamsize __n = 0; williamr@2: ios_base::iostate __status = 0; williamr@2: bool __done = false; williamr@2: williamr@2: _STLP_TRY { williamr@2: while (__buf->_M_egptr() != __buf->_M_gptr() && !__done) { williamr@2: const _CharT* __first = __buf->_M_gptr(); williamr@2: const _CharT* __last = __buf->_M_egptr(); williamr@2: ptrdiff_t __request = _Num - __n; williamr@2: williamr@2: const _CharT* __p = __scan_delim(__first, __last); williamr@2: ptrdiff_t __chunk = (min) (ptrdiff_t(__p - __first), __request); williamr@2: _Traits::copy(__s, __first, __chunk); williamr@2: __s += __chunk; williamr@2: __n += __chunk; williamr@2: __buf->_M_gbump((int)__chunk); williamr@2: williamr@2: // We terminated by finding delim. williamr@2: if (__p != __last && __p - __first <= __request) { williamr@2: if (__extract_delim) { williamr@2: __n += 1; williamr@2: __buf->_M_gbump(1); williamr@2: } williamr@2: __done = true; williamr@2: } williamr@2: williamr@2: // We terminated by reading all the characters we were asked for. williamr@2: else if(__n == _Num) { williamr@2: williamr@2: // Find out if we have reached eof. This matters for getline. williamr@2: if (__is_getline) { williamr@2: if (__chunk == __last - __first) { williamr@2: if (__that->_S_eof(__buf->sgetc())) williamr@2: __status |= ios_base::eofbit; williamr@2: } williamr@2: else williamr@2: __status |= ios_base::failbit; williamr@2: } williamr@2: __done = true; williamr@2: } williamr@2: williamr@2: // The buffer contained fewer than _Num - __n characters. Either we're williamr@2: // at eof, or we should refill the buffer and try again. williamr@2: else { williamr@2: if (__that->_S_eof(__buf->sgetc())) { williamr@2: __status |= ios_base::eofbit; williamr@2: __done = true; williamr@2: } williamr@2: } williamr@2: } // Close the while loop. williamr@2: } williamr@2: _STLP_CATCH_ALL { williamr@2: __that->_M_handle_exception(ios_base::badbit); williamr@2: __done = true; williamr@2: } williamr@2: williamr@2: if (__done) { williamr@2: if (__append_null) williamr@2: *__s = _STLP_DEFAULT_CONSTRUCTED(_CharT); williamr@2: if (__status != 0) williamr@2: __that->setstate(__status); // This might throw. williamr@2: return __n; williamr@2: } williamr@2: williamr@2: // If execution has reached this point, then we have an empty buffer but williamr@2: // we have not reached eof. What that means is that the streambuf has williamr@2: // decided to switch from buffered to unbuffered input. We switch to williamr@2: // to _M_read_unbuffered. williamr@2: williamr@2: return __n + _M_read_unbuffered(__that, __buf, _Num - __n, __s, __is_delim, williamr@2: __extract_delim,__append_null,__is_getline); williamr@2: } williamr@2: williamr@2: williamr@2: williamr@2: williamr@2: template williamr@2: basic_istream<_CharT, _Traits>& williamr@2: basic_istream<_CharT, _Traits>::get(_CharT* __s, streamsize __n, williamr@2: _CharT __delim) { williamr@2: sentry __sentry(*this, _No_Skip_WS()); williamr@2: this->_M_gcount = 0; williamr@2: williamr@2: if (__sentry) { williamr@2: if (__n > 0) { williamr@2: basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); williamr@2: williamr@2: if (__buf->egptr() != __buf->gptr()) williamr@2: this->_M_gcount = williamr@2: _M_read_buffered(this, __buf, __n - 1, __s, williamr@2: _Eq_char_bound<_Traits>(__delim), williamr@2: _Scan_for_char_val<_Traits>(__delim), williamr@2: false, true, false); williamr@2: else williamr@2: this->_M_gcount = williamr@2: _M_read_unbuffered(this, __buf, __n - 1, __s, williamr@2: _Eq_char_bound<_Traits>(__delim), williamr@2: false, true, false); williamr@2: } williamr@2: } williamr@2: #ifdef __SYMBIAN32__ williamr@2: *(__s + this->_M_gcount) = _STLP_DEFAULT_CONSTRUCTED(_CharT); williamr@2: #endif //__SYMBIAN32__ williamr@2: if (this->_M_gcount == 0) williamr@2: this->setstate(ios_base::failbit); williamr@2: williamr@2: return *this; williamr@2: } williamr@2: williamr@2: // Getline is essentially identical to get, except that it extracts williamr@2: // the delimiter. williamr@2: template williamr@2: basic_istream<_CharT, _Traits>& williamr@2: basic_istream<_CharT, _Traits>::getline(_CharT* __s, streamsize __n, williamr@2: _CharT __delim) { williamr@2: sentry __sentry(*this, _No_Skip_WS()); williamr@2: this->_M_gcount = 0; williamr@2: williamr@2: if (__sentry) { williamr@2: if (__n > 0) { williamr@2: basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); williamr@2: this->_M_gcount = __buf->egptr() != __buf->gptr() williamr@2: ? _M_read_buffered(this, __buf, __n - 1, __s, williamr@2: _Eq_char_bound<_Traits>(__delim), williamr@2: _Scan_for_char_val<_Traits>(__delim), williamr@2: true, true, true) williamr@2: : _M_read_unbuffered(this, __buf, __n - 1, __s, williamr@2: _Eq_char_bound<_Traits>(__delim), williamr@2: true, true, true); williamr@2: } williamr@2: } williamr@2: williamr@2: if (this->_M_gcount == 0) williamr@2: this->setstate(ios_base::failbit); williamr@2: williamr@2: return *this; williamr@2: } williamr@2: williamr@2: // Read n characters. We don't look for any delimiter, and we don't williamr@2: // put in a terminating null character. williamr@2: template williamr@2: basic_istream<_CharT, _Traits>& williamr@2: basic_istream<_CharT, _Traits>::read(char_type* __s, streamsize __n) williamr@2: { williamr@2: sentry __sentry(*this, _No_Skip_WS()); williamr@2: this->_M_gcount = 0; williamr@2: williamr@2: if (__sentry && !this->eof()) { williamr@2: basic_streambuf<_CharT, _Traits>*__buf = this->rdbuf(); williamr@2: if (__buf->gptr() != __buf->egptr()) williamr@2: _M_gcount williamr@2: = _M_read_buffered(this, __buf, __n, __s, williamr@2: _Constant_unary_fun(false), williamr@2: _Project2nd(), williamr@2: false, false, false); williamr@2: else williamr@2: _M_gcount williamr@2: = _M_read_unbuffered(this, __buf, __n, __s, williamr@2: _Constant_unary_fun(false), williamr@2: false, false, false); williamr@2: } williamr@2: else williamr@2: this->setstate(ios_base::failbit); williamr@2: williamr@2: if (this->eof()) williamr@2: this->setstate(ios_base::eofbit | ios_base::failbit); williamr@2: williamr@2: return *this; williamr@2: } williamr@2: williamr@2: williamr@2: // Read n or fewer characters. We don't look for any delimiter, and williamr@2: // we don't put in a terminating null character. williamr@2: template williamr@2: streamsize williamr@2: basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __nmax) williamr@2: { williamr@2: sentry __sentry(*this, _No_Skip_WS()); williamr@2: this->_M_gcount = 0; williamr@2: williamr@2: if (__sentry && !this->eof() && __nmax >= 0) { williamr@2: williamr@2: basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); williamr@2: streamsize __avail = __buf->in_avail(); williamr@2: williamr@2: // fbp : isn't full-blown setstate required here ? williamr@2: if (__avail == -1) williamr@2: this->_M_setstate_nothrow(ios_base::eofbit); williamr@2: williamr@2: else if (__avail != 0) { williamr@2: williamr@2: if (__buf->gptr() != __buf->egptr()) williamr@2: _M_gcount williamr@2: = _M_read_buffered(this, __buf, (min) (__avail, __nmax), __s, williamr@2: _Constant_unary_fun(false), williamr@2: _Project2nd(), williamr@2: false, false, false); williamr@2: else williamr@2: _M_gcount williamr@2: = _M_read_unbuffered(this, __buf, (min) (__avail, __nmax), __s, williamr@2: _Constant_unary_fun(false), williamr@2: false, false, false); williamr@2: } williamr@2: } williamr@2: else { williamr@2: // fbp : changed so that failbit is set only there, to pass Dietmar's test williamr@2: if (this->eof()) williamr@2: this->setstate(ios_base::eofbit | ios_base::failbit); williamr@2: else williamr@2: { williamr@2: if (__nmax < 0) williamr@2: { williamr@2: basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); williamr@2: streamsize __avail = __buf->in_avail(); williamr@2: if(__avail == -1) williamr@2: this->setstate(ios_base::eofbit); williamr@2: } williamr@2: else williamr@2: this->setstate(ios_base::failbit); williamr@2: } williamr@2: } williamr@2: williamr@2: // if (this->eof()) williamr@2: // this->setstate(ios_base::eofbit | ios_base::failbit); williamr@2: williamr@2: return _M_gcount; williamr@2: } williamr@2: williamr@2: template williamr@2: void basic_istream<_CharT, _Traits>::_M_formatted_get(_CharT* __s) williamr@2: { williamr@2: sentry __sentry(*this); // Skip whitespace. williamr@2: williamr@2: if (__sentry) { williamr@2: basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); williamr@2: streamsize __nmax = this->width() > 0 williamr@2: ? this->width() - 1 williamr@2: : (numeric_limits::max)() / sizeof(_CharT) - 1; williamr@2: williamr@2: streamsize __n = __buf->gptr() != __buf->egptr() williamr@2: ? _M_read_buffered(this, __buf, __nmax, __s, williamr@2: _Is_wspace_null<_Traits>((const ctype<_CharT>*)this->_M_ctype_facet()), williamr@2: _Scan_wspace_null<_Traits>((const ctype<_CharT>*)this->_M_ctype_facet()), williamr@2: false, true, false) williamr@2: : _M_read_unbuffered(this, __buf, __nmax, __s, williamr@2: _Is_wspace_null<_Traits>((const ctype<_CharT>*)this->_M_ctype_facet()), williamr@2: false, true, false); williamr@2: if (__n == 0) williamr@2: this->setstate(ios_base::failbit); williamr@2: } williamr@2: this->width(0); williamr@2: } williamr@2: williamr@2: // A generic unbuffered function for ignoring characters. We stop williamr@2: // when we reach EOF, or when the function object __is_delim returns williamr@2: // true. In the last case, it extracts the character for which williamr@2: // __is_delim is true, if and only if __extract_delim is true. williamr@2: williamr@2: template < class _CharT, class _Traits, class _Is_Delim> williamr@2: void _STLP_CALL williamr@2: _M_ignore_unbuffered(basic_istream<_CharT, _Traits>* __that, williamr@2: basic_streambuf<_CharT, _Traits>* __buf, williamr@2: _Is_Delim __is_delim, williamr@2: bool __extract_delim, bool __set_failbit) williamr@2: { williamr@2: bool __done = false; williamr@2: ios_base::iostate __status = 0; williamr@2: typedef typename basic_istream<_CharT, _Traits>::int_type int_type; williamr@2: williamr@2: _STLP_TRY { williamr@2: #ifdef __SYMBIAN32__ williamr@2: int_type __c = __buf->sgetc(); williamr@2: do { williamr@2: williamr@2: if (__that->_S_eof(__c)) { williamr@2: __done = true; williamr@2: __status |= __set_failbit ? ios_base::eofbit | ios_base::failbit williamr@2: : ios_base::eofbit; williamr@2: break; williamr@2: } williamr@2: williamr@2: else if (__is_delim(__c)) { williamr@2: __done = true; williamr@2: if (__extract_delim) williamr@2: __buf->snextc(); williamr@2: break; williamr@2: williamr@2: } williamr@2: __c = __buf->snextc(); williamr@2: } while(!__done); williamr@2: #else williamr@2: while (!__done) { williamr@2: int_type __c = __buf->sbumpc(); williamr@2: williamr@2: if (__that->_S_eof(__c)) { williamr@2: __done = true; williamr@2: __status |= __set_failbit ? ios_base::eofbit | ios_base::failbit williamr@2: : ios_base::eofbit; williamr@2: } williamr@2: williamr@2: else if (__is_delim(__c)) { williamr@2: __done = true; williamr@2: if (!__extract_delim) williamr@2: if (__that->_S_eof(__buf->sputbackc(_Traits::to_char_type(__c)))) williamr@2: __status |= ios_base::failbit; williamr@2: } williamr@2: } williamr@2: #endif williamr@2: } williamr@2: _STLP_CATCH_ALL { williamr@2: __that->_M_handle_exception(ios_base::badbit); williamr@2: } williamr@2: williamr@2: __that->setstate(__status); williamr@2: } williamr@2: williamr@2: // A generic buffered function for ignoring characters. Much like williamr@2: // _M_ignore_unbuffered, but with one additional function object: williamr@2: // __scan_delim(first, last) returns the first pointer p in [first, williamr@2: // last) such that __is_delim(p) is true. williamr@2: williamr@2: template < class _CharT, class _Traits, class _Is_Delim, class _Scan_Delim> williamr@2: void _STLP_CALL williamr@2: _M_ignore_buffered(basic_istream<_CharT, _Traits>* __that, williamr@2: basic_streambuf<_CharT, _Traits>* __buf, williamr@2: _Is_Delim __is_delim, _Scan_Delim __scan_delim, williamr@2: bool __extract_delim, bool __set_failbit) williamr@2: { williamr@2: bool __at_eof = false; williamr@2: bool __found_delim = false; williamr@2: williamr@2: _STLP_TRY { williamr@2: while (__buf->_M_egptr() != __buf->_M_gptr() && !__at_eof && !__found_delim) { williamr@2: const _CharT* __p = __scan_delim(__buf->_M_gptr(), __buf->_M_egptr()); williamr@2: __buf->_M_gbump((int)(__p - __buf->_M_gptr())); williamr@2: williamr@2: if (__p != __buf->_M_egptr()) { // We found delim, so we're done. williamr@2: if (__extract_delim) williamr@2: __buf->_M_gbump(1); williamr@2: __found_delim = true; williamr@2: } williamr@2: williamr@2: else // No delim. Try to refil the buffer. williamr@2: __at_eof = __that->_S_eof(__buf->sgetc()); williamr@2: } // Close the while loop. williamr@2: } williamr@2: _STLP_CATCH_ALL { williamr@2: __that->_M_handle_exception(ios_base::badbit); williamr@2: return; williamr@2: } williamr@2: williamr@2: if (__at_eof) { williamr@2: __that->setstate(__set_failbit ? ios_base::eofbit | ios_base::failbit williamr@2: : ios_base::eofbit); williamr@2: return; williamr@2: } williamr@2: if (__found_delim) williamr@2: return; williamr@2: williamr@2: // If execution has reached this point, then we have an empty buffer but williamr@2: // we have not reached eof. What that means is that the streambuf has williamr@2: // decided to switch from a buffered to an unbuffered mode. We switch williamr@2: // to _M_ignore_unbuffered. williamr@2: _M_ignore_unbuffered(__that, __buf, __is_delim, __extract_delim, __set_failbit); williamr@2: } williamr@2: williamr@2: // Overloaded versions of _M_ignore_unbuffered and _M_ignore_unbuffered williamr@2: // with an explicit count _Num. Return value is the number of williamr@2: // characters extracted. williamr@2: // williamr@2: // The function object __max_chars takes two arguments, _Num and __n williamr@2: // (the latter being the number of characters we have already read), williamr@2: // and returns the maximum number of characters to read from the buffer. williamr@2: // We parameterize _M_ignore_buffered so that we can use it for both williamr@2: // bounded and unbounded input; for the former the function object should williamr@2: // be minus<>, and for the latter it should return a constant maximum value. williamr@2: williamr@2: template < class _CharT, class _Traits, class _Max_Chars, class _Is_Delim> williamr@2: streamsize _STLP_CALL williamr@2: _M_ignore_unbuffered(basic_istream<_CharT, _Traits>* __that, williamr@2: basic_streambuf<_CharT, _Traits>* __buf, williamr@2: streamsize _Num, _Max_Chars __max_chars, williamr@2: _Is_Delim __is_delim, williamr@2: bool __extract_delim, bool __set_failbit) williamr@2: { williamr@2: streamsize __n = 0; williamr@2: ios_base::iostate __status = 0; williamr@2: typedef typename basic_istream<_CharT, _Traits>::int_type int_type; williamr@2: williamr@2: _STLP_TRY { williamr@2: while (__max_chars(_Num, __n) > 0) { williamr@2: int_type __c = __buf->sbumpc(); williamr@2: williamr@2: if (__that->_S_eof(__c)) { williamr@2: __status |= __set_failbit ? ios_base::eofbit | ios_base::failbit williamr@2: : ios_base::eofbit; williamr@2: break; williamr@2: } williamr@2: williamr@2: else if (__is_delim(__c)) { williamr@2: if (__extract_delim) williamr@2: ++__n; williamr@2: else if (__that->_S_eof(__buf->sputbackc(_Traits::to_char_type(__c)))) williamr@2: __status |= ios_base::failbit; williamr@2: williamr@2: break; williamr@2: } williamr@2: // fbp : added counter increment to pass Dietmar's test williamr@2: ++__n; williamr@2: } williamr@2: } williamr@2: _STLP_CATCH_ALL { williamr@2: __that->_M_handle_exception(ios_base::badbit); williamr@2: } williamr@2: williamr@2: if (__status) williamr@2: __that->setstate(__status); // This might throw. williamr@2: return __n; williamr@2: } williamr@2: williamr@2: template < class _CharT, class _Traits, class _Max_Chars, class _Is_Delim, class _Scan_Delim> williamr@2: streamsize _STLP_CALL williamr@2: _M_ignore_buffered(basic_istream<_CharT, _Traits>* __that, williamr@2: basic_streambuf<_CharT, _Traits>* __buf, williamr@2: streamsize _Num, williamr@2: _Max_Chars __max_chars, williamr@2: _Is_Delim __is_delim, _Scan_Delim __scan_delim, williamr@2: bool __extract_delim, bool __set_failbit) williamr@2: { williamr@2: streamsize __n = 0; williamr@2: bool __at_eof = false; williamr@2: bool __done = false; williamr@2: williamr@2: _STLP_TRY { williamr@2: while (__buf->_M_egptr() != __buf->_M_gptr() && !__done) { williamr@2: ptrdiff_t __avail = __buf->_M_egptr() - __buf->_M_gptr(); williamr@2: streamsize __m = __max_chars(_Num, __n); williamr@2: williamr@2: if (__avail >= __m) { // We have more characters than we need. williamr@2: const _CharT* __last = __buf->_M_gptr() + __m; williamr@2: const _CharT* __p = __scan_delim(__buf->_M_gptr(), __last); williamr@2: ptrdiff_t __chunk = __p - __buf->_M_gptr(); williamr@2: __n += __chunk; williamr@2: __buf->_M_gbump((int)__chunk); williamr@2: williamr@2: if (__extract_delim && __p != __last) { williamr@2: __n += 1; williamr@2: __buf->_M_gbump(1); williamr@2: } williamr@2: williamr@2: __done = true; williamr@2: } williamr@2: williamr@2: else { williamr@2: const _CharT* __p = __scan_delim(__buf->_M_gptr(), __buf->_M_egptr()); williamr@2: ptrdiff_t __chunk = __p - __buf->_M_gptr(); williamr@2: __n += __chunk; williamr@2: __buf->_M_gbump((int)__chunk); williamr@2: williamr@2: if (__p != __buf->_M_egptr()) { // We found delim. williamr@2: if (__extract_delim) { williamr@2: __n += 1; williamr@2: __buf->_M_gbump(1); williamr@2: } williamr@2: williamr@2: __done = true; williamr@2: } williamr@2: williamr@2: // We didn't find delim. Try to refill the buffer. williamr@2: else if (__that->_S_eof(__buf->sgetc())) { williamr@2: __done = true; williamr@2: __at_eof = true; williamr@2: } williamr@2: } williamr@2: } // Close the while loop. williamr@2: } williamr@2: _STLP_CATCH_ALL { williamr@2: __that->_M_handle_exception(ios_base::badbit); williamr@2: return __n; williamr@2: } williamr@2: williamr@2: if (__at_eof) williamr@2: __that->setstate(__set_failbit ? ios_base::eofbit | ios_base::failbit williamr@2: : ios_base::eofbit); williamr@2: williamr@2: if (__done) williamr@2: return __n; williamr@2: williamr@2: // If execution has reached this point, then we have an empty buffer but williamr@2: // we have not reached eof. What that means is that the streambuf has williamr@2: // decided to switch from buffered to unbuffered input. We switch to williamr@2: // to _M_ignore_unbuffered. williamr@2: williamr@2: return __n + _M_ignore_unbuffered( __that, __buf, _Num, __max_chars, williamr@2: __is_delim, __extract_delim, __set_failbit); williamr@2: } williamr@2: williamr@2: williamr@2: template williamr@2: basic_istream<_CharT, _Traits>& williamr@2: basic_istream<_CharT, _Traits>::ignore(streamsize __n) williamr@2: { williamr@2: sentry __sentry(*this, _No_Skip_WS()); williamr@2: this->_M_gcount = 0; williamr@2: williamr@2: if (__sentry) { williamr@2: basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); williamr@2: typedef _Constant_unary_fun _Const_bool; williamr@2: typedef _Constant_binary_fun williamr@2: _Const_streamsize; williamr@2: const streamsize __maxss = (numeric_limits::max)(); williamr@2: williamr@2: if (__n == (numeric_limits::max)()) { williamr@2: if (__buf->gptr() != __buf->egptr()) williamr@2: _M_gcount williamr@2: = _M_ignore_buffered(this, __buf, williamr@2: __maxss, _Const_streamsize(__maxss), williamr@2: _Const_bool(false), williamr@2: _Project2nd(), williamr@2: false, false); williamr@2: else williamr@2: _M_gcount = _M_ignore_unbuffered(this, __buf, williamr@2: __maxss, _Const_streamsize(__maxss), williamr@2: _Const_bool(false), false, false); williamr@2: } williamr@2: else { williamr@2: if (__buf->gptr() != __buf->egptr()) williamr@2: _M_gcount williamr@2: = _M_ignore_buffered(this, __buf, williamr@2: __n, minus(), williamr@2: _Const_bool(false), williamr@2: _Project2nd(), williamr@2: false, false); williamr@2: else williamr@2: _M_gcount = _M_ignore_unbuffered(this, __buf, __n, minus(), williamr@2: _Const_bool(false), false, false); williamr@2: } williamr@2: } williamr@2: williamr@2: return *this; williamr@2: } williamr@2: williamr@2: template williamr@2: basic_istream<_CharT, _Traits>& williamr@2: basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __delim) williamr@2: { williamr@2: sentry __sentry(*this, _No_Skip_WS()); williamr@2: this->_M_gcount = 0; williamr@2: williamr@2: if (__sentry) { williamr@2: basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); williamr@2: typedef _Constant_unary_fun _Const_bool; williamr@2: typedef _Constant_binary_fun williamr@2: _Const_streamsize; williamr@2: const streamsize __maxss = (numeric_limits::max)(); williamr@2: williamr@2: if (__n == (numeric_limits::max)()) { williamr@2: if (__buf->gptr() != __buf->egptr()) williamr@2: _M_gcount = _M_ignore_buffered(this, __buf, williamr@2: __maxss, _Const_streamsize(__maxss), williamr@2: _Eq_int_bound<_Traits>(__delim), williamr@2: _Scan_for_int_val<_Traits>(__delim), williamr@2: true, false); williamr@2: else williamr@2: _M_gcount = _M_ignore_unbuffered(this, __buf, williamr@2: __maxss, _Const_streamsize(__maxss), williamr@2: _Eq_int_bound<_Traits>(__delim), williamr@2: true, false); williamr@2: } williamr@2: else { williamr@2: if (__buf->gptr() != __buf->egptr()) williamr@2: _M_gcount = _M_ignore_buffered(this, __buf, williamr@2: __n, minus(), williamr@2: _Eq_int_bound<_Traits>( williamr@2: __delim), williamr@2: _Scan_for_int_val<_Traits>(__delim), williamr@2: true, false); williamr@2: else williamr@2: _M_gcount = _M_ignore_unbuffered(this, __buf, __n, minus(), williamr@2: _Eq_int_bound<_Traits>(__delim), williamr@2: true, false); williamr@2: } williamr@2: } williamr@2: williamr@2: return *this; williamr@2: } williamr@2: williamr@2: // This member function does not construct a sentry object, because williamr@2: // it is called from sentry's constructor. williamr@2: template williamr@2: void basic_istream<_CharT, _Traits>::_M_skip_whitespace(bool __set_failbit) williamr@2: { williamr@2: basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); williamr@2: if (!__buf) williamr@2: this->setstate(ios_base::badbit); williamr@2: else if (__buf->gptr() != __buf->egptr()) williamr@2: _M_ignore_buffered(this, __buf, williamr@2: _Is_not_wspace<_Traits>((const ctype<_CharT>*)this->_M_ctype_facet()), williamr@2: _Scan_for_not_wspace<_Traits>((const ctype<_CharT>*)this->_M_ctype_facet()), williamr@2: false, __set_failbit); williamr@2: else williamr@2: _M_ignore_unbuffered(this, __buf, williamr@2: _Is_not_wspace<_Traits>((const ctype<_CharT>*)this->_M_ctype_facet()), williamr@2: false, __set_failbit); williamr@2: } williamr@2: williamr@2: williamr@2: // This is a very simple loop that reads characters from __src and puts williamr@2: // them into __dest. It looks complicated because of the (standard- williamr@2: // mandated) exception handling policy. williamr@2: // williamr@2: // We stop when we get an exception, when we fail to insert into the williamr@2: // output streambuf, or when __is_delim is true. williamr@2: williamr@2: template < class _CharT, class _Traits, class _Is_Delim> williamr@2: streamsize _STLP_CALL williamr@2: _M_copy_unbuffered( basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __src, williamr@2: basic_streambuf<_CharT, _Traits>* __dest, williamr@2: _Is_Delim __is_delim, williamr@2: bool __extract_delim, bool __rethrow) williamr@2: { williamr@2: streamsize __extracted = 0; williamr@2: ios_base::iostate __status = 0; williamr@2: typedef typename basic_istream<_CharT, _Traits>::int_type int_type; williamr@2: int_type __c; williamr@2: williamr@2: _STLP_TRY { williamr@2: #ifdef __SYMBIAN32__ williamr@2: __c = __src->sgetc(); williamr@2: for(;; __c = __src->snextc()){ williamr@2: williamr@2: // If we failed to get a character, then quit. williamr@2: if (__that->_S_eof(__c)) { williamr@2: __status |= ios_base::eofbit; williamr@2: break; williamr@2: } williamr@2: // If it's the delimiter, then quit. williamr@2: else if (__is_delim(__c)) { williamr@2: if (!__extract_delim) williamr@2: __status |= ios_base::failbit; williamr@2: break; williamr@2: } williamr@2: williamr@2: else { williamr@2: williamr@2: // Try to put the character in the output streambuf. williamr@2: _STLP_TRY { williamr@2: if (!__that->_S_eof(__dest->sputc(__c))) williamr@2: ++__extracted; williamr@2: else williamr@2: break; williamr@2: } williamr@2: _STLP_CATCH_ALL { williamr@2: __status |= ios_base::failbit; williamr@2: break; williamr@2: } williamr@2: williamr@2: } williamr@2: williamr@2: } /* while (true) */ williamr@2: #else williamr@2: while (true) { williamr@2: williamr@2: // Get a character. If there's an exception, catch and (maybe) rethrow it. williamr@2: __c = __src->sbumpc(); williamr@2: williamr@2: // If we failed to get a character, then quit. williamr@2: if (__that->_S_eof(__c)) { williamr@2: __status |= ios_base::eofbit; williamr@2: break; williamr@2: } williamr@2: // If it's the delimiter, then quit. williamr@2: else if (__is_delim(__c)) { williamr@2: if (!__extract_delim && !__pushback(__src, _Traits::to_char_type(__c))) williamr@2: __status |= ios_base::failbit; williamr@2: break; williamr@2: } williamr@2: williamr@2: else { williamr@2: williamr@2: // Try to put the character in the output streambuf. williamr@2: bool __failed = false; williamr@2: _STLP_TRY { williamr@2: if (!__that->_S_eof(__dest->sputc(__c))) williamr@2: ++__extracted; williamr@2: else williamr@2: __failed = true; williamr@2: } williamr@2: _STLP_CATCH_ALL { williamr@2: __failed = true; williamr@2: } williamr@2: williamr@2: // If we failed to put the character in the output streambuf, then williamr@2: // try to push it back to the input streambuf. williamr@2: if (__failed && !__pushback(__src, _Traits::to_char_type(__c))) williamr@2: __status |= ios_base::failbit; williamr@2: williamr@2: // fbp : avoiding infinite loop in io-27-6-1-2-3.exp williamr@2: if (__failed) williamr@2: break; williamr@2: } williamr@2: williamr@2: } /* while (true) */ williamr@2: #endif williamr@2: } williamr@2: // fbp : this try/catch moved here in reasonable assumption williamr@2: // __is_delim never throw (__pushback is guaranteed not to) williamr@2: _STLP_CATCH_ALL { williamr@2: // See 27.6.1.2.3, paragraph 13. williamr@2: if (__rethrow && __extracted == 0) williamr@2: __that->_M_handle_exception(ios_base::failbit); williamr@2: } williamr@2: __that->setstate(__status); williamr@2: return __extracted; williamr@2: } williamr@2: williamr@2: // Buffered copying from one streambuf to another. We copy the characters williamr@2: // in chunks, rather than one at a time. We still have to worry about all williamr@2: // of the error conditions we checked in _M_copy_unbuffered, plus one more: williamr@2: // the streambuf might decide to switch from a buffered to an unbuffered mode. williamr@2: williamr@2: template < class _CharT, class _Traits, class _Is_Delim, class _Scan_Delim> williamr@2: streamsize _STLP_CALL williamr@2: _M_copy_buffered(basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __src, williamr@2: basic_streambuf<_CharT, _Traits>* __dest, williamr@2: _Scan_Delim __scan_delim, _Is_Delim __is_delim, williamr@2: bool __extract_delim, bool __rethrow) williamr@2: { williamr@2: streamsize __extracted = 0; williamr@2: ios_base::iostate __status = 0; williamr@2: typedef typename basic_istream<_CharT, _Traits>::int_type int_type; williamr@2: int_type __c = _Traits::eof(); williamr@2: _CharT* __first = __src->_M_gptr(); williamr@2: ptrdiff_t __avail = __src->_M_egptr() - __first; williamr@2: // fbp : introduced to move catch/try blocks out of the loop williamr@2: bool __do_handle_exceptions; williamr@2: williamr@2: _STLP_TRY { williamr@2: while (true) { williamr@2: __do_handle_exceptions = false ; williamr@2: const _CharT* __last = __scan_delim(__first, __src->_M_egptr()); williamr@2: williamr@2: // Try to copy the entire input buffer to the output buffer. williamr@2: streamsize __n = __dest->sputn(__first, __extract_delim && __last != __src->_M_egptr() williamr@2: ? (__last - __first) + 1 williamr@2: : (__last - __first)); williamr@2: __src->_M_gbump((int)__n); williamr@2: __extracted += __n; williamr@2: williamr@2: // from this on, catch() will call _M_handle_exceptions() williamr@2: __do_handle_exceptions = true; williamr@2: williamr@2: if (__n < __avail) // We found the delimiter, or else failed to williamr@2: break; // copy some characters. williamr@2: williamr@2: __c = __src->sgetc(); williamr@2: williamr@2: // Three possibilities: we succeeded in refilling the buffer, or williamr@2: // we got EOF, or the streambuf has switched to unbuffered mode. williamr@2: __first = __src->_M_gptr(); williamr@2: __avail = __src->_M_egptr() - __first; williamr@2: williamr@2: if (__avail > 0) williamr@2: {} // dwa 1/16/00 -- suppress a Metrowerks warning williamr@2: else if (__that->_S_eof(__c)) { williamr@2: __status |= ios_base::eofbit; williamr@2: break; williamr@2: } williamr@2: else williamr@2: return __extracted + _M_copy_unbuffered(__that, __src, __dest, __is_delim, williamr@2: __extract_delim, __rethrow); williamr@2: } /* while */ williamr@2: } williamr@2: williamr@2: _STLP_CATCH_ALL { williamr@2: // See 27.6.1.2.3, paragraph 13. williamr@2: if (__rethrow && __do_handle_exceptions && __extracted == 0) williamr@2: __that->_M_handle_exception(ios_base::failbit); williamr@2: } williamr@2: williamr@2: if (__status) williamr@2: __that->setstate(__status); // This might throw. williamr@2: return __extracted; williamr@2: } williamr@2: williamr@2: williamr@2: williamr@2: template williamr@2: basic_istream<_CharT, _Traits>& williamr@2: basic_istream<_CharT, _Traits> williamr@2: ::get(basic_streambuf<_CharT, _Traits>& __dest, _CharT __delim) williamr@2: { williamr@2: sentry __sentry(*this, _No_Skip_WS()); williamr@2: this->_M_gcount = 0; williamr@2: williamr@2: if (__sentry) { williamr@2: basic_streambuf<_CharT, _Traits>* __src = this->rdbuf(); williamr@2: williamr@2: if (__src) williamr@2: this->_M_gcount = __src->egptr() != __src->gptr() williamr@2: ? _M_copy_buffered(this, __src, &__dest, williamr@2: _Scan_for_char_val<_Traits>(__delim), williamr@2: _Eq_char_bound<_Traits>(__delim), williamr@2: false, false) williamr@2: : _M_copy_unbuffered(this, __src, &__dest, williamr@2: _Eq_char_bound<_Traits>(__delim), williamr@2: false, false); williamr@2: } williamr@2: williamr@2: if (this->_M_gcount == 0) williamr@2: this->setstate(ios_base::failbit); williamr@2: williamr@2: return *this; williamr@2: } williamr@2: williamr@2: // Copying characters into a streambuf. williamr@2: template williamr@2: basic_istream<_CharT, _Traits>& williamr@2: basic_istream<_CharT, _Traits> williamr@2: ::operator>>(basic_streambuf<_CharT, _Traits>* __dest) williamr@2: { williamr@2: streamsize __n = 0; williamr@2: typedef typename basic_istream<_CharT, _Traits>::sentry _Sentry; williamr@2: _Sentry __sentry(*this); williamr@2: if (__sentry) { williamr@2: basic_streambuf<_CharT, _Traits>* __src = this->rdbuf(); williamr@2: if (__src && __dest) williamr@2: __n = __src->egptr() != __src->gptr() williamr@2: ? _M_copy_buffered(this, __src, __dest, williamr@2: _Project2nd(), williamr@2: _Constant_unary_fun(false), williamr@2: false, true) williamr@2: : _M_copy_unbuffered(this, __src, __dest, williamr@2: _Constant_unary_fun(false), williamr@2: false, true); williamr@2: } williamr@2: williamr@2: if (__n == 0) williamr@2: this->setstate(ios_base::failbit); williamr@2: williamr@2: return *this; williamr@2: } williamr@2: williamr@2: // ---------------------------------------------------------------- williamr@2: // basic_iostream<> class williamr@2: // ---------------------------------------------------------------- williamr@2: williamr@2: template williamr@2: _STLP_EXP_DECLSPEC basic_iostream<_CharT, _Traits> williamr@2: ::basic_iostream(basic_streambuf<_CharT, _Traits>* __buf) williamr@2: : basic_ios<_CharT, _Traits>(), williamr@2: basic_istream<_CharT, _Traits>(__buf), williamr@2: basic_ostream<_CharT, _Traits>(__buf) williamr@2: { williamr@2: this->init(__buf); williamr@2: } williamr@2: williamr@2: template williamr@2: _STLP_EXP_DECLSPEC basic_iostream<_CharT, _Traits>::~basic_iostream() williamr@2: {} williamr@2: williamr@2: williamr@2: template williamr@2: _STLP_EXP_DECLSPEC basic_istream<_CharT, _Traits> williamr@2: ::basic_istream(basic_streambuf<_CharT, _Traits>* __buf) : williamr@2: basic_ios<_CharT, _Traits>(), _M_gcount(0) { williamr@2: this->init(__buf); williamr@2: } williamr@2: williamr@2: template williamr@2: _STLP_EXP_DECLSPEC basic_istream<_CharT, _Traits> williamr@2: ::~basic_istream() {} williamr@2: williamr@2: williamr@2: williamr@2: _STLP_END_NAMESPACE williamr@2: williamr@2: # undef __BIS_int_type__ williamr@2: # undef __BIS_pos_type__ williamr@2: # undef __BIS_off_type__ williamr@2: williamr@2: # endif /* defined (_STLP_EXPOSE_STREAM_IMPLEMENTATION) */ williamr@2: williamr@2: #endif /* _STLP_ISTREAM_C */