streambuf.tcc

00001 // Stream buffer classes -*- C++ -*-
00002 
00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
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       if (!__testpos || !traits_type::eq(__c, this->gptr()[-1]))
00071     __ret = this->pbackfail(traits_type::to_int_type(__c));
00072       else 
00073     {
00074       _M_in_cur_move(-1);
00075       __ret = traits_type::to_int_type(*this->gptr());
00076     }
00077       return __ret;
00078     }
00079   
00080   template<typename _CharT, typename _Traits>
00081     typename basic_streambuf<_CharT, _Traits>::int_type
00082     basic_streambuf<_CharT, _Traits>::
00083     sungetc()
00084     {
00085       int_type __ret;
00086       if (_M_in_cur && _M_in_beg < _M_in_cur)
00087     {
00088       _M_in_cur_move(-1);
00089       __ret = traits_type::to_int_type(*_M_in_cur);
00090     }
00091       else 
00092     __ret = this->pbackfail();
00093       return __ret;
00094     }
00095 
00096   // Don't test against _M_buf + _M_buf_size, because _M_buf reflects
00097   // allocated space, and on certain (rare but entirely legal)
00098   // situations, there will be no allocated space yet the internal
00099   // buffers will still be valid. (This happens if setp is used to set
00100   // the internal buffer to say some externally-allocated sequence.)
00101   template<typename _CharT, typename _Traits>
00102     typename basic_streambuf<_CharT, _Traits>::int_type
00103     basic_streambuf<_CharT, _Traits>::
00104     sputc(char_type __c)
00105     {
00106       int_type __ret;
00107       if (_M_out_buf_size())
00108     {
00109       *_M_out_cur = __c;
00110       _M_out_cur_move(1);
00111       __ret = traits_type::to_int_type(__c);
00112     }
00113       else
00114     __ret = this->overflow(traits_type::to_int_type(__c));
00115       return __ret;
00116     }
00117 
00118   template<typename _CharT, typename _Traits>
00119     streamsize
00120     basic_streambuf<_CharT, _Traits>::
00121     xsgetn(char_type* __s, streamsize __n)
00122     {
00123       streamsize __ret = 0;
00124       while (__ret < __n)
00125     {
00126       size_t __buf_len = _M_in_end - _M_in_cur;
00127       if (__buf_len > 0)
00128         {
00129           size_t __remaining = __n - __ret;
00130           size_t __len = min(__buf_len, __remaining);
00131           traits_type::copy(__s, _M_in_cur, __len);
00132           __ret += __len;
00133           __s += __len;
00134           _M_in_cur_move(__len);
00135         }
00136       
00137       if (__ret < __n)
00138         {
00139           int_type __c = this->uflow();  
00140           if (!traits_type::eq_int_type(__c, traits_type::eof()))
00141         {
00142           traits_type::assign(*__s++, traits_type::to_char_type(__c));
00143           ++__ret;
00144         }
00145           else
00146         break;
00147         }
00148     }
00149       return __ret;
00150     }
00151 
00152   // Don't test against _M_buf + _M_buf_size, because _M_buf reflects
00153   // allocated space, and on certain (rare but entirely legal)
00154   // situations, there will be no allocated space yet the internal
00155   // buffers will still be valid. (This happens if setp is used to set
00156   // the internal buffer to say some externally-allocated sequence.)
00157   template<typename _CharT, typename _Traits>
00158     streamsize
00159     basic_streambuf<_CharT, _Traits>::
00160     xsputn(const char_type* __s, streamsize __n)
00161     {
00162       streamsize __ret = 0;
00163       while (__ret < __n)
00164     {
00165       off_type __buf_len = _M_out_buf_size();
00166       if (__buf_len > 0)
00167         {
00168           off_type __remaining = __n - __ret;
00169           off_type __len = min(__buf_len, __remaining);
00170           traits_type::copy(_M_out_cur, __s, __len);
00171           __ret += __len;
00172           __s += __len;
00173           _M_out_cur_move(__len);
00174         }
00175 
00176       if (__ret < __n)
00177         {
00178           int_type __c = this->overflow(traits_type::to_int_type(*__s));
00179           if (!traits_type::eq_int_type(__c, traits_type::eof()))
00180         {
00181           ++__ret;
00182           ++__s;
00183         }
00184           else
00185         break;
00186         }
00187     }
00188       return __ret;
00189     }
00190 
00191   // Conceivably, this could be used to implement buffer-to-buffer
00192   // copies, if this was ever desired in an un-ambiguous way by the
00193   // standard. If so, then checks for __ios being zero would be
00194   // necessary.
00195   template<typename _CharT, typename _Traits>
00196     streamsize
00197     __copy_streambufs(basic_ios<_CharT, _Traits>&,
00198               basic_streambuf<_CharT, _Traits>* __sbin,
00199               basic_streambuf<_CharT, _Traits>* __sbout) 
00200   {
00201     streamsize __ret = 0;
00202     typename _Traits::int_type __c = __sbin->sgetc();
00203     while (!_Traits::eq_int_type(__c, _Traits::eof()))
00204       {
00205     const size_t __n = __sbin->_M_in_end - __sbin->_M_in_cur;
00206     if (__n > 1)
00207       {
00208         const size_t __wrote = __sbout->sputn(__sbin->_M_in_cur, __n);
00209         __sbin->_M_in_cur_move(__wrote);
00210         __ret += __wrote;
00211         if (__wrote < __n)
00212           break;
00213         __c = __sbin->underflow();
00214       }
00215     else 
00216       {
00217         __c = __sbout->sputc(_Traits::to_char_type(__c));
00218         if (_Traits::eq_int_type(__c, _Traits::eof()))
00219           break;
00220         ++__ret;
00221         __c = __sbin->snextc();
00222       }
00223       }
00224     return __ret;
00225   }
00226 
00227   // Inhibit implicit instantiations for required instantiations,
00228   // which are defined via explicit instantiations elsewhere.  
00229   // NB:  This syntax is a GNU extension.
00230 #if _GLIBCPP_EXTERN_TEMPLATE
00231   extern template class basic_streambuf<char>;
00232   extern template
00233     streamsize
00234     __copy_streambufs(basic_ios<char>&, basic_streambuf<char>*,
00235               basic_streambuf<char>*); 
00236 
00237 #ifdef _GLIBCPP_USE_WCHAR_T
00238   extern template class basic_streambuf<wchar_t>;
00239   extern template
00240     streamsize
00241     __copy_streambufs(basic_ios<wchar_t>&, basic_streambuf<wchar_t>*,
00242               basic_streambuf<wchar_t>*); 
00243 #endif
00244 #endif
00245 } // namespace std
00246 
00247 #endif 

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