sstream

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

Generated on Thu Feb 10 23:22:57 2005 for libstdc++-v3 Source by  doxygen 1.4.0