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