------------- Listing 1: The header <<strstream>> ------------------

// strstream standard header
#ifndef _STRSTREAM_
#define _STRSTREAM_
#include <<istream>>
#include <<ostream>>
		// constants
const int _ALSIZE = 512;	// default allocation size
const int _MINSIZE = 32;	// minimum allocation size
		// class strstreambuf
class strstreambuf : public streambuf {
public:
	enum __Strstate {_Allocated = 1, _Constant = 2,
		_Dynamic = 4, _Frozen = 8, _Noread = 16,
		_Strzero = 0};
	_BITMASK(__Strstate, _Strstate);
	strstreambuf(streamsize _N = 0)
		{_Init(_N); }
	strstreambuf(void *(*_A)(size_t), void (*_F)(void *))
		{_Init(), _Palloc = _A, _Pfree = _F; }
	strstreambuf(char *_G, streamsize _N, char *_P = 0,
		_Strstate _S = _Strzero)
		{_Init(_N, _G, _P, _S); }
	strstreambuf(unsigned char *_G, streamsize _N,
		unsigned char *_P = 0)
		{_Init(_N, (char *)_G, (char *)_P); }
	strstreambuf(const char *_G, streamsize _N)
		{_Init(_N, (char *)_G, 0, _Constant); }
	strstreambuf(const unsigned char *_G, streamsize _N)
		{_Init(_N, (char *)_G, 0, _Constant); }
	virtual ~strstreambuf();
	void freeze(bool = 1);
	char *str()
		{freeze(); return (gptr()); }
	streamsize pcount() const
		{return (pptr() == 0 ? 0 : pptr() - pbase()); } 
#if _HAS_SIGNED_CHAR
	strstreambuf(signed char *_G, streamsize _N,
		signed char *_P = 0)
		{_Init(_N, (char *)_G, (char *)_P); }
	strstreambuf(const signed char *_G, streamsize _N)
		{_Init(_N, (char *)_G, 0, _Constant); }
#endif /* _HAS_SIGNED_CHAR */
protected:
	virtual int overflow(int = EOF);
	virtual int pbackfail(int = EOF);
	virtual int underflow();
	virtual streampos seekoff(streamoff, ios::seekdir,
		ios::openmode = ios::in | ios::out);
	virtual streampos seekpos(streampos,
		ios::openmode = ios::in | ios::out);
	void _Init(int = 0, char * = 0, char * = 0,
		_Strstate = _Strzero);
	void _Tidy();
	_Strstate _Strmode;
private:
	char *_Pendsave, *_Seekhigh;
	int _Alsize;
	void *(*_Palloc)(size_t);
	void (*_Pfree)(void *);
	};
_BITMASK_OPS(strstreambuf::__Strstate)
		// class istrstream
class istrstream : public istream {
public:
	istrstream(const char *_S)
		: istream(&_Sb), _Sb(_S, 0) {}
	istrstream(const char *_S, streamsize _N)
		: istream(&_Sb), _Sb(_S, _N) {}
	istrstream(char *_S)
		: istream(&_Sb), _Sb((const char *)_S, 0) {}
	istrstream(char *_S, int _N)
		: istream(&_Sb), _Sb((const char *)_S, _N) {}
	virtual ~istrstream();
	strstreambuf *rdbuf() const
		{return ((strstreambuf *)&_Sb); }
	char *str()
		{return (_Sb.str()); }
private:
	strstreambuf _Sb;
	};
		// class ostrstream
class ostrstream : public ostream {
public:
	ostrstream()
		: ostream(&_Sb), _Sb() {}
	ostrstream(char *, streamsize, openmode = out);
	virtual ~ostrstream();
	strstreambuf *rdbuf() const
		{return ((strstreambuf *)&_Sb); }
	void freeze(int _F = 1)
		{_Sb.freeze(_F); }
	char *str()
		{return (_Sb.str()); }
	int pcount() const
		{return (_Sb.pcount()); }
private:
	strstreambuf _Sb;
	};
#endif /* _STRSTREAM_ */

