std_sstream.h revision 146897
156657Smckusick// String based streams -*- C++ -*-
21541Srgrimes
31541Srgrimes// Copyright (C) 1997, 1998, 1999, 2002, 2003, 2004
444344Smckusick// Free Software Foundation, Inc.
51541Srgrimes//
644344Smckusick// This file is part of the GNU ISO C++ Library.  This library is free
744344Smckusick// software; you can redistribute it and/or modify it under the
81541Srgrimes// terms of the GNU General Public License as published by the
944344Smckusick// Free Software Foundation; either version 2, or (at your option)
1044344Smckusick// any later version.
1144344Smckusick
1244344Smckusick// This library is distributed in the hope that it will be useful,
1344344Smckusick// but WITHOUT ANY WARRANTY; without even the implied warranty of
1456657Smckusick// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1544344Smckusick// GNU General Public License for more details.
1644344Smckusick
1744344Smckusick// You should have received a copy of the GNU General Public License along
1844344Smckusick// with this library; see the file COPYING.  If not, write to the Free
1944344Smckusick// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
2044344Smckusick// USA.
2144344Smckusick
2244344Smckusick// As a special exception, you may use this file as part of a free software
2344344Smckusick// library without restriction.  Specifically, if other files instantiate
2444344Smckusick// templates or use macros or inline functions from this file, or you compile
2544344Smckusick// this file and link it with other files to produce an executable, this
2644344Smckusick// file does not by itself cause the resulting executable to be covered by
2744344Smckusick// the GNU General Public License.  This exception does not however
2844344Smckusick// invalidate any other reasons why the executable file might be covered by
2944344Smckusick// the GNU General Public License.
3044344Smckusick
3144344Smckusick//
3244344Smckusick// ISO C++ 14882: 27.7  String-based streams
3344344Smckusick//
3444344Smckusick
3544344Smckusick/** @file sstream
3644344Smckusick *  This is a Standard C++ Library header.  You should @c #include this header
3744344Smckusick *  in your programs, rather than any of the "st[dl]_*.h" implementation files.
3844344Smckusick */
3944344Smckusick
4044344Smckusick#ifndef _GLIBCXX_SSTREAM
4144344Smckusick#define _GLIBCXX_SSTREAM 1
4244344Smckusick
4344344Smckusick#pragma GCC system_header
4444344Smckusick
4544344Smckusick#include <istream>
4644344Smckusick#include <ostream>
4744344Smckusick
4844344Smckusicknamespace std
4944344Smckusick{
5044344Smckusick  // [27.7.1] template class basic_stringbuf
5144344Smckusick  /**
5244344Smckusick   *  @brief  The actual work of input and output (for std::string).
5344344Smckusick   *
5444344Smckusick   *  This class associates either or both of its input and output sequences
5544344Smckusick   *  with a sequence of characters, which can be initialized from, or made
5644344Smckusick   *  available as, a @c std::basic_string.  (Paraphrased from [27.7.1]/1.)
5744344Smckusick   *
5844344Smckusick   *  For this class, open modes (of type @c ios_base::openmode) have
5944344Smckusick   *  @c in set if the input sequence can be read, and @c out set if the
6044344Smckusick   *  output sequence can be written.
6144344Smckusick  */
6244344Smckusick  template<typename _CharT, typename _Traits, typename _Alloc>
6344344Smckusick    class basic_stringbuf : public basic_streambuf<_CharT, _Traits>
6444344Smckusick    {
6544344Smckusick    public:
6644344Smckusick      // Types:
6744344Smckusick      typedef _CharT 					char_type;
6844344Smckusick      typedef _Traits 					traits_type;
6944344Smckusick      // _GLIBCXX_RESOLVE_LIB_DEFECTS
7044344Smckusick      // 251. basic_stringbuf missing allocator_type
7144344Smckusick      typedef _Alloc				       	allocator_type;
7244344Smckusick      typedef typename traits_type::int_type 		int_type;
7344344Smckusick      typedef typename traits_type::pos_type 		pos_type;
7444344Smckusick      typedef typename traits_type::off_type 		off_type;
7544344Smckusick
7644344Smckusick      //@{
7744344Smckusick      /**
7844344Smckusick       *  @if maint
7944344Smckusick       *  @doctodo
8056657Smckusick       *  @endif
8156657Smckusick      */
8244344Smckusick      typedef basic_streambuf<char_type, traits_type>  	__streambuf_type;
8344344Smckusick      typedef basic_string<char_type, _Traits, _Alloc> 	__string_type;
8444344Smckusick      typedef typename __string_type::size_type		__size_type;
8544344Smckusick      //@}
8644344Smckusick
8744344Smckusick    protected:
8844344Smckusick      /**
8944344Smckusick       *  @if maint
9044344Smckusick       *  Place to stash in || out || in | out settings for current stringbuf.
9144344Smckusick       *  @endif
9244344Smckusick      */
9344344Smckusick      ios_base::openmode 	_M_mode;
9444344Smckusick
9544344Smckusick      // Data Members:
9644344Smckusick      /**
9744344Smckusick       *  @if maint
9844344Smckusick       *  @doctodo
9944344Smckusick       *  @endif
10044344Smckusick      */
10144344Smckusick      __string_type 		_M_string;
10244344Smckusick
10344344Smckusick    public:
10444344Smckusick      // Constructors:
10544344Smckusick      /**
10644344Smckusick       *  @brief  Starts with an empty string buffer.
10744344Smckusick       *  @param  mode  Whether the buffer can read, or write, or both.
10844344Smckusick       *
10944344Smckusick       *  The default constructor initializes the parent class using its
11044344Smckusick       *  own default ctor.
11144344Smckusick      */
11244344Smckusick      explicit
113      basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out)
114      : __streambuf_type(), _M_mode(__mode), _M_string()
115      { }
116
117      /**
118       *  @brief  Starts with an existing string buffer.
119       *  @param  str  A string to copy as a starting buffer.
120       *  @param  mode  Whether the buffer can read, or write, or both.
121       *
122       *  This constructor initializes the parent class using its
123       *  own default ctor.
124      */
125      explicit
126      basic_stringbuf(const __string_type& __str,
127		      ios_base::openmode __mode = ios_base::in | ios_base::out)
128      : __streambuf_type(), _M_mode(), _M_string(__str.data(), __str.size())
129      { _M_stringbuf_init(__mode); }
130
131      // Get and set:
132      /**
133       *  @brief  Copying out the string buffer.
134       *  @return  A copy of one of the underlying sequences.
135       *
136       *  "If the buffer is only created in input mode, the underlying
137       *  character sequence is equal to the input sequence; otherwise, it
138       *  is equal to the output sequence." [27.7.1.2]/1
139      */
140      __string_type
141      str() const
142      {
143	if (this->pptr())
144	  {
145	    // The current egptr() may not be the actual string end.
146	    if (this->pptr() > this->egptr())
147	      return __string_type(this->pbase(), this->pptr());
148	    else
149 	      return __string_type(this->pbase(), this->egptr());
150	  }
151	else
152	  return _M_string;
153      }
154
155      /**
156       *  @brief  Setting a new buffer.
157       *  @param  s  The string to use as a new sequence.
158       *
159       *  Deallocates any previous stored sequence, then copies @a s to
160       *  use as a new one.
161      */
162      void
163      str(const __string_type& __s)
164      {
165	// Cannot use _M_string = __s, since v3 strings are COW.
166	_M_string.assign(__s.data(), __s.size());
167	_M_stringbuf_init(this->_M_mode);
168      }
169
170    protected:
171      // Common initialization code goes here.
172      /**
173       *  @if maint
174       *  @doctodo
175       *  @endif
176      */
177      void
178      _M_stringbuf_init(ios_base::openmode __mode)
179      {
180	this->_M_mode = __mode;
181
182	__size_type __len = 0;
183	if (this->_M_mode & (ios_base::ate | ios_base::app))
184	  __len = _M_string.size();
185	_M_sync(const_cast<char_type*>(_M_string.data()), 0, __len);
186      }
187
188      // [documentation is inherited]
189      virtual int_type
190      underflow();
191
192      // [documentation is inherited]
193      virtual int_type
194      pbackfail(int_type __c = traits_type::eof());
195
196      // [documentation is inherited]
197      virtual int_type
198      overflow(int_type __c = traits_type::eof());
199
200      /**
201       *  @brief  Manipulates the buffer.
202       *  @param  s  Pointer to a buffer area.
203       *  @param  n  Size of @a s.
204       *  @return  @c this
205       *
206       *  If no buffer has already been created, and both @a s and @a n are
207       *  non-zero, then @c s is used as a buffer; see
208       *  http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2
209       *  for more.
210      */
211      virtual __streambuf_type*
212      setbuf(char_type* __s, streamsize __n)
213      {
214	if (__s && __n >= 0)
215	  {
216	    // This is implementation-defined behavior, and assumes
217	    // that an external char_type array of length __n exists
218	    // and has been pre-allocated. If this is not the case,
219	    // things will quickly blow up.
220
221	    // Step 1: Destroy the current internal array.
222	    _M_string = __string_type(__s, __n);
223
224	    // Step 2: Use the external array.
225	    _M_sync(__s, 0, 0);
226	  }
227	return this;
228      }
229
230      // [documentation is inherited]
231      virtual pos_type
232      seekoff(off_type __off, ios_base::seekdir __way,
233	      ios_base::openmode __mode = ios_base::in | ios_base::out);
234
235      // [documentation is inherited]
236      virtual pos_type
237      seekpos(pos_type __sp,
238	      ios_base::openmode __mode = ios_base::in | ios_base::out);
239
240      // Internal function for correctly updating the internal buffer
241      // for a particular _M_string, due to initialization or
242      // re-sizing of an existing _M_string.
243      // Assumes: contents of _M_string and internal buffer match exactly.
244      // __i == _M_in_cur - _M_in_beg
245      // __o == _M_out_cur - _M_out_beg
246      /**
247       *  @if maint
248       *  @doctodo
249       *  @endif
250      */
251      void
252      _M_sync(char_type* __base, __size_type __i, __size_type __o)
253      {
254	const bool __testin = this->_M_mode & ios_base::in;
255	const bool __testout = this->_M_mode & ios_base::out;
256	const __size_type __len = _M_string.size();
257
258	if (__testin)
259	  this->setg(__base, __base + __i, __base + __len);
260	if (__testout)
261	  {
262	    this->setp(__base, __base + _M_string.capacity());
263	    this->pbump(__o);
264	    // We need a pointer to the string end anyway, even when
265	    // !__testin: in that case, however, for the correct
266	    // functioning of the streambuf inlines all the get area
267	    // pointers must be identical.
268	    if (!__testin)
269	      this->setg(__base + __len, __base + __len, __base + __len);
270	  }
271      }
272
273      // Internal function for correctly updating egptr() to the actual
274      // string end.
275      void
276      _M_update_egptr()
277      {
278	const bool __testin = this->_M_mode & ios_base::in;
279
280	if (this->pptr() && this->pptr() > this->egptr())
281	  if (__testin)
282	    this->setg(this->eback(), this->gptr(), this->pptr());
283	  else
284	    this->setg(this->pptr(), this->pptr(), this->pptr());
285      }
286    };
287
288
289  // [27.7.2] Template class basic_istringstream
290  /**
291   *  @brief  Controlling input for std::string.
292   *
293   *  This class supports reading from objects of type std::basic_string,
294   *  using the inherited functions from std::basic_istream.  To control
295   *  the associated sequence, an instance of std::basic_stringbuf is used,
296   *  which this page refers to as @c sb.
297  */
298  template<typename _CharT, typename _Traits, typename _Alloc>
299    class basic_istringstream : public basic_istream<_CharT, _Traits>
300    {
301    public:
302      // Types:
303      typedef _CharT 					char_type;
304      typedef _Traits 					traits_type;
305      // _GLIBCXX_RESOLVE_LIB_DEFECTS
306      // 251. basic_stringbuf missing allocator_type
307      typedef _Alloc				       	allocator_type;
308      typedef typename traits_type::int_type 		int_type;
309      typedef typename traits_type::pos_type 		pos_type;
310      typedef typename traits_type::off_type 		off_type;
311
312      // Non-standard types:
313      typedef basic_string<_CharT, _Traits, _Alloc> 	__string_type;
314      typedef basic_stringbuf<_CharT, _Traits, _Alloc> 	__stringbuf_type;
315      typedef basic_istream<char_type, traits_type>	__istream_type;
316
317    private:
318      /**
319       *  @if maint
320       *  @doctodo
321       *  @endif
322      */
323      __stringbuf_type	_M_stringbuf;
324
325    public:
326      // Constructors:
327      /**
328       *  @brief  Default constructor starts with an empty string buffer.
329       *  @param  mode  Whether the buffer can read, or write, or both.
330       *
331       *  @c ios_base::in is automatically included in @a mode.
332       *
333       *  Initializes @c sb using @c mode|in, and passes @c &sb to the base
334       *  class initializer.  Does not allocate any buffer.
335       *
336       *  @if maint
337       *  That's a lie.  We initialize the base class with NULL, because the
338       *  string class does its own memory management.
339       *  @endif
340      */
341      explicit
342      basic_istringstream(ios_base::openmode __mode = ios_base::in)
343      : __istream_type(), _M_stringbuf(__mode | ios_base::in)
344      { this->init(&_M_stringbuf); }
345
346      /**
347       *  @brief  Starts with an existing string buffer.
348       *  @param  str  A string to copy as a starting buffer.
349       *  @param  mode  Whether the buffer can read, or write, or both.
350       *
351       *  @c ios_base::in is automatically included in @a mode.
352       *
353       *  Initializes @c sb using @a str and @c mode|in, and passes @c &sb
354       *  to the base class initializer.
355       *
356       *  @if maint
357       *  That's a lie.  We initialize the base class with NULL, because the
358       *  string class does its own memory management.
359       *  @endif
360      */
361      explicit
362      basic_istringstream(const __string_type& __str,
363			  ios_base::openmode __mode = ios_base::in)
364      : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in)
365      { this->init(&_M_stringbuf); }
366
367      /**
368       *  @brief  The destructor does nothing.
369       *
370       *  The buffer is deallocated by the stringbuf object, not the
371       *  formatting stream.
372      */
373      ~basic_istringstream()
374      { }
375
376      // Members:
377      /**
378       *  @brief  Accessing the underlying buffer.
379       *  @return  The current basic_stringbuf buffer.
380       *
381       *  This hides both signatures of std::basic_ios::rdbuf().
382      */
383      __stringbuf_type*
384      rdbuf() const
385      { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
386
387      /**
388       *  @brief  Copying out the string buffer.
389       *  @return  @c rdbuf()->str()
390      */
391      __string_type
392      str() const
393      { return _M_stringbuf.str(); }
394
395      /**
396       *  @brief  Setting a new buffer.
397       *  @param  s  The string to use as a new sequence.
398       *
399       *  Calls @c rdbuf()->str(s).
400      */
401      void
402      str(const __string_type& __s)
403      { _M_stringbuf.str(__s); }
404    };
405
406
407  // [27.7.3] Template class basic_ostringstream
408  /**
409   *  @brief  Controlling output for std::string.
410   *
411   *  This class supports writing to objects of type std::basic_string,
412   *  using the inherited functions from std::basic_ostream.  To control
413   *  the associated sequence, an instance of std::basic_stringbuf is used,
414   *  which this page refers to as @c sb.
415  */
416  template <typename _CharT, typename _Traits, typename _Alloc>
417    class basic_ostringstream : public basic_ostream<_CharT, _Traits>
418    {
419    public:
420      // Types:
421      typedef _CharT 					char_type;
422      typedef _Traits 					traits_type;
423      // _GLIBCXX_RESOLVE_LIB_DEFECTS
424      // 251. basic_stringbuf missing allocator_type
425      typedef _Alloc				       	allocator_type;
426      typedef typename traits_type::int_type 		int_type;
427      typedef typename traits_type::pos_type 		pos_type;
428      typedef typename traits_type::off_type 		off_type;
429
430      // Non-standard types:
431      typedef basic_string<_CharT, _Traits, _Alloc> 	__string_type;
432      typedef basic_stringbuf<_CharT, _Traits, _Alloc> 	__stringbuf_type;
433      typedef basic_ostream<char_type, traits_type>	__ostream_type;
434
435    private:
436      /**
437       *  @if maint
438       *  @doctodo
439       *  @endif
440      */
441      __stringbuf_type	_M_stringbuf;
442
443    public:
444      // Constructors/destructor:
445      /**
446       *  @brief  Default constructor starts with an empty string buffer.
447       *  @param  mode  Whether the buffer can read, or write, or both.
448       *
449       *  @c ios_base::out is automatically included in @a mode.
450       *
451       *  Initializes @c sb using @c mode|out, and passes @c &sb to the base
452       *  class initializer.  Does not allocate any buffer.
453       *
454       *  @if maint
455       *  That's a lie.  We initialize the base class with NULL, because the
456       *  string class does its own memory management.
457       *  @endif
458      */
459      explicit
460      basic_ostringstream(ios_base::openmode __mode = ios_base::out)
461      : __ostream_type(), _M_stringbuf(__mode | ios_base::out)
462      { this->init(&_M_stringbuf); }
463
464      /**
465       *  @brief  Starts with an existing string buffer.
466       *  @param  str  A string to copy as a starting buffer.
467       *  @param  mode  Whether the buffer can read, or write, or both.
468       *
469       *  @c ios_base::out is automatically included in @a mode.
470       *
471       *  Initializes @c sb using @a str and @c mode|out, and passes @c &sb
472       *  to the base class initializer.
473       *
474       *  @if maint
475       *  That's a lie.  We initialize the base class with NULL, because the
476       *  string class does its own memory management.
477       *  @endif
478      */
479      explicit
480      basic_ostringstream(const __string_type& __str,
481			  ios_base::openmode __mode = ios_base::out)
482      : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out)
483      { this->init(&_M_stringbuf); }
484
485      /**
486       *  @brief  The destructor does nothing.
487       *
488       *  The buffer is deallocated by the stringbuf object, not the
489       *  formatting stream.
490      */
491      ~basic_ostringstream()
492      { }
493
494      // Members:
495      /**
496       *  @brief  Accessing the underlying buffer.
497       *  @return  The current basic_stringbuf buffer.
498       *
499       *  This hides both signatures of std::basic_ios::rdbuf().
500      */
501      __stringbuf_type*
502      rdbuf() const
503      { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
504
505      /**
506       *  @brief  Copying out the string buffer.
507       *  @return  @c rdbuf()->str()
508      */
509      __string_type
510      str() const
511      { return _M_stringbuf.str(); }
512
513      /**
514       *  @brief  Setting a new buffer.
515       *  @param  s  The string to use as a new sequence.
516       *
517       *  Calls @c rdbuf()->str(s).
518      */
519      void
520      str(const __string_type& __s)
521      { _M_stringbuf.str(__s); }
522    };
523
524
525  // [27.7.4] Template class basic_stringstream
526  /**
527   *  @brief  Controlling input and output for std::string.
528   *
529   *  This class supports reading from and writing to objects of type
530   *  std::basic_string, using the inherited functions from
531   *  std::basic_iostream.  To control the associated sequence, an instance
532   *  of std::basic_stringbuf is used, which this page refers to as @c sb.
533  */
534  template <typename _CharT, typename _Traits, typename _Alloc>
535    class basic_stringstream : public basic_iostream<_CharT, _Traits>
536    {
537    public:
538      // Types:
539      typedef _CharT 					char_type;
540      typedef _Traits 					traits_type;
541      // _GLIBCXX_RESOLVE_LIB_DEFECTS
542      // 251. basic_stringbuf missing allocator_type
543      typedef _Alloc				       	allocator_type;
544      typedef typename traits_type::int_type 		int_type;
545      typedef typename traits_type::pos_type 		pos_type;
546      typedef typename traits_type::off_type 		off_type;
547
548      // Non-standard Types:
549      typedef basic_string<_CharT, _Traits, _Alloc> 	__string_type;
550      typedef basic_stringbuf<_CharT, _Traits, _Alloc> 	__stringbuf_type;
551      typedef basic_iostream<char_type, traits_type>	__iostream_type;
552
553    private:
554      /**
555       *  @if maint
556       *  @doctodo
557       *  @endif
558      */
559      __stringbuf_type	_M_stringbuf;
560
561    public:
562      // Constructors/destructors
563      /**
564       *  @brief  Default constructor starts with an empty string buffer.
565       *  @param  mode  Whether the buffer can read, or write, or both.
566       *
567       *  Initializes @c sb using @c mode, and passes @c &sb to the base
568       *  class initializer.  Does not allocate any buffer.
569       *
570       *  @if maint
571       *  That's a lie.  We initialize the base class with NULL, because the
572       *  string class does its own memory management.
573       *  @endif
574      */
575      explicit
576      basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in)
577      : __iostream_type(), _M_stringbuf(__m)
578      { this->init(&_M_stringbuf); }
579
580      /**
581       *  @brief  Starts with an existing string buffer.
582       *  @param  str  A string to copy as a starting buffer.
583       *  @param  mode  Whether the buffer can read, or write, or both.
584       *
585       *  Initializes @c sb using @a str and @c mode, and passes @c &sb
586       *  to the base class initializer.
587       *
588       *  @if maint
589       *  That's a lie.  We initialize the base class with NULL, because the
590       *  string class does its own memory management.
591       *  @endif
592      */
593      explicit
594      basic_stringstream(const __string_type& __str,
595			 ios_base::openmode __m = ios_base::out | ios_base::in)
596      : __iostream_type(), _M_stringbuf(__str, __m)
597      { this->init(&_M_stringbuf); }
598
599      /**
600       *  @brief  The destructor does nothing.
601       *
602       *  The buffer is deallocated by the stringbuf object, not the
603       *  formatting stream.
604      */
605      ~basic_stringstream()
606      { }
607
608      // Members:
609      /**
610       *  @brief  Accessing the underlying buffer.
611       *  @return  The current basic_stringbuf buffer.
612       *
613       *  This hides both signatures of std::basic_ios::rdbuf().
614      */
615      __stringbuf_type*
616      rdbuf() const
617      { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
618
619      /**
620       *  @brief  Copying out the string buffer.
621       *  @return  @c rdbuf()->str()
622      */
623      __string_type
624      str() const
625      { return _M_stringbuf.str(); }
626
627      /**
628       *  @brief  Setting a new buffer.
629       *  @param  s  The string to use as a new sequence.
630       *
631       *  Calls @c rdbuf()->str(s).
632      */
633      void
634      str(const __string_type& __s)
635      { _M_stringbuf.str(__s); }
636    };
637} // namespace std
638
639#ifndef _GLIBCXX_EXPORT_TEMPLATE
640# include <bits/sstream.tcc>
641#endif
642
643#endif /* _GLIBCXX_SSTREAM */
644