# sstream

Go to the documentation of this file.

    00001 // String based streams -*- C++ -*-
    00002
    00003 // Copyright (C) 1997, 1998, 1999, 2002, 2003, 2004
    00004 // Free Software Foundation, Inc.
    00005 //
    00006 // This file is part of the GNU ISO C++ Library.  This library is free
    00007 // software; you can redistribute it and/or modify it under the
    00008 // terms of the GNU General Public License as published by the
    00009 // Free Software Foundation; either version 2, or (at your option)
    00010 // any later version.
    00011
    00012 // This library is distributed in the hope that it will be useful,
    00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00015 // GNU General Public License for more details.
    00016
    00017 // You should have received a copy of the GNU General Public License along
    00018 // with this library; see the file COPYING.  If not, write to the Free
    00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
    00020 // USA.
    00021
    00022 // As a special exception, you may use this file as part of a free software
    00023 // library without restriction.  Specifically, if other files instantiate
    00024 // templates or use macros or inline functions from this file, or you compile
    00025 // this file and link it with other files to produce an executable, this
    00026 // file does not by itself cause the resulting executable to be covered by
    00027 // the GNU General Public License.  This exception does not however
    00028 // invalidate any other reasons why the executable file might be covered by
    00029 // the GNU General Public License.
    00030
    00031 //
    00032 // ISO C++ 14882: 27.7  String-based streams
    00033 //
    00034
    00035 /** @file sstream
    00036  *  This is a Standard C++ Library header.  You should @c #include this header
    00037  *  in your programs, rather than any of the "st[dl]_*.h" implementation files.
    00038  */
    00039
    00040 #ifndef _GLIBCXX_SSTREAM
    00041 #define _GLIBCXX_SSTREAM 1
    00042
    00043 #pragma GCC system_header
    00044
    00045 #include <istream>
    00046 #include <ostream>
    00047
    00048 namespace std
    00049 {
    00050   // [27.7.1] template class basic_stringbuf
    00051   /**
    00052    *  @brief  The actual work of input and output (for std::string).
    00053    *
    00054    *  This class associates either or both of its input and output sequences
    00055    *  with a sequence of characters, which can be initialized from, or made
    00056    *  available as, a @c std::basic_string.  (Paraphrased from [27.7.1]/1.)
    00057    *
    00058    *  For this class, open modes (of type @c ios_base::openmode) have
    00059    *  @c in set if the input sequence can be read, and @c out set if the
    00060    *  output sequence can be written.
    00061   */
    00062   template<typename _CharT, typename _Traits, typename _Alloc>
    00063     class basic_stringbuf : public basic_streambuf<_CharT, _Traits>
    00064     {
    00065     public:
    00066       // Types:
    00067       typedef _CharT                    char_type;
    00068       typedef _Traits                   traits_type;
    00069       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    00070       // 251. basic_stringbuf missing allocator_type
    00071       typedef _Alloc                        allocator_type;
    00072       typedef typename traits_type::int_type        int_type;
    00073       typedef typename traits_type::pos_type        pos_type;
    00074       typedef typename traits_type::off_type        off_type;
    00075
    00076       //@{
    00077       /**
    00078        *  @if maint
    00079        *  @doctodo
    00080        *  @endif
    00081       */
    00082       typedef basic_streambuf<char_type, traits_type>   __streambuf_type;
    00083       typedef basic_string<char_type, _Traits, _Alloc>  __string_type;
    00084       typedef typename __string_type::size_type     __size_type;
    00085       //@}
    00086
    00087     protected:
    00088       /**
    00089        *  @if maint
    00090        *  Place to stash in || out || in | out settings for current stringbuf.
    00091        *  @endif
    00092       */
    00093       ios_base::openmode    _M_mode;
    00094
    00095       // Data Members:
    00096       /**
    00097        *  @if maint
    00098        *  @doctodo
    00099        *  @endif
    00100       */
    00101       __string_type         _M_string;
    00102
    00103     public:
    00104       // Constructors:
    00105       /**
    00106        *  @brief  Starts with an empty string buffer.
    00107        *  @param  mode  Whether the buffer can read, or write, or both.
    00108        *
    00109        *  The default constructor initializes the parent class using its
    00110        *  own default ctor.
    00111       */
    00112       explicit
    00113       basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out)
    00114       : __streambuf_type(), _M_mode(), _M_string()
    00115       { _M_stringbuf_init(__mode); }
    00116
    00117       /**
    00118        *  @brief  Starts with an existing string buffer.
    00119        *  @param  str  A string to copy as a starting buffer.
    00120        *  @param  mode  Whether the buffer can read, or write, or both.
    00121        *
    00122        *  This constructor initializes the parent class using its
    00123        *  own default ctor.
    00124       */
    00125       explicit
    00126       basic_stringbuf(const __string_type& __str,
    00127               ios_base::openmode __mode = ios_base::in | ios_base::out)
    00128       : __streambuf_type(), _M_mode(), _M_string(__str.data(), __str.size())
    00129       { _M_stringbuf_init(__mode); }
    00130
    00131       // Get and set:
    00132       /**
    00133        *  @brief  Copying out the string buffer.
    00134        *  @return  A copy of one of the underlying sequences.
    00135        *
    00136        *  "If the buffer is only created in input mode, the underlying
    00137        *  character sequence is equal to the input sequence; otherwise, it
    00138        *  is equal to the output sequence." [27.7.1.2]/1
    00139       */
    00140       __string_type
    00141       str() const
    00142       {
    00143     const bool __testout = this->_M_mode & ios_base::out;
    00144     if (__testout)
    00145       {
    00146         // The current egptr() may not be the actual string end.
    00147         if (this->pptr() > this->egptr())
    00148           return __string_type(this->pbase(), this->pptr());
    00149         else
    00150           return __string_type(this->pbase(), this->egptr());
    00151       }
    00152     else
    00153       return _M_string;
    00154       }
    00155
    00156       /**
    00157        *  @brief  Setting a new buffer.
    00158        *  @param  s  The string to use as a new sequence.
    00159        *
    00160        *  Deallocates any previous stored sequence, then copies @a s to
    00161        *  use as a new one.
    00162       */
    00163       void
    00164       str(const __string_type& __s)
    00165       {
    00166     // Cannot use _M_string = __s, since v3 strings are COW.
    00167     _M_string.assign(__s.data(), __s.size());
    00168     _M_stringbuf_init(this->_M_mode);
    00169       }
    00170
    00171     protected:
    00172       // Common initialization code for both ctors goes here.
    00173       /**
    00174        *  @if maint
    00175        *  @doctodo
    00176        *  @endif
    00177       */
    00178       void
    00179       _M_stringbuf_init(ios_base::openmode __mode)
    00180       {
    00181     this->_M_mode = __mode;
    00182
    00183     __size_type __len = 0;
    00184     if (this->_M_mode & (ios_base::ate | ios_base::app))
    00185       __len = _M_string.size();
    00186     _M_sync(const_cast<char_type*>(_M_string.data()), 0, __len);
    00187       }
    00188
    00189       // [documentation is inherited]
    00190       virtual int_type
    00191       underflow();
    00192
    00193       // [documentation is inherited]
    00194       virtual int_type
    00195       pbackfail(int_type __c = traits_type::eof());
    00196
    00197       // [documentation is inherited]
    00198       virtual int_type
    00199       overflow(int_type __c = traits_type::eof());
    00200
    00201       /**
    00202        *  @brief  Manipulates the buffer.
    00203        *  @param  s  Pointer to a buffer area.
    00204        *  @param  n  Size of @a s.
    00205        *  @return  @c this
    00206        *
    00207        *  If no buffer has already been created, and both @a s and @a n are
    00208        *  non-zero, then @c s is used as a buffer; see
    00209        *  http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2
    00210        *  for more.
    00211       */
    00212       virtual __streambuf_type*
    00213       setbuf(char_type* __s, streamsize __n)
    00214       {
    00215     if (__s && __n >= 0)
    00216       {
    00217         // This is implementation-defined behavior, and assumes
    00218         // that an external char_type array of length __n exists
    00219         // and has been pre-allocated. If this is not the case,
    00220         // things will quickly blow up.
    00221
    00222         // Step 1: Destroy the current internal array.
    00223         _M_string = __string_type(__s, __n);
    00224
    00225         // Step 2: Use the external array.
    00226         _M_sync(__s, 0, 0);
    00227       }
    00228     return this;
    00229       }
    00230
    00231       // [documentation is inherited]
    00232       virtual pos_type
    00233       seekoff(off_type __off, ios_base::seekdir __way,
    00234           ios_base::openmode __mode = ios_base::in | ios_base::out);
    00235
    00236       // [documentation is inherited]
    00237       virtual pos_type
    00238       seekpos(pos_type __sp,
    00239           ios_base::openmode __mode = ios_base::in | ios_base::out);
    00240
    00241       // Internal function for correctly updating the internal buffer
    00242       // for a particular _M_string, due to initialization or
    00243       // re-sizing of an existing _M_string.
    00244       // Assumes: contents of _M_string and internal buffer match exactly.
    00245       // __i == _M_in_cur - _M_in_beg
    00246       // __o == _M_out_cur - _M_out_beg
    00247       /**
    00248        *  @if maint
    00249        *  @doctodo
    00250        *  @endif
    00251       */
    00252       void
    00253       _M_sync(char_type* __base, __size_type __i, __size_type __o)
    00254       {
    00255     const bool __testin = this->_M_mode & ios_base::in;
    00256     const bool __testout = this->_M_mode & ios_base::out;
    00257     const __size_type __len = _M_string.size();
    00258
    00259     if (__testin)
    00260       this->setg(__base, __base + __i, __base + __len);
    00261     if (__testout)
    00262       {
    00263         this->setp(__base, __base + _M_string.capacity());
    00264         this->pbump(__o);
    00265         // We need a pointer to the string end anyway, even when
    00266         // !__testin: in that case, however, for the correct
    00267         // functioning of the streambuf inlines all the get area
    00268         // pointers must be identical.
    00269         if (!__testin)
    00270           this->setg(__base + __len, __base + __len, __base + __len);
    00271       }
    00272       }
    00273
    00274       // Internal function for correctly updating egptr() to the actual
    00275       // string end.
    00276       void
    00277       _M_update_egptr()
    00278       {
    00279     const bool __testin = this->_M_mode & ios_base::in;
    00280     const bool __testout = this->_M_mode & ios_base::out;
    00281
    00282     if (__testout && this->pptr() > this->egptr())
    00283       if (__testin)
    00284         this->setg(this->eback(), this->gptr(), this->pptr());
    00285       else
    00286         this->setg(this->pptr(), this->pptr(), this->pptr());
    00287       }
    00288     };
    00289
    00290
    00291   // [27.7.2] Template class basic_istringstream
    00292   /**
    00293    *  @brief  Controlling input for std::string.
    00294    *
    00295    *  This class supports reading from objects of type std::basic_string,
    00296    *  using the inherited functions from std::basic_istream.  To control
    00297    *  the associated sequence, an instance of std::basic_stringbuf is used,
    00298    *  which this page refers to as @c sb.
    00299   */
    00300   template<typename _CharT, typename _Traits, typename _Alloc>
    00301     class basic_istringstream : public basic_istream<_CharT, _Traits>
    00302     {
    00303     public:
    00304       // Types:
    00305       typedef _CharT                    char_type;
    00306       typedef _Traits                   traits_type;
    00307       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    00308       // 251. basic_stringbuf missing allocator_type
    00309       typedef _Alloc                        allocator_type;
    00310       typedef typename traits_type::int_type        int_type;
    00311       typedef typename traits_type::pos_type        pos_type;
    00312       typedef typename traits_type::off_type        off_type;
    00313
    00314       // Non-standard types:
    00315       typedef basic_string<_CharT, _Traits, _Alloc>     __string_type;
    00316       typedef basic_stringbuf<_CharT, _Traits, _Alloc>  __stringbuf_type;
    00317       typedef basic_istream<char_type, traits_type> __istream_type;
    00318
    00319     private:
    00320       /**
    00321        *  @if maint
    00322        *  @doctodo
    00323        *  @endif
    00324       */
    00325       __stringbuf_type  _M_stringbuf;
    00326
    00327     public:
    00328       // Constructors:
    00329       /**
    00330        *  @brief  Default constructor starts with an empty string buffer.
    00331        *  @param  mode  Whether the buffer can read, or write, or both.
    00332        *
    00333        *  @c ios_base::in is automatically included in @a mode.
    00334        *
    00335        *  Initializes @c sb using @c mode|in, and passes @c &sb to the base
    00336        *  class initializer.  Does not allocate any buffer.
    00337        *
    00338        *  @if maint
    00339        *  That's a lie.  We initialize the base class with NULL, because the
    00340        *  string class does its own memory management.
    00341        *  @endif
    00342       */
    00343       explicit
    00344       basic_istringstream(ios_base::openmode __mode = ios_base::in)
    00345       : __istream_type(), _M_stringbuf(__mode | ios_base::in)
    00346       { this->init(&_M_stringbuf); }
    00347
    00348       /**
    00349        *  @brief  Starts with an existing string buffer.
    00350        *  @param  str  A string to copy as a starting buffer.
    00351        *  @param  mode  Whether the buffer can read, or write, or both.
    00352        *
    00353        *  @c ios_base::in is automatically included in @a mode.
    00354        *
    00355        *  Initializes @c sb using @a str and @c mode|in, and passes @c &sb
    00356        *  to the base class initializer.
    00357        *
    00358        *  @if maint
    00359        *  That's a lie.  We initialize the base class with NULL, because the
    00360        *  string class does its own memory management.
    00361        *  @endif
    00362       */
    00363       explicit
    00364       basic_istringstream(const __string_type& __str,
    00365               ios_base::openmode __mode = ios_base::in)
    00366       : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in)
    00367       { this->init(&_M_stringbuf); }
    00368
    00369       /**
    00370        *  @brief  The destructor does nothing.
    00371        *
    00372        *  The buffer is deallocated by the stringbuf object, not the
    00373        *  formatting stream.
    00374       */
    00375       ~basic_istringstream()
    00376       { }
    00377
    00378       // Members:
    00379       /**
    00380        *  @brief  Accessing the underlying buffer.
    00381        *  @return  The current basic_stringbuf buffer.
    00382        *
    00383        *  This hides both signatures of std::basic_ios::rdbuf().
    00384       */
    00385       __stringbuf_type*
    00386       rdbuf() const
    00387       { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
    00388
    00389       /**
    00390        *  @brief  Copying out the string buffer.
    00391        *  @return  @c rdbuf()->str()
    00392       */
    00393       __string_type
    00394       str() const
    00395       { return _M_stringbuf.str(); }
    00396
    00397       /**
    00398        *  @brief  Setting a new buffer.
    00399        *  @param  s  The string to use as a new sequence.
    00400        *
    00401        *  Calls @c rdbuf()->str(s).
    00402       */
    00403       void
    00404       str(const __string_type& __s)
    00405       { _M_stringbuf.str(__s); }
    00406     };
    00407
    00408
    00409   // [27.7.3] Template class basic_ostringstream
    00410   /**
    00411    *  @brief  Controlling output for std::string.
    00412    *
    00413    *  This class supports writing to objects of type std::basic_string,
    00414    *  using the inherited functions from std::basic_ostream.  To control
    00415    *  the associated sequence, an instance of std::basic_stringbuf is used,
    00416    *  which this page refers to as @c sb.
    00417   */
    00418   template <typename _CharT, typename _Traits, typename _Alloc>
    00419     class basic_ostringstream : public basic_ostream<_CharT, _Traits>
    00420     {
    00421     public:
    00422       // Types:
    00423       typedef _CharT                    char_type;
    00424       typedef _Traits                   traits_type;
    00425       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    00426       // 251. basic_stringbuf missing allocator_type
    00427       typedef _Alloc                        allocator_type;
    00428       typedef typename traits_type::int_type        int_type;
    00429       typedef typename traits_type::pos_type        pos_type;
    00430       typedef typename traits_type::off_type        off_type;
    00431
    00432       // Non-standard types:
    00433       typedef basic_string<_CharT, _Traits, _Alloc>     __string_type;
    00434       typedef basic_stringbuf<_CharT, _Traits, _Alloc>  __stringbuf_type;
    00435       typedef basic_ostream<char_type, traits_type> __ostream_type;
    00436
    00437     private:
    00438       /**
    00439        *  @if maint
    00440        *  @doctodo
    00441        *  @endif
    00442       */
    00443       __stringbuf_type  _M_stringbuf;
    00444
    00445     public:
    00446       // Constructors/destructor:
    00447       /**
    00448        *  @brief  Default constructor starts with an empty string buffer.
    00449        *  @param  mode  Whether the buffer can read, or write, or both.
    00450        *
    00451        *  @c ios_base::out is automatically included in @a mode.
    00452        *
    00453        *  Initializes @c sb using @c mode|out, and passes @c &sb to the base
    00454        *  class initializer.  Does not allocate any buffer.
    00455        *
    00456        *  @if maint
    00457        *  That's a lie.  We initialize the base class with NULL, because the
    00458        *  string class does its own memory management.
    00459        *  @endif
    00460       */
    00461       explicit
    00462       basic_ostringstream(ios_base::openmode __mode = ios_base::out)
    00463       : __ostream_type(), _M_stringbuf(__mode | ios_base::out)
    00464       { this->init(&_M_stringbuf); }
    00465
    00466       /**
    00467        *  @brief  Starts with an existing string buffer.
    00468        *  @param  str  A string to copy as a starting buffer.
    00469        *  @param  mode  Whether the buffer can read, or write, or both.
    00470        *
    00471        *  @c ios_base::out is automatically included in @a mode.
    00472        *
    00473        *  Initializes @c sb using @a str and @c mode|out, and passes @c &sb
    00474        *  to the base class initializer.
    00475        *
    00476        *  @if maint
    00477        *  That's a lie.  We initialize the base class with NULL, because the
    00478        *  string class does its own memory management.
    00479        *  @endif
    00480       */
    00481       explicit
    00482       basic_ostringstream(const __string_type& __str,
    00483               ios_base::openmode __mode = ios_base::out)
    00484       : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out)
    00485       { this->init(&_M_stringbuf); }
    00486
    00487       /**
    00488        *  @brief  The destructor does nothing.
    00489        *
    00490        *  The buffer is deallocated by the stringbuf object, not the
    00491        *  formatting stream.
    00492       */
    00493       ~basic_ostringstream()
    00494       { }
    00495
    00496       // Members:
    00497       /**
    00498        *  @brief  Accessing the underlying buffer.
    00499        *  @return  The current basic_stringbuf buffer.
    00500        *
    00501        *  This hides both signatures of std::basic_ios::rdbuf().
    00502       */
    00503       __stringbuf_type*
    00504       rdbuf() const
    00505       { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
    00506
    00507       /**
    00508        *  @brief  Copying out the string buffer.
    00509        *  @return  @c rdbuf()->str()
    00510       */
    00511       __string_type
    00512       str() const
    00513       { return _M_stringbuf.str(); }
    00514
    00515       /**
    00516        *  @brief  Setting a new buffer.
    00517        *  @param  s  The string to use as a new sequence.
    00518        *
    00519        *  Calls @c rdbuf()->str(s).
    00520       */
    00521       void
    00522       str(const __string_type& __s)
    00523       { _M_stringbuf.str(__s); }
    00524     };
    00525
    00526
    00527   // [27.7.4] Template class basic_stringstream
    00528   /**
    00529    *  @brief  Controlling input and output for std::string.
    00530    *
    00531    *  This class supports reading from and writing to objects of type
    00532    *  std::basic_string, using the inherited functions from
    00533    *  std::basic_iostream.  To control the associated sequence, an instance
    00534    *  of std::basic_stringbuf is used, which this page refers to as @c sb.
    00535   */
    00536   template <typename _CharT, typename _Traits, typename _Alloc>
    00537     class basic_stringstream : public basic_iostream<_CharT, _Traits>
    00538     {
    00539     public:
    00540       // Types:
    00541       typedef _CharT                    char_type;
    00542       typedef _Traits                   traits_type;
    00543       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    00544       // 251. basic_stringbuf missing allocator_type
    00545       typedef _Alloc                        allocator_type;
    00546       typedef typename traits_type::int_type        int_type;
    00547       typedef typename traits_type::pos_type        pos_type;
    00548       typedef typename traits_type::off_type        off_type;
    00549
    00550       // Non-standard Types:
    00551       typedef basic_string<_CharT, _Traits, _Alloc>     __string_type;
    00552       typedef basic_stringbuf<_CharT, _Traits, _Alloc>  __stringbuf_type;
    00553       typedef basic_iostream<char_type, traits_type>    __iostream_type;
    00554
    00555     private:
    00556       /**
    00557        *  @if maint
    00558        *  @doctodo
    00559        *  @endif
    00560       */
    00561       __stringbuf_type  _M_stringbuf;
    00562
    00563     public:
    00564       // Constructors/destructors
    00565       /**
    00566        *  @brief  Default constructor starts with an empty string buffer.
    00567        *  @param  mode  Whether the buffer can read, or write, or both.
    00568        *
    00569        *  Initializes @c sb using @c mode, and passes @c &sb to the base
    00570        *  class initializer.  Does not allocate any buffer.
    00571        *
    00572        *  @if maint
    00573        *  That's a lie.  We initialize the base class with NULL, because the
    00574        *  string class does its own memory management.
    00575        *  @endif
    00576       */
    00577       explicit
    00578       basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in)
    00579       : __iostream_type(), _M_stringbuf(__m)
    00580       { this->init(&_M_stringbuf); }
    00581
    00582       /**
    00583        *  @brief  Starts with an existing string buffer.
    00584        *  @param  str  A string to copy as a starting buffer.
    00585        *  @param  mode  Whether the buffer can read, or write, or both.
    00586        *
    00587        *  Initializes @c sb using @a str and @c mode, and passes @c &sb
    00588        *  to the base class initializer.
    00589        *
    00590        *  @if maint
    00591        *  That's a lie.  We initialize the base class with NULL, because the
    00592        *  string class does its own memory management.
    00593        *  @endif
    00594       */
    00595       explicit
    00596       basic_stringstream(const __string_type& __str,
    00597              ios_base::openmode __m = ios_base::out | ios_base::in)
    00598       : __iostream_type(), _M_stringbuf(__str, __m)
    00599       { this->init(&_M_stringbuf); }
    00600
    00601       /**
    00602        *  @brief  The destructor does nothing.
    00603        *
    00604        *  The buffer is deallocated by the stringbuf object, not the
    00605        *  formatting stream.
    00606       */
    00607       ~basic_stringstream()
    00608       { }
    00609
    00610       // Members:
    00611       /**
    00612        *  @brief  Accessing the underlying buffer.
    00613        *  @return  The current basic_stringbuf buffer.
    00614        *
    00615        *  This hides both signatures of std::basic_ios::rdbuf().
    00616       */
    00617       __stringbuf_type*
    00618       rdbuf() const
    00619       { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
    00620
    00621       /**
    00622        *  @brief  Copying out the string buffer.
    00623        *  @return  @c rdbuf()->str()
    00624       */
    00625       __string_type
    00626       str() const
    00627       { return _M_stringbuf.str(); }
    00628
    00629       /**
    00630        *  @brief  Setting a new buffer.
    00631        *  @param  s  The string to use as a new sequence.
    00632        *
    00633        *  Calls @c rdbuf()->str(s).
    00634       */
    00635       void
    00636       str(const __string_type& __s)
    00637       { _M_stringbuf.str(__s); }
    00638     };
    00639 } // namespace std
    00640
    00641 #ifndef _GLIBCXX_EXPORT_TEMPLATE
    00642 # include <bits/sstream.tcc>
    00643 #endif
    00644
    00645 #endif /* _GLIBCXX_SSTREAM */