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