// Stream buffer classes -*- C++ -*- // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 2, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // As a special exception, you may use this file as part of a free software // library without restriction. Specifically, if other files instantiate // templates or use macros or inline functions from this file, or you compile // this file and link it with other files to produce an executable, this // file does not by itself cause the resulting executable to be covered by // the GNU General Public License. This exception does not however // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. // // ISO C++ 14882: 27.5 Stream buffers // #ifndef _CPP_BITS_STREAMBUF_TCC #define _CPP_BITS_STREAMBUF_TCC 1 #pragma GCC system_header namespace std { template typename basic_streambuf<_CharT, _Traits>::int_type basic_streambuf<_CharT, _Traits>:: sbumpc() { int_type __ret; if (_M_in_cur < _M_in_end) { char_type __c = *this->_M_in_cur; _M_move_in_cur(1); __ret = traits_type::to_int_type(__c); } else __ret = this->uflow(); return __ret; } template typename basic_streambuf<_CharT, _Traits>::int_type basic_streambuf<_CharT, _Traits>:: sputbackc(char_type __c) { int_type __ret; const bool __testpos = _M_in_beg < _M_in_cur; if (!__testpos || !traits_type::eq(__c, this->_M_in_cur[-1])) __ret = this->pbackfail(traits_type::to_int_type(__c)); else { _M_move_in_cur(-1); __ret = traits_type::to_int_type(*this->_M_in_cur); } return __ret; } template typename basic_streambuf<_CharT, _Traits>::int_type basic_streambuf<_CharT, _Traits>:: sungetc() { int_type __ret; if (_M_in_beg < _M_in_cur) { _M_move_in_cur(-1); __ret = traits_type::to_int_type(*_M_in_cur); } else __ret = this->pbackfail(); return __ret; } template typename basic_streambuf<_CharT, _Traits>::int_type basic_streambuf<_CharT, _Traits>:: sputc(char_type __c) { int_type __ret; if (_M_out_cur < _M_out_end) { *_M_out_cur = __c; _M_move_out_cur(1); __ret = traits_type::to_int_type(__c); } else __ret = this->overflow(traits_type::to_int_type(__c)); return __ret; } template streamsize basic_streambuf<_CharT, _Traits>:: xsgetn(char_type* __s, streamsize __n) { streamsize __ret = 0; while (__ret < __n) { size_t __buf_len = _M_in_end - _M_in_cur; if (__buf_len > 0) { size_t __remaining = __n - __ret; size_t __len = std::min(__buf_len, __remaining); traits_type::copy(__s, _M_in_cur, __len); __ret += __len; __s += __len; _M_move_in_cur(__len); } if (__ret < __n) { int_type __c = this->uflow(); if (!traits_type::eq_int_type(__c, traits_type::eof())) { traits_type::assign(*__s++, traits_type::to_char_type(__c)); ++__ret; } else break; } } return __ret; } template streamsize basic_streambuf<_CharT, _Traits>:: xsputn(const char_type* __s, streamsize __n) { streamsize __ret = 0; while (__ret < __n) { off_type __buf_len = _M_out_end - _M_out_cur; if (__buf_len > 0) { off_type __remaining = __n - __ret; off_type __len = std::min(__buf_len, __remaining); traits_type::copy(_M_out_cur, __s, __len); __ret += __len; __s += __len; _M_move_out_cur(__len); } if (__ret < __n) { int_type __c = this->overflow(traits_type::to_int_type(*__s)); if (!traits_type::eq_int_type(__c, traits_type::eof())) { ++__ret; ++__s; } else break; } } return __ret; } // Conceivably, this could be used to implement buffer-to-buffer // copies, if this was ever desired in an un-ambiguous way by the // standard. If so, then checks for __ios being zero would be // necessary. template streamsize __copy_streambufs(basic_ios<_CharT, _Traits>& __ios, basic_streambuf<_CharT, _Traits>* __sbin, basic_streambuf<_CharT, _Traits>* __sbout) { typedef typename _Traits::int_type int_type; typedef typename _Traits::off_type off_type; streamsize __ret = 0; const off_type __buf_size = __sbin->_M_buf_size > 0 ? __sbin->_M_buf_size : 1; try { for (;;) { streamsize __xtrct; const off_type __avail = __sbin->_M_in_end - __sbin->_M_in_cur; if (__avail) { __xtrct = __sbout->sputn(__sbin->_M_in_cur, __avail); __ret += __xtrct; __sbin->_M_move_in_cur(__xtrct); if (__xtrct != __avail) break; } else { streamsize __charsread; const off_type __size = std::min(__buf_size, off_type(__sbout->_M_out_end - __sbout->_M_out_cur)); if (__size > 1) { _CharT* __buf = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __size)); // Since the next sputn cannot fail sgetn can be // safely used. __charsread = __sbin->sgetn(__buf, __size); __xtrct = __sbout->sputn(__buf, __charsread); } else { __xtrct = __charsread = 0; int_type __c = __sbin->sgetc(); while (!_Traits::eq_int_type(__c, _Traits::eof())) { ++__charsread; if (_Traits::eq_int_type(__sbout->sputc(_Traits::to_char_type(__c)), _Traits::eof())) break; ++__xtrct; __c = __sbin->snextc(); } } __ret += __xtrct; if (__xtrct != __charsread) break; } if (_Traits::eq_int_type(__sbin->sgetc(), _Traits::eof())) break; } } catch(exception& __fail) { __ios.setstate(ios_base::failbit); if ((__ios.exceptions() & ios_base::failbit) != 0) __throw_exception_again; } return __ret; } // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. #if _GLIBCPP_EXTERN_TEMPLATE extern template class basic_streambuf; extern template streamsize __copy_streambufs(basic_ios&, basic_streambuf*, basic_streambuf*); #ifdef _GLIBCPP_USE_WCHAR_T extern template class basic_streambuf; extern template streamsize __copy_streambufs(basic_ios&, basic_streambuf*, basic_streambuf*); #endif #endif } // namespace std #endif