libstdc++

sstream

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