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