blob: a8f2977173531152f1e3f7690a5a7a7d552f3357 [file] [log] [blame]
// -*- C++ -*-
/***************************************************************************
*
* streambuf.cc - definitions of basic_streambuf members
*
* $Id$
*
***************************************************************************
*
* Copyright 2006 The Apache Software Foundation or its licensors,
* as applicable.
*
* Copyright 1994-2006 Rogue Wave Software.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**************************************************************************/
_RWSTD_NAMESPACE (std) {
template <class _CharT, class _Traits>
basic_streambuf<_CharT, _Traits>::
basic_streambuf (ios_base::openmode __mode /* = ios_base::in | ios_base::out */)
: _C_buffer (0),
_C_bufsize (0),
_C_state (__mode),
_C_eback (0),
_C_gptr (0),
_C_egptr (0),
_C_pbase (0),
_C_pptr (0),
_C_epptr (0)
{
// no op
}
template <class _CharT, class _Traits>
_TYPENAME basic_streambuf<_CharT, _Traits>::int_type
basic_streambuf<_CharT, _Traits>::
uflow ()
{
_RWSTD_ASSERT (_C_is_valid ());
const int_type __c = underflow ();
if (traits_type::eq_int_type (__c, traits_type::eof ()))
return traits_type::eof ();
// handle unbuffered input mode
if (_C_gptr < _C_egptr)
return traits_type::to_int_type (*_C_gptr++);
return __c;
}
template <class _CharT, class _Traits>
streamsize
basic_streambuf<_CharT, _Traits>::
xsgetn (char_type* __buf, streamsize __n)
{
_RWSTD_ASSERT (_C_is_valid ());
// number of characters read
streamsize __nget = 0;
while (__n) {
// save the value returned from underflow() since the function
// can fill the buffer and still fail, say due to a code
// conversion error
const int_type __c = gptr () == egptr () ?
underflow () : traits_type::not_eof (traits_type::eof ());
// number of characters available in get area
streamsize __navail = egptr () - gptr ();
if (0 == __navail)
break;
if (__navail > __n)
__navail = __n;
// copy contents of get area to the destination buffer
traits_type::copy (__buf + __nget, gptr (), __navail);
// increment pointers and counts by the number of characters copied
gbump (__navail);
__n -= __navail;
__nget += __navail;
// break out on underflow error
if (traits_type::eq_int_type (__c, traits_type::eof ()))
break;
}
return __nget;
}
template<class _CharT, class _Traits>
streamsize
basic_streambuf<_CharT, _Traits>::
xsputn (const char_type* __buf, streamsize __n)
{
_RWSTD_ASSERT (0 != __buf || 0 == __n);
_RWSTD_ASSERT (_C_is_valid ());
if (__n <= 0 || !_C_is_out ())
return 0;
streamsize __nput = 0;
for (; ; ++__buf, --__n, ++__nput) {
const streamsize __navail = epptr () - pptr ();
const streamsize __nwrite = __navail < __n ? __navail : __n;
traits_type::copy (pptr (), __buf, __nwrite);
pbump (__nwrite);
__nput += __nwrite;
if (__nwrite == __n)
break;
__buf += __nwrite;
__n -= __nwrite;
const int_type __c = overflow (traits_type::to_int_type (*__buf));
if (traits_type::eq_int_type (traits_type::eof (), __c))
break;
}
return __nput;
}
} // namespace std