/***************************************************************************
 *
 * sstream.cc - Declarations for the Standard Library basic strings
 *
 * $Id$
 *
 ***************************************************************************
 *
 * Licensed to the Apache Software  Foundation (ASF) under one or more
 * contributor  license agreements.  See  the NOTICE  file distributed
 * with  this  work  for  additional information  regarding  copyright
 * ownership.   The ASF  licenses this  file to  you 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.
 *
 * Copyright 1994-2006 Rogue Wave Software.
 *
 **************************************************************************/


_RWSTD_NAMESPACE (std) {


template<class _CharT, class _Traits, class _Allocator>
basic_stringbuf<_CharT, _Traits, _Allocator>::
basic_stringbuf (const _C_string_type& __str, ios_base::openmode __mode)
    : basic_streambuf<_CharT, _Traits>(__mode)
{
    str (__str);
}


// extension
template<class _CharT, class _Traits, class _Allocator>
basic_stringbuf<_CharT, _Traits, _Allocator>::
basic_stringbuf (const char_type *__s, ios_base::openmode __mode)
    : basic_streambuf<_CharT, _Traits>(__mode)
{
    _RWSTD_ASSERT (0 != __s);

    str (__s, traits_type::length (__s));
}


template <class _CharT, class _Traits, class _Allocator>
/* virtual */
basic_stringbuf<_CharT, _Traits, _Allocator>::
~basic_stringbuf ()
{
    typedef _RWSTD_ALLOC_TYPE (allocator_type, char_type) _ValueAlloc;

    if (this->_C_own_buf ())
        _ValueAlloc ().deallocate (this->_C_buffer, this->_C_bufsize);
}


// extension
template<class _CharT, class _Traits, class _Allocator>
void
basic_stringbuf<_CharT, _Traits, _Allocator>::
str (const char_type *__s, _RWSTD_SIZE_T __slen)
{
    _RWSTD_ASSERT (this->_C_is_valid ());

    typedef _RWSTD_ALLOC_TYPE (allocator_type, char_type) _ValueAlloc;

    typedef _RWSTD_STREAMSIZE _Streamsize;

    // compute the lenth if not specified
    if (_RWSTD_SIZE_MAX == __slen)
        __slen = traits_type::length (__s);

    _ValueAlloc __alloc;

    // new buffer and size
    char_type     *__buf;
    _RWSTD_SIZE_T  __bufsize = __slen;

    if (__s == this->_C_buffer) {
        // special case: str(_C_buffer, _C_bufsize + N) called
        // to increase the capacity of buffer

        _C_catchup (this->eback ());

        // set `slen' to the number of initialized characters
        // in the buffer
        __slen = this->egptr () - this->pbase ();
    }

    if (this->_C_bufsize < __bufsize) {
        // requested capacity is greater than the current capacity
        // allocate a new buffer of sufficient size
        __bufsize = _C_grow (__bufsize);

        if (__s != this->_C_buffer && this->_C_own_buf ()) {
            // deallocate the existing buffer here only if the string
            // is not the same as the buffer itself; otherwise, copy
            // it to the newly allocated buffer first and deallocate
            // it later
            __alloc.deallocate (this->_C_buffer, this->_C_bufsize);
            this->_C_buffer = 0;
        }

        __buf = __alloc.allocate (__bufsize);

        // take ownsership of the allocated buffer
        this->_C_own_buf (true);
    }
    else if (0 < __bufsize) {
        // requested capacity is the same or less than the current one
        __buf     = this->_C_buffer;
        __bufsize = this->_C_bufsize;
    }
    else {
        // zero size and capacity, deallocate and reset all pointers
        __buf     = 0;
        __bufsize = 0;

        _RWSTD_ASSERT (0 == __slen);
    }

    // compute the "high mark" (see lwg issue 432)
    char_type* const __egptr = __buf + __slen;

    if (__s != __buf) {
        // copy the provided string to buffer
        traits_type::copy (__buf, __s, __slen);

        if (this->_C_buffer != __buf) {
            if (this->_C_buffer && this->_C_own_buf ())
                __alloc.deallocate (this->_C_buffer, this->_C_bufsize);

            this->_C_buffer  = __buf;
            this->_C_bufsize = __bufsize;
        }
    }

    if (this->_C_is_in ())
        this->setg (this->_C_buffer, this->_C_buffer, __egptr);
    else {
        // when not in in mode set all get pointers to the same
        // value and use egptr() as the "high mark" (see lwg
        // issue 432)
        this->setg (__egptr, __egptr, __egptr);
    }

    if (this->_C_is_out ()) {
        this->setp (this->_C_buffer, this->_C_buffer + this->_C_bufsize);

        if (   __s != __buf && this->_C_state & ios_base::in
            || this->_C_state & (ios_base::app | ios_base::ate)) {
            // in input or append/ate modes seek to end
            // (see also lwg issue 562 for clarification)
            this->pbump (__slen);
        }
    }

    _RWSTD_ASSERT (this->_C_is_valid ());
}


template <class _CharT, class _Traits, class _Allocator>
streamsize
basic_stringbuf<_CharT, _Traits, _Allocator>::
xsputn (const char_type* __s, streamsize __n)
{
    _RWSTD_ASSERT (0 != __s || 0 == __n);
    _RWSTD_ASSERT (this->_C_is_valid ());

    if (__n <= 0 || !this->_C_is_out ())
        return 0;

    if (this->epptr () - this->pptr () < __n) {

        // compute the total amount of space necessary
        const _RWSTD_SIZE_T __bufsize =
            __n + (this->pptr () - this->pbase ());

        // grow the buffer if necessary to accommodate the whole
        // string plus the contents of the buffer up to pptr()
        str (this->_C_buffer, __bufsize);

        _RWSTD_ASSERT (__n <= this->epptr () - this->pptr ());
    }

    // copy the whole string
    traits_type::copy (this->pptr (), __s, __n);

    this->pbump (__n);

    _C_catchup (this->eback ());

    return __n;
}


template <class _CharT, class _Traits, class _Allocator>
/* virtual */ streamsize
basic_stringbuf<_CharT, _Traits, _Allocator>::
showmanyc ()
{
    _RWSTD_ASSERT (this->_C_is_valid ());

    // get egptr() caught up with pptr()
    _C_catchup (this->eback ());

    return streamsize (this->egptr () - this->gptr ());
}


template <class _CharT, class _Traits, class _Allocator>
/* virtual */ _TYPENAME basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
basic_stringbuf<_CharT, _Traits, _Allocator>::
underflow ()
{
    _RWSTD_ASSERT (this->_C_is_valid ());

    if (this->gptr () < this->egptr ()) {

        _RWSTD_ASSERT (0 != this->gptr ());

        return traits_type::to_int_type (*this->gptr ());
    }
    else if (this->gptr () < this->pptr ()) {

        // get egptr() caught up with pptr()
        _C_catchup (this->eback ());

        if (this->gptr () < this->egptr ())
            return traits_type::to_int_type (*this->gptr ());
    }

    return traits_type::eof ();
}


template<class _CharT, class _Traits, class _Allocator>
_TYPENAME basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
basic_stringbuf<_CharT, _Traits, _Allocator>::
overflow (int_type __c)
{
    _RWSTD_ASSERT (this->_C_is_valid ());

    // 27.7.1.3, p5, bullet 2 of C++ '03: when (c == eof)
    // indicate success even when not in out mode
    if (this->_C_is_eof (__c))
        return traits_type::not_eof (__c);

    if (!this->_C_is_out ())
        return traits_type::eof ();

    char_type* const __bufend = this->_C_buffer + this->_C_bufsize;

    if (this->pptr () == this->epptr ()) {
        // reallocate buffer
        str (this->_C_buffer, this->_C_bufsize + 1);
    }
    else if (this->epptr () < __bufend) {
        // bump up epptr() keeping pbase() and pptr() unchanged

        const _RWSTD_STREAMSIZE __off = this->pptr () - this->pbase ();
        this->setp (this->pbase (), __bufend);
        this->pbump (__off);
    }

    const int_type __retval = this->sputc (traits_type::to_char_type (__c));

    // get egptr() caught up with the value of pptr() after the call
    _C_catchup (this->_C_buffer);

    return __retval;
}


template<class _CharT, class _Traits, class _Allocator>
/* virtual */ _TYPENAME basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
basic_stringbuf<_CharT, _Traits, _Allocator>::
pbackfail (int_type __c)
{
    _RWSTD_ASSERT (this->_C_is_valid ());

    if (!this->_C_putback_avail ())
        return traits_type::eof ();

    int_type __retval;

    const char_type __ch = traits_type::to_char_type (__c);

    if (traits_type::eq (__ch, *(this->gptr () - 1)) || this->_C_is_eof (__c)) {
        // "put back" original value
        this->gbump (-1);
        __retval = traits_type::not_eof (__c);
    }
    else if (this->_C_is_out ()) {
        // overwrite existing value with new value
        this->gbump (-1);
        traits_type::assign (*this->gptr (), __ch);
        __retval = __c;
    }
    else
        __retval = traits_type::eof ();

    return __retval;
}


template<class _CharT, class _Traits, class _Allocator>
/* virtual */ basic_streambuf<_CharT, _Traits>*
basic_stringbuf<_CharT, _Traits, _Allocator>::
setbuf (char_type* __buf, _RWSTD_STREAMSIZE __n)
{
    _RWSTD_ASSERT (this->_C_is_valid ());

    if (!__buf && !__n)   // 27.7.1.3, p16
        return this;

    const _RWSTD_STREAMSIZE __slen = (this->egptr () < this->pptr () ?
        this->pptr () : this->egptr ()) - this->pbase ();

    if (__n < __slen || !this->_C_is_out())
        return 0;   // failure

    // compute the gptr and pptr offsets so the pointers can be restored
    const _RWSTD_STREAMSIZE __goff = this->gptr () - this->eback ();
    const _RWSTD_STREAMSIZE __poff = this->pptr () - this->pbase ();

    const bool __own_old_buf = this->_C_own_buf ();

    typedef _RWSTD_ALLOC_TYPE (allocator_type, char_type) _ValueAlloc;

    if (0 == __buf) {
        // allocate a new buffer of the specified size
        __buf = _ValueAlloc ().allocate (__n);
        this->_C_own_buf (true);
    }
    else
        this->_C_own_buf (false);

    // copy the contents of the existing buffer to the new one
    traits_type::copy (__buf, this->_C_buffer, __slen);

    if (__own_old_buf)
        _ValueAlloc ().deallocate (this->_C_buffer, this->_C_bufsize);

    this->_C_buffer  = __buf;
    this->_C_bufsize = __n;

    // reset the output and input sequences within the new buffer
    this->setp (this->_C_buffer, this->_C_buffer + this->_C_bufsize);
    this->pbump (__poff);   // ... and restore it

    char_type* const __egptr = this->_C_buffer + __slen;

    if (this->_C_is_in ())
        this->setg (this->_C_buffer, this->_C_buffer + __goff, __egptr);
    else {
        // use egptr as the "high mark" (see lwg issue 432)
        this->setg (__egptr, __egptr, __egptr);
    }

    return this;
}


template<class _CharT, class _Traits, class _Allocator>
/* virtual */ _TYPENAME basic_stringbuf<_CharT, _Traits, _Allocator>::pos_type
basic_stringbuf<_CharT, _Traits, _Allocator>::
seekoff (off_type __off, ios_base::seekdir __way, ios_base::openmode __which)
{
    _RWSTD_ASSERT (this->_C_is_valid ());

    // should implicitly hold as long as ios::seekdir is an enum
    _RWSTD_ASSERT (   ios_base::beg == __way
                   || ios_base::cur == __way
                   || ios_base::end == __way);

    _RWSTD_STREAMSIZE __newoff = -1;

    // get egptr() caught up with pptr()
    _C_catchup (this->eback ());

    if (__which & ios_base::in) {

        // LWG issue 453: the operation fails if either gptr() or pptr()
        // is a null pointer and the new offset newoff is nonzero
        if (!this->_C_is_in () || __off && !this->gptr ())
            return pos_type (off_type (-1));

        // do the checks for in|out mode here
        if (   __which & ios_base::out
            && (ios_base::cur == __way || !this->_C_is_out ()))
            return pos_type (off_type (-1));

        switch (__way) {
        case ios_base::beg: __newoff = 0; break;
        case ios_base::cur: __newoff = this->gptr () - this->eback (); break;
        case ios_base::end: __newoff = this->egptr () - this->eback (); break;
        }

        __newoff += __off;

        if (__newoff < 0 || this->egptr () - this->eback () < __newoff)
            return pos_type (off_type (-1));

        this->setg (this->eback (), this->eback () + __newoff, this->egptr ());
    }

    if (__which & ios_base::out) {

        // LWG issue 453: the operation fails if either gptr() or pptr()
        // is a null pointer and the new offset newoff is nonzero
        if (!this->_C_is_out () || __off && !this->pptr ())
            return pos_type (off_type (-1));

        // egptr() is used as the "high mark" even when not in "in" mode
        _RWSTD_ASSERT (0 == this->pbase () || 0 != this->egptr ());

        // compute the number of initialized characters in the buffer
        // (see LWG issue 432)
        const _RWSTD_STREAMSIZE __high = this->egptr () - this->pbase ();
        const _RWSTD_STREAMSIZE __cur  = this->pptr () - this->pbase ();

        switch (__way) {
        case ios_base::beg: __newoff = 0; break;
        case ios_base::cur: __newoff = __cur; break;
        case ios_base::end: __newoff = __high; break;
        }

        __newoff += __off;

        if (__newoff < 0 || __high < __newoff)
            return pos_type (off_type (-1));

        // bump pptr up (or down) to the new position
        this->pbump (__newoff - __cur);
    }

    _RWSTD_ASSERT (this->_C_is_valid ());

    return __newoff < 0 ? pos_type (off_type (-1)) : pos_type (__newoff);
}


template<class _CharT, class _Traits, class _Allocator>
/* virtual */ _TYPENAME basic_stringbuf<_CharT, _Traits, _Allocator>::pos_type
basic_stringbuf<_CharT, _Traits, _Allocator>::
seekpos (pos_type __pos, ios_base::openmode __which)
{
    _RWSTD_ASSERT (this->_C_is_valid ());

    // typedef helps HP aCC 3.27
    typedef basic_stringbuf _StringBuf;

    return pos_type (_StringBuf::seekoff (__pos, ios_base::beg, __which));
}


}   // namespace std
