// -*- 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, Inc.
 * 
 **************************************************************************/

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