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 

Generated on Thu Nov 21 03:12:51 2002 for libstdc++-v3 Source by doxygen1.2.18-20021030