# sstream.tcc

    00001 // String based streams -*- C++ -*-
    00002
    00003 // Copyright (C) 1997, 1998, 1999, 2001, 2002
    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 #ifndef _CPP_BITS_SSTREAM_TCC
    00036 #define _CPP_BITS_SSTREAM_TCC   1
    00037
    00038 #pragma GCC system_header
    00039
    00040 #include <sstream>
    00041
    00042 namespace std
    00043 {
    00044   template <class _CharT, class _Traits, class _Alloc>
    00045     typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type
    00046     basic_stringbuf<_CharT, _Traits, _Alloc>::
    00047     pbackfail(int_type __c)
    00048     {
    00049       int_type __ret = traits_type::eof();
    00050       bool __testeof = traits_type::eq_int_type(__c, traits_type::eof());
    00051       bool __testpos = _M_in_cur && _M_in_beg < _M_in_cur;
    00052
    00053       // Try to put back __c into input sequence in one of three ways.
    00054       // Order these tests done in is unspecified by the standard.
    00055       if (__testpos)
    00056     {
    00057       if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])
    00058           && !__testeof)
    00059         {
    00060           --_M_in_cur;
    00061           __ret = __c;
    00062         }
    00063       else if (!__testeof)
    00064         {
    00065           --_M_in_cur;
    00066           *_M_in_cur = traits_type::to_char_type(__c);
    00067           __ret = __c;
    00068         }
    00069       else if (__testeof)
    00070         {
    00071           --_M_in_cur;
    00072           __ret = traits_type::not_eof(__c);
    00073         }
    00074     }
    00075       return __ret;
    00076     }
    00077
    00078   template <class _CharT, class _Traits, class _Alloc>
    00079     typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type
    00080     basic_stringbuf<_CharT, _Traits, _Alloc>::
    00081     overflow(int_type __c)
    00082     {
    00083       int_type __ret = traits_type::eof();
    00084       bool __testeof = traits_type::eq_int_type(__c, __ret);
    00085       bool __testwrite = _M_out_cur < _M_buf + _M_buf_size;
    00086       bool __testout = _M_mode & ios_base::out;
    00087
    00088       // Try to append __c into output sequence in one of two ways.
    00089       // Order these tests done in is unspecified by the standard.
    00090       if (__testout)
    00091     {
    00092       if (!__testeof)
    00093         {
    00094           __size_type __len = max(_M_buf_size, _M_buf_size_opt);
    00095           __len *= 2;
    00096
    00097           if (__testwrite)
    00098         __ret = this->sputc(traits_type::to_char_type(__c));
    00099           else if (__len <= _M_string.max_size())
    00100         {
    00101           // Force-allocate, re-sync.
    00102           _M_string = this->str();
    00103           _M_string.reserve(__len);
    00104           _M_buf_size = __len;
    00105           _M_really_sync(_M_in_cur - _M_in_beg,
    00106                  _M_out_cur - _M_out_beg);
    00107           *_M_out_cur = traits_type::to_char_type(__c);
    00108           _M_out_cur_move(1);
    00109           __ret = __c;
    00110         }
    00111         }
    00112       else
    00113         __ret = traits_type::not_eof(__c);
    00114     }
    00115       return __ret;
    00116     }
    00117
    00118   template <class _CharT, class _Traits, class _Alloc>
    00119     typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type
    00120     basic_stringbuf<_CharT, _Traits, _Alloc>::
    00121     seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode)
    00122     {
    00123       pos_type __ret =  pos_type(off_type(-1));
    00124       bool __testin = (ios_base::in & _M_mode & __mode) != 0;
    00125       bool __testout = (ios_base::out & _M_mode & __mode) != 0;
    00126       bool __testboth = __testin && __testout && __way != ios_base::cur;
    00127       __testin &= !(__mode & ios_base::out);
    00128       __testout &= !(__mode & ios_base::in);
    00129
    00130       if (_M_buf_size && (__testin || __testout || __testboth))
    00131     {
    00132       char_type* __beg = _M_buf;
    00133       char_type* __curi = NULL;
    00134       char_type* __curo = NULL;
    00135       char_type* __endi = NULL;
    00136       char_type* __endo = NULL;
    00137
    00138       if (__testin || __testboth)
    00139         {
    00140           __curi = this->gptr();
    00141           __endi = this->egptr();
    00142         }
    00143       if (__testout || __testboth)
    00144         {
    00145           __curo = this->pptr();
    00146           __endo = this->epptr();
    00147         }
    00148
    00149       off_type __newoffi = 0;
    00150       off_type __newoffo = 0;
    00151       if (__way == ios_base::cur)
    00152         {
    00153           __newoffi = __curi - __beg;
    00154           __newoffo = __curo - __beg;
    00155         }
    00156       else if (__way == ios_base::end)
    00157         {
    00158           __newoffi = __endi - __beg;
    00159           __newoffo = __endo - __beg;
    00160         }
    00161
    00162       if ((__testin || __testboth)
    00163           && __newoffi + __off >= 0 && __endi - __beg >= __newoffi + __off)
    00164         {
    00165           _M_in_cur = __beg + __newoffi + __off;
    00166           __ret = pos_type(__newoffi);
    00167         }
    00168       if ((__testout || __testboth)
    00169           && __newoffo + __off >= 0 && __endo - __beg >= __newoffo + __off)
    00170         {
    00171           _M_out_cur_move(__newoffo + __off - (_M_out_cur - __beg));
    00172           __ret = pos_type(__newoffo);
    00173         }
    00174     }
    00175       return __ret;
    00176     }
    00177
    00178   template <class _CharT, class _Traits, class _Alloc>
    00179     typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type
    00180     basic_stringbuf<_CharT, _Traits, _Alloc>::
    00181     seekpos(pos_type __sp, ios_base::openmode __mode)
    00182     {
    00183       pos_type __ret =  pos_type(off_type(-1));
    00184
    00185       if (_M_buf_size)
    00186     {
    00187       off_type __pos = __sp; // Use streamoff operator to do conversion.
    00188       char_type* __beg = NULL;
    00189       char_type* __end = NULL;
    00190       bool __testin = (ios_base::in & _M_mode & __mode) != 0;
    00191       bool __testout = (ios_base::out & _M_mode & __mode) != 0;
    00192       bool __testboth = __testin && __testout;
    00193       __testin &= !(__mode & ios_base::out);
    00194       __testout &= !(__mode & ios_base::in);
    00195
    00196       // NB: Ordered.
    00197       bool __testposi = false;
    00198       bool __testposo = false;
    00199       if (__testin || __testboth)
    00200         {
    00201           __beg = this->eback();
    00202           __end = this->egptr();
    00203           if (0 <= __pos && __pos <= __end - __beg)
    00204         __testposi = true;
    00205         }
    00206       if (__testout || __testboth)
    00207         {
    00208           __beg = this->pbase();
    00209           __end = _M_buf + _M_buf_size;
    00210           if (0 <= __pos && __pos <= __end - __beg)
    00211         __testposo = true;
    00212         }
    00213       if (__testposi || __testposo)
    00214         {
    00215           if (__testposi)
    00216         _M_in_cur = _M_in_beg + __pos;
    00217           if (__testposo)
    00218         _M_out_cur_move((__pos) - (_M_out_cur - __beg));
    00219           __ret = pos_type(off_type(__pos));
    00220         }
    00221     }
    00222       return __ret;
    00223     }
    00224
    00225   // Inhibit implicit instantiations for required instantiations,
    00226   // which are defined via explicit instantiations elsewhere.
    00227   // NB:  This syntax is a GNU extension.
    00228   extern template class basic_stringbuf<char>;
    00229   extern template class basic_istringstream<char>;
    00230   extern template class basic_ostringstream<char>;
    00231   extern template class basic_stringstream<char>;
    00232
    00233 #ifdef _GLIBCPP_USE_WCHAR_T
    00234   extern template class basic_stringbuf<wchar_t>;
    00235   extern template class basic_istringstream<wchar_t>;
    00236   extern template class basic_ostringstream<wchar_t>;
    00237   extern template class basic_stringstream<wchar_t>;
    00238 #endif
    00239 } // namespace std
    00240
    00241 #endif