# streambuf.tcc

    00001 // Stream buffer classes -*- C++ -*-
    00002
    00003 // Copyright (C) 1997, 1998, 1999, 2000, 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.5  Stream buffers
    00033 //
    00034
    00035 #ifndef _CPP_BITS_STREAMBUF_TCC
    00036 #define _CPP_BITS_STREAMBUF_TCC 1
    00037
    00038 #pragma GCC system_header
    00039
    00040 namespace std
    00041 {
    00042   template<typename _CharT, typename _Traits>
    00043     const size_t
    00044     basic_streambuf<_CharT, _Traits>::_S_pback_size;
    00045
    00046   template<typename _CharT, typename _Traits>
    00047     typename basic_streambuf<_CharT, _Traits>::int_type
    00048     basic_streambuf<_CharT, _Traits>::
    00049     sbumpc()
    00050     {
    00051       int_type __ret;
    00052       if (_M_in_cur && _M_in_cur < _M_in_end)
    00053     {
    00054       char_type __c = *(this->gptr());
    00055       _M_in_cur_move(1);
    00056       __ret = traits_type::to_int_type(__c);
    00057     }
    00058       else
    00059     __ret = this->uflow();
    00060       return __ret;
    00061     }
    00062
    00063   template<typename _CharT, typename _Traits>
    00064     typename basic_streambuf<_CharT, _Traits>::int_type
    00065     basic_streambuf<_CharT, _Traits>::
    00066     sputbackc(char_type __c)
    00067     {
    00068       int_type __ret;
    00069       bool __testpos = _M_in_cur && _M_in_beg < _M_in_cur;
    00070       bool __testne = _M_in_cur && !traits_type::eq(__c, this->gptr()[-1]);
    00071       if (!__testpos || __testne)
    00072     __ret = this->pbackfail(traits_type::to_int_type(__c));
    00073       else
    00074     {
    00075       _M_in_cur_move(-1);
    00076       __ret = traits_type::to_int_type(*this->gptr());
    00077     }
    00078       return __ret;
    00079     }
    00080
    00081   template<typename _CharT, typename _Traits>
    00082     typename basic_streambuf<_CharT, _Traits>::int_type
    00083     basic_streambuf<_CharT, _Traits>::
    00084     sungetc()
    00085     {
    00086       int_type __ret;
    00087       if (_M_in_cur && _M_in_beg < _M_in_cur)
    00088     {
    00089       _M_in_cur_move(-1);
    00090       __ret = traits_type::to_int_type(*_M_in_cur);
    00091     }
    00092       else
    00093     __ret = this->pbackfail();
    00094       return __ret;
    00095     }
    00096
    00097   // Don't test against _M_buf + _M_buf_size, because _M_buf reflects
    00098   // allocated space, and on certain (rare but entirely legal)
    00099   // situations, there will be no allocated space yet the internal
    00100   // buffers will still be valid. (This happens if setp is used to set
    00101   // the internal buffer to say some externally-allocated sequence.)
    00102   template<typename _CharT, typename _Traits>
    00103     typename basic_streambuf<_CharT, _Traits>::int_type
    00104     basic_streambuf<_CharT, _Traits>::
    00105     sputc(char_type __c)
    00106     {
    00107       int_type __ret;
    00108       if (_M_out_buf_size())
    00109     {
    00110       *_M_out_cur = __c;
    00111       _M_out_cur_move(1);
    00112       __ret = traits_type::to_int_type(__c);
    00113     }
    00114       else
    00115     __ret = this->overflow(traits_type::to_int_type(__c));
    00116       return __ret;
    00117     }
    00118
    00119   template<typename _CharT, typename _Traits>
    00120     streamsize
    00121     basic_streambuf<_CharT, _Traits>::
    00122     xsgetn(char_type* __s, streamsize __n)
    00123     {
    00124       streamsize __ret = 0;
    00125       while (__ret < __n)
    00126     {
    00127       size_t __buf_len = _M_in_end - _M_in_cur;
    00128       if (__buf_len > 0)
    00129         {
    00130           size_t __remaining = __n - __ret;
    00131           size_t __len = min(__buf_len, __remaining);
    00132           traits_type::copy(__s, _M_in_cur, __len);
    00133           __ret += __len;
    00134           __s += __len;
    00135           _M_in_cur_move(__len);
    00136         }
    00137
    00138       if (__ret < __n)
    00139         {
    00140           int_type __c = this->uflow();
    00141           if (!traits_type::eq_int_type(__c, traits_type::eof()))
    00142         {
    00143           traits_type::assign(*__s++, traits_type::to_char_type(__c));
    00144           ++__ret;
    00145         }
    00146           else
    00147         break;
    00148         }
    00149     }
    00150       return __ret;
    00151     }
    00152
    00153   // Don't test against _M_buf + _M_buf_size, because _M_buf reflects
    00154   // allocated space, and on certain (rare but entirely legal)
    00155   // situations, there will be no allocated space yet the internal
    00156   // buffers will still be valid. (This happens if setp is used to set
    00157   // the internal buffer to say some externally-allocated sequence.)
    00158   template<typename _CharT, typename _Traits>
    00159     streamsize
    00160     basic_streambuf<_CharT, _Traits>::
    00161     xsputn(const char_type* __s, streamsize __n)
    00162     {
    00163       streamsize __ret = 0;
    00164       while (__ret < __n)
    00165     {
    00166       off_type __buf_len = _M_out_buf_size();
    00167       if (__buf_len > 0)
    00168         {
    00169           off_type __remaining = __n - __ret;
    00170           off_type __len = min(__buf_len, __remaining);
    00171           traits_type::copy(_M_out_cur, __s, __len);
    00172           __ret += __len;
    00173           __s += __len;
    00174           _M_out_cur_move(__len);
    00175         }
    00176
    00177       if (__ret < __n)
    00178         {
    00179           int_type __c = this->overflow(traits_type::to_int_type(*__s));
    00180           if (!traits_type::eq_int_type(__c, traits_type::eof()))
    00181         {
    00182           ++__ret;
    00183           ++__s;
    00184         }
    00185           else
    00186         break;
    00187         }
    00188     }
    00189       return __ret;
    00190     }
    00191
    00192   // Conceivably, this could be used to implement buffer-to-buffer
    00193   // copies, if this was ever desired in an un-ambiguous way by the
    00194   // standard. If so, then checks for __ios being zero would be
    00195   // necessary.
    00196   template<typename _CharT, typename _Traits>
    00197     streamsize
    00198     __copy_streambufs(basic_ios<_CharT, _Traits>& __ios,
    00199               basic_streambuf<_CharT, _Traits>* __sbin,
    00200               basic_streambuf<_CharT, _Traits>* __sbout)
    00201   {
    00202       typedef typename _Traits::int_type    int_type;
    00203
    00204       streamsize __ret = 0;
    00205       streamsize __bufsize = __sbin->in_avail();
    00206       streamsize __xtrct;
    00207       bool __testput = __sbout->_M_mode & ios_base::out;
    00208       try
    00209     {
    00210       while (__testput && __bufsize != -1)
    00211         {
    00212           if (__bufsize != 0 && __sbin->gptr() != NULL
    00213           && __sbin->gptr() + __bufsize <= __sbin->egptr())
    00214         {
    00215           __xtrct = __sbout->sputn(__sbin->gptr(), __bufsize);
    00216           __ret += __xtrct;
    00217           __sbin->_M_in_cur_move(__xtrct);
    00218           if (__xtrct != __bufsize)
    00219             break;
    00220         }
    00221           else
    00222         {
    00223           size_t __size =
    00224             __sbin->_M_buf_size_opt > 0 ? __sbin->_M_buf_size_opt : 1;
    00225           _CharT* __buf =
    00226             static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __size));
    00227           streamsize __charsread = __sbin->sgetn(__buf, __size);
    00228           __xtrct = __sbout->sputn(__buf, __charsread);
    00229           __ret += __xtrct;
    00230           if (__xtrct != __charsread)
    00231             break;
    00232         }
    00233           if (_Traits::eq_int_type(__sbin->sgetc(), _Traits::eof()))
    00234         break;
    00235           __bufsize = __sbin->in_avail();
    00236         }
    00237     }
    00238       catch(exception& __fail)
    00239     {
    00240       __ios.setstate(ios_base::failbit);
    00241       if ((__ios.exceptions() & ios_base::failbit) != 0)
    00242         __throw_exception_again;
    00243     }
    00244       return __ret;
    00245     }
    00246
    00247   // Inhibit implicit instantiations for required instantiations,
    00248   // which are defined via explicit instantiations elsewhere.
    00249   // NB:  This syntax is a GNU extension.
    00250   extern template class basic_streambuf<char>;
    00251   extern template
    00252     streamsize
    00253     __copy_streambufs(basic_ios<char>&, basic_streambuf<char>*,
    00254               basic_streambuf<char>*);
    00255
    00256 #ifdef _GLIBCPP_USE_WCHAR_T
    00257   extern template class basic_streambuf<wchar_t>;
    00258   extern template
    00259     streamsize
    00260     __copy_streambufs(basic_ios<wchar_t>&, basic_streambuf<wchar_t>*,
    00261               basic_streambuf<wchar_t>*);
    00262 #endif
    00263 } // namespace std
    00264
    00265 #endif