streambuf.tcc

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

Generated on Wed Sep 29 13:54:53 2004 for libstdc++-v3 Source by doxygen 1.3.7