197403Sobrien// Stream buffer classes -*- C++ -*-
297403Sobrien
3169691Skan// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
497403Sobrien// Free Software Foundation, Inc.
597403Sobrien//
697403Sobrien// This file is part of the GNU ISO C++ Library.  This library is free
797403Sobrien// software; you can redistribute it and/or modify it under the
897403Sobrien// terms of the GNU General Public License as published by the
997403Sobrien// Free Software Foundation; either version 2, or (at your option)
1097403Sobrien// any later version.
1197403Sobrien
1297403Sobrien// This library is distributed in the hope that it will be useful,
1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of
1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1597403Sobrien// GNU General Public License for more details.
1697403Sobrien
1797403Sobrien// You should have received a copy of the GNU General Public License along
1897403Sobrien// with this library; see the file COPYING.  If not, write to the Free
19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
2097403Sobrien// USA.
2197403Sobrien
2297403Sobrien// As a special exception, you may use this file as part of a free software
2397403Sobrien// library without restriction.  Specifically, if other files instantiate
2497403Sobrien// templates or use macros or inline functions from this file, or you compile
2597403Sobrien// this file and link it with other files to produce an executable, this
2697403Sobrien// file does not by itself cause the resulting executable to be covered by
2797403Sobrien// the GNU General Public License.  This exception does not however
2897403Sobrien// invalidate any other reasons why the executable file might be covered by
2997403Sobrien// the GNU General Public License.
3097403Sobrien
31169691Skan/** @file streambuf.tcc
32169691Skan *  This is an internal header file, included by other library headers.
33169691Skan *  You should not attempt to use it directly.
34169691Skan */
35169691Skan
3697403Sobrien//
3797403Sobrien// ISO C++ 14882: 27.5  Stream buffers
3897403Sobrien//
3997403Sobrien
40132720Skan#ifndef _STREAMBUF_TCC
41132720Skan#define _STREAMBUF_TCC 1
4297403Sobrien
4397403Sobrien#pragma GCC system_header
4497403Sobrien
45169691Skan_GLIBCXX_BEGIN_NAMESPACE(std)
46169691Skan
4797403Sobrien  template<typename _CharT, typename _Traits>
4897403Sobrien    streamsize
4997403Sobrien    basic_streambuf<_CharT, _Traits>::
5097403Sobrien    xsgetn(char_type* __s, streamsize __n)
5197403Sobrien    {
5297403Sobrien      streamsize __ret = 0;
5397403Sobrien      while (__ret < __n)
5497403Sobrien	{
55169691Skan	  const streamsize __buf_len = this->egptr() - this->gptr();
56132720Skan	  if (__buf_len)
5797403Sobrien	    {
58169691Skan	      const streamsize __remaining = __n - __ret;
59169691Skan	      const streamsize __len = std::min(__buf_len, __remaining);
60132720Skan	      traits_type::copy(__s, this->gptr(), __len);
6197403Sobrien	      __ret += __len;
6297403Sobrien	      __s += __len;
63132720Skan	      this->gbump(__len);
6497403Sobrien	    }
65132720Skan
6697403Sobrien	  if (__ret < __n)
6797403Sobrien	    {
68132720Skan	      const int_type __c = this->uflow();
69102782Skan	      if (!traits_type::eq_int_type(__c, traits_type::eof()))
7097403Sobrien		{
7197403Sobrien		  traits_type::assign(*__s++, traits_type::to_char_type(__c));
7297403Sobrien		  ++__ret;
7397403Sobrien		}
7497403Sobrien	      else
7597403Sobrien		break;
7697403Sobrien	    }
7797403Sobrien	}
7897403Sobrien      return __ret;
7997403Sobrien    }
8097403Sobrien
8197403Sobrien  template<typename _CharT, typename _Traits>
8297403Sobrien    streamsize
8397403Sobrien    basic_streambuf<_CharT, _Traits>::
8497403Sobrien    xsputn(const char_type* __s, streamsize __n)
8597403Sobrien    {
8697403Sobrien      streamsize __ret = 0;
8797403Sobrien      while (__ret < __n)
8897403Sobrien	{
89169691Skan	  const streamsize __buf_len = this->epptr() - this->pptr();
90132720Skan	  if (__buf_len)
9197403Sobrien	    {
92169691Skan	      const streamsize __remaining = __n - __ret;
93169691Skan	      const streamsize __len = std::min(__buf_len, __remaining);
94132720Skan	      traits_type::copy(this->pptr(), __s, __len);
9597403Sobrien	      __ret += __len;
9697403Sobrien	      __s += __len;
97132720Skan	      this->pbump(__len);
9897403Sobrien	    }
9997403Sobrien
10097403Sobrien	  if (__ret < __n)
10197403Sobrien	    {
10297403Sobrien	      int_type __c = this->overflow(traits_type::to_int_type(*__s));
103102782Skan	      if (!traits_type::eq_int_type(__c, traits_type::eof()))
10497403Sobrien		{
10597403Sobrien		  ++__ret;
10697403Sobrien		  ++__s;
10797403Sobrien		}
10897403Sobrien	      else
10997403Sobrien		break;
11097403Sobrien	    }
11197403Sobrien	}
11297403Sobrien      return __ret;
11397403Sobrien    }
11497403Sobrien
11597403Sobrien  // Conceivably, this could be used to implement buffer-to-buffer
11697403Sobrien  // copies, if this was ever desired in an un-ambiguous way by the
117169691Skan  // standard.
11897403Sobrien  template<typename _CharT, typename _Traits>
11997403Sobrien    streamsize
120169691Skan    __copy_streambufs_eof(basic_streambuf<_CharT, _Traits>* __sbin,
121169691Skan			  basic_streambuf<_CharT, _Traits>* __sbout,
122169691Skan			  bool& __ineof)
123132720Skan    {
124132720Skan      streamsize __ret = 0;
125169691Skan      __ineof = true;
126132720Skan      typename _Traits::int_type __c = __sbin->sgetc();
127132720Skan      while (!_Traits::eq_int_type(__c, _Traits::eof()))
128132720Skan	{
129169691Skan	  __c = __sbout->sputc(_Traits::to_char_type(__c));
130169691Skan	  if (_Traits::eq_int_type(__c, _Traits::eof()))
131132720Skan	    {
132169691Skan	      __ineof = false;
133169691Skan	      break;
134132720Skan	    }
135169691Skan	  ++__ret;
136169691Skan	  __c = __sbin->snextc();
137132720Skan	}
138132720Skan      return __ret;
139132720Skan    }
14097403Sobrien
141169691Skan  template<typename _CharT, typename _Traits>
142169691Skan    inline streamsize
143169691Skan    __copy_streambufs(basic_streambuf<_CharT, _Traits>* __sbin,
144169691Skan		      basic_streambuf<_CharT, _Traits>* __sbout)
145169691Skan    {
146169691Skan      bool __ineof;
147169691Skan      return __copy_streambufs_eof(__sbin, __sbout, __ineof);
148169691Skan    }
149169691Skan
15097403Sobrien  // Inhibit implicit instantiations for required instantiations,
151132720Skan  // which are defined via explicit instantiations elsewhere.
15297403Sobrien  // NB:  This syntax is a GNU extension.
153132720Skan#if _GLIBCXX_EXTERN_TEMPLATE
15497403Sobrien  extern template class basic_streambuf<char>;
15597403Sobrien  extern template
15697403Sobrien    streamsize
157169691Skan    __copy_streambufs(basic_streambuf<char>*,
158169691Skan		      basic_streambuf<char>*);
159169691Skan  extern template
160169691Skan    streamsize
161169691Skan    __copy_streambufs_eof(basic_streambuf<char>*,
162169691Skan			  basic_streambuf<char>*, bool&);
16397403Sobrien
164132720Skan#ifdef _GLIBCXX_USE_WCHAR_T
16597403Sobrien  extern template class basic_streambuf<wchar_t>;
16697403Sobrien  extern template
16797403Sobrien    streamsize
168169691Skan    __copy_streambufs(basic_streambuf<wchar_t>*,
169169691Skan		      basic_streambuf<wchar_t>*);
170169691Skan  extern template
171169691Skan    streamsize
172169691Skan    __copy_streambufs_eof(basic_streambuf<wchar_t>*,
173169691Skan			  basic_streambuf<wchar_t>*, bool&);
174107606Sobrien#endif
175117397Skan#endif
17697403Sobrien
177169691Skan_GLIBCXX_END_NAMESPACE
178169691Skan
179132720Skan#endif
180