1// Stream buffer classes -*- C++ -*-
2
3// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4// 2006, 2007, 2008, 2009, 2010, 2011  Free Software Foundation, Inc.
5//
6// This file is part of the GNU ISO C++ Library.  This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 3, or (at your option)
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16
17// Under Section 7 of GPL version 3, you are granted additional
18// permissions described in the GCC Runtime Library Exception, version
19// 3.1, as published by the Free Software Foundation.
20
21// You should have received a copy of the GNU General Public License and
22// a copy of the GCC Runtime Library Exception along with this program;
23// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24// <http://www.gnu.org/licenses/>.
25
26/** @file bits/streambuf.tcc
27 *  This is an internal header file, included by other library headers.
28 *  Do not attempt to use it directly. @headername{streambuf}
29 */
30
31//
32// ISO C++ 14882: 27.5  Stream buffers
33//
34
35#ifndef _STREAMBUF_TCC
36#define _STREAMBUF_TCC 1
37
38#pragma GCC system_header
39
40namespace std _GLIBCXX_VISIBILITY(default)
41{
42_GLIBCXX_BEGIN_NAMESPACE_VERSION
43
44  template<typename _CharT, typename _Traits>
45    streamsize
46    basic_streambuf<_CharT, _Traits>::
47    xsgetn(char_type* __s, streamsize __n)
48    {
49      streamsize __ret = 0;
50      while (__ret < __n)
51	{
52	  const streamsize __buf_len = this->egptr() - this->gptr();
53	  if (__buf_len)
54	    {
55	      const streamsize __remaining = __n - __ret;
56	      const streamsize __len = std::min(__buf_len, __remaining);
57	      traits_type::copy(__s, this->gptr(), __len);
58	      __ret += __len;
59	      __s += __len;
60	      this->__safe_gbump(__len);
61	    }
62
63	  if (__ret < __n)
64	    {
65	      const int_type __c = this->uflow();
66	      if (!traits_type::eq_int_type(__c, traits_type::eof()))
67		{
68		  traits_type::assign(*__s++, traits_type::to_char_type(__c));
69		  ++__ret;
70		}
71	      else
72		break;
73	    }
74	}
75      return __ret;
76    }
77
78  template<typename _CharT, typename _Traits>
79    streamsize
80    basic_streambuf<_CharT, _Traits>::
81    xsputn(const char_type* __s, streamsize __n)
82    {
83      streamsize __ret = 0;
84      while (__ret < __n)
85	{
86	  const streamsize __buf_len = this->epptr() - this->pptr();
87	  if (__buf_len)
88	    {
89	      const streamsize __remaining = __n - __ret;
90	      const streamsize __len = std::min(__buf_len, __remaining);
91	      traits_type::copy(this->pptr(), __s, __len);
92	      __ret += __len;
93	      __s += __len;
94	      this->__safe_pbump(__len);
95	    }
96
97	  if (__ret < __n)
98	    {
99	      int_type __c = this->overflow(traits_type::to_int_type(*__s));
100	      if (!traits_type::eq_int_type(__c, traits_type::eof()))
101		{
102		  ++__ret;
103		  ++__s;
104		}
105	      else
106		break;
107	    }
108	}
109      return __ret;
110    }
111
112  // Conceivably, this could be used to implement buffer-to-buffer
113  // copies, if this was ever desired in an un-ambiguous way by the
114  // standard.
115  template<typename _CharT, typename _Traits>
116    streamsize
117    __copy_streambufs_eof(basic_streambuf<_CharT, _Traits>* __sbin,
118			  basic_streambuf<_CharT, _Traits>* __sbout,
119			  bool& __ineof)
120    {
121      streamsize __ret = 0;
122      __ineof = true;
123      typename _Traits::int_type __c = __sbin->sgetc();
124      while (!_Traits::eq_int_type(__c, _Traits::eof()))
125	{
126	  __c = __sbout->sputc(_Traits::to_char_type(__c));
127	  if (_Traits::eq_int_type(__c, _Traits::eof()))
128	    {
129	      __ineof = false;
130	      break;
131	    }
132	  ++__ret;
133	  __c = __sbin->snextc();
134	}
135      return __ret;
136    }
137
138  template<typename _CharT, typename _Traits>
139    inline streamsize
140    __copy_streambufs(basic_streambuf<_CharT, _Traits>* __sbin,
141		      basic_streambuf<_CharT, _Traits>* __sbout)
142    {
143      bool __ineof;
144      return __copy_streambufs_eof(__sbin, __sbout, __ineof);
145    }
146
147  // Inhibit implicit instantiations for required instantiations,
148  // which are defined via explicit instantiations elsewhere.
149#if _GLIBCXX_EXTERN_TEMPLATE
150  extern template class basic_streambuf<char>;
151  extern template
152    streamsize
153    __copy_streambufs(basic_streambuf<char>*,
154		      basic_streambuf<char>*);
155  extern template
156    streamsize
157    __copy_streambufs_eof(basic_streambuf<char>*,
158			  basic_streambuf<char>*, bool&);
159
160#ifdef _GLIBCXX_USE_WCHAR_T
161  extern template class basic_streambuf<wchar_t>;
162  extern template
163    streamsize
164    __copy_streambufs(basic_streambuf<wchar_t>*,
165		      basic_streambuf<wchar_t>*);
166  extern template
167    streamsize
168    __copy_streambufs_eof(basic_streambuf<wchar_t>*,
169			  basic_streambuf<wchar_t>*, bool&);
170#endif
171#endif
172
173_GLIBCXX_END_NAMESPACE_VERSION
174} // namespace std
175
176#endif
177