1 : // String based streams -*- C++ -*-
2 :
3 : // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4 : // 2006, 2007, 2009
5 : // Free Software Foundation, Inc.
6 : //
7 : // This file is part of the GNU ISO C++ Library. This library is free
8 : // software; you can redistribute it and/or modify it under the
9 : // terms of the GNU General Public License as published by the
10 : // Free Software Foundation; either version 3, or (at your option)
11 : // any later version.
12 :
13 : // This library is distributed in the hope that it will be useful,
14 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : // GNU General Public License for more details.
17 :
18 : // Under Section 7 of GPL version 3, you are granted additional
19 : // permissions described in the GCC Runtime Library Exception, version
20 : // 3.1, as published by the Free Software Foundation.
21 :
22 : // You should have received a copy of the GNU General Public License and
23 : // a copy of the GCC Runtime Library Exception along with this program;
24 : // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 : // <http://www.gnu.org/licenses/>.
26 :
27 : /** @file sstream.tcc
28 : * This is an internal header file, included by other library headers.
29 : * You should not attempt to use it directly.
30 : */
31 :
32 : //
33 : // ISO C++ 14882: 27.7 String-based streams
34 : //
35 :
36 : #ifndef _SSTREAM_TCC
37 : #define _SSTREAM_TCC 1
38 :
39 : #pragma GCC system_header
40 :
41 : _GLIBCXX_BEGIN_NAMESPACE(std)
42 :
43 : template <class _CharT, class _Traits, class _Alloc>
44 : typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type
45 0 : basic_stringbuf<_CharT, _Traits, _Alloc>::
46 : pbackfail(int_type __c)
47 : {
48 0 : int_type __ret = traits_type::eof();
49 0 : if (this->eback() < this->gptr())
50 : {
51 : // Try to put back __c into input sequence in one of three ways.
52 : // Order these tests done in is unspecified by the standard.
53 0 : const bool __testeof = traits_type::eq_int_type(__c, __ret);
54 0 : if (!__testeof)
55 : {
56 : const bool __testeq = traits_type::eq(traits_type::
57 : to_char_type(__c),
58 0 : this->gptr()[-1]);
59 0 : const bool __testout = this->_M_mode & ios_base::out;
60 0 : if (__testeq || __testout)
61 : {
62 0 : this->gbump(-1);
63 0 : if (!__testeq)
64 0 : *this->gptr() = traits_type::to_char_type(__c);
65 0 : __ret = __c;
66 : }
67 : }
68 : else
69 : {
70 0 : this->gbump(-1);
71 0 : __ret = traits_type::not_eof(__c);
72 : }
73 : }
74 0 : return __ret;
75 : }
76 :
77 : template <class _CharT, class _Traits, class _Alloc>
78 : typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type
79 0 : basic_stringbuf<_CharT, _Traits, _Alloc>::
80 : overflow(int_type __c)
81 : {
82 0 : const bool __testout = this->_M_mode & ios_base::out;
83 0 : if (__builtin_expect(!__testout, false))
84 0 : return traits_type::eof();
85 :
86 0 : const bool __testeof = traits_type::eq_int_type(__c, traits_type::eof());
87 0 : if (__builtin_expect(__testeof, false))
88 0 : return traits_type::not_eof(__c);
89 :
90 0 : const __size_type __capacity = _M_string.capacity();
91 0 : const __size_type __max_size = _M_string.max_size();
92 0 : const bool __testput = this->pptr() < this->epptr();
93 0 : if (__builtin_expect(!__testput && __capacity == __max_size, false))
94 0 : return traits_type::eof();
95 :
96 : // Try to append __c into output sequence in one of two ways.
97 : // Order these tests done in is unspecified by the standard.
98 0 : const char_type __conv = traits_type::to_char_type(__c);
99 0 : if (!__testput)
100 : {
101 : // NB: Start ostringstream buffers at 512 chars. This is an
102 : // experimental value (pronounced "arbitrary" in some of the
103 : // hipper English-speaking countries), and can be changed to
104 : // suit particular needs.
105 : //
106 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
107 : // 169. Bad efficiency of overflow() mandated
108 : // 432. stringbuf::overflow() makes only one write position
109 : // available
110 : const __size_type __opt_len = std::max(__size_type(2 * __capacity),
111 0 : __size_type(512));
112 0 : const __size_type __len = std::min(__opt_len, __max_size);
113 0 : __string_type __tmp;
114 0 : __tmp.reserve(__len);
115 0 : if (this->pbase())
116 0 : __tmp.assign(this->pbase(), this->epptr() - this->pbase());
117 0 : __tmp.push_back(__conv);
118 0 : _M_string.swap(__tmp);
119 0 : _M_sync(const_cast<char_type*>(_M_string.data()),
120 : this->gptr() - this->eback(), this->pptr() - this->pbase());
121 : }
122 : else
123 0 : *this->pptr() = __conv;
124 0 : this->pbump(1);
125 0 : return __c;
126 : }
127 :
128 : template <class _CharT, class _Traits, class _Alloc>
129 : typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type
130 0 : basic_stringbuf<_CharT, _Traits, _Alloc>::
131 : underflow()
132 : {
133 0 : int_type __ret = traits_type::eof();
134 0 : const bool __testin = this->_M_mode & ios_base::in;
135 0 : if (__testin)
136 : {
137 : // Update egptr() to match the actual string end.
138 0 : _M_update_egptr();
139 :
140 0 : if (this->gptr() < this->egptr())
141 0 : __ret = traits_type::to_int_type(*this->gptr());
142 : }
143 0 : return __ret;
144 : }
145 :
146 : template <class _CharT, class _Traits, class _Alloc>
147 : typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type
148 0 : basic_stringbuf<_CharT, _Traits, _Alloc>::
149 : seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode)
150 : {
151 0 : pos_type __ret = pos_type(off_type(-1));
152 0 : bool __testin = (ios_base::in & this->_M_mode & __mode) != 0;
153 0 : bool __testout = (ios_base::out & this->_M_mode & __mode) != 0;
154 0 : const bool __testboth = __testin && __testout && __way != ios_base::cur;
155 0 : __testin &= !(__mode & ios_base::out);
156 0 : __testout &= !(__mode & ios_base::in);
157 :
158 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
159 : // 453. basic_stringbuf::seekoff need not always fail for an empty stream.
160 0 : const char_type* __beg = __testin ? this->eback() : this->pbase();
161 0 : if ((__beg || !__off) && (__testin || __testout || __testboth))
162 : {
163 0 : _M_update_egptr();
164 :
165 0 : off_type __newoffi = __off;
166 0 : off_type __newoffo = __newoffi;
167 0 : if (__way == ios_base::cur)
168 : {
169 0 : __newoffi += this->gptr() - __beg;
170 0 : __newoffo += this->pptr() - __beg;
171 : }
172 0 : else if (__way == ios_base::end)
173 0 : __newoffo = __newoffi += this->egptr() - __beg;
174 :
175 0 : if ((__testin || __testboth)
176 : && __newoffi >= 0
177 : && this->egptr() - __beg >= __newoffi)
178 : {
179 0 : this->gbump((__beg + __newoffi) - this->gptr());
180 0 : __ret = pos_type(__newoffi);
181 : }
182 0 : if ((__testout || __testboth)
183 : && __newoffo >= 0
184 : && this->egptr() - __beg >= __newoffo)
185 : {
186 0 : this->pbump((__beg + __newoffo) - this->pptr());
187 0 : __ret = pos_type(__newoffo);
188 : }
189 : }
190 : return __ret;
191 : }
192 :
193 : template <class _CharT, class _Traits, class _Alloc>
194 : typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type
195 0 : basic_stringbuf<_CharT, _Traits, _Alloc>::
196 : seekpos(pos_type __sp, ios_base::openmode __mode)
197 : {
198 0 : pos_type __ret = pos_type(off_type(-1));
199 0 : const bool __testin = (ios_base::in & this->_M_mode & __mode) != 0;
200 0 : const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0;
201 :
202 0 : const char_type* __beg = __testin ? this->eback() : this->pbase();
203 0 : if ((__beg || !off_type(__sp)) && (__testin || __testout))
204 : {
205 0 : _M_update_egptr();
206 :
207 0 : const off_type __pos(__sp);
208 : const bool __testpos = (0 <= __pos
209 0 : && __pos <= this->egptr() - __beg);
210 0 : if (__testpos)
211 : {
212 0 : if (__testin)
213 0 : this->gbump((__beg + __pos) - this->gptr());
214 0 : if (__testout)
215 0 : this->pbump((__beg + __pos) - this->pptr());
216 0 : __ret = __sp;
217 : }
218 : }
219 : return __ret;
220 : }
221 :
222 : template <class _CharT, class _Traits, class _Alloc>
223 : void
224 0 : basic_stringbuf<_CharT, _Traits, _Alloc>::
225 : _M_sync(char_type* __base, __size_type __i, __size_type __o)
226 : {
227 0 : const bool __testin = _M_mode & ios_base::in;
228 0 : const bool __testout = _M_mode & ios_base::out;
229 0 : char_type* __endg = __base + _M_string.size();
230 0 : char_type* __endp = __base + _M_string.capacity();
231 :
232 0 : if (__base != _M_string.data())
233 : {
234 : // setbuf: __i == size of buffer area (_M_string.size() == 0).
235 0 : __endg += __i;
236 0 : __i = 0;
237 0 : __endp = __endg;
238 : }
239 :
240 0 : if (__testin)
241 0 : this->setg(__base, __base + __i, __endg);
242 0 : if (__testout)
243 : {
244 0 : this->setp(__base, __endp);
245 0 : this->pbump(__o);
246 : // egptr() always tracks the string end. When !__testin,
247 : // for the correct functioning of the streambuf inlines
248 : // the other get area pointers are identical.
249 0 : if (!__testin)
250 0 : this->setg(__endg, __endg, __endg);
251 : }
252 0 : }
253 :
254 : // Inhibit implicit instantiations for required instantiations,
255 : // which are defined via explicit instantiations elsewhere.
256 : // NB: This syntax is a GNU extension.
257 : #if _GLIBCXX_EXTERN_TEMPLATE
258 : extern template class basic_stringbuf<char>;
259 : extern template class basic_istringstream<char>;
260 : extern template class basic_ostringstream<char>;
261 : extern template class basic_stringstream<char>;
262 :
263 : #ifdef _GLIBCXX_USE_WCHAR_T
264 : extern template class basic_stringbuf<wchar_t>;
265 : extern template class basic_istringstream<wchar_t>;
266 : extern template class basic_ostringstream<wchar_t>;
267 : extern template class basic_stringstream<wchar_t>;
268 : #endif
269 : #endif
270 :
271 : _GLIBCXX_END_NAMESPACE
272 :
273 : #endif
|