// strstream standard header
#ifndef _STRSTREAM_
#define _STRSTREAM_
#include <istream>
_STD_BEGIN

		// CLASS strstreambuf
class strstreambuf
	: public streambuf
	{	// stream buffer associated with static or allocated character array
public:
	enum
		{	// constants for bits in stream state
		_Allocated = 1,	// set if character array storage has been allocated
		_Constant = 2,	// set if character array nonmutable
		_Dynamic = 4,	// set if character array length grows on demand
		_Frozen = 8};	// set if character array ownership given away
	typedef int _Strstate;

	explicit strstreambuf(streamsize _Count = 0)
		{	// construct with empty character array, suggested initial size
		_Init(_Count);
		}

	strstreambuf(void *(*_Allocfunc)(size_t),
		void (*_Freefunc)(void *))
		{	// construct with empty character array, allocation functions
		_Init();
		_Palloc = _Allocfunc;
		_Pfree = _Freefunc;
		}

	strstreambuf(char *_Getptr, streamsize _Count, char *_Putptr = 0)
		{	// construct with [_Getptr, _Getptr + _Count), possibly mutable
		_Init(_Count, _Getptr, _Putptr);
		}

	strstreambuf(unsigned char *_Getptr, streamsize _Count,
		unsigned char *_Putptr = 0)
		{	// construct with [_Getptr, _Getptr + _Count), possibly mutable
		_Init(_Count, (char *)_Getptr, (char *)_Putptr);
		}

	strstreambuf(const char *_Getptr, streamsize _Count)
		{	// construct with [_Getptr, _Getptr + _Count), nonmutable
		_Init(_Count, (char *)_Getptr, 0, _Constant);
		}

	strstreambuf(const unsigned char *_Getptr, streamsize _Count)
		{	// construct with [_Getptr, _Getptr + _Count), nonmutable
		_Init(_Count, (char *)_Getptr, 0, _Constant);
		}

	virtual ~strstreambuf();	// destroy the object

	void freeze(bool = true);	// freeze or unfreeze writing

	char *str()
		{	// freeze and return pointer to character array
		freeze();
		return (gptr());
		}

	streamsize pcount() const
		{	// return size of writable character array
		return (pptr() == 0 ? 0 : (streamsize)(pptr() - pbase()));
		}

	strstreambuf(signed char *_Getptr, streamsize _Count,
		signed char *_Putptr = 0)
		{	// construct with [_Getptr, _Getptr + _Count), possibly mutable
		_Init(_Count, (char *)_Getptr, (char *)_Putptr);
		}

	strstreambuf(const signed char *_Getptr, streamsize _Count)
		{	// construct with [_Getptr, _Getptr + _Count), nonmutable
		_Init(_Count, (char *)_Getptr, 0, _Constant);
		}

protected:
	virtual int overflow(int = EOF);	// try to extend write area

	virtual int pbackfail(int = EOF);	// try to putback a character

	virtual int underflow();	// read if read position available

	virtual streampos seekoff(streamoff,
		ios_base::seekdir,
		ios_base::openmode =
			ios_base::in | ios_base::out);	// seek by specified offset

	virtual streampos seekpos(streampos,
		ios_base::openmode =
			ios_base::in | ios_base::out);	// seek to memorized position

	void _Init(streamsize = 0, char * = 0, char * = 0,
		_Strstate = (_Strstate)0);	// initialize with possibly static buffer

	void _Tidy();	// free any allocated storage

private:
	enum
		{	// constant for default minimum buffer size
		_MINSIZE = 32};

	streamsize _Minsize;	// the minimum buffer size
	char *_Pendsave;	// the saved end pointer during freeze
	char *_Seekhigh;	// the high-water pointer in character array
	_Strstate _Strmode;	// the stream state
	void *(*_Palloc)(size_t);	// the pointer to allocator function
	void (*_Pfree)(void *);	// the pointer to free function
	};

		// CLASS istrstream
class istrstream
	: public istream
	{	// input stream associated with a character array
public:

	explicit istrstream(const char *_Ptr)
		: istream(&_Mysb), _Mysb(_Ptr, 0)
		{	// construct with NTBS
		}

	istrstream(const char *_Ptr, streamsize _Count)
		: istream(&_Mysb), _Mysb(_Ptr, _Count)
		{	// construct with [_Ptr, _Ptr + _Count)
		}

	explicit istrstream(char *_Ptr)
		: istream(&_Mysb), _Mysb((const char *)_Ptr, 0)
		{	// construct with NTBS
		}

	istrstream(char *_Ptr, int _Count)
		: istream(&_Mysb), _Mysb((const char *)_Ptr, _Count)
		{	// construct with [_Ptr, _Ptr + _Count)
		}

	virtual ~istrstream();	// destroy the object

	strstreambuf *rdbuf() const
		{	// return pointer to character array buffer
		return ((strstreambuf *)&_Mysb);
		}

	char *str()
		{	// freeze and return pointer to character array
		return (_Mysb.str());
		}

private:
	strstreambuf _Mysb;	// the string buffer
	};

		// CLASS ostrstream
class ostrstream
	: public ostream
	{	// output stream associated with a character array
public:
	ostrstream()
		: ostream(&_Mysb), _Mysb()
		{	// construct with empty character array
		}

	ostrstream(char *, streamsize,
		ios_base::openmode =
			ios_base::out);	// construct with static array

	virtual ~ostrstream();	// destroy the object

	strstreambuf *rdbuf() const
		{	// return pointer to character array buffer
		return ((strstreambuf *)&_Mysb);
		}

	void freeze(bool _Freezeit = true)
		{	// freeze or unfreeze writing
		_Mysb.freeze(_Freezeit);
		}

	char *str()
		{	// freeze and return pointer to character array
		return (_Mysb.str());
		}

	streamsize pcount() const
		{	// return size of writable character array
		return (_Mysb.pcount());
		}

private:
	strstreambuf _Mysb;	// the character array buffer
	};

		// CLASS strstream
class strstream
	: public iostream
	{	// input/output stream associated with character array buffer
public:
	typedef char char_type;
	typedef int int_type;
	typedef streampos pos_type;
	typedef streamoff off_type;

	strstream()
		: iostream(&_Mysb), _Mysb()
		{	// construct with empty character array
		}

	strstream(char *, streamsize,
		ios_base::openmode =
			ios_base::in | ios_base::out);	// construct with static array

	virtual ~strstream();	// destroy the object

	strstreambuf *rdbuf() const
		{	// return pointer to character array buffer
		return ((strstreambuf *)&_Mysb);
		}

	void freeze(bool _Freezeit = true)
		{	// freeze or unfreeze writing
		_Mysb.freeze(_Freezeit);
		}

	char *str()
		{	// freeze and return pointer to character array
		return (_Mysb.str());
		}

	streamsize pcount() const
		{	// return size of writable character array
		return (_Mysb.pcount());
		}

private:
	strstreambuf _Mysb;	// the character array buffer
	};
_STD_END
#endif /* _STRSTREAM_ */

/*
 * Copyright (c) 1992-2003 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
V4.02:0216 */
