streambuf.tcc revision 117397
1// Stream buffer classes -*- C++ -*- 2 3// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 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 if (!__testpos || !traits_type::eq(__c, this->gptr()[-1])) 71 __ret = this->pbackfail(traits_type::to_int_type(__c)); 72 else 73 { 74 _M_in_cur_move(-1); 75 __ret = traits_type::to_int_type(*this->gptr()); 76 } 77 return __ret; 78 } 79 80 template<typename _CharT, typename _Traits> 81 typename basic_streambuf<_CharT, _Traits>::int_type 82 basic_streambuf<_CharT, _Traits>:: 83 sungetc() 84 { 85 int_type __ret; 86 if (_M_in_cur && _M_in_beg < _M_in_cur) 87 { 88 _M_in_cur_move(-1); 89 __ret = traits_type::to_int_type(*_M_in_cur); 90 } 91 else 92 __ret = this->pbackfail(); 93 return __ret; 94 } 95 96 // Don't test against _M_buf + _M_buf_size, because _M_buf reflects 97 // allocated space, and on certain (rare but entirely legal) 98 // situations, there will be no allocated space yet the internal 99 // buffers will still be valid. (This happens if setp is used to set 100 // the internal buffer to say some externally-allocated sequence.) 101 template<typename _CharT, typename _Traits> 102 typename basic_streambuf<_CharT, _Traits>::int_type 103 basic_streambuf<_CharT, _Traits>:: 104 sputc(char_type __c) 105 { 106 int_type __ret; 107 if (_M_out_buf_size()) 108 { 109 *_M_out_cur = __c; 110 _M_out_cur_move(1); 111 __ret = traits_type::to_int_type(__c); 112 } 113 else 114 __ret = this->overflow(traits_type::to_int_type(__c)); 115 return __ret; 116 } 117 118 template<typename _CharT, typename _Traits> 119 streamsize 120 basic_streambuf<_CharT, _Traits>:: 121 xsgetn(char_type* __s, streamsize __n) 122 { 123 streamsize __ret = 0; 124 while (__ret < __n) 125 { 126 size_t __buf_len = _M_in_end - _M_in_cur; 127 if (__buf_len > 0) 128 { 129 size_t __remaining = __n - __ret; 130 size_t __len = min(__buf_len, __remaining); 131 traits_type::copy(__s, _M_in_cur, __len); 132 __ret += __len; 133 __s += __len; 134 _M_in_cur_move(__len); 135 } 136 137 if (__ret < __n) 138 { 139 int_type __c = this->uflow(); 140 if (!traits_type::eq_int_type(__c, traits_type::eof())) 141 { 142 traits_type::assign(*__s++, traits_type::to_char_type(__c)); 143 ++__ret; 144 } 145 else 146 break; 147 } 148 } 149 return __ret; 150 } 151 152 // Don't test against _M_buf + _M_buf_size, because _M_buf reflects 153 // allocated space, and on certain (rare but entirely legal) 154 // situations, there will be no allocated space yet the internal 155 // buffers will still be valid. (This happens if setp is used to set 156 // the internal buffer to say some externally-allocated sequence.) 157 template<typename _CharT, typename _Traits> 158 streamsize 159 basic_streambuf<_CharT, _Traits>:: 160 xsputn(const char_type* __s, streamsize __n) 161 { 162 streamsize __ret = 0; 163 while (__ret < __n) 164 { 165 off_type __buf_len = _M_out_buf_size(); 166 if (__buf_len > 0) 167 { 168 off_type __remaining = __n - __ret; 169 off_type __len = min(__buf_len, __remaining); 170 traits_type::copy(_M_out_cur, __s, __len); 171 __ret += __len; 172 __s += __len; 173 _M_out_cur_move(__len); 174 } 175 176 if (__ret < __n) 177 { 178 int_type __c = this->overflow(traits_type::to_int_type(*__s)); 179 if (!traits_type::eq_int_type(__c, traits_type::eof())) 180 { 181 ++__ret; 182 ++__s; 183 } 184 else 185 break; 186 } 187 } 188 return __ret; 189 } 190 191 // Conceivably, this could be used to implement buffer-to-buffer 192 // copies, if this was ever desired in an un-ambiguous way by the 193 // standard. If so, then checks for __ios being zero would be 194 // necessary. 195 template<typename _CharT, typename _Traits> 196 streamsize 197 __copy_streambufs(basic_ios<_CharT, _Traits>& __ios, 198 basic_streambuf<_CharT, _Traits>* __sbin, 199 basic_streambuf<_CharT, _Traits>* __sbout) 200 { 201 streamsize __ret = 0; 202 try 203 { 204 typename _Traits::int_type __c = __sbin->sgetc(); 205 while (!_Traits::eq_int_type(__c, _Traits::eof())) 206 { 207 const size_t __n = __sbin->_M_in_end - __sbin->_M_in_cur; 208 if (__n > 1) 209 { 210 const size_t __wrote = __sbout->sputn(__sbin->_M_in_cur, 211 __n); 212 __sbin->_M_in_cur_move(__wrote); 213 __ret += __wrote; 214 if (__wrote < __n) 215 break; 216 __c = __sbin->underflow(); 217 } 218 else 219 { 220 __c = __sbout->sputc(_Traits::to_char_type(__c)); 221 if (_Traits::eq_int_type(__c, _Traits::eof())) 222 break; 223 ++__ret; 224 __c = __sbin->snextc(); 225 } 226 } 227 } 228 catch(exception& __fail) 229 { 230 __ios.setstate(ios_base::failbit); 231 if ((__ios.exceptions() & ios_base::failbit) != 0) 232 __throw_exception_again; 233 } 234 return __ret; 235 } 236 237 // Inhibit implicit instantiations for required instantiations, 238 // which are defined via explicit instantiations elsewhere. 239 // NB: This syntax is a GNU extension. 240#if _GLIBCPP_EXTERN_TEMPLATE 241 extern template class basic_streambuf<char>; 242 extern template 243 streamsize 244 __copy_streambufs(basic_ios<char>&, basic_streambuf<char>*, 245 basic_streambuf<char>*); 246 247#ifdef _GLIBCPP_USE_WCHAR_T 248 extern template class basic_streambuf<wchar_t>; 249 extern template 250 streamsize 251 __copy_streambufs(basic_ios<wchar_t>&, basic_streambuf<wchar_t>*, 252 basic_streambuf<wchar_t>*); 253#endif 254#endif 255} // namespace std 256 257#endif 258