]>
Commit | Line | Data |
---|---|---|
725dc051 BK |
1 | // Stream buffer classes -*- C++ -*- |
2 | ||
1bc8b0ad | 3 | // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 |
6f48900c | 4 | // Free Software Foundation, Inc. |
725dc051 BK |
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 | ||
3b794528 BK |
38 | #pragma GCC system_header |
39 | ||
6f48900c BK |
40 | namespace std |
41 | { | |
d3a193e3 | 42 | template<typename _CharT, typename _Traits> |
31bfa177 | 43 | typename basic_streambuf<_CharT, _Traits>::int_type |
725dc051 BK |
44 | basic_streambuf<_CharT, _Traits>:: |
45 | sbumpc() | |
46 | { | |
47 | int_type __ret; | |
0b176c1a | 48 | if (_M_in_cur < _M_in_end) |
725dc051 | 49 | { |
07c2b60d | 50 | char_type __c = *this->_M_in_cur; |
aa438e8f | 51 | _M_move_in_cur(1); |
725dc051 BK |
52 | __ret = traits_type::to_int_type(__c); |
53 | } | |
54 | else | |
55 | __ret = this->uflow(); | |
56 | return __ret; | |
57 | } | |
58 | ||
59 | template<typename _CharT, typename _Traits> | |
31bfa177 | 60 | typename basic_streambuf<_CharT, _Traits>::int_type |
725dc051 BK |
61 | basic_streambuf<_CharT, _Traits>:: |
62 | sputbackc(char_type __c) | |
63 | { | |
64 | int_type __ret; | |
0b176c1a | 65 | const bool __testpos = _M_in_beg < _M_in_cur; |
07c2b60d | 66 | if (!__testpos || !traits_type::eq(__c, this->_M_in_cur[-1])) |
a8a4259d | 67 | __ret = this->pbackfail(traits_type::to_int_type(__c)); |
725dc051 BK |
68 | else |
69 | { | |
aa438e8f | 70 | _M_move_in_cur(-1); |
07c2b60d | 71 | __ret = traits_type::to_int_type(*this->_M_in_cur); |
725dc051 BK |
72 | } |
73 | return __ret; | |
74 | } | |
75 | ||
76 | template<typename _CharT, typename _Traits> | |
31bfa177 | 77 | typename basic_streambuf<_CharT, _Traits>::int_type |
725dc051 BK |
78 | basic_streambuf<_CharT, _Traits>:: |
79 | sungetc() | |
80 | { | |
81 | int_type __ret; | |
0b176c1a | 82 | if (_M_in_beg < _M_in_cur) |
725dc051 | 83 | { |
aa438e8f | 84 | _M_move_in_cur(-1); |
725dc051 BK |
85 | __ret = traits_type::to_int_type(*_M_in_cur); |
86 | } | |
87 | else | |
88 | __ret = this->pbackfail(); | |
89 | return __ret; | |
90 | } | |
91 | ||
725dc051 | 92 | template<typename _CharT, typename _Traits> |
31bfa177 | 93 | typename basic_streambuf<_CharT, _Traits>::int_type |
725dc051 BK |
94 | basic_streambuf<_CharT, _Traits>:: |
95 | sputc(char_type __c) | |
96 | { | |
97 | int_type __ret; | |
0b176c1a | 98 | if (_M_out_cur < _M_out_end) |
725dc051 BK |
99 | { |
100 | *_M_out_cur = __c; | |
aa438e8f | 101 | _M_move_out_cur(1); |
725dc051 BK |
102 | __ret = traits_type::to_int_type(__c); |
103 | } | |
104 | else | |
105 | __ret = this->overflow(traits_type::to_int_type(__c)); | |
106 | return __ret; | |
107 | } | |
108 | ||
109 | template<typename _CharT, typename _Traits> | |
110 | streamsize | |
111 | basic_streambuf<_CharT, _Traits>:: | |
112 | xsgetn(char_type* __s, streamsize __n) | |
113 | { | |
725dc051 | 114 | streamsize __ret = 0; |
13187a45 | 115 | while (__ret < __n) |
725dc051 | 116 | { |
13187a45 BK |
117 | size_t __buf_len = _M_in_end - _M_in_cur; |
118 | if (__buf_len > 0) | |
725dc051 | 119 | { |
13187a45 | 120 | size_t __remaining = __n - __ret; |
4977bab6 | 121 | size_t __len = std::min(__buf_len, __remaining); |
13187a45 BK |
122 | traits_type::copy(__s, _M_in_cur, __len); |
123 | __ret += __len; | |
124 | __s += __len; | |
aa438e8f | 125 | _M_move_in_cur(__len); |
13187a45 BK |
126 | } |
127 | ||
128 | if (__ret < __n) | |
129 | { | |
130 | int_type __c = this->uflow(); | |
49433044 | 131 | if (!traits_type::eq_int_type(__c, traits_type::eof())) |
5fa9abc3 BK |
132 | { |
133 | traits_type::assign(*__s++, traits_type::to_char_type(__c)); | |
134 | ++__ret; | |
135 | } | |
136 | else | |
13187a45 | 137 | break; |
725dc051 BK |
138 | } |
139 | } | |
140 | return __ret; | |
141 | } | |
142 | ||
725dc051 BK |
143 | template<typename _CharT, typename _Traits> |
144 | streamsize | |
145 | basic_streambuf<_CharT, _Traits>:: | |
146 | xsputn(const char_type* __s, streamsize __n) | |
147 | { | |
148 | streamsize __ret = 0; | |
13187a45 | 149 | while (__ret < __n) |
725dc051 | 150 | { |
eb98bd16 | 151 | off_type __buf_len = _M_out_end - _M_out_cur; |
13187a45 | 152 | if (__buf_len > 0) |
725dc051 | 153 | { |
13187a45 | 154 | off_type __remaining = __n - __ret; |
4977bab6 | 155 | off_type __len = std::min(__buf_len, __remaining); |
13187a45 BK |
156 | traits_type::copy(_M_out_cur, __s, __len); |
157 | __ret += __len; | |
158 | __s += __len; | |
aa438e8f | 159 | _M_move_out_cur(__len); |
13187a45 BK |
160 | } |
161 | ||
162 | if (__ret < __n) | |
163 | { | |
5fa9abc3 | 164 | int_type __c = this->overflow(traits_type::to_int_type(*__s)); |
49433044 | 165 | if (!traits_type::eq_int_type(__c, traits_type::eof())) |
5fa9abc3 BK |
166 | { |
167 | ++__ret; | |
168 | ++__s; | |
169 | } | |
170 | else | |
13187a45 | 171 | break; |
725dc051 BK |
172 | } |
173 | } | |
174 | return __ret; | |
175 | } | |
176 | ||
725dc051 BK |
177 | // Conceivably, this could be used to implement buffer-to-buffer |
178 | // copies, if this was ever desired in an un-ambiguous way by the | |
179 | // standard. If so, then checks for __ios being zero would be | |
180 | // necessary. | |
181 | template<typename _CharT, typename _Traits> | |
182 | streamsize | |
72ed2836 BK |
183 | __copy_streambufs(basic_ios<_CharT, _Traits>& __ios, |
184 | basic_streambuf<_CharT, _Traits>* __sbin, | |
185 | basic_streambuf<_CharT, _Traits>* __sbout) | |
186 | { | |
725dc051 | 187 | typedef typename _Traits::int_type int_type; |
eb98bd16 | 188 | typedef typename _Traits::off_type off_type; |
725dc051 BK |
189 | |
190 | streamsize __ret = 0; | |
6cf5465d BK |
191 | try |
192 | { | |
ac5b7972 | 193 | for (;;) |
3279e88a | 194 | { |
ac5b7972 PC |
195 | streamsize __xtrct; |
196 | const off_type __avail = __sbin->_M_in_end | |
197 | - __sbin->_M_in_cur; | |
198 | if (__avail) | |
6cf5465d | 199 | { |
ac5b7972 | 200 | __xtrct = __sbout->sputn(__sbin->_M_in_cur, __avail); |
3279e88a | 201 | __ret += __xtrct; |
aa438e8f | 202 | __sbin->_M_move_in_cur(__xtrct); |
ac5b7972 | 203 | if (__xtrct != __avail) |
6cf5465d | 204 | break; |
6cf5465d | 205 | } |
3279e88a JL |
206 | else |
207 | { | |
feecf614 | 208 | streamsize __charsread; |
44b84cc9 PC |
209 | const off_type __size = __sbout->_M_out_end |
210 | - __sbout->_M_out_cur; | |
211 | if (__size) | |
feecf614 PC |
212 | { |
213 | _CharT* __buf = | |
214 | static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) | |
215 | * __size)); | |
216 | // Since the next sputn cannot fail sgetn can be | |
217 | // safely used. | |
218 | __charsread = __sbin->sgetn(__buf, __size); | |
219 | __xtrct = __sbout->sputn(__buf, __charsread); | |
220 | } | |
221 | else | |
222 | { | |
223 | __xtrct = __charsread = 0; | |
44b84cc9 PC |
224 | const int_type __c = __sbin->sgetc(); |
225 | if (!_Traits::eq_int_type(__c, _Traits::eof())) | |
feecf614 PC |
226 | { |
227 | ++__charsread; | |
44b84cc9 | 228 | if (_Traits::eq_int_type(__sbout->overflow(__c), |
feecf614 PC |
229 | _Traits::eof())) |
230 | break; | |
231 | ++__xtrct; | |
44b84cc9 | 232 | __sbin->sbumpc(); |
feecf614 PC |
233 | } |
234 | } | |
3279e88a JL |
235 | __ret += __xtrct; |
236 | if (__xtrct != __charsread) | |
237 | break; | |
238 | } | |
239 | if (_Traits::eq_int_type(__sbin->sgetc(), _Traits::eof())) | |
240 | break; | |
3279e88a | 241 | } |
6cf5465d BK |
242 | } |
243 | catch(exception& __fail) | |
244 | { | |
245 | __ios.setstate(ios_base::failbit); | |
246 | if ((__ios.exceptions() & ios_base::failbit) != 0) | |
247 | __throw_exception_again; | |
248 | } | |
725dc051 BK |
249 | return __ret; |
250 | } | |
a32e3c09 BK |
251 | |
252 | // Inhibit implicit instantiations for required instantiations, | |
253 | // which are defined via explicit instantiations elsewhere. | |
254 | // NB: This syntax is a GNU extension. | |
1bc8b0ad | 255 | #if _GLIBCPP_EXTERN_TEMPLATE |
a32e3c09 BK |
256 | extern template class basic_streambuf<char>; |
257 | extern template | |
258 | streamsize | |
259 | __copy_streambufs(basic_ios<char>&, basic_streambuf<char>*, | |
260 | basic_streambuf<char>*); | |
261 | ||
5112ae3a | 262 | #ifdef _GLIBCPP_USE_WCHAR_T |
a32e3c09 BK |
263 | extern template class basic_streambuf<wchar_t>; |
264 | extern template | |
265 | streamsize | |
266 | __copy_streambufs(basic_ios<wchar_t>&, basic_streambuf<wchar_t>*, | |
267 | basic_streambuf<wchar_t>*); | |
5112ae3a | 268 | #endif |
1bc8b0ad | 269 | #endif |
725dc051 BK |
270 | } // namespace std |
271 | ||
6f48900c | 272 | #endif |