Include the iostreams
standard header <strstream>
to define several classes that support
iostreams operations on
sequences stored in an allocated array of char object.
Such sequences are easily converted to and from
C strings.

The class describes a
stream buffer that controls
the transmission of elements to and from a sequence of elements
stored in a char array object. Depending on how it
is constructed, the object can be allocated, extended, and
freed as necessary to accommodate changes in the sequence.

An object of class strstreambuf
stores several bits of mode information as its
strstreambuf mode.
These bits indicate whether the controlled sequence:

has been allocated,
and hence needs to be freed eventually

is modifiable

is extendable by reallocating storage

has been frozen
and hence needs to be unfrozen before the object is destroyed,
or freed (if allocated) by an agency other than the object

A controlled sequence that is frozen cannot be modified or extended,
regardless of the state of these separate mode bits.

The object also stores pointers to two functions that control
strstreambuf allocation.
If these are null pointers, the object devises its own method
of allocating and freeing storage for the controlled sequence.

The member function returns a count of the number of elements
written to the controlled sequence. Specifically, if
pptr() is a
null pointer, the function returns zero. Otherwise, it returns
pptr() -
pbase().

If meta != EOF,
the protected virtual member function endeavors to insert the element
(char)meta
into the
output buffer.
It can do so in various ways:

If a write position
is available, it can store the element into the write position
and increment the next pointer for the output buffer.

If the stored
strstreambuf mode says the
controlled sequence is modifiable, extendable, and not frozen,
the function can make a write position available by allocating
new for the output buffer. (Extending the
output buffer this way also extends any associated
input buffer.)

If the function cannot succeed, it returns
EOF. Otherwise, if meta == EOF it returns some
value other than EOF. Otherwise, it returns meta.

The protected virtual member function endeavors to put back an element
into the
input buffer,
then make it the current element (pointed to
by the next pointer).

If meta == EOF,
the element to push back is effectively the one already in the stream
before the current element. Otherwise, that element is replaced by
ch = (char)meta.
The function can put back an element in various ways:

If a putback position
is available, and the element stored there compares equal to ch,
it can simply decrement the next pointer for the input buffer.

If a putback position is available,
and if the strstreambuf mode
says the controlled sequence is modifiable, the function
can store ch into the putback position and decrement the
next pointer for the input buffer.

If the function cannot succeed, it returns
EOF. Otherwise, if meta == EOF it returns some
value other than EOF. Otherwise, it returns meta.

The protected virtual member function endeavors to alter the current
positions for the controlled streams. For an object of class
strstreambuf, a stream position consists
purely of a stream offset. Offset zero designates the first element
of the controlled sequence.

The new position is determined as follows:

If way ==
ios_base::beg,
the new position is the beginning of the stream plus off.

If way ==
ios_base::cur,
the new position is the current stream position plus off.

If way ==
ios_base::end,
the new position is the end of the stream plus off.

If
which & ios_base::in is nonzero and
the input buffer exist,
the function alters the next position to read in the
input buffer.
If which & ios_base::out is also nonzero,
way != ios_base::cur,
and the output buffer exists,
the function also sets the next position to write to
match the next position to read.

Otherwise, if which & ios_base::out is nonzero
and the output buffer exists,
the function alters the next position to write in the
output buffer.
Otherwise, the positioning operation fails.
For a positioning operation to succeed, the resulting
stream position must lie within the controlled sequence.

If the function succeeds in altering either or both stream positions,
it returns the resultant stream position.
Otherwise, it fails and returns an invalid stream position.

The protected virtual member function endeavors to alter the current
positions for the controlled streams. For an object of class
strstreambuf, a stream position consists
purely of a stream offset. Offset zero designates the first element
of the controlled sequence. The new position is determined
by sp.

If
which & ios_base::in is nonzero
and the input buffer exists,
the function alters the next position to read in the
input buffer.
(If which & ios_base::out is nonzero
and the output buffer exists,
the function also sets the next position to write to
match the next position to read.)
Otherwise, if which & ios_base::out is nonzero
and the output buffer exists,
the function alters the next position to write in the
output buffer.
Otherwise, the positioning operation fails.
For a positioning operation to succeed, the resulting
stream position must lie within the controlled sequence.

If the function succeeds in altering either or both stream positions,
it returns the resultant stream position.
Otherwise, it fails and returns an invalid stream position.

The second constructor behaves much as the first, except that
it stores allocfunc as the pointer to the function to
call to allocate storage, and freefunc as the pointer
to the function to call to free that storage.

also behave much as the first, except that getptr
designates the array object used to hold the controlled
sequence. (Hence, it must not be a null pointer.) The number
of elements N in the array is determined as
follows:

The protected virtual member function endeavors to extract the current
element ch from the
input buffer,
then advance the current stream position, and return the element as
(int)(unsigned char)ch.
It can do so in only one way:
If a read position
is available, it takes ch as the element stored
in the read position and advances the next pointer for the input buffer.

If the function cannot succeed, it returns
EOF. Otherwise,
it returns the current element in the input stream,
converted as described above.

All the constructors initialize the base class by calling
istream(sb),
where sb is the stored object of class
strstreambuf.
The first two constructors also initialize sb by calling
strstreambuf((const
char *)ptr, 0). The remaining two constructors instead call
strstreambuf((const char *)ptr, count).

Both constructors initialize the base class by calling
ostream(sb),
where sb is the stored object of class
strstreambuf.
The first constructor also initializes sb by calling
strstreambuf().
The second constructor initializes the base class one of two ways:

If mode &
ios_base::app == 0, then
ptr must designate the first element of an array of count
elements, and the constructor calls
strstreambuf(ptr, count, ptr).

Otherwise, ptr must designate the first element of an
array of count elements that contains a
C string
whose first element is designated
by ptr, and the constructor calls
strstreambuf(ptr, count, ptr +
strlen(ptr).

Both constructors initialize the base class by calling
streambuf(sb),
where sb is the stored object of class
strstreambuf.
The first constructor also initializes sb by calling
strstreambuf().
The second constructor initializes the base class one of two ways:

If mode &
ios_base::app == 0, then
ptr must designate the first element of an array of count
elements, and the constructor calls
strstreambuf(ptr, count, ptr).

Otherwise, ptr must designate the first element of an
array of count elements that contains a
C string
whose first element is designated
by ptr, and the constructor calls
strstreambuf(ptr, count, ptr +
strlen(ptr).