// -*- C++ -*-
/***************************************************************************
 *
 * strstream - Declarations for the Standard Library string stream classes
 *
 * $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_STRSTREAM_INCLUDED
#define _RWSTD_STRSTREAM_INCLUDED

#include <streambuf>
#include <istream>
#include <ostream>

#include <rw/_defs.h>

#ifdef _RWSTD_NO_DEPRECATED
#  error deprecated header included
#endif


_RWSTD_NAMESPACE (std) { 
  

// D.7.1
class _RWSTD_EXPORT strstreambuf
    : public basic_streambuf<char, char_traits<char> >
{
    typedef basic_streambuf<char, char_traits<char> > _Base;

    void _C_init (streamsize, const void*, streamsize, const void*,
                  void* (*)(_RWSTD_SIZE_T), void (*)(void*), int);
public:

    // D.7.1.1, p1
    _EXPLICIT
    strstreambuf (streamsize __alsize = 0)
        : _Base () {
        _C_init (__alsize, 0, 0, 0, 0, 0, _C_dynamic);
    }
      
    // D.7.1.1, p2
    strstreambuf (void* (*__palloc)(_RWSTD_SIZE_T), void (*__pfree)(void *))
        : _Base () {
        _C_init (0, 0, 0, 0, __palloc, __pfree, _C_dynamic);
    }

    // D.7.1.1, p3
    strstreambuf (char_type *__gnext, streamsize __n, char_type *__pbeg = 0)
        : _Base () {
        _C_init (0, __gnext, __n, __pbeg, 0, 0, 0);
    }

    // D.7.1.1, p3
    strstreambuf (unsigned char *__gnext, streamsize __n,
                  unsigned char *__pbeg = 0)
        : _Base () {
        _C_init (0, __gnext, __n, __pbeg, 0, 0, 0);
    }

    // D.7.1.1, p3
    strstreambuf (signed char *__gnext, streamsize __n,
                  signed char *__pbeg = 0)
        : _Base () {
        _C_init (0, __gnext, __n, __pbeg, 0, 0, 0);
    }

    // D.7.1.1, p7
    strstreambuf (const char_type *__gnext, streamsize __n)
        : _Base () {
        _C_init (0, __gnext, __n, 0, 0, 0, _C_constant);
    }

    // D.7.1.1, p7
    strstreambuf (const unsigned char *__gnext, streamsize __n)
        : _Base () {
        _C_init (0, __gnext, __n, 0, 0, 0, _C_constant);
    }

    // D.7.1.1, p7
    strstreambuf (const signed char *__gnext, streamsize __n)
        : _Base () {
        _C_init (0, __gnext, __n, 0, 0, 0, _C_constant);
    }
      
    // D.7.1.1, p8
    virtual ~strstreambuf ();

    // D.7.1.2, p1
    void freeze (bool __f = true) {
        if (__f)
            _C_state |= _C_frozen;
        else
            _C_state &= ~_C_frozen;
    }
      
    // D.7.1.2, p2
    char_type* str () {
        freeze ();
        return eback ();
    }
      
    // D.7.1.2, p4
    int pcount () const {
        return int (pptr () - pbase ());
    }

protected:

    // D.7.1.3, p1
    virtual int_type
    overflow (int_type = traits_type::eof ());

    // D.7.1.3, p6
    virtual int_type
    pbackfail (int_type = traits_type::eof ());

    // D.7.1.3, p9
    virtual int_type
    underflow ();

    // D.7.1.3, p12
    virtual pos_type
    seekoff (off_type, ios_base::seekdir,
             ios_base::openmode = ios_base::in | ios_base::out);

    // D.7.1.3, p15
    virtual pos_type
    seekpos (pos_type, ios_base::openmode = ios_base::in | ios_base::out);

    // D.7.1.3, p19
    virtual basic_streambuf<char, char_traits<char> >*
    setbuf (char_type*, streamsize);

private:

    streamsize    _C_alsize;
    void       *(*_C_palloc)(_RWSTD_SIZE_T);
    void        (*_C_pfree)(void*);
};


// D.7.2
class _RWSTD_EXPORT istrstream
    : public basic_istream<char, char_traits<char> >
{
    typedef basic_istream<char, char_traits<char> > _Base;

public:

    // D.7.2.2, p1
    strstreambuf* rdbuf() const {
        return _RWSTD_CONST_CAST (strstreambuf*, &_C_sb);
    }

    // D.7.2.1, p1, and p2
    _EXPLICIT
    istrstream (const char_type *__s, streamsize __n = 0)
        : _Base (rdbuf ()), _C_sb (__s, __n) { }

    _EXPLICIT
    istrstream (char_type *__s, streamsize __n = 0)
        : _Base (rdbuf ()), _C_sb (__s, __n) { }

    // D.7.2.2, p2
    char_type* str () {
        return rdbuf ()->str ();
    }

private:

    strstreambuf _C_sb;
};


class _RWSTD_EXPORT ostrstream
    : public basic_ostream<char, char_traits<char> >
{
    typedef basic_ostream<char, char_traits<char> > _Base;
public:
  
    strstreambuf* rdbuf() const {
        return _RWSTD_CONST_CAST (strstreambuf*, &_C_sb);
    }

    ostrstream (): _Base (rdbuf ()) { }

    ostrstream (char_type *__s, int __n,
                ios_base::openmode __mode = ios_base::out)
        : _Base (rdbuf ()),
          _C_sb (__s, streamsize (__n),
                __mode & (ios_base::app | ios_base::ate) ?
                 __s + traits_type::length (__s) : __s)
        { }

    void freeze (bool __freezefl = true) {
        rdbuf ()->freeze (__freezefl);
    }
    
    char_type *str () {
        return rdbuf ()->str();
    }
    
    int pcount() const {
        return rdbuf ()->pcount();
    }

private:

    strstreambuf _C_sb;
};


// D.7.3
class _RWSTD_EXPORT strstream
    : public basic_iostream<char, char_traits<char> >
{
    typedef basic_iostream<char, char_traits<char> > _Base;

public:
  
    strstreambuf* rdbuf() const {
        return _RWSTD_CONST_CAST (strstreambuf*, &_C_sb);
    }

    strstream (): _Base (rdbuf ()), _C_sb () { }

    strstream (char_type *__s, int __n,
               ios_base::openmode __mode = ios_base::out | ios_base::in)
        : _Base (rdbuf ()),
        _C_sb (__s, streamsize (__n),
               __mode & (ios_base::app | ios_base::ate) ?
               __s + traits_type::length (__s) : __s)
          { }

    void freeze (bool __freezefl = true) {
        rdbuf ()->freeze (__freezefl);
    }

    int pcount() const {
        return rdbuf ()->pcount();
    }
      
    char_type *str() {
        return rdbuf ()->str();
    }

private:

    strstreambuf _C_sb;
};


}   // namespace std


#endif   //_RWSTD_STRSTREAM_INCLUDED
