streambuf.tcc revision 132720
197403Sobrien// Stream buffer classes -*- C++ -*- 297403Sobrien 3117397Skan// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 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 1997403Sobrien// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 3197403Sobrien// 3297403Sobrien// ISO C++ 14882: 27.5 Stream buffers 3397403Sobrien// 3497403Sobrien 35132720Skan#ifndef _STREAMBUF_TCC 36132720Skan#define _STREAMBUF_TCC 1 3797403Sobrien 3897403Sobrien#pragma GCC system_header 3997403Sobrien 40132720Skannamespace std 4197403Sobrien{ 4297403Sobrien template<typename _CharT, typename _Traits> 4397403Sobrien streamsize 4497403Sobrien basic_streambuf<_CharT, _Traits>:: 4597403Sobrien xsgetn(char_type* __s, streamsize __n) 4697403Sobrien { 4797403Sobrien streamsize __ret = 0; 4897403Sobrien while (__ret < __n) 4997403Sobrien { 50132720Skan const size_t __buf_len = this->egptr() - this->gptr(); 51132720Skan if (__buf_len) 5297403Sobrien { 53132720Skan const size_t __remaining = __n - __ret; 54132720Skan const size_t __len = std::min(__buf_len, __remaining); 55132720Skan traits_type::copy(__s, this->gptr(), __len); 5697403Sobrien __ret += __len; 5797403Sobrien __s += __len; 58132720Skan this->gbump(__len); 5997403Sobrien } 60132720Skan 6197403Sobrien if (__ret < __n) 6297403Sobrien { 63132720Skan const int_type __c = this->uflow(); 64102782Skan if (!traits_type::eq_int_type(__c, traits_type::eof())) 6597403Sobrien { 6697403Sobrien traits_type::assign(*__s++, traits_type::to_char_type(__c)); 6797403Sobrien ++__ret; 6897403Sobrien } 6997403Sobrien else 7097403Sobrien break; 7197403Sobrien } 7297403Sobrien } 7397403Sobrien return __ret; 7497403Sobrien } 7597403Sobrien 7697403Sobrien template<typename _CharT, typename _Traits> 7797403Sobrien streamsize 7897403Sobrien basic_streambuf<_CharT, _Traits>:: 7997403Sobrien xsputn(const char_type* __s, streamsize __n) 8097403Sobrien { 8197403Sobrien streamsize __ret = 0; 8297403Sobrien while (__ret < __n) 8397403Sobrien { 84132720Skan const size_t __buf_len = this->epptr() - this->pptr(); 85132720Skan if (__buf_len) 8697403Sobrien { 87132720Skan const size_t __remaining = __n - __ret; 88132720Skan const size_t __len = std::min(__buf_len, __remaining); 89132720Skan traits_type::copy(this->pptr(), __s, __len); 9097403Sobrien __ret += __len; 9197403Sobrien __s += __len; 92132720Skan this->pbump(__len); 9397403Sobrien } 9497403Sobrien 9597403Sobrien if (__ret < __n) 9697403Sobrien { 9797403Sobrien int_type __c = this->overflow(traits_type::to_int_type(*__s)); 98102782Skan if (!traits_type::eq_int_type(__c, traits_type::eof())) 9997403Sobrien { 10097403Sobrien ++__ret; 10197403Sobrien ++__s; 10297403Sobrien } 10397403Sobrien else 10497403Sobrien break; 10597403Sobrien } 10697403Sobrien } 10797403Sobrien return __ret; 10897403Sobrien } 10997403Sobrien 11097403Sobrien // Conceivably, this could be used to implement buffer-to-buffer 11197403Sobrien // copies, if this was ever desired in an un-ambiguous way by the 11297403Sobrien // standard. If so, then checks for __ios being zero would be 11397403Sobrien // necessary. 11497403Sobrien template<typename _CharT, typename _Traits> 11597403Sobrien streamsize 116132720Skan __copy_streambufs(basic_streambuf<_CharT, _Traits>* __sbin, 117132720Skan basic_streambuf<_CharT, _Traits>* __sbout) 118132720Skan { 119132720Skan streamsize __ret = 0; 120132720Skan typename _Traits::int_type __c = __sbin->sgetc(); 121132720Skan while (!_Traits::eq_int_type(__c, _Traits::eof())) 122132720Skan { 123132720Skan const size_t __n = __sbin->egptr() - __sbin->gptr(); 124132720Skan if (__n > 1) 125132720Skan { 126132720Skan const size_t __wrote = __sbout->sputn(__sbin->gptr(), __n); 127132720Skan __sbin->gbump(__wrote); 128132720Skan __ret += __wrote; 129132720Skan if (__wrote < __n) 130132720Skan break; 131132720Skan __c = __sbin->underflow(); 132132720Skan } 133132720Skan else 134132720Skan { 135132720Skan __c = __sbout->sputc(_Traits::to_char_type(__c)); 136132720Skan if (_Traits::eq_int_type(__c, _Traits::eof())) 137132720Skan break; 138132720Skan ++__ret; 139132720Skan __c = __sbin->snextc(); 140132720Skan } 141132720Skan } 142132720Skan return __ret; 143132720Skan } 14497403Sobrien 14597403Sobrien // Inhibit implicit instantiations for required instantiations, 146132720Skan // which are defined via explicit instantiations elsewhere. 14797403Sobrien // NB: This syntax is a GNU extension. 148132720Skan#if _GLIBCXX_EXTERN_TEMPLATE 14997403Sobrien extern template class basic_streambuf<char>; 15097403Sobrien extern template 15197403Sobrien streamsize 152132720Skan __copy_streambufs(basic_streambuf<char>*, basic_streambuf<char>*); 15397403Sobrien 154132720Skan#ifdef _GLIBCXX_USE_WCHAR_T 15597403Sobrien extern template class basic_streambuf<wchar_t>; 15697403Sobrien extern template 15797403Sobrien streamsize 158132720Skan __copy_streambufs(basic_streambuf<wchar_t>*, basic_streambuf<wchar_t>*); 159107606Sobrien#endif 160117397Skan#endif 16197403Sobrien} // namespace std 16297403Sobrien 163132720Skan#endif 164