// -*- C++ -*-
/***************************************************************************
 *
 * sstream - Declarations for the Standard Library basic streams
 *
 * $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.
 * 
 **************************************************************************/

#ifndef _RWSTD_SSTREAM_INCLUDED
#define _RWSTD_SSTREAM_INCLUDED

#if __GNUG__ >= 3
#  pragma GCC system_header
#endif   // gcc >= 3

#include <streambuf>

#include <rw/_iosbase.h>
#include <rw/_iosfwd.h>
#include <rw/_defs.h>

#ifndef _RWSTD_NO_REDUNDANT_DEFINITIONS
#  include <istream>
#  include <ostream>
#endif   // _RWSTD_NO_REDUNDANT_DEFINITIONS



_RWSTD_NAMESPACE (std) { 

#ifndef _RWSTD_IOSFWD_INCLUDED

_EXPORT
template <class _CharT,
          class _Traits = char_traits<_CharT>,
          class _Alloc = allocator<_CharT> >
class basic_stringbuf;

_EXPORT
template <class _CharT,
          class _Traits = char_traits<_CharT>,
          class _Alloc = allocator<_CharT> >
class basic_istringstream;

_EXPORT
template <class _CharT,
          class _Traits = char_traits<_CharT>,
          class _Alloc = allocator<_CharT> >
class basic_ostringstream;

_EXPORT
template <class _CharT,
          class _Traits = char_traits<_CharT>,
          class _Alloc = allocator<_CharT> >
class basic_stringstream;

typedef basic_stringbuf<char>     stringbuf;
typedef basic_istringstream<char> istringstream;
typedef basic_ostringstream<char> ostringstream;
typedef basic_stringstream<char>  stringstream;

#  ifndef _RWSTD_NO_WCHAR_T

typedef basic_stringbuf<wchar_t>     wstringbuf;
typedef basic_istringstream<wchar_t> wistringstream;
typedef basic_ostringstream<wchar_t> wostringstream;
typedef basic_stringstream<wchar_t>  wstringstream;

#  endif   // _RWSTD_NO_WCHAR_T
#endif   // _RWSTD_IOSFWD_INCLUDED


_EXPORT
template <class _CharT, class _Traits, class _Allocator>
class basic_stringbuf: public basic_streambuf<_CharT, _Traits>
{
    typedef basic_string<_CharT, _Traits, _Allocator> _C_string_type;

public:

    typedef _CharT                          char_type;
    typedef _Traits                         traits_type;
    typedef _Allocator                      allocator_type;   // lwg issue 251

    typedef _TYPENAME traits_type::int_type int_type;
    typedef _TYPENAME traits_type::pos_type pos_type;
    typedef _TYPENAME traits_type::off_type off_type;

    _EXPLICIT
    basic_stringbuf (ios_base::openmode __mode = _RW::__rw_in_out)
        : basic_streambuf<char_type, traits_type>(__mode) {
        this->_C_own_buf (true);
    }

    _EXPLICIT
    basic_stringbuf (const _C_string_type&,
                     ios_base::openmode = _RW::__rw_in_out);

    // undetectable extension
    _EXPLICIT
    basic_stringbuf (const char_type*,
                     ios_base::openmode = _RW::__rw_in_out);

    virtual ~basic_stringbuf ();
    
    _C_string_type str () const;

#ifdef _RWSTD_NO_EXT_STRINGBUF_STR

private:

#endif   // _RWSTD_NO_EXT_STRINGBUF_STR

    // extension
    void str (const char_type*, _RWSTD_SIZE_T);

public:

    // undetectable extension for efficiency
    void str (const char_type *__s) {
        str (__s, traits_type::length (__s));
    }

    void str (const _C_string_type &__str) {
        str (__str.data (), __str.size ());
    }

protected:
    
    virtual streamsize xsputn (const char_type*, streamsize);

    virtual streamsize showmanyc ();
    
    virtual int_type overflow (int_type = traits_type::eof ());

    virtual int_type pbackfail (int_type = traits_type::eof ());

    virtual int_type underflow ();

    virtual pos_type
    seekoff (off_type, ios_base::seekdir, ios_base::openmode =
             _RW::__rw_in_out);
    
    virtual pos_type
    seekpos (pos_type, ios_base::openmode = _RW::__rw_in_out);

    virtual basic_streambuf<char_type, traits_type>*
    setbuf (char_type*, streamsize);

private:

    _RWSTD_STREAMSIZE _C_grow (_RWSTD_STREAMSIZE) const;

    // called from overflow, underflow, et al to get egptr()
    // caught up with pptr()
    void _C_catchup (char_type*);
};

template <class _CharT, class _Traits, class _Allocator>
inline basic_string<_CharT, _Traits, _Allocator>
basic_stringbuf<_CharT, _Traits, _Allocator>::
str () const {

    const char_type * __first = 0;
    const char_type * __last = 0;

    if (this->_C_is_out ()) {
        // in out only or in|out mode
        __first = this->pbase ();
        __last = this->egptr () < this->pptr () ?
            this->pptr () : this->egptr ();
    }
    else if (this->_C_is_in ()) {
        // in in only mode
        __first = this->eback ();
        __last = this->egptr ();
    }

    return _C_string_type (__first, __last - __first);
}

template <class _CharT, class _Traits, class _Allocator>
inline _RWSTD_STREAMSIZE
basic_stringbuf<_CharT, _Traits, _Allocator>::
_C_grow (_RWSTD_STREAMSIZE __to) const
{
    const _RWSTD_STREAMSIZE __cap =
        _RWSTD_STATIC_CAST (_RWSTD_STREAMSIZE,
                            this->_C_bufsize ?
                            this->_C_bufsize * _RWSTD_NEW_CAPACITY_RATIO
                            : _RWSTD_MINIMUM_STRINGBUF_CAPACITY);

    return __cap < __to ? __to : __cap;
}


template <class _CharT, class _Traits, class _Allocator>
inline void
basic_stringbuf<_CharT, _Traits, _Allocator>::
_C_catchup (char_type *__gbeg)
{
    if (this->egptr () < this->pptr ()) {

        if (this->_C_is_in ()) {
        
            // in in|out mode use the relative offset of gptr ()
            // from eback() to set the new gptr() and use egptr()
            // as the "high mark" (see LWG issue 432)
            char_type* const __gptr = __gbeg + (this->gptr () - this->eback ());

            this->setg (__gbeg, __gptr, this->pptr ());
        }
        else {

            // in out only mode use egptr() as the "high mark"
            // (see LWG issue 432)
            this->setg (this->pptr (), this->pptr (), this->pptr ());
        }

        _RWSTD_ASSERT (this->_C_is_valid ());
    }
}


template <class _CharT, class _Traits, class _Allocator>
class basic_istringstream: public basic_istream<_CharT, _Traits>
{
    typedef basic_string<_CharT, _Traits, _Allocator> _C_string_type;

public:
    typedef _CharT                           char_type;
    typedef _Traits                          traits_type;
    typedef _Allocator                       allocator_type;

    typedef _TYPENAME traits_type::int_type  int_type;
    typedef _TYPENAME traits_type::pos_type  pos_type;
    typedef _TYPENAME traits_type::off_type  off_type;
  
    _EXPLICIT
    basic_istringstream (ios_base::openmode __mode = ios_base::in)
        : basic_istream<char_type, traits_type>(rdbuf ()),
          _C_sb (__mode | ios_base::in) { }

    _EXPLICIT
    basic_istringstream (const _C_string_type& __str, 
                         ios_base::openmode __mode = ios_base::in)
        : basic_istream<char_type, traits_type>(rdbuf ()),
          _C_sb (__str, __mode | ios_base::in) { }

    // undetectable extension
    _EXPLICIT
    basic_istringstream (const char_type   * __s, 
                         ios_base::openmode __mode = ios_base::in)
        : basic_istream<char_type, traits_type>(rdbuf ()),
          _C_sb (__s, __mode | ios_base::in) { }

    basic_stringbuf<char_type, traits_type, allocator_type> *rdbuf () const {
        // necessary to help SunPro 5.0/T9
        typedef basic_istringstream <char_type, traits_type, allocator_type>
            _SelfT;
        return &_RWSTD_CONST_CAST (_SelfT*, this)->_C_sb;
    }

    _C_string_type str () const {
        return rdbuf ()->str ();
    }

#ifdef _RWSTD_NO_EXT_STRINGBUF_STR

    // extension
    void str (const char_type *__s, _RWSTD_SIZE_T __len) {
        rdbuf ()->str (__s, __len);
    }

#endif   //  _RWSTD_NO_EXT_STRINGBUF_STR

    // undetectable extension for efficiency
    void str (const char_type *__s) {
        rdbuf ()->str (__s);
    }

    void str (const _C_string_type &__str) {
        rdbuf ()->str (__str);
    }

private:

    basic_stringbuf<char_type, traits_type, allocator_type> _C_sb;
};


template <class _CharT, class _Traits, class _Allocator>
class basic_ostringstream: public basic_ostream<_CharT, _Traits>
{
    typedef basic_string<_CharT, _Traits, _Allocator> _C_string_type;

public:

    typedef _CharT                          char_type;
    typedef _Traits                         traits_type;
    typedef _Allocator                      allocator_type;

    typedef _TYPENAME traits_type::int_type int_type;
    typedef _TYPENAME traits_type::pos_type pos_type;
    typedef _TYPENAME traits_type::off_type off_type;

    // NOTE: the constructors pass the address of a yet uninitialized
    //       data member to the constructor of the base class
    _EXPLICIT
    basic_ostringstream (ios_base::openmode __mode = ios_base::out)
        : basic_ostream<char_type, traits_type> (rdbuf ()),
          _C_sb (__mode | ios_base::out) { }
        
    _EXPLICIT
    basic_ostringstream (const _C_string_type  &__str, 
                         ios_base::openmode  __mode = ios_base::out)
        : basic_ostream<char_type, traits_type>(rdbuf ()),
          _C_sb (__str, __mode | ios_base::out) { }

    // undetectable extension
    _EXPLICIT
    basic_ostringstream (const char_type    *__s, 
                         ios_base::openmode  __mode = ios_base::out)
        : basic_ostream<char_type, traits_type>(rdbuf ()),
          _C_sb (__s, __mode | ios_base::out) { }

    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf () const {
        // necessary to help SunPro 5.0/T9
        typedef basic_ostringstream <char_type, traits_type, allocator_type>
            _SelfT;
        return &_RWSTD_CONST_CAST (_SelfT*, this)->_C_sb;
    }

    _C_string_type str () const {
        return rdbuf ()->str ();
    }

#ifdef _RWSTD_NO_EXT_STRINGBUF_STR

    // extension
    void str (const char_type *__s, _RWSTD_SIZE_T __len) {
        rdbuf ()->str (__s, __len);
    }

#endif   //  _RWSTD_NO_EXT_STRINGBUF_STR

    // undetectable extension for efficiency
    void str (const char_type *__s) {
        rdbuf ()->str (__s);
    }

    void str (const _C_string_type &__str) {
        rdbuf ()->str (__str);
    }

private:

    basic_stringbuf<char_type, traits_type, allocator_type> _C_sb;
};


template <class _CharT, class _Traits, class _Allocator>
class basic_stringstream: public basic_iostream<_CharT, _Traits>
{
    typedef basic_string<_CharT, _Traits, _Allocator> _C_string_type;

public:

    typedef _CharT                          char_type;
    typedef _Traits                         traits_type;
    typedef _Allocator                      allocator_type;

    typedef _TYPENAME traits_type::int_type int_type;
    typedef _TYPENAME traits_type::pos_type pos_type;
    typedef _TYPENAME traits_type::int_type off_type;

    _EXPLICIT
    basic_stringstream (ios_base::openmode __mode = _RW::__rw_in_out)
        : basic_iostream<char_type, traits_type>(rdbuf ()),
          _C_sb (__mode) { }

    _EXPLICIT
    basic_stringstream (const _C_string_type &__str,
                        ios_base::openmode __mode = _RW::__rw_in_out)
        : basic_iostream<char_type, traits_type>(rdbuf ()),
          _C_sb (__str, __mode) { }

    // undetectable extension
    _EXPLICIT
    basic_stringstream (const char_type    *__s, 
                        ios_base::openmode __mode = _RW::__rw_in_out)
        : basic_iostream<char_type, traits_type>(rdbuf ()),
          _C_sb (__s, __mode) { }

    basic_stringbuf<char_type, traits_type, allocator_type> *rdbuf () const {
        // necessary to help SunPro 5.0/T9
        typedef basic_stringstream <char_type, traits_type, allocator_type>
            _SelfT;
        return &_RWSTD_CONST_CAST (_SelfT*, this)->_C_sb;
    }

    _C_string_type str () const {
        return rdbuf ()->str ();
    }

#ifdef _RWSTD_NO_EXT_STRINGBUF_STR

    // extension
    void str (const char_type *__s, _RWSTD_SIZE_T __len) {
        rdbuf ()->str (__s, __len);
    }

#endif   //  _RWSTD_NO_EXT_STRINGBUF_STR

    // undetectable extension for efficiency
    void str (const char_type *__s) {
        rdbuf ()->str (__s);
    }

    void str (const _C_string_type &__str) {
        rdbuf ()->str (__str);
    }

private:

    basic_stringbuf<char_type, traits_type, allocator_type> _C_sb;
};

}   // namespace std


#if _RWSTD_DEFINE_TEMPLATE_FIRST (_BASIC_STRINGBUF)
#  include <sstream.cc>
#endif   // _RWSTD_DEFINE_TEMPLATE_FIRST (_BASIC_STRINGBUF)


_RWSTD_NAMESPACE (std) { 

#if _RWSTD_INSTANTIATE (_BASIC_STRINGBUF, _CHAR)

_RWSTD_INSTANTIATE_1 (class _RWSTD_EXPORT basic_stringbuf<char>);

#endif   // _RWSTD_INSTANTIATE (_BASIC_STRINGBUF, _CHAR)

#if _RWSTD_INSTANTIATE (_BASIC_STRINGBUF, _WCHAR_T)

_RWSTD_INSTANTIATE_1 (class _RWSTD_EXPORT basic_stringbuf<wchar_t>);

#endif   // _RWSTD_INSTANTIATE (_BASIC_STRINGBUF, _WCHAR_T)

}   // namespace std


#if _RWSTD_DEFINE_TEMPLATE_LAST (_BASIC_STRINGBUF)
#  include <sstream.cc>
#endif   // _RWSTD_DEFINE_TEMPLATE_LAST (_BASIC_STRINGBUF)


#endif   // _RWSTD_SSTREAM_INCLUDED
