Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6554 serge 1
// String based streams -*- C++ -*-
2
 
3
// Copyright (C) 1997-2015 Free Software Foundation, Inc.
4
//
5
// This file is part of the GNU ISO C++ Library.  This library is free
6
// software; you can redistribute it and/or modify it under the
7
// terms of the GNU General Public License as published by the
8
// Free Software Foundation; either version 3, or (at your option)
9
// any later version.
10
 
11
// This library is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
// GNU General Public License for more details.
15
 
16
// Under Section 7 of GPL version 3, you are granted additional
17
// permissions described in the GCC Runtime Library Exception, version
18
// 3.1, as published by the Free Software Foundation.
19
 
20
// You should have received a copy of the GNU General Public License and
21
// a copy of the GCC Runtime Library Exception along with this program;
22
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23
// .
24
 
25
/** @file bits/sstream.tcc
26
 *  This is an internal header file, included by other library headers.
27
 *  Do not attempt to use it directly. @headername{sstream}
28
 */
29
 
30
//
31
// ISO C++ 14882: 27.7  String-based streams
32
//
33
 
34
#ifndef _SSTREAM_TCC
35
#define _SSTREAM_TCC 1
36
 
37
#pragma GCC system_header
38
 
39
namespace std _GLIBCXX_VISIBILITY(default)
40
{
41
_GLIBCXX_BEGIN_NAMESPACE_VERSION
42
 
43
  template 
44
    typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type
45
    basic_stringbuf<_CharT, _Traits, _Alloc>::
46
    pbackfail(int_type __c)
47
    {
48
      int_type __ret = traits_type::eof();
49
      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
	  const bool __testeof = traits_type::eq_int_type(__c, __ret);
54
	  if (!__testeof)
55
	    {
56
	      const bool __testeq = traits_type::eq(traits_type::
57
						    to_char_type(__c),
58
						    this->gptr()[-1]);
59
	      const bool __testout = this->_M_mode & ios_base::out;
60
	      if (__testeq || __testout)
61
		{
62
		  this->gbump(-1);
63
		  if (!__testeq)
64
		    *this->gptr() = traits_type::to_char_type(__c);
65
		  __ret = __c;
66
		}
67
	    }
68
	  else
69
	    {
70
	      this->gbump(-1);
71
	      __ret = traits_type::not_eof(__c);
72
	    }
73
	}
74
      return __ret;
75
    }
76
 
77
  template 
78
    typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type
79
    basic_stringbuf<_CharT, _Traits, _Alloc>::
80
    overflow(int_type __c)
81
    {
82
      const bool __testout = this->_M_mode & ios_base::out;
83
      if (__builtin_expect(!__testout, false))
84
	return traits_type::eof();
85
 
86
      const bool __testeof = traits_type::eq_int_type(__c, traits_type::eof());
87
      if (__builtin_expect(__testeof, false))
88
	return traits_type::not_eof(__c);
89
 
90
      const __size_type __capacity = _M_string.capacity();
91
      const __size_type __max_size = _M_string.max_size();
92
      const bool __testput = this->pptr() < this->epptr();
93
      if (__builtin_expect(!__testput && __capacity == __max_size, false))
94
	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
      const char_type __conv = traits_type::to_char_type(__c);
99
      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
						 __size_type(512));
112
	  const __size_type __len = std::min(__opt_len, __max_size);
113
	  __string_type __tmp;
114
	  __tmp.reserve(__len);
115
	  if (this->pbase())
116
	    __tmp.assign(this->pbase(), this->epptr() - this->pbase());
117
	  __tmp.push_back(__conv);
118
	  _M_string.swap(__tmp);
119
	  _M_sync(const_cast(_M_string.data()),
120
		  this->gptr() - this->eback(), this->pptr() - this->pbase());
121
	}
122
      else
123
	*this->pptr() = __conv;
124
      this->pbump(1);
125
      return __c;
126
    }
127
 
128
  template 
129
    typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type
130
    basic_stringbuf<_CharT, _Traits, _Alloc>::
131
    underflow()
132
    {
133
      int_type __ret = traits_type::eof();
134
      const bool __testin = this->_M_mode & ios_base::in;
135
      if (__testin)
136
	{
137
	  // Update egptr() to match the actual string end.
138
	  _M_update_egptr();
139
 
140
	  if (this->gptr() < this->egptr())
141
	    __ret = traits_type::to_int_type(*this->gptr());
142
	}
143
      return __ret;
144
    }
145
 
146
  template 
147
    typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type
148
    basic_stringbuf<_CharT, _Traits, _Alloc>::
149
    seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode)
