xref: /openbsd-src/gnu/lib/libstdc++/libstdc++/include/std/std_sstream.h (revision 03a78d155d6fff5698289342b62759a75b20d130)
1 // String based streams -*- C++ -*-
2 
3 // Copyright (C) 1997, 1998, 1999, 2002, 2003 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   // [27.7.1] template class basic_stringbuf
50   /**
51    *  @brief  The actual work of input and output (for std::string).
52    *
53    *  This class associates either or both of its input and output sequences
54    *  with a sequence of characters, which can be initialized from, or made
55    *  available as, a @c std::basic_string.  (Paraphrased from [27.7.1]/1.)
56    *
57    *  For this class, open modes (of type @c ios_base::openmode) have
58    *  @c in set if the input sequence can be read, and @c out set if the
59    *  output sequence can be written.
60   */
61   template<typename _CharT, typename _Traits, typename _Alloc>
62     class basic_stringbuf : public basic_streambuf<_CharT, _Traits>
63     {
64     public:
65       // Types:
66       typedef _CharT 					char_type;
67       typedef _Traits 					traits_type;
68 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
69 // 251. basic_stringbuf missing allocator_type
70       typedef _Alloc				       	allocator_type;
71 #endif
72       typedef typename traits_type::int_type 		int_type;
73       typedef typename traits_type::pos_type 		pos_type;
74       typedef typename traits_type::off_type 		off_type;
75 
76       //@{
77       /**
78        *  @if maint
79        *  @doctodo
80        *  @endif
81       */
82       typedef basic_streambuf<char_type, traits_type>  	__streambuf_type;
83       typedef basic_string<char_type, _Traits, _Alloc> 	__string_type;
84       typedef typename __string_type::size_type		__size_type;
85       //@}
86 
87     protected:
88       // Data Members:
89       /**
90        *  @if maint
91        *  @doctodo
92        *  @endif
93       */
94       __string_type 		_M_string;
95 
96     public:
97       // Constructors:
98       /**
99        *  @brief  Starts with an empty string buffer.
100        *  @param  mode  Whether the buffer can read, or write, or both.
101        *
102        *  The default constructor initializes the parent class using its
103        *  own default ctor.
104       */
105       explicit
106       basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out)
__streambuf_type()107       : __streambuf_type(), _M_string()
108       { _M_stringbuf_init(__mode); }
109 
110       /**
111        *  @brief  Starts with an existing string buffer.
112        *  @param  str  A string to copy as a starting buffer.
113        *  @param  mode  Whether the buffer can read, or write, or both.
114        *
115        *  This constructor initializes the parent class using its
116        *  own default ctor.
117       */
118       explicit
119       basic_stringbuf(const __string_type& __str,
120 		      ios_base::openmode __mode = ios_base::in | ios_base::out)
__streambuf_type()121       : __streambuf_type(), _M_string(__str.data(), __str.size())
122       { _M_stringbuf_init(__mode); }
123 
124       // Get and set:
125       /**
126        *  @brief  Copying out the string buffer.
127        *  @return  A copy of one of the underlying sequences.
128        *
129        *  "If the buffer is only created in input mode, the underlying
130        *  character sequence is equal to the input sequence; otherwise, it
131        *  is equal to the output sequence." [27.7.1.2]/1
132       */
133       __string_type
str()134       str() const
135       {
136 	if (_M_mode & ios_base::out)
137 	  {
138 	    // This is the deal: _M_string.size() is a value that
139 	    // represents the size of the initial string that makes
140 	    // _M_string, and may not be the correct size of the
141 	    // current stringbuf internal buffer.
142 	    __size_type __len = _M_string.size();
143 	    if (_M_out_end > _M_out_beg)
144 	      __len = max(__size_type(_M_out_end - _M_out_beg), __len);
145 	    return __string_type(_M_out_beg, _M_out_beg + __len);
146 	  }
147 	else
148 	  return _M_string;
149       }
150 
151       /**
152        *  @brief  Setting a new buffer.
153        *  @param  s  The string to use as a new sequence.
154        *
155        *  Deallocates any previous stored sequence, then copies @a s to
156        *  use as a new one.
157       */
158       void
str(const __string_type & __s)159       str(const __string_type& __s)
160       {
161 	// Cannot use _M_string = __s, since v3 strings are COW.
162 	_M_string.assign(__s.data(), __s.size());
163 	_M_stringbuf_init(_M_mode);
164       }
165 
166     protected:
167       // Common initialization code for both ctors goes here.
168       /**
169        *  @if maint
170        *  @doctodo
171        *  @endif
172       */
173       void
_M_stringbuf_init(ios_base::openmode __mode)174       _M_stringbuf_init(ios_base::openmode __mode)
175       {
176 	// _M_buf_size is a convenient alias for "what the streambuf
177 	// thinks the allocated size of the string really is." This is
178 	// necessary as ostringstreams are implemented with the
179 	// streambufs having control of the allocation and
180 	// re-allocation of the internal string object, _M_string.
181 	_M_buf_size = _M_string.size();
182 
183 	// NB: Start ostringstream buffers at 512 bytes. This is an
184 	// experimental value (pronounced "arbitrary" in some of the
185 	// hipper english-speaking countries), and can be changed to
186 	// suit particular needs.
187 	_M_buf_size_opt = 512;
188 	_M_mode = __mode;
189 	if (_M_mode & (ios_base::ate | ios_base::app))
190 	  _M_really_sync(0, _M_buf_size);
191 	else
192 	  _M_really_sync(0, 0);
193       }
194 
195       // Overridden virtual functions:
196       // [documentation is inherited]
197       virtual int_type
underflow()198       underflow()
199       {
200 	if (_M_in_cur && _M_in_cur < _M_in_end)
201 	  return traits_type::to_int_type(*gptr());
202 	else
203 	  return traits_type::eof();
204       }
205 
206       // [documentation is inherited]
207       virtual int_type
208       pbackfail(int_type __c = traits_type::eof());
209 
210       // [documentation is inherited]
211       virtual int_type
212       overflow(int_type __c = traits_type::eof());
213 
214       /**
215        *  @brief  Manipulates the buffer.
216        *  @param  s  Pointer to a buffer area.
217        *  @param  n  Size of @a s.
218        *  @return  @c this
219        *
220        *  If no buffer has already been created, and both @a s and @a n are
221        *  non-zero, then @c s is used as a buffer; see
222        *  http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2
223        *  for more.
224       */
225       virtual __streambuf_type*
setbuf(char_type * __s,streamsize __n)226       setbuf(char_type* __s, streamsize __n)
227       {
228 	if (__s && __n)
229 	  {
230 	    _M_string = __string_type(__s, __n);
231 	    _M_really_sync(0, 0);
232 	  }
233 	return this;
234       }
235 
236       // [documentation is inherited]
237       virtual pos_type
238       seekoff(off_type __off, ios_base::seekdir __way,
239 	      ios_base::openmode __mode = ios_base::in | ios_base::out);
240 
241       // [documentation is inherited]
242       virtual pos_type
243       seekpos(pos_type __sp,
244 	      ios_base::openmode __mode = ios_base::in | ios_base::out);
245 
246       // Internal function for correctly updating the internal buffer
247       // for a particular _M_string, due to initialization or
248       // re-sizing of an existing _M_string.
249       // Assumes: contents of _M_string and internal buffer match exactly.
250       // __i == _M_in_cur - _M_in_beg
251       // __o == _M_out_cur - _M_out_beg
252       /**
253        *  @if maint
254        *  @doctodo
255        *  @endif
256       */
257       virtual int
_M_really_sync(__size_type __i,__size_type __o)258       _M_really_sync(__size_type __i, __size_type __o)
259       {
260 	char_type* __base = const_cast<char_type*>(_M_string.data());
261 	bool __testin = _M_mode & ios_base::in;
262 	bool __testout = _M_mode & ios_base::out;
263 	__size_type __len = _M_string.size();
264 
265 	_M_buf = __base;
266 	if (__testin)
267 	    this->setg(__base, __base + __i, __base + __len);
268 	if (__testout)
269 	  {
270 	    this->setp(__base, __base + __len);
271 	    _M_out_cur += __o;
272 	  }
273 	return 0;
274       }
275     };
276 
277 
278   // [27.7.2] Template class basic_istringstream
279   /**
280    *  @brief  Controlling input for std::string.
281    *
282    *  This class supports reading from objects of type std::basic_string,
283    *  using the inherited functions from std::basic_istream.  To control
284    *  the associated sequence, an instance of std::basic_stringbuf is used,
285    *  which this page refers to as @c sb.
286   */
287   template<typename _CharT, typename _Traits, typename _Alloc>
288     class basic_istringstream : public basic_istream<_CharT, _Traits>
289     {
290     public:
291       // Types:
292       typedef _CharT 					char_type;
293       typedef _Traits 					traits_type;
294 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
295 // 251. basic_stringbuf missing allocator_type
296       typedef _Alloc				       	allocator_type;
297 #endif
298       typedef typename traits_type::int_type 		int_type;
299       typedef typename traits_type::pos_type 		pos_type;
300       typedef typename traits_type::off_type 		off_type;
301 
302       // Non-standard types:
303       typedef basic_string<_CharT, _Traits, _Alloc> 	__string_type;
304       typedef basic_stringbuf<_CharT, _Traits, _Alloc> 	__stringbuf_type;
305       typedef basic_istream<char_type, traits_type>	__istream_type;
306 
307     private:
308       /**
309        *  @if maint
310        *  @doctodo
311        *  @endif
312       */
313       __stringbuf_type	_M_stringbuf;
314 
315     public:
316       // Constructors:
317       /**
318        *  @brief  Default constructor starts with an empty string buffer.
319        *  @param  mode  Whether the buffer can read, or write, or both.
320        *
321        *  @c ios_base::in is automatically included in @a mode.
322        *
323        *  Initializes @c sb using @c mode|in, and passes @c &sb to the base
324        *  class initializer.  Does not allocate any buffer.
325        *
326        *  @if maint
327        *  That's a lie.  We initialize the base class with NULL, because the
328        *  string class does its own memory management.
329        *  @endif
330       */
331       explicit
332       basic_istringstream(ios_base::openmode __mode = ios_base::in)
__istream_type(NULL)333       : __istream_type(NULL), _M_stringbuf(__mode | ios_base::in)
334       { this->init(&_M_stringbuf); }
335 
336       /**
337        *  @brief  Starts with an existing string buffer.
338        *  @param  str  A string to copy as a starting buffer.
339        *  @param  mode  Whether the buffer can read, or write, or both.
340        *
341        *  @c ios_base::in is automatically included in @a mode.
342        *
343        *  Initializes @c sb using @a str and @c mode|in, and passes @c &sb
344        *  to the base class initializer.
345        *
346        *  @if maint
347        *  That's a lie.  We initialize the base class with NULL, because the
348        *  string class does its own memory management.
349        *  @endif
350       */
351       explicit
352       basic_istringstream(const __string_type& __str,
353 			  ios_base::openmode __mode = ios_base::in)
__istream_type(NULL)354       : __istream_type(NULL), _M_stringbuf(__str, __mode | ios_base::in)
355       { this->init(&_M_stringbuf); }
356 
357       /**
358        *  @brief  The destructor does nothing.
359        *
360        *  The buffer is deallocated by the stringbuf object, not the
361        *  formatting stream.
362       */
~basic_istringstream()363       ~basic_istringstream()
364       { }
365 
366       // Members:
367       /**
368        *  @brief  Accessing the underlying buffer.
369        *  @return  The current basic_stringbuf buffer.
370        *
371        *  This hides both signatures of std::basic_ios::rdbuf().
372       */
373       __stringbuf_type*
rdbuf()374       rdbuf() const
375       { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
376 
377       /**
378        *  @brief  Copying out the string buffer.
379        *  @return  @c rdbuf()->str()
380       */
381       __string_type
str()382       str() const
383       { return _M_stringbuf.str(); }
384 
385       /**
386        *  @brief  Setting a new buffer.
387        *  @param  s  The string to use as a new sequence.
388        *
389        *  Calls @c rdbuf()->str(s).
390       */
391       void
str(const __string_type & __s)392       str(const __string_type& __s)
393       { _M_stringbuf.str(__s); }
394     };
395 
396 
397   // [27.7.3] Template class basic_ostringstream
398   /**
399    *  @brief  Controlling output for std::string.
400    *
401    *  This class supports writing to objects of type std::basic_string,
402    *  using the inherited functions from std::basic_ostream.  To control
403    *  the associated sequence, an instance of std::basic_stringbuf is used,
404    *  which this page refers to as @c sb.
405   */
406   template <typename _CharT, typename _Traits, typename _Alloc>
407     class basic_ostringstream : public basic_ostream<_CharT, _Traits>
408     {
409     public:
410       // Types:
411       typedef _CharT 					char_type;
412       typedef _Traits 					traits_type;
413 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
414 // 251. basic_stringbuf missing allocator_type
415       typedef _Alloc				       	allocator_type;
416 #endif
417       typedef typename traits_type::int_type 		int_type;
418       typedef typename traits_type::pos_type 		pos_type;
419       typedef typename traits_type::off_type 		off_type;
420 
421       // Non-standard types:
422       typedef basic_string<_CharT, _Traits, _Alloc> 	__string_type;
423       typedef basic_stringbuf<_CharT, _Traits, _Alloc> 	__stringbuf_type;
424       typedef basic_ostream<char_type, traits_type>	__ostream_type;
425 
426     private:
427       /**
428        *  @if maint
429        *  @doctodo
430        *  @endif
431       */
432       __stringbuf_type	_M_stringbuf;
433 
434     public:
435       // Constructors/destructor:
436       /**
437        *  @brief  Default constructor starts with an empty string buffer.
438        *  @param  mode  Whether the buffer can read, or write, or both.
439        *
440        *  @c ios_base::out is automatically included in @a mode.
441        *
442        *  Initializes @c sb using @c mode|out, and passes @c &sb to the base
443        *  class initializer.  Does not allocate any buffer.
444        *
445        *  @if maint
446        *  That's a lie.  We initialize the base class with NULL, because the
447        *  string class does its own memory management.
448        *  @endif
449       */
450       explicit
451       basic_ostringstream(ios_base::openmode __mode = ios_base::out)
__ostream_type(NULL)452       : __ostream_type(NULL), _M_stringbuf(__mode | ios_base::out)
453       { this->init(&_M_stringbuf); }
454 
455       /**
456        *  @brief  Starts with an existing string buffer.
457        *  @param  str  A string to copy as a starting buffer.
458        *  @param  mode  Whether the buffer can read, or write, or both.
459        *
460        *  @c ios_base::out is automatically included in @a mode.
461        *
462        *  Initializes @c sb using @a str and @c mode|out, and passes @c &sb
463        *  to the base class initializer.
464        *
465        *  @if maint
466        *  That's a lie.  We initialize the base class with NULL, because the
467        *  string class does its own memory management.
468        *  @endif
469       */
470       explicit
471       basic_ostringstream(const __string_type& __str,
472 			  ios_base::openmode __mode = ios_base::out)
__ostream_type(NULL)473       : __ostream_type(NULL), _M_stringbuf(__str, __mode | ios_base::out)
474       { this->init(&_M_stringbuf); }
475 
476       /**
477        *  @brief  The destructor does nothing.
478        *
479        *  The buffer is deallocated by the stringbuf object, not the
480        *  formatting stream.
481       */
~basic_ostringstream()482       ~basic_ostringstream()
483       { }
484 
485       // Members:
486       /**
487        *  @brief  Accessing the underlying buffer.
488        *  @return  The current basic_stringbuf buffer.
489        *
490        *  This hides both signatures of std::basic_ios::rdbuf().
491       */
492       __stringbuf_type*
rdbuf()493       rdbuf() const
494       { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
495 
496       /**
497        *  @brief  Copying out the string buffer.
498        *  @return  @c rdbuf()->str()
499       */
500       __string_type
str()501       str() const
502       { return _M_stringbuf.str(); }
503 
504       /**
505        *  @brief  Setting a new buffer.
506        *  @param  s  The string to use as a new sequence.
507        *
508        *  Calls @c rdbuf()->str(s).
509       */
510       void
str(const __string_type & __s)511       str(const __string_type& __s)
512       { _M_stringbuf.str(__s); }
513     };
514 
515 
516   // [27.7.4] Template class basic_stringstream
517   /**
518    *  @brief  Controlling input and output for std::string.
519    *
520    *  This class supports reading from and writing to objects of type
521    *  std::basic_string, using the inherited functions from
522    *  std::basic_iostream.  To control the associated sequence, an instance
523    *  of std::basic_stringbuf is used, which this page refers to as @c sb.
524   */
525   template <typename _CharT, typename _Traits, typename _Alloc>
526     class basic_stringstream : public basic_iostream<_CharT, _Traits>
527     {
528     public:
529       // Types:
530       typedef _CharT 					char_type;
531       typedef _Traits 					traits_type;
532 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
533 // 251. basic_stringbuf missing allocator_type
534       typedef _Alloc				       	allocator_type;
535 #endif
536       typedef typename traits_type::int_type 		int_type;
537       typedef typename traits_type::pos_type 		pos_type;
538       typedef typename traits_type::off_type 		off_type;
539 
540       // Non-standard Types:
541       typedef basic_string<_CharT, _Traits, _Alloc> 	__string_type;
542       typedef basic_stringbuf<_CharT, _Traits, _Alloc> 	__stringbuf_type;
543       typedef basic_iostream<char_type, traits_type>	__iostream_type;
544 
545     private:
546       /**
547        *  @if maint
548        *  @doctodo
549        *  @endif
550       */
551       __stringbuf_type	_M_stringbuf;
552 
553     public:
554       // Constructors/destructors
555       /**
556        *  @brief  Default constructor starts with an empty string buffer.
557        *  @param  mode  Whether the buffer can read, or write, or both.
558        *
559        *  Initializes @c sb using @c mode, and passes @c &sb to the base
560        *  class initializer.  Does not allocate any buffer.
561        *
562        *  @if maint
563        *  That's a lie.  We initialize the base class with NULL, because the
564        *  string class does its own memory management.
565        *  @endif
566       */
567       explicit
568       basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in)
__iostream_type(NULL)569       : __iostream_type(NULL), _M_stringbuf(__m)
570       { this->init(&_M_stringbuf); }
571 
572       /**
573        *  @brief  Starts with an existing string buffer.
574        *  @param  str  A string to copy as a starting buffer.
575        *  @param  mode  Whether the buffer can read, or write, or both.
576        *
577        *  Initializes @c sb using @a str and @c mode, and passes @c &sb
578        *  to the base class initializer.
579        *
580        *  @if maint
581        *  That's a lie.  We initialize the base class with NULL, because the
582        *  string class does its own memory management.
583        *  @endif
584       */
585       explicit
586       basic_stringstream(const __string_type& __str,
587 			 ios_base::openmode __m = ios_base::out | ios_base::in)
__iostream_type(NULL)588       : __iostream_type(NULL), _M_stringbuf(__str, __m)
589       { this->init(&_M_stringbuf); }
590 
591       /**
592        *  @brief  The destructor does nothing.
593        *
594        *  The buffer is deallocated by the stringbuf object, not the
595        *  formatting stream.
596       */
~basic_stringstream()597       ~basic_stringstream()
598       { }
599 
600       // Members:
601       /**
602        *  @brief  Accessing the underlying buffer.
603        *  @return  The current basic_stringbuf buffer.
604        *
605        *  This hides both signatures of std::basic_ios::rdbuf().
606       */
607       __stringbuf_type*
rdbuf()608       rdbuf() const
609       { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
610 
611       /**
612        *  @brief  Copying out the string buffer.
613        *  @return  @c rdbuf()->str()
614       */
615       __string_type
str()616       str() const
617       { return _M_stringbuf.str(); }
618 
619       /**
620        *  @brief  Setting a new buffer.
621        *  @param  s  The string to use as a new sequence.
622        *
623        *  Calls @c rdbuf()->str(s).
624       */
625       void
str(const __string_type & __s)626       str(const __string_type& __s)
627       { _M_stringbuf.str(__s); }
628     };
629 } // namespace std
630 
631 #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
632 # define export
633 #endif
634 #ifdef  _GLIBCPP_FULLY_COMPLIANT_HEADERS
635 # include <bits/sstream.tcc>
636 #endif
637 
638 #endif
639