streambuf.tcc revision 102782
1// Stream buffer classes -*- C++ -*- 2 3// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 4// Free Software Foundation, Inc. 5// 6// This file is part of the GNU ISO C++ Library. This library is free 7// software; you can redistribute it and/or modify it under the 8// terms of the GNU General Public License as published by the 9// Free Software Foundation; either version 2, or (at your option) 10// any later version. 11 12// This library is distributed in the hope that it will be useful, 13// but WITHOUT ANY WARRANTY; without even the implied warranty of 14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15// GNU General Public License for more details. 16 17// You should have received a copy of the GNU General Public License along 18// with this library; see the file COPYING. If not, write to the Free 19// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 20// USA. 21 22// As a special exception, you may use this file as part of a free software 23// library without restriction. Specifically, if other files instantiate 24// templates or use macros or inline functions from this file, or you compile 25// this file and link it with other files to produce an executable, this 26// file does not by itself cause the resulting executable to be covered by 27// the GNU General Public License. This exception does not however 28// invalidate any other reasons why the executable file might be covered by 29// the GNU General Public License. 30 31// 32// ISO C++ 14882: 27.5 Stream buffers 33// 34 35#ifndef _CPP_BITS_STREAMBUF_TCC 36#define _CPP_BITS_STREAMBUF_TCC 1 37 38#pragma GCC system_header 39 40namespace std 41{ 42 template<typename _CharT, typename _Traits> 43 const size_t 44 basic_streambuf<_CharT, _Traits>::_S_pback_size; 45 46 template<typename _CharT, typename _Traits> 47 typename basic_streambuf<_CharT, _Traits>::int_type 48 basic_streambuf<_CharT, _Traits>:: 49 sbumpc() 50 { 51 int_type __ret; 52 if (_M_in_cur && _M_in_cur < _M_in_end) 53 { 54 char_type __c = *(this->gptr()); 55 _M_in_cur_move(1); 56 __ret = traits_type::to_int_type(__c); 57 } 58 else 59 __ret = this->uflow(); 60 return __ret; 61 } 62 63 template<typename _CharT, typename _Traits> 64 typename basic_streambuf<_CharT, _Traits>::int_type 65 basic_streambuf<_CharT, _Traits>:: 66 sputbackc(char_type __c) 67 { 68 int_type __ret; 69 bool __testpos = _M_in_cur && _M_in_beg < _M_in_cur; 70 bool __testne = _M_in_cur && !traits_type::eq(__c, this->gptr()[-1]); 71 if (!__testpos || __testne) 72 __ret = pbackfail(traits_type::to_int_type(__c)); 73 else 74 { 75 _M_in_cur_move(-1); 76 __ret = traits_type::to_int_type(*this->gptr()); 77 } 78 return __ret; 79 } 80 81 template<typename _CharT, typename _Traits> 82 typename basic_streambuf<_CharT, _Traits>::int_type 83 basic_streambuf<_CharT, _Traits>:: 84 sungetc() 85 { 86 int_type __ret; 87 if (_M_in_cur && _M_in_beg < _M_in_cur) 88 { 89 _M_in_cur_move(-1); 90 __ret = traits_type::to_int_type(*_M_in_cur); 91 } 92 else 93 __ret = this->pbackfail(); 94 return __ret; 95 } 96 97 // Don't test against _M_buf + _M_buf_size, because _M_buf reflects 98 // allocated space, and on certain (rare but entirely legal) 99 // situations, there will be no allocated space yet the internal 100 // buffers will still be valid. (This happens if setp is used to set 101 // the internal buffer to say some externally-allocated sequence.) 102 template<typename _CharT, typename _Traits> 103 typename basic_streambuf<_CharT, _Traits>::int_type 104 basic_streambuf<_CharT, _Traits>:: 105 sputc(char_type __c) 106 { 107 int_type __ret; 108 if (_M_out_buf_size()) 109 { 110 *_M_out_cur = __c; 111 _M_out_cur_move(1); 112 __ret = traits_type::to_int_type(__c); 113 } 114 else 115 __ret = this->overflow(traits_type::to_int_type(__c)); 116 return __ret; 117 } 118 119 template<typename _CharT, typename _Traits> 120 streamsize 121 basic_streambuf<_CharT, _Traits>:: 122 xsgetn(char_type* __s, streamsize __n) 123 { 124 streamsize __ret = 0; 125 while (__ret < __n) 126 { 127 size_t __buf_len = _M_in_end - _M_in_cur; 128 if (__buf_len > 0) 129 { 130 size_t __remaining = __n - __ret; 131 size_t __len = min(__buf_len, __remaining); 132 traits_type::copy(__s, _M_in_cur, __len); 133 __ret += __len; 134 __s += __len; 135 _M_in_cur_move(__len); 136 } 137 138 if (__ret < __n) 139 { 140 int_type __c = this->uflow(); 141 if (!traits_type::eq_int_type(__c, traits_type::eof())) 142 { 143 traits_type::assign(*__s++, traits_type::to_char_type(__c)); 144 ++__ret; 145 } 146 else 147 break; 148 } 149 } 150 return __ret; 151 } 152 153 // Don't test against _M_buf + _M_buf_size, because _M_buf reflects 154 // allocated space, and on certain (rare but entirely legal) 155 // situations, there will be no allocated space yet the internal 156 // buffers will still be valid. (This happens if setp is used to set 157 // the internal buffer to say some externally-allocated sequence.) 158 template<typename _CharT, typename _Traits> 159 streamsize 160 basic_streambuf<_CharT, _Traits>:: 161 xsputn(const char_type* __s, streamsize __n) 162 { 163 streamsize __ret = 0; 164 while (__ret < __n) 165 { 166 off_type __buf_len = _M_out_buf_size(); 167 if (__buf_len > 0) 168 { 169 off_type __remaining = __n - __ret; 170 off_type __len = min(__buf_len, __remaining); 171 traits_type::copy(_M_out_cur, __s, __len); 172 __ret += __len; 173 __s += __len; 174 _M_out_cur_move(__len); 175 } 176 177 if (__ret < __n) 178 { 179 int_type __c = this->overflow(traits_type::to_int_type(*__s)); 180 if (!traits_type::eq_int_type(__c, traits_type::eof())) 181 { 182 ++__ret; 183 ++__s; 184 } 185 else 186 break; 187 } 188 } 189 return __ret; 190 } 191 192 // Conceivably, this could be used to implement buffer-to-buffer 193 // copies, if this was ever desired in an un-ambiguous way by the 194 // standard. If so, then checks for __ios being zero would be 195 // necessary. 196 template<typename _CharT, typename _Traits> 197 streamsize 198 __copy_streambufs(basic_ios<_CharT, _Traits>& __ios, 199 basic_streambuf<_CharT, _Traits>* __sbin, 200 basic_streambuf<_CharT, _Traits>* __sbout) 201 { 202 typedef typename _Traits::int_type int_type; 203 204 streamsize __ret = 0; 205 streamsize __bufsize = __sbin->in_avail(); 206 streamsize __xtrct; 207 bool __testput = __sbout->_M_mode & ios_base::out; 208 try 209 { 210 while (__testput && __bufsize != -1) 211 { 212 __xtrct = __sbout->sputn(__sbin->gptr(), __bufsize); 213 __ret += __xtrct; 214 __sbin->_M_in_cur_move(__xtrct); 215 if (__xtrct == __bufsize) 216 { 217 if (_Traits::eq_int_type(__sbin->sgetc(), _Traits::eof())) 218 break; 219 __bufsize = __sbin->in_avail(); 220 } 221 else 222 break; 223 } 224 } 225 catch(exception& __fail) 226 { 227 __ios.setstate(ios_base::failbit); 228 if ((__ios.exceptions() & ios_base::failbit) != 0) 229 __throw_exception_again; 230 } 231 return __ret; 232 } 233 234 // Inhibit implicit instantiations for required instantiations, 235 // which are defined via explicit instantiations elsewhere. 236 // NB: This syntax is a GNU extension. 237 extern template class basic_streambuf<char>; 238 extern template 239 streamsize 240 __copy_streambufs(basic_ios<char>&, basic_streambuf<char>*, 241 basic_streambuf<char>*); 242 243 extern template class basic_streambuf<wchar_t>; 244 extern template 245 streamsize 246 __copy_streambufs(basic_ios<wchar_t>&, basic_streambuf<wchar_t>*, 247 basic_streambuf<wchar_t>*); 248} // namespace std 249 250#endif 251