|
|
#include <iostream.h>typedef long streamoff, streampos; class ios { public: enum seek_dir { beg, cur, end }; enum open_mode { in, out, ate, app, trunc, nocreate, noreplace }; // and lots of other stuff ... See ios(C++) } ;
class streambuf { public :
int in_avail(); int out_waiting(); int sbumpc(); streambuf* setbuf(char* ptr, int len); streampos seekpos(streampos, int =ios::in|ios::out); streampos seekoff(streamoff, seek_dir, int =ios::in|ios::out); int sgetc(); int sgetn(char* ptr, int n); int snextc(); int sputbackc(char); int sputc(int c); int sputn(const char* s, int n); void stossc(); virtual int sync(); };
streambuf
class supports buffers into which
characters can be inserted (put) or from which characters can be
fetched (gotten).
Abstractly, such a buffer is a sequence of characters together with one or
two pointers (a get and/or a put pointer) that define
the location at which characters are to be inserted or fetched.
The pointers should be thought of as pointing between characters
rather than at them.
This makes it easier to understand the
boundary conditions (a pointer before the first character or after
the last).
Some of the effects of getting and putting are defined
by this class but most of the details are left to specialized
classes derived from streambuf
.
(See
filebuf(C++),
ssbuf(C++),
and
stdiobuf(C++).)
Classes derived from streambuf
vary in their
treatments of the get and put pointers.
The simplest are unidirectional buffers which permit only gets or
only puts.
Such classes serve as pure sources (producers) or sinks (consumers)
of characters.
Queuelike buffers (e.g., see
strstream(C++)
and
ssbuf(C++))
have a put and a get pointer which move independently of each other.
In such buffers characters that are stored are held (i.e., queued)
until they are later fetched.
Filelike buffers (e.g., filebuf
, see
filebuf(C++))
permit both gets and puts but have only a single pointer.
(An alternative description is that the get and put pointers are tied
together so that when one moves so does the other.)
Most streambuf
member functions are organized into two phases.
As far as possible, operations are performed inline by storing into
or fetching from arrays (the get area and the put area,
which together form the reserve area, or buffer).
From time to time, virtual functions are called to
deal with collections of characters in the get and put areas.
That is, the virtual functions are called to fetch more characters
from the ultimate producer or to flush a collection of characters
to the ultimate consumer.
Generally the user of a streambuf
does not have to know
anything about these
details, but some of the public members pass back information
about the state of the areas.
Further detail about these areas is provided in
sbuf.prot(C++),
which describes the protected interface.
The public member functions of the streambuf
class
are described below.
In the following descriptions assume:
int
s
int
. It always holds a ``character''
value or EOF. A ``character'' value is always positive
even when char
is normally sign extended.
streambuf*
s
char*
streamoff
streampos
seek_dir
int
representing an open_mode
=
sb->in_avail()
=
sb->out_waiting()
=
sb->sbumpc()
=
sb->seekoff(
off,
dir,
mode)
ios::out
bit set) or
the get pointer (ios::in
bit set) is to be modified.
Both bits may be set in which case both pointers should be affected.
off is interpreted as a byte offset.
(Notice that it is a signed quantity.)
The meanings of possible values of dir are:
ios::beg
ios::cur
ios::end
Not all classes derived from streambuf
support repositioning.
seekoff()
will return EOF if the class does not support
repositioning.
If the class does support repositioning, seekoff()
will return the new
position or EOF on error.
=
sb->seekpos(
pos,
mode)
seekoff()
.
Returns pos (the argument) or EOF if the class does
not support repositioning or an error occurs.
In general a streampos
should be treated as a ``magic cookie''
and no arithmetic should be performed on it.
Two particular values have special meaning:
streampos(0)
streampos(EOF)
=
sb->sgetc()
=
sb->setbuf(
ptr,
len,
i)-
Offers the
len bytes starting at ptr as the reserve area.
If ptr is null or len is zero or less, then an unbuffered
state is requested.
Whether the offered area is used, or a request for unbuffered
state is honored depends on details of the derived class.
setbuf()
normally returns sb, but if it does not
accept the offer or honor the request, it returns 0.
=
sb->sgetn(
ptr,
n)
sgetn()
fetches whatever characters remain.
sgetn()
repositions the get pointer following the fetched
characters and returns the number of characters fetched.
=
sb->snextc()
=
sb->sputbackc(
c)
sputbackc()
is undefined if c is not
the character before the get pointer.
sputbackc()
returns EOF when it fails.
The conditions under which it can fail depend on the details of
the derived class.
=
sb->sputc(
c)
=
sb->sputn(
ptr,
n)
sputn()
returns i, the number of characters stored successfully.
Normally i is n, but it may be less when errors occur.
->stossc()
=
sb->sync()
sync()
returns EOF to indicate errors.
setbuf
does not really belong in the public interface.
It is there for compatibility with the stream package.
Requiring the program to provide the previously fetched character to
sputback
is probably a botch.