Whole document tree streambuf.tccGo to the documentation of this file.00001 // Stream buffer classes -*- C++ -*- 00002 00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 2, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // You should have received a copy of the GNU General Public License along 00017 // with this library; see the file COPYING. If not, write to the Free 00018 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00019 // USA. 00020 00021 // As a special exception, you may use this file as part of a free software 00022 // library without restriction. Specifically, if other files instantiate 00023 // templates or use macros or inline functions from this file, or you compile 00024 // this file and link it with other files to produce an executable, this 00025 // file does not by itself cause the resulting executable to be covered by 00026 // the GNU General Public License. This exception does not however 00027 // invalidate any other reasons why the executable file might be covered by 00028 // the GNU General Public License. 00029 00030 // 00031 // ISO C++ 14882: 27.5 Stream buffers 00032 // 00033 00034 #ifndef _CPP_BITS_STREAMBUF_TCC 00035 #define _CPP_BITS_STREAMBUF_TCC 1 00036 00037 namespace std { 00038 00039 template<typename _CharT, typename _Traits> 00040 typename basic_streambuf<_CharT, _Traits>::int_type 00041 basic_streambuf<_CharT, _Traits>:: 00042 sbumpc() 00043 { 00044 int_type __ret; 00045 if (_M_in_cur && _M_in_cur < _M_in_end) 00046 { 00047 char_type __c = *gptr(); 00048 _M_in_cur_move(1); 00049 __ret = traits_type::to_int_type(__c); 00050 } 00051 else 00052 __ret = this->uflow(); 00053 return __ret; 00054 } 00055 00056 template<typename _CharT, typename _Traits> 00057 typename basic_streambuf<_CharT, _Traits>::int_type 00058 basic_streambuf<_CharT, _Traits>:: 00059 sputbackc(char_type __c) 00060 { 00061 int_type __ret; 00062 bool __testpos = _M_in_cur && _M_in_beg < _M_in_cur; 00063 bool __testne = _M_in_cur && !traits_type::eq(__c, this->gptr()[-1]); 00064 if (!__testpos || __testne) 00065 __ret = pbackfail(traits_type::to_int_type(__c)); 00066 else 00067 { 00068 _M_in_cur_move(-1); 00069 __ret = traits_type::to_int_type(*this->gptr()); 00070 } 00071 return __ret; 00072 } 00073 00074 template<typename _CharT, typename _Traits> 00075 typename basic_streambuf<_CharT, _Traits>::int_type 00076 basic_streambuf<_CharT, _Traits>:: 00077 sungetc() 00078 { 00079 int_type __ret; 00080 if (_M_in_cur && _M_in_beg < _M_in_cur) 00081 { 00082 _M_in_cur_move(-1); 00083 __ret = traits_type::to_int_type(*_M_in_cur); 00084 } 00085 else 00086 __ret = this->pbackfail(); 00087 return __ret; 00088 } 00089 00090 // Don't test against _M_buf + _M_buf_size, because _M_buf reflects 00091 // allocated space, and on certain (rare but entirely legal) 00092 // situations, there will be no allocated space yet the internal 00093 // buffers will still be valid. (This happens if setp is used to set 00094 // the internal buffer to say some externally-allocated sequence.) 00095 template<typename _CharT, typename _Traits> 00096 typename basic_streambuf<_CharT, _Traits>::int_type 00097 basic_streambuf<_CharT, _Traits>:: 00098 sputc(char_type __c) 00099 { 00100 int_type __ret; 00101 if (_M_out_buf_size()) 00102 { 00103 *_M_out_cur = __c; 00104 _M_out_cur_move(1); 00105 __ret = traits_type::to_int_type(__c); 00106 } 00107 else 00108 __ret = this->overflow(traits_type::to_int_type(__c)); 00109 return __ret; 00110 } 00111 00112 template<typename _CharT, typename _Traits> 00113 streamsize 00114 basic_streambuf<_CharT, _Traits>:: 00115 xsgetn(char_type* __s, streamsize __n) 00116 { 00117 streamsize __ret = 0; 00118 while (__ret < __n) 00119 { 00120 size_t __buf_len = _M_in_end - _M_in_cur; 00121 if (__buf_len > 0) 00122 { 00123 size_t __remaining = __n - __ret; 00124 size_t __len = min(__buf_len, __remaining); 00125 traits_type::copy(__s, _M_in_cur, __len); 00126 __ret += __len; 00127 __s += __len; 00128 _M_in_cur_move(__len); 00129 } 00130 00131 if (__ret < __n) 00132 { 00133 int_type __c = this->uflow(); 00134 if (__c != traits_type::eof()) 00135 { 00136 traits_type::assign(*__s++, traits_type::to_char_type(__c)); 00137 ++__ret; 00138 } 00139 else 00140 break; 00141 } 00142 } 00143 return __ret; 00144 } 00145 00146 // Don't test against _M_buf + _M_buf_size, because _M_buf reflects 00147 // allocated space, and on certain (rare but entirely legal) 00148 // situations, there will be no allocated space yet the internal 00149 // buffers will still be valid. (This happens if setp is used to set 00150 // the internal buffer to say some externally-allocated sequence.) 00151 template<typename _CharT, typename _Traits> 00152 streamsize 00153 basic_streambuf<_CharT, _Traits>:: 00154 xsputn(const char_type* __s, streamsize __n) 00155 { 00156 streamsize __ret = 0; 00157 while (__ret < __n) 00158 { 00159 off_type __buf_len = _M_out_buf_size(); 00160 if (__buf_len > 0) 00161 { 00162 off_type __remaining = __n - __ret; 00163 off_type __len = min(__buf_len, __remaining); 00164 traits_type::copy(_M_out_cur, __s, __len); 00165 __ret += __len; 00166 __s += __len; 00167 _M_out_cur_move(__len); 00168 } 00169 00170 if (__ret < __n) 00171 { 00172 int_type __c = this->overflow(traits_type::to_int_type(*__s)); 00173 if (__c != traits_type::eof()) 00174 { 00175 ++__ret; 00176 ++__s; 00177 } 00178 else 00179 break; 00180 } 00181 } 00182 return __ret; 00183 } 00184 00185 // Conceivably, this could be used to implement buffer-to-buffer 00186 // copies, if this was ever desired in an un-ambiguous way by the 00187 // standard. If so, then checks for __ios being zero would be 00188 // necessary. 00189 template<typename _CharT, typename _Traits> 00190 streamsize 00191 __copy_streambufs(basic_ios<_CharT, _Traits>& __ios, 00192 basic_streambuf<_CharT, _Traits>* __sbin, 00193 basic_streambuf<_CharT, _Traits>* __sbout) 00194 { 00195 typedef typename _Traits::int_type int_type; 00196 00197 streamsize __ret = 0; 00198 streamsize __bufsize = __sbin->in_avail(); 00199 streamsize __xtrct; 00200 bool __testput = __sbout->_M_mode & ios_base::out; 00201 try { 00202 while (__testput && __bufsize != -1) 00203 { 00204 __xtrct = __sbout->sputn(__sbin->gptr(), __bufsize); 00205 __ret += __xtrct; 00206 __sbin->_M_in_cur_move(__xtrct); 00207 if (__xtrct == __bufsize) 00208 { 00209 if (__sbin->sgetc() == _Traits::eof()) 00210 break; 00211 __bufsize = __sbin->in_avail(); 00212 } 00213 else 00214 break; 00215 } 00216 } 00217 catch(exception& __fail) { 00218 if ((__ios.exceptions() & ios_base::failbit) != 0) 00219 __throw_exception_again; 00220 } 00221 return __ret; 00222 } 00223 } // namespace std 00224 00225 #endif // _CPP_BITS_STREAMBUF_TCC 00226 Generated on Mon Apr 8 03:11:46 2002 for libstdc++-v3 Source by ![]() |