/***************************************************************************
 *
 * 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);
    }
    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);

            // take ownership of the allocated buffer
            this->_C_own_buf (true);

            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 ());

        _RWSTD_PTRDIFF_T __off = -1;

        if (this->pbase () <= __s && this->pptr () > __s) {
            // __s is a part of the buffer
            _RWSTD_ASSERT (this->epptr () >= __s + __n);
            // save the offset from pbase()
            __off = this->pbase () - __s;
        }

        // preserve current pptr() since str() would seek to end
        const streamsize __cur = 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);

        // restore pptr()
        this->pbump (__cur - (this->pptr () - this->pbase ()));

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

        if (0 <= __off) {
            // correct __s after the buffer reallocation
            __s = this->pbase () + __off;
        }
    }

    // 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