150
    {
151
      pos_type __ret =  pos_type(off_type(-1));
152
      bool __testin = (ios_base::in & this->_M_mode & __mode) != 0;
153
      bool __testout = (ios_base::out & this->_M_mode & __mode) != 0;
154
      const bool __testboth = __testin && __testout && __way != ios_base::cur;
155
      __testin &= !(__mode & ios_base::out);
156
      __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
      const char_type* __beg = __testin ? this->eback() : this->pbase();
161
      if ((__beg || !__off) && (__testin || __testout || __testboth))
162
	{
163
	  _M_update_egptr();
164
 
165
	  off_type __newoffi = __off;
166
	  off_type __newoffo = __newoffi;
167
	  if (__way == ios_base::cur)
168
	    {
169
	      __newoffi += this->gptr() - __beg;
170
	      __newoffo += this->pptr() - __beg;
171
	    }
172
	  else if (__way == ios_base::end)
173
	    __newoffo = __newoffi += this->egptr() - __beg;
174
 
175
	  if ((__testin || __testboth)
176
	      && __newoffi >= 0
177
	      && this->egptr() - __beg >= __newoffi)
178
	    {
179
	      this->setg(this->eback(), this->eback() + __newoffi,
180
			 this->egptr());
181
	      __ret = pos_type(__newoffi);
182
	    }
183
	  if ((__testout || __testboth)
184
	      && __newoffo >= 0
185
	      && this->egptr() - __beg >= __newoffo)
186
	    {
187
	      _M_pbump(this->pbase(), this->epptr(), __newoffo);
188
	      __ret = pos_type(__newoffo);
189
	    }
190
	}
191
      return __ret;
192
    }
193
 
194
  template 
195
    typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type
196
    basic_stringbuf<_CharT, _Traits, _Alloc>::
197
    seekpos(pos_type __sp, ios_base::openmode __mode)
198
    {
199
      pos_type __ret =  pos_type(off_type(-1));
200
      const bool __testin = (ios_base::in & this->_M_mode & __mode) != 0;
201
      const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0;
202
 
203
      const char_type* __beg = __testin ? this->eback() : this->pbase();
204
      if ((__beg || !off_type(__sp)) && (__testin || __testout))
205
	{
206
	  _M_update_egptr();
207
 
208
	  const off_type __pos(__sp);
209
	  const bool __testpos = (0 <= __pos
210
				  && __pos <= this->egptr() - __beg);
211
	  if (__testpos)
212
	    {
213
	      if (__testin)
214
		this->setg(this->eback(), this->eback() + __pos,
215
			   this->egptr());
216
	      if (__testout)
217
		_M_pbump(this->pbase(), this->epptr(), __pos);
218
	      __ret = __sp;
219
	    }
220
	}
221
      return __ret;
222
    }
223
 
224
  template 
225
    void
226
    basic_stringbuf<_CharT, _Traits, _Alloc>::
227
    _M_sync(char_type* __base, __size_type __i, __size_type __o)
228
    {
229
      const bool __testin = _M_mode & ios_base::in;
230
      const bool __testout = _M_mode & ios_base::out;
231
      char_type* __endg = __base + _M_string.size();
232
      char_type* __endp = __base + _M_string.capacity();
233
 
234
      if (__base != _M_string.data())
235
	{
236
	  // setbuf: __i == size of buffer area (_M_string.size() == 0).
237
	  __endg += __i;
238
	  __i = 0;
239
	  __endp = __endg;
240
	}
241
 
242
      if (__testin)
243
	this->setg(__base, __base + __i, __endg);
244
      if (__testout)
245
	{
246
	  _M_pbump(__base, __endp, __o);
247
	  // egptr() always tracks the string end.  When !__testin,
248
	  // for the correct functioning of the streambuf inlines
249
	  // the other get area pointers are identical.
250
	  if (!__testin)
251
	    this->setg(__endg, __endg, __endg);
252
	}
253
    }
254
 
255
  template 
256
    void
257
    basic_stringbuf<_CharT, _Traits, _Alloc>::
258
    _M_pbump(char_type* __pbeg, char_type* __pend, off_type __off)
259
    {
260
      this->setp(__pbeg, __pend);
261
      while (__off > __gnu_cxx::__numeric_traits::__max)
262
	{
263
	  this->pbump(__gnu_cxx::__numeric_traits::__max);
264
	  __off -= __gnu_cxx::__numeric_traits::__max;
265
	}
266
      this->pbump(__off);
267
    }
268
 
269
  // Inhibit implicit instantiations for required instantiations,
270
  // which are defined via explicit instantiations elsewhere.
271
#if _GLIBCXX_EXTERN_TEMPLATE
272
  extern template class basic_stringbuf;
273
  extern template class basic_istringstream;
274
  extern template class basic_ostringstream;
275
  extern template class basic_stringstream;
276
 
277
#ifdef _GLIBCXX_USE_WCHAR_T
278
  extern template class basic_stringbuf;
279
  extern template class basic_istringstream;
280
  extern template class basic_ostringstream;
281
  extern template class basic_stringstream;
282
#endif
283
#endif
284
 
285
_GLIBCXX_END_NAMESPACE_VERSION
286
} // namespace std
287
 
288
#endif