1 // Stream buffer classes -*- C++ -*-
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
4 // Free Software Foundation, Inc.
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)
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.
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,
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.
32 // ISO C++ 14882: 27.5 Stream buffers
35 #ifndef _CPP_BITS_STREAMBUF_TCC
36 #define _CPP_BITS_STREAMBUF_TCC 1
38 #pragma GCC system_header
40 #ifdef _GLIBCPP_HAVE_UNISTD_H
46 template<typename _CharT, typename _Traits>
48 basic_streambuf<_CharT, _Traits>::_S_pback_size;
50 template<typename _CharT, typename _Traits>
51 typename basic_streambuf<_CharT, _Traits>::int_type
52 basic_streambuf<_CharT, _Traits>::
56 if (_M_in_cur && _M_in_cur < _M_in_end)
58 char_type __c = *(this->gptr());
60 __ret = traits_type::to_int_type(__c);
63 __ret = this->uflow();
67 template<typename _CharT, typename _Traits>
68 typename basic_streambuf<_CharT, _Traits>::int_type
69 basic_streambuf<_CharT, _Traits>::
70 sputbackc(char_type __c)
73 bool __testpos = _M_in_cur && _M_in_beg < _M_in_cur;
74 bool __testne = _M_in_cur && !traits_type::eq(__c, this->gptr()[-1]);
75 if (!__testpos || __testne)
76 __ret = pbackfail(traits_type::to_int_type(__c));
80 __ret = traits_type::to_int_type(*this->gptr());
85 template<typename _CharT, typename _Traits>
86 typename basic_streambuf<_CharT, _Traits>::int_type
87 basic_streambuf<_CharT, _Traits>::
91 if (_M_in_cur && _M_in_beg < _M_in_cur)
94 __ret = traits_type::to_int_type(*_M_in_cur);
97 __ret = this->pbackfail();
101 // Don't test against _M_buf + _M_buf_size, because _M_buf reflects
102 // allocated space, and on certain (rare but entirely legal)
103 // situations, there will be no allocated space yet the internal
104 // buffers will still be valid. (This happens if setp is used to set
105 // the internal buffer to say some externally-allocated sequence.)
106 template<typename _CharT, typename _Traits>
107 typename basic_streambuf<_CharT, _Traits>::int_type
108 basic_streambuf<_CharT, _Traits>::
112 if (_M_out_buf_size())
116 __ret = traits_type::to_int_type(__c);
119 __ret = this->overflow(traits_type::to_int_type(__c));
123 template<typename _CharT, typename _Traits>
125 basic_streambuf<_CharT, _Traits>::
126 xsgetn(char_type* __s, streamsize __n)
128 streamsize __ret = 0;
131 size_t __buf_len = _M_in_end - _M_in_cur;
134 size_t __remaining = __n - __ret;
135 size_t __len = min(__buf_len, __remaining);
136 traits_type::copy(__s, _M_in_cur, __len);
139 _M_in_cur_move(__len);
144 int_type __c = this->uflow();
145 if (!traits_type::eq_int_type(__c, traits_type::eof()))
147 traits_type::assign(*__s++, traits_type::to_char_type(__c));
157 // Don't test against _M_buf + _M_buf_size, because _M_buf reflects
158 // allocated space, and on certain (rare but entirely legal)
159 // situations, there will be no allocated space yet the internal
160 // buffers will still be valid. (This happens if setp is used to set
161 // the internal buffer to say some externally-allocated sequence.)
162 template<typename _CharT, typename _Traits>
164 basic_streambuf<_CharT, _Traits>::
165 xsputn(const char_type* __s, streamsize __n)
167 streamsize __ret = 0;
170 off_type __buf_len = _M_out_buf_size();
173 off_type __remaining = __n - __ret;
174 off_type __len = min(__buf_len, __remaining);
175 traits_type::copy(_M_out_cur, __s, __len);
178 _M_out_cur_move(__len);
183 int_type __c = this->overflow(traits_type::to_int_type(*__s));
184 if (!traits_type::eq_int_type(__c, traits_type::eof()))
196 // Conceivably, this could be used to implement buffer-to-buffer
197 // copies, if this was ever desired in an un-ambiguous way by the
198 // standard. If so, then checks for __ios being zero would be
200 template<typename _CharT, typename _Traits>
202 __copy_streambufs(basic_ios<_CharT, _Traits>& __ios,
203 basic_streambuf<_CharT, _Traits>* __sbin,
204 basic_streambuf<_CharT, _Traits>* __sbout)
206 typedef typename _Traits::int_type int_type;
208 streamsize __ret = 0;
209 streamsize __bufsize = __sbin->in_avail();
211 bool __testput = __sbout->_M_mode & ios_base::out;
214 while (__testput && __bufsize != -1)
216 if (__bufsize != 0 && __sbin->gptr() != NULL
217 && __sbin->gptr() + __bufsize <= __sbin->egptr())
219 __xtrct = __sbout->sputn(__sbin->gptr(), __bufsize);
221 __sbin->_M_in_cur_move(__xtrct);
222 if (__xtrct != __bufsize)
227 #ifdef _GLIBCPP_HAVE_ISATTY
228 size_t __size = isatty(0) ? 1 : static_cast<size_t>(BUFSIZ);
233 static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __size));
234 streamsize __charsread = __sbin->sgetn(__buf, __size);
235 __xtrct = __sbout->sputn(__buf, __charsread);
237 if (__xtrct != __charsread)
240 if (_Traits::eq_int_type(__sbin->sgetc(), _Traits::eof()))
242 __bufsize = __sbin->in_avail();
245 catch(exception& __fail)
247 __ios.setstate(ios_base::failbit);
248 if ((__ios.exceptions() & ios_base::failbit) != 0)
249 __throw_exception_again;
254 // Inhibit implicit instantiations for required instantiations,
255 // which are defined via explicit instantiations elsewhere.
256 // NB: This syntax is a GNU extension.
257 extern template class basic_streambuf<char>;
260 __copy_streambufs(basic_ios<char>&, basic_streambuf<char>*,
261 basic_streambuf<char>*);
263 #ifdef _GLIBCPP_USE_WCHAR_T
264 extern template class basic_streambuf<wchar_t>;
267 __copy_streambufs(basic_ios<wchar_t>&, basic_streambuf<wchar_t>*,
268 basic_streambuf<wchar_t>*);