SBUFPROT(3CC4)SBUFPROT(3CC4)NAME
sbufprot - protected interface of the stream buffer base class
SYNOPSIS
#include <iostream.h>
typedef long streampos;
typedef long streamoff;
class ios : virtual public unsafe_ios, public stream_MT {
public:
enum open_mode {
in = 0x01, // open for reading
out = 0x02, // open for writing
ate = 0x04, // seek to eof upon original open
app = 0x08, // append mode: all additions at eof
trunc = 0x10, // truncate file if already exists
nocreate = 0x20, // open fails if file doesn't exist
noreplace= 0x40 // open fails if file already exists
};
// stream seek direction
enum seek_dir { beg=0, cur=1, end=2 };
// see ios(3CC4) for remainder ...
} ;
class streambuf : public stream_MT {
public:
streambuf() ;
streambuf(char* p, int len);
void dbp() ;
protected:
int allocate();
char* base();
int blen();
char* eback();
char* ebuf();
char* egptr();
char* epptr();
void gbump(int n);
char* gptr();
char* pbase();
void pbump(int n);
char* pptr();
void setg(char* eb, char* g, char* eg);
void setp(char* p, char* ep);
void setb(char* b, char* eb, int a=0);
int unbuffered();
void unbuffered(int);
virtual int doallocate();
virtual ~streambuf() ;
int allocate_unlocked();
char* base_unlocked();
int blen_unlocked();
char* eback_unlocked();
char* ebuf_unlocked();
char* egptr_unlocked();
char* epptr_unlocked();
void gbump_unlocked(int n);
char* gptr_unlocked();
char* pbase_unlocked();
void pbump_unlocked(int n);
char* pptr_unlocked();
void setg_unlocked(char* eb, char* g, char* eg);
void setp_unlocked(char* p, char* ep);
int unbuffered_unlocked();
void unbuffered_unlocked(int);
public:
virtual int pbackfail(int c);
virtual int overflow(int c=EOF);
virtual int underflow();
virtual streambuf*
setbuf(char* p, int len);
streambuf*
setbuf(unsigned char* p, in len);
virtual streampos
seekpos(streampos, int =ios::in|ios:out);
virtual streampos
seekoff(streamoff, seek_dir, int =ios::in|ios:out);
virtual int sync();
};
DESCRIPTION
The public interface of streambufs is described in sbufpub(3CC4). Here
we discuss the protected interface, necessary to derive a usable buffer
class. The streambuf class is intended only to be a base class; no
streambuf object is intended to be constructed. Three predefined
derived buffer classes are provided; see filebuf(3CC4), ssbuf(3CC4),
stdiobuf(3CC4).
Generally speaking, the non-virtual functions described here are not
intended to be over-ridden; they provide low-level buffer-management
functions.
We describe virtual functions here in terms of their functionality, and
their default behavior. Where the default behavior is suitable for a
derived buffer class, the function need not be overridden. For exam‐
ple, a buffer class which has no input source need not do anything on
underflow except return EOF, the default behavior. Where the default
behavior is not appropriate, a class-specific version of the function
should be provided. For example, an input buffer connected to a file
should attempt to read more data on underflow. A replacement virtual
function should conform to the specification given for the streambuf
version to ensure that other functions which depend on this behavior
will continue to work.
Each of the protected member functions of streambuf uses locking to
help in making streambuf work correctly in a multi-threaded environ‐
ment.
A set of unlocked functions are provided that do not implement the
locking associated with making streambuf MT safe. These functions are
distinguished by the suffix _unlocked appended to the function name.
Constructors and assignment
streambuf()
This constructor creates an empty buffer for an empty input
stream.
streambuf(ptr, len)
This constructor creates an empty buffer, or reserve area (see
below) using the len bytes beginning at the location pointed to
by ptr.
streambuf(streambuf&) // private
operator= (streambuf&) // private
The copy constructor and assignment operator are private and not
implemented to ensure that a streambuf cannot be copied. You
don't want to copy a streambuf, but rather pass around pointers
to one.
The get, put, and reserve areas
The buffer of a streambuf may be considered to have three parts: the
get area, the put area, and the reserve area (which is the same as the
buffer area). The get area contains the characters immediately avail‐
able for input. The put area holds characters stored for output but
not yet consumed by (flushed to) their ultimate destination. The get
and put areas may be disjoint or may overlap. The reserve area is the
entire buffer, overlapped by the get and put areas. The get and put
areas may expand into the remainder of the reserve area. In the course
of input and output operations, the sizes of the get and put areas
expand and shrink, always bounded by the total buffer size.
The buffer and its areas are defined by private pointer variables which
may be read and set via protected member functions. The pointers,
described below, should be thought of as pointing between characters;
that is, although a pointer points ``at'' a character, it is more help‐
ful to view it as pointing ``just before'' it. This establishes a cor‐
respondence to the abstraction described in sbufpub(3CC4),
Non-virtual functions for examining pointers
char* ptr = sbuf.base()
Returns a pointer to the beginning of the reserve area.
char* ptr = sbuf.ebuf()
Returns a pointer just past the end of the reserve area. The
space from base() through ebuf()-1 is the reserve area. If
ebuf()==base(), the stream is unbuffered.
char* ptr = sbuf.gptr()
Returns a pointer to the beginning of the get area, and thus to
the next character to be fetched (if there are any). The char‐
acters immediately available are from gptr() through egptr()-1.
If egptr()<=gptr(), no characters are available.
char* ptr = sbuf.egptr()
Returns a pointer just past the end of the get area, the maximum
possible value for gptr().
char* ptr = sbuf.eback()
Returns the lowest possible value for gptr(). The space from
eback() through gptr()-1 is available for putting characters
back (backing up the get pointer). If eback()==gptr(), an
attempted putback operation might fail.
char* ptr = sbuf.pptr()
Returns a pointer to the beginning of the put area, and thus to
the location of the next character that is stored (if possible).
char* ptr = sbuf.pbase()
Returns the a pointer to the beginning of the space available
for the put area, the lowest possible value for pptr(). The
area from pbase() through pptr()-1 represents characters which
have been stored in the buffer but not yet consumed.
char* ptr = sbuf.epptr()
Returns a pointer just past the end of the put area, the maximum
possible value for pptr(). The space from pptr() through
epptr() is immediately available for storing characters without
a flush operation.
Non-virtual functions for setting pointers
These functions provide the only way to set the pointers. Direct
access is disallowed in order to ensure consistency among the various
pointers. The pointer arguments to a function should all be zero to
indicate that there is no area (get, put, reserve). Using equal non-
zero pointers might result in improper behavior.
sbuf.setb(buf, end, del)
Establishes the reserve area (the buffer). Sets base() to buf
and ebuf() to end. If del is non-zero, the buffer will be
deleted whenever base() is changed by another call to setb(), or
when the streambuf destructor is invoked. If del is zero, the
buffer will not be deleted automatically by these functions.
sbuf.setg(back, g, eg)
Establishes the get area. Sets eback() to back, gptr() to g,
and egptr() to eg.
sbuf.setp(p, ep)
Establishes the put area. Sets pptr() to p and epptr() to ep.
Other non-virtual functions
int i = sbuf.allocate()
This function is not called by any non-virtual member of stream‐
buf. It tries to set up a reserve area of an unspecified
default size. It returns zero and does nothing if there is
already a reserve area or if the streambuf is marked unbuffered.
Otherwise, it attempts the allocation by calling the virtual
function doallocate(). It returns 1 on success, EOF on failure.
See below for unbuffered() and doallocate().
int i = sbuf.blen()
Returns the size in chars of the reserve area, ebuf()-base().
sbuf.gbump(n)
Add n, a signed quantity, to the get pointer, without any valid‐
ity checks.
sbuf.pbump(n)
Add n, a signed quantity, to the put pointer, without any valid‐
ity checks.
int i = sbuf.unbuffered()sbuf.unbuffered(i)
A streambuf has a private variable which keeps track of whether
the stream is buffered or unbuffered, independent of whether a
reserve area has been assigned. The main use of this variable
is to control whether allocate() will actually allocate a
reserve area. The first form of the function returns nonzero if
the variable is set, zero otherwise. The second form sets the
variable if i is nonzero, clears it otherwise.
dpb() Writes all the state variables of the streambuf as text directly
to file descriptor 1 (standard output). This data is useful for
debugging an implementation. It is a public function so that it
may be called anywhere for debugging purposes, even though it is
logically part of the protected interface.
Virtual functions
These are the virtual functions which may be or should be redefined by
specialized buffer classes, as noted above. Replacement functions
should meet the specifications listed here to ensure proper operation
of other functions which may depend on them. This section also docu‐
ments the default behavior of the base class versions of these func‐
tions.
int i = sbuf.doallocate()
This function is called by allocate when unbuffered() is zero
and base() is zero. It attempts to make a buffer of suitable
size available. On success it must call setb to establish the
reserve area, then return a value greater than zero. On failure
it returns EOF. The default behavior is to allocate a buffer
using new.
int i = sbuf.overflow(c)
This function is called to consume characters (flush them to
output), typically when the put area is full and an attempt is
made to store another character. If c is not EOF, overflow must
either store or consume the character, following those already
in the put area. It returns EOF on error, any other value on
success.
The default behavior of the base class version is undefined, so
each derived class must define its own overflow. The normal
action for a derived class version is to consume the characters
in the put area (those between pbase() and pptr()), call setp()
to set up a new put area, then store c (using sputc()) if it is
not EOF.
int i = sbuf.pbackfail(c)
This function is called when an attempt is made to put back the
character c and there is no space in the putback area; that is,
eback()==gptr(). If this situation can be handled, such as by
repositioning an external device, the derived class version of
pbackfail should do so and return c. If the character cannot be
put back for whatever reason, it should return EOF. The default
behavior of the base class version is to return EOF.
streampos pos = sbuf.seekoff(off, dir, mode)
See sbufpub(3CC4) for a description of the parameters, return
value, and purpose of this function. The abstract get and put
pointers, as opposed to gptr() and pptr() specifically, are mod‐
ified by this function if possible. A derived class version
should return EOF if the stream does not support repositioning
or if there is any error, and the new position otherwise. The
default behavior of the base class version is to return EOF.
streampos pos2 = sbuf.seekpos(pos, mode)
See sbufpub(3CC4) for a description of the parameters, return
value, and purpose of this function. The abstract get and put
pointers, as opposed to gptr() and pptr() specifically, are mod‐
ified by this function if possible. The default behavior of the
base class version is just to return the value of
sbuf.seekoff( (streamoff)pos, ios::beg, mode )
This means that it is usually only necessary to implement
seekoff in a derived class, and inherit the base class seekpos.
streambuf* sb = sbuf.setbuf(ptr, len)
A call of this function is a request to use the array of len
bytes starting at the location pointed to by ptr as the buffer
area. Setting ptr to zero or len to less than or equal to zero
requests an unbuffered state. The derived class version may
choose to ignore the request. It should return the address of
sbuf if it accepts the request, EOF otherwise. The default
behavior of the base class version is to honor the request if
there is no reserve area.
int i = sbuf.sync()
This function synchronizes the streambuf with its actual stream
of characters. The derived class version should flush any char‐
acters in the put area to their final destination, and if possi‐
ble give back any characters in the input buffer to their
source. It should return EOF on any error, zero on success.
The default behavior of the base class version is to return zero
if there are no pending input or output characters (in_avail()
and out_waiting() are both zero), and return EOF otherwise.
int i = sbuf.underflow()
This function is called to supply characters for input (from
some source) when the get area is empty, although it may be
called at other times. If the get area is not empty, it should
just return the first character (without advancing the get
pointer). If the get area is empty, it should establish a new
get area, aquire new input, and return the first character, if
any. If no input characters are available, it should leave an
empty get area and return EOF. The default behavior of the base
class version is undefined, so each derived class must define
its own underflow.
SEE ALSOios.intro(3CC4), filebuf(3CC4), ios(3CC4), sbufpub(3CC4), ssbuf(3CC4),
stdiobuf(3CC4),
C++ Library Reference
Chapter 3, "The Classic iostream Library",
Chapter 4, "Using Classic iostream in a Multithreaded Environ‐
ment."
06 February 1996 SBUFPROT(3CC4)