1 // String based streams -*- C++ -*-
2 
3 // Copyright (C) 1997, 1998, 1999, 2002 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 2, 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 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING.  If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 // USA.
20 
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction.  Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License.  This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
29 
30 //
31 // ISO C++ 14882: 27.7  String-based streams
32 //
33 
34 /** @file sstream
35  *  This is a Standard C++ Library header.  You should @c #include this header
36  *  in your programs, rather than any of the "st[dl]_*.h" implementation files.
37  */
38 
39 #ifndef _CPP_SSTREAM
40 #define _CPP_SSTREAM	1
41 
42 #pragma GCC system_header
43 
44 #include <istream>
45 #include <ostream>
46 
47 namespace std
48 {
49   template<typename _CharT, typename _Traits, typename _Alloc>
50     class basic_stringbuf : public basic_streambuf<_CharT, _Traits>
51     {
52     public:
53       // Types:
54       typedef _CharT 					char_type;
55       typedef _Traits 					traits_type;
56 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
57 // 251. basic_stringbuf missing allocator_type
58       typedef _Alloc				       	allocator_type;
59 #endif
60       typedef typename traits_type::int_type 		int_type;
61       typedef typename traits_type::pos_type 		pos_type;
62       typedef typename traits_type::off_type 		off_type;
63 
64       // Non-standard Types:
65       typedef basic_streambuf<char_type, traits_type>  	__streambuf_type;
66       typedef basic_string<char_type, _Traits, _Alloc> 	__string_type;
67       typedef typename __string_type::size_type		__size_type;
68 
69     protected:
70       // Data Members:
71       __string_type 		_M_string;
72 
73     public:
74       // Constructors:
75       explicit
76       basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out)
77       : __streambuf_type(), _M_string()
78       { _M_stringbuf_init(__mode); }
79 
80       explicit
81       basic_stringbuf(const __string_type& __str,
82 		      ios_base::openmode __mode = ios_base::in | ios_base::out)
83       : __streambuf_type(), _M_string(__str.data(), __str.size())
84       { _M_stringbuf_init(__mode); }
85 
86       // Get and set:
87       __string_type
88       str() const
89       {
90 	if (_M_mode & ios_base::out)
91 	  {
92 	    // This is the deal: _M_string.size() is a value that
93 	    // represents the size of the initial string that makes
94 	    // _M_string, and may not be the correct size of the
95 	    // current stringbuf internal buffer.
96 	    __size_type __len = _M_string.size();
97 	    if (_M_out_cur > _M_out_beg)
98 	      __len = max(__size_type(_M_out_end - _M_out_beg), __len);
99 	    return __string_type(_M_out_beg, _M_out_beg + __len);
100 	  }
101 	else
102 	  return _M_string;
103       }
104 
105       void
106       str(const __string_type& __s)
107       {
108 	// Cannot use _M_string = __s, since v3 strings are COW.
109 	_M_string.assign(__s.data(), __s.size());
110 	_M_stringbuf_init(_M_mode);
111       }
112 
113     protected:
114       // Common initialization code for both ctors goes here.
115       void
116       _M_stringbuf_init(ios_base::openmode __mode)
117       {
118 	// _M_buf_size is a convenient alias for "what the streambuf
119 	// thinks the allocated size of the string really is." This is
120 	// necessary as ostringstreams are implemented with the
121 	// streambufs having control of the allocation and
122 	// re-allocation of the internal string object, _M_string.
123 	_M_buf_size = _M_string.size();
124 
125 	// NB: Start ostringstream buffers at 512 bytes. This is an
126 	// experimental value (pronounced "arbitrary" in some of the
127 	// hipper english-speaking countries), and can be changed to
128 	// suit particular needs.
129 	_M_buf_size_opt = 512;
130 	_M_mode = __mode;
131 	if (_M_mode & (ios_base::ate | ios_base::app))
132 	  _M_really_sync(0, _M_buf_size);
133 	else
134 	  _M_really_sync(0, 0);
135       }
136 
137       // Overridden virtual functions:
138       virtual int_type
139       underflow()
140       {
141 	if (_M_in_cur && _M_in_cur < _M_in_end)
142 	  return traits_type::to_int_type(*gptr());
143 	else
144 	  return traits_type::eof();
145       }
146 
147       virtual int_type
148       pbackfail(int_type __c = traits_type::eof());
149 
150       virtual int_type
151       overflow(int_type __c = traits_type::eof());
152 
153       virtual __streambuf_type*
154       setbuf(char_type* __s, streamsize __n)
155       {
156 	if (__s && __n)
157 	  {
158 	    _M_string = __string_type(__s, __n);
159 	    _M_really_sync(0, 0);
160 	  }
161 	return this;
162       }
163 
164       virtual pos_type
165       seekoff(off_type __off, ios_base::seekdir __way,
166 	      ios_base::openmode __mode = ios_base::in | ios_base::out);
167 
168       virtual pos_type
169       seekpos(pos_type __sp,
170 	      ios_base::openmode __mode = ios_base::in | ios_base::out);
171 
172       // Internal function for correctly updating the internal buffer
173       // for a particular _M_string, due to initialization or
174       // re-sizing of an existing _M_string.
175       // Assumes: contents of _M_string and internal buffer match exactly.
176       // __i == _M_in_cur - _M_in_beg
177       // __o == _M_out_cur - _M_out_beg
178       virtual int
179       _M_really_sync(__size_type __i, __size_type __o)
180       {
181 	char_type* __base = const_cast<char_type*>(_M_string.data());
182 	bool __testin = _M_mode & ios_base::in;
183 	bool __testout = _M_mode & ios_base::out;
184 	__size_type __len = _M_string.size();
185 
186 	_M_buf = __base;
187 	if (__testin)
188 	    this->setg(__base, __base + __i, __base + __len);
189 	if (__testout)
190 	  {
191 	    this->setp(__base, __base + __len);
192 	    _M_out_cur += __o;
193 	  }
194 	return 0;
195       }
196     };
197 
198 
199   // 27.7.2  Template class basic_istringstream
200   template<typename _CharT, typename _Traits, typename _Alloc>
201     class basic_istringstream : public basic_istream<_CharT, _Traits>
202     {
203     public:
204       // Types:
205       typedef _CharT 					char_type;
206       typedef _Traits 					traits_type;
207 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
208 // 251. basic_stringbuf missing allocator_type
209       typedef _Alloc				       	allocator_type;
210 #endif
211       typedef typename traits_type::int_type 		int_type;
212       typedef typename traits_type::pos_type 		pos_type;
213       typedef typename traits_type::off_type 		off_type;
214 
215       // Non-standard types:
216       typedef basic_string<_CharT, _Traits, _Alloc> 	__string_type;
217       typedef basic_stringbuf<_CharT, _Traits, _Alloc> 	__stringbuf_type;
218       typedef basic_istream<char_type, traits_type>	__istream_type;
219 
220     private:
221       __stringbuf_type	_M_stringbuf;
222 
223     public:
224       // Constructors:
225       explicit
226       basic_istringstream(ios_base::openmode __mode = ios_base::in)
227       : __istream_type(NULL), _M_stringbuf(__mode | ios_base::in)
228       { this->init(&_M_stringbuf); }
229 
230       explicit
231       basic_istringstream(const __string_type& __str,
232 			  ios_base::openmode __mode = ios_base::in)
233       : __istream_type(NULL), _M_stringbuf(__str, __mode | ios_base::in)
234       { this->init(&_M_stringbuf); }
235 
236       ~basic_istringstream()
237       { }
238 
239       // Members:
240       __stringbuf_type*
241       rdbuf() const
242       { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
243 
244       __string_type
245       str() const
246       { return _M_stringbuf.str(); }
247 
248       void
249       str(const __string_type& __s)
250       { _M_stringbuf.str(__s); }
251     };
252 
253 
254   // 27.7.3  Template class basic_ostringstream
255   template <typename _CharT, typename _Traits, typename _Alloc>
256     class basic_ostringstream : public basic_ostream<_CharT, _Traits>
257     {
258     public:
259       // Types:
260       typedef _CharT 					char_type;
261       typedef _Traits 					traits_type;
262 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
263 // 251. basic_stringbuf missing allocator_type
264       typedef _Alloc				       	allocator_type;
265 #endif
266       typedef typename traits_type::int_type 		int_type;
267       typedef typename traits_type::pos_type 		pos_type;
268       typedef typename traits_type::off_type 		off_type;
269 
270       // Non-standard types:
271       typedef basic_string<_CharT, _Traits, _Alloc> 	__string_type;
272       typedef basic_stringbuf<_CharT, _Traits, _Alloc> 	__stringbuf_type;
273       typedef basic_ostream<char_type, traits_type>	__ostream_type;
274 
275     private:
276       __stringbuf_type	_M_stringbuf;
277 
278     public:
279      // Constructors/destructor:
280       explicit
281       basic_ostringstream(ios_base::openmode __mode = ios_base::out)
282       : __ostream_type(NULL), _M_stringbuf(__mode | ios_base::out)
283       { this->init(&_M_stringbuf); }
284 
285       explicit
286       basic_ostringstream(const __string_type& __str,
287 			  ios_base::openmode __mode = ios_base::out)
288       : __ostream_type(NULL), _M_stringbuf(__str, __mode | ios_base::out)
289       { this->init(&_M_stringbuf); }
290 
291       ~basic_ostringstream()
292       { }
293 
294       // Members:
295       __stringbuf_type*
296       rdbuf() const
297       { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
298 
299       __string_type
300       str() const
301       { return _M_stringbuf.str(); }
302 
303       void
304       str(const __string_type& __s)
305       { _M_stringbuf.str(__s); }
306     };
307 
308 
309   // 27.7.4  Template class basic_stringstream
310   template <typename _CharT, typename _Traits, typename _Alloc>
311     class basic_stringstream : public basic_iostream<_CharT, _Traits>
312     {
313     public:
314       // Types:
315       typedef _CharT 					char_type;
316       typedef _Traits 					traits_type;
317 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
318 // 251. basic_stringbuf missing allocator_type
319       typedef _Alloc				       	allocator_type;
320 #endif
321       typedef typename traits_type::int_type 		int_type;
322       typedef typename traits_type::pos_type 		pos_type;
323       typedef typename traits_type::off_type 		off_type;
324 
325       // Non-standard Types:
326       typedef basic_string<_CharT, _Traits, _Alloc> 	__string_type;
327       typedef basic_stringbuf<_CharT, _Traits, _Alloc> 	__stringbuf_type;
328       typedef basic_iostream<char_type, traits_type>	__iostream_type;
329 
330     private:
331       __stringbuf_type	_M_stringbuf;
332 
333     public:
334       // Constructors/destructors
335       explicit
336       basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in)
337       : __iostream_type(NULL), _M_stringbuf(__m)
338       { this->init(&_M_stringbuf); }
339 
340       explicit
341       basic_stringstream(const __string_type& __str,
342 			 ios_base::openmode __m = ios_base::out | ios_base::in)
343       : __iostream_type(NULL), _M_stringbuf(__str, __m)
344       { this->init(&_M_stringbuf); }
345 
346       ~basic_stringstream()
347       { }
348 
349       // Members:
350       __stringbuf_type*
351       rdbuf() const
352       { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
353 
354       __string_type
355       str() const
356       { return _M_stringbuf.str(); }
357 
358       void
359       str(const __string_type& __s)
360       { _M_stringbuf.str(__s); }
361     };
362 } // namespace std
363 
364 #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
365 # define export
366 #endif
367 #ifdef  _GLIBCPP_FULLY_COMPLIANT_HEADERS
368 # include <bits/sstream.tcc>
369 #endif
370 
371 #endif
372