# sstream

Go to the documentation of this file.

    00001 // String based streams -*- C++ -*-
    00002
    00003 // Copyright (C) 1997, 1998, 1999, 2002 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
    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
    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
    00077
    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;
    00086
    00087     protected:
    00088       // Data Members:
    00094       __string_type         _M_string;
    00095
    00096     public:
    00097       // Constructors:
    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
    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:
    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_cur > _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
    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.
    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
    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
    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
    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:
    00313       __stringbuf_type  _M_stringbuf;
    00314
    00315     public:
    00316       // Constructors:
    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
    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
    00363       ~basic_istringstream()
    00364       { }
    00365
    00366       // Members:
    00373       __stringbuf_type*
    00374       rdbuf() const
    00375       { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
    00376
    00381       __string_type
    00382       str() const
    00383       { return _M_stringbuf.str(); }
    00384
    00391       void
    00392       str(const __string_type& __s)
    00393       { _M_stringbuf.str(__s); }
    00394     };
    00395
    00396
    00397   // [27.7.3] Template class basic_ostringstream
    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:
    00432       __stringbuf_type  _M_stringbuf;
    00433
    00434     public:
    00435       // Constructors/destructor:
    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
    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
    00482       ~basic_ostringstream()
    00483       { }
    00484
    00485       // Members:
    00492       __stringbuf_type*
    00493       rdbuf() const
    00494       { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
    00495
    00500       __string_type
    00501       str() const
    00502       { return _M_stringbuf.str(); }
    00503
    00510       void
    00511       str(const __string_type& __s)
    00512       { _M_stringbuf.str(__s); }
    00513     };
    00514
    00515
    00516   // [27.7.4] Template class basic_stringstream
    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:
    00551       __stringbuf_type  _M_stringbuf;
    00552
    00553     public:
    00554       // Constructors/destructors
    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
    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
    00597       ~basic_stringstream()
    00598       { }
    00599
    00600       // Members:
    00607       __stringbuf_type*
    00608       rdbuf() const
    00609       { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
    00610
    00615       __string_type
    00616       str() const
    00617       { return _M_stringbuf.str(); }
    00618
    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