/***************************************************************************
 *
 * 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;
    // saved offset of pptr 
    _RWSTD_STREAMSIZE __off = -1;

    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 ();
        // save the offset of pptr
        __off = this->pptr () - 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 (0 <= __off) {
            // restore the pptr
            this->pbump (__off);
        }
        else if (   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;
        }

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

        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
