100db7afdSDavid E. O'Brien // Stream buffer classes -*- C++ -*-
200db7afdSDavid E. O'Brien
3*f8a1b7d9SAlexander Kabaev // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
400db7afdSDavid E. O'Brien // Free Software Foundation, Inc.
500db7afdSDavid E. O'Brien //
600db7afdSDavid E. O'Brien // This file is part of the GNU ISO C++ Library. This library is free
700db7afdSDavid E. O'Brien // software; you can redistribute it and/or modify it under the
800db7afdSDavid E. O'Brien // terms of the GNU General Public License as published by the
900db7afdSDavid E. O'Brien // Free Software Foundation; either version 2, or (at your option)
1000db7afdSDavid E. O'Brien // any later version.
1100db7afdSDavid E. O'Brien
1200db7afdSDavid E. O'Brien // This library is distributed in the hope that it will be useful,
1300db7afdSDavid E. O'Brien // but WITHOUT ANY WARRANTY; without even the implied warranty of
1400db7afdSDavid E. O'Brien // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1500db7afdSDavid E. O'Brien // GNU General Public License for more details.
1600db7afdSDavid E. O'Brien
1700db7afdSDavid E. O'Brien // You should have received a copy of the GNU General Public License along
1800db7afdSDavid E. O'Brien // with this library; see the file COPYING. If not, write to the Free
19*f8a1b7d9SAlexander Kabaev // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
2000db7afdSDavid E. O'Brien // USA.
2100db7afdSDavid E. O'Brien
2200db7afdSDavid E. O'Brien // As a special exception, you may use this file as part of a free software
2300db7afdSDavid E. O'Brien // library without restriction. Specifically, if other files instantiate
2400db7afdSDavid E. O'Brien // templates or use macros or inline functions from this file, or you compile
2500db7afdSDavid E. O'Brien // this file and link it with other files to produce an executable, this
2600db7afdSDavid E. O'Brien // file does not by itself cause the resulting executable to be covered by
2700db7afdSDavid E. O'Brien // the GNU General Public License. This exception does not however
2800db7afdSDavid E. O'Brien // invalidate any other reasons why the executable file might be covered by
2900db7afdSDavid E. O'Brien // the GNU General Public License.
3000db7afdSDavid E. O'Brien
31*f8a1b7d9SAlexander Kabaev /** @file streambuf.tcc
32*f8a1b7d9SAlexander Kabaev * This is an internal header file, included by other library headers.
33*f8a1b7d9SAlexander Kabaev * You should not attempt to use it directly.
34*f8a1b7d9SAlexander Kabaev */
35*f8a1b7d9SAlexander Kabaev
3600db7afdSDavid E. O'Brien //
3700db7afdSDavid E. O'Brien // ISO C++ 14882: 27.5 Stream buffers
3800db7afdSDavid E. O'Brien //
3900db7afdSDavid E. O'Brien
40ffeaf689SAlexander Kabaev #ifndef _STREAMBUF_TCC
41ffeaf689SAlexander Kabaev #define _STREAMBUF_TCC 1
4200db7afdSDavid E. O'Brien
4300db7afdSDavid E. O'Brien #pragma GCC system_header
4400db7afdSDavid E. O'Brien
_GLIBCXX_BEGIN_NAMESPACE(std)45*f8a1b7d9SAlexander Kabaev _GLIBCXX_BEGIN_NAMESPACE(std)
46*f8a1b7d9SAlexander Kabaev
4700db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits>
4800db7afdSDavid E. O'Brien streamsize
4900db7afdSDavid E. O'Brien basic_streambuf<_CharT, _Traits>::
5000db7afdSDavid E. O'Brien xsgetn(char_type* __s, streamsize __n)
5100db7afdSDavid E. O'Brien {
5200db7afdSDavid E. O'Brien streamsize __ret = 0;
5300db7afdSDavid E. O'Brien while (__ret < __n)
5400db7afdSDavid E. O'Brien {
55*f8a1b7d9SAlexander Kabaev const streamsize __buf_len = this->egptr() - this->gptr();
56ffeaf689SAlexander Kabaev if (__buf_len)
5700db7afdSDavid E. O'Brien {
58*f8a1b7d9SAlexander Kabaev const streamsize __remaining = __n - __ret;
59*f8a1b7d9SAlexander Kabaev const streamsize __len = std::min(__buf_len, __remaining);
60ffeaf689SAlexander Kabaev traits_type::copy(__s, this->gptr(), __len);
6100db7afdSDavid E. O'Brien __ret += __len;
6200db7afdSDavid E. O'Brien __s += __len;
63ffeaf689SAlexander Kabaev this->gbump(__len);
6400db7afdSDavid E. O'Brien }
6500db7afdSDavid E. O'Brien
6600db7afdSDavid E. O'Brien if (__ret < __n)
6700db7afdSDavid E. O'Brien {
68ffeaf689SAlexander Kabaev const int_type __c = this->uflow();
69ca6500fcSAlexander Kabaev if (!traits_type::eq_int_type(__c, traits_type::eof()))
7000db7afdSDavid E. O'Brien {
7100db7afdSDavid E. O'Brien traits_type::assign(*__s++, traits_type::to_char_type(__c));
7200db7afdSDavid E. O'Brien ++__ret;
7300db7afdSDavid E. O'Brien }
7400db7afdSDavid E. O'Brien else
7500db7afdSDavid E. O'Brien break;
7600db7afdSDavid E. O'Brien }
7700db7afdSDavid E. O'Brien }
7800db7afdSDavid E. O'Brien return __ret;
7900db7afdSDavid E. O'Brien }
8000db7afdSDavid E. O'Brien
8100db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits>
8200db7afdSDavid E. O'Brien streamsize
8300db7afdSDavid E. O'Brien basic_streambuf<_CharT, _Traits>::
xsputn(const char_type * __s,streamsize __n)8400db7afdSDavid E. O'Brien xsputn(const char_type* __s, streamsize __n)
8500db7afdSDavid E. O'Brien {
8600db7afdSDavid E. O'Brien streamsize __ret = 0;
8700db7afdSDavid E. O'Brien while (__ret < __n)
8800db7afdSDavid E. O'Brien {
89*f8a1b7d9SAlexander Kabaev const streamsize __buf_len = this->epptr() - this->pptr();
90ffeaf689SAlexander Kabaev if (__buf_len)
9100db7afdSDavid E. O'Brien {
92*f8a1b7d9SAlexander Kabaev const streamsize __remaining = __n - __ret;
93*f8a1b7d9SAlexander Kabaev const streamsize __len = std::min(__buf_len, __remaining);
94ffeaf689SAlexander Kabaev traits_type::copy(this->pptr(), __s, __len);
9500db7afdSDavid E. O'Brien __ret += __len;
9600db7afdSDavid E. O'Brien __s += __len;
97ffeaf689SAlexander Kabaev this->pbump(__len);
9800db7afdSDavid E. O'Brien }
9900db7afdSDavid E. O'Brien
10000db7afdSDavid E. O'Brien if (__ret < __n)
10100db7afdSDavid E. O'Brien {
10200db7afdSDavid E. O'Brien int_type __c = this->overflow(traits_type::to_int_type(*__s));
103ca6500fcSAlexander Kabaev if (!traits_type::eq_int_type(__c, traits_type::eof()))
10400db7afdSDavid E. O'Brien {
10500db7afdSDavid E. O'Brien ++__ret;
10600db7afdSDavid E. O'Brien ++__s;
10700db7afdSDavid E. O'Brien }
10800db7afdSDavid E. O'Brien else
10900db7afdSDavid E. O'Brien break;
11000db7afdSDavid E. O'Brien }
11100db7afdSDavid E. O'Brien }
11200db7afdSDavid E. O'Brien return __ret;
11300db7afdSDavid E. O'Brien }
11400db7afdSDavid E. O'Brien
11500db7afdSDavid E. O'Brien // Conceivably, this could be used to implement buffer-to-buffer
11600db7afdSDavid E. O'Brien // copies, if this was ever desired in an un-ambiguous way by the
117*f8a1b7d9SAlexander Kabaev // standard.
11800db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits>
11900db7afdSDavid E. O'Brien streamsize
__copy_streambufs_eof(basic_streambuf<_CharT,_Traits> * __sbin,basic_streambuf<_CharT,_Traits> * __sbout,bool & __ineof)120*f8a1b7d9SAlexander Kabaev __copy_streambufs_eof(basic_streambuf<_CharT, _Traits>* __sbin,
121*f8a1b7d9SAlexander Kabaev basic_streambuf<_CharT, _Traits>* __sbout,
122*f8a1b7d9SAlexander Kabaev bool& __ineof)
12300db7afdSDavid E. O'Brien {
12400db7afdSDavid E. O'Brien streamsize __ret = 0;
125*f8a1b7d9SAlexander Kabaev __ineof = true;
1261b86b14eSAlexander Kabaev typename _Traits::int_type __c = __sbin->sgetc();
1271b86b14eSAlexander Kabaev while (!_Traits::eq_int_type(__c, _Traits::eof()))
12800db7afdSDavid E. O'Brien {
1291b86b14eSAlexander Kabaev __c = __sbout->sputc(_Traits::to_char_type(__c));
1301b86b14eSAlexander Kabaev if (_Traits::eq_int_type(__c, _Traits::eof()))
131*f8a1b7d9SAlexander Kabaev {
132*f8a1b7d9SAlexander Kabaev __ineof = false;
1338f1134fbSDavid E. O'Brien break;
134*f8a1b7d9SAlexander Kabaev }
1351b86b14eSAlexander Kabaev ++__ret;
1361b86b14eSAlexander Kabaev __c = __sbin->snextc();
1378f1134fbSDavid E. O'Brien }
13800db7afdSDavid E. O'Brien return __ret;
13900db7afdSDavid E. O'Brien }
14000db7afdSDavid E. O'Brien
141*f8a1b7d9SAlexander Kabaev template<typename _CharT, typename _Traits>
142*f8a1b7d9SAlexander Kabaev inline streamsize
__copy_streambufs(basic_streambuf<_CharT,_Traits> * __sbin,basic_streambuf<_CharT,_Traits> * __sbout)143*f8a1b7d9SAlexander Kabaev __copy_streambufs(basic_streambuf<_CharT, _Traits>* __sbin,
144*f8a1b7d9SAlexander Kabaev basic_streambuf<_CharT, _Traits>* __sbout)
145*f8a1b7d9SAlexander Kabaev {
146*f8a1b7d9SAlexander Kabaev bool __ineof;
147*f8a1b7d9SAlexander Kabaev return __copy_streambufs_eof(__sbin, __sbout, __ineof);
148*f8a1b7d9SAlexander Kabaev }
149*f8a1b7d9SAlexander Kabaev
15000db7afdSDavid E. O'Brien // Inhibit implicit instantiations for required instantiations,
15100db7afdSDavid E. O'Brien // which are defined via explicit instantiations elsewhere.
15200db7afdSDavid E. O'Brien // NB: This syntax is a GNU extension.
153ffeaf689SAlexander Kabaev #if _GLIBCXX_EXTERN_TEMPLATE
15400db7afdSDavid E. O'Brien extern template class basic_streambuf<char>;
15500db7afdSDavid E. O'Brien extern template
15600db7afdSDavid E. O'Brien streamsize
157*f8a1b7d9SAlexander Kabaev __copy_streambufs(basic_streambuf<char>*,
158*f8a1b7d9SAlexander Kabaev basic_streambuf<char>*);
159*f8a1b7d9SAlexander Kabaev extern template
160*f8a1b7d9SAlexander Kabaev streamsize
161*f8a1b7d9SAlexander Kabaev __copy_streambufs_eof(basic_streambuf<char>*,
162*f8a1b7d9SAlexander Kabaev basic_streambuf<char>*, bool&);
16300db7afdSDavid E. O'Brien
164ffeaf689SAlexander Kabaev #ifdef _GLIBCXX_USE_WCHAR_T
16500db7afdSDavid E. O'Brien extern template class basic_streambuf<wchar_t>;
16600db7afdSDavid E. O'Brien extern template
16700db7afdSDavid E. O'Brien streamsize
168*f8a1b7d9SAlexander Kabaev __copy_streambufs(basic_streambuf<wchar_t>*,
169*f8a1b7d9SAlexander Kabaev basic_streambuf<wchar_t>*);
170*f8a1b7d9SAlexander Kabaev extern template
171*f8a1b7d9SAlexander Kabaev streamsize
172*f8a1b7d9SAlexander Kabaev __copy_streambufs_eof(basic_streambuf<wchar_t>*,
173*f8a1b7d9SAlexander Kabaev basic_streambuf<wchar_t>*, bool&);
1748f1134fbSDavid E. O'Brien #endif
1751b86b14eSAlexander Kabaev #endif
176*f8a1b7d9SAlexander Kabaev
177*f8a1b7d9SAlexander Kabaev _GLIBCXX_END_NAMESPACE
17800db7afdSDavid E. O'Brien
17900db7afdSDavid E. O'Brien #endif
180