sbuf.prot(3C)

streambuf.prot - Interface for derived classes

As shipped in IRIX 6.5.19. Last changed in IRIX 6.5.19.

NAME
     streambuf.prot - Interface for derived classes

SYNOPSIS
     #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(3C) ...
     } ;

     class streambuf {
     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() ;
     public:
          virtual int    pbackfail(int c);
          virtual int    overflow(int c=EOF);
          virtual int    underflow();
          virtual streambuf*
               setbuf(char* p, int 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
     A streambuf implements the buffer abstraction described in
     sbuf.pub(3C).  However, the streambuf class itself contains only basic
     members for manipulating the characters and, usually a class derived
     from streambuf will be used.

     This man page describes the interface needed by programmers who are
     coding a derived class.  Two kinds of member functions are described.

     The nonvirtual functions are provided for manipulating a streambuf in
     ways that are appropriate in a derived class.  Their descriptions
     reveal details of the implementation that would be inappropriate in
     the public interface.

     The virtual functions permit the derived class to specialize the
     streambuf class in ways appropriate to the specific sources and sinks
     that it is implementing.  The descriptions of the virtual functions
     explain the obligations of the virtuals of the derived class.  If the
     virtuals behave as specified, the streambuf will perform as specified
     in the public interface.  However, if the virtuals do not perform as
     specified, then the streambuf may not perform properly, and an
     iostream (or any other code) that relies on proper behavior of the
     streambuf may not perform properly either.

     In the following descriptions, the following assumptions are made:

     * sb is a streambuf*.

     * i and n are ints.

     * ptr, b, eb, p, ep, eb, g, and eg are char*s.

     * -c is an int character (positive or EOF)).

     * pos is a streampos. (See sbuf.pub(3C).)

     * off is a streamoff.

     * dir is a seekdir.

     * mode is an int representing an open_mode.

   Constructors
     streambuf()
          Constructs an empty buffer corresponding to an empty sequence.

     streambuf(b,len)
          Constructs an empty buffer and then sets up the reserve area to
          be the len bytes starting at b.

   The Get, Put, and Reserver Area
     The protected members of streambuf present an interface to derived
     classes organized around three areas (arrays of bytes) managed
     cooperatively by the base and derived classes.  They are the get area,
     the put area, and the reserve area (or buffer).  The get and the put
     areas are normally disjoint, but they may both overlap the reserve
     area, whose primary purpose is to be a resource in which space for the
     put and get areas can be allocated.  The get and the put areas are
     changed as characters are put into and gotten from the buffer, but the
     reserve area normally remains fixed.  The areas are defined by a
     collection of char* values.  The buffer abstraction is described in
     terms of pointers that point between characters, but the char* values
     must point at chars.  To establish a correspondence, the char* values
     should be thought of as pointing just before the byte they really
     point at.

   Functions to Examine the Pointers
     ptr=sb->base()
          Returns a pointer to the first byte of the reserve area.  The
          reserve area is the space between sb->base() and sb->ebuf().

     ptr=sb->eback()
          Returns a pointer to a lower bound on sb->gptr().  The space
          between sb->eback() and sb->gptr() is available for putback.

     ptr=sb->ebuf()
          Returns a pointer to the byte after the last byte of the reserve
          area.

     ptr=sb->egptr()
          Returns a pointer to the byte after the last byte of the get
          area.

     ptr=sb->epptr()
          Returns a pointer to the byte after the last byte of the put
          area.

     ptr=sb->gptr()
          Returns a pointer to the first byte of the get area.  The
          available characters are those between sb->gptr() and
          sb->egptr().  The next character fetched will be *sb->gptr())
          unless sb->egptr() is less than or equal to sb->gptr().

     ptr=sb->pbase()
          Returns a pointer to the put area base.  Characters between
          sb->pbase() and sb->pptr() have been stored into the buffer and
          not yet consumed.

     ptr=sb->pptr()
          Returns a pointer to the first byte of the put area.  The space
          between sb->pptr() and sb->epptr() is the put area.  This is
          where characters will be stored.

   Functions for Setting the Pointers
     Note that to indicate that a particular area (get, put, or reserve)
     does not exist, all the associated pointers should be set to zero.

     sb->setb(b, eb, i)
          Sets base() and ebuf() to b and eb respectively.  i controls
          whether the area will be subject to automatic deletion.  If i is
          non-zero, then b will be deleted when base is changed by another
          call of setb(), or when the destructor is called for *sb.  If b
          and eb are both null then we say that there is no reserve area.
          If b is non-null, there is a reserve area even if eb is less than
          b and so the reserve area has zero length.

     sb->setp(p, ep)
          Sets pptr() to p, pbase() to p, and epptr() to ep.

     sb->setg(eb, g, eg)
          Sets eback() to eb, gptr() to g, and egptr() to eg.

   Other Non-virtual Members
     i=sb->allocate()
          Tries to set up a reserve area.  If a reserve area already exists
          or if sb->unbuffered() is nonzero, allocate() returns 0 without
          doing anything.  If the attempt to allocate space fails,
          allocate() returns EOF, otherwise (allocation succeeds)
          allocate() returns 1.  allocate() is not called by any non-
          virtual member function of streambuf.

     i=sb->blen()
          Returns the size (in chars) of the current reserve area.

     dbp()
          Writes directly on file descriptor 1 information in ASCII about
          the state of the buffer.  It is intended for debugging and
          nothing is specified about the form of the output.  It is
          considered part of the protected interface because the
          information it prints can only be understood in relation to that
          interface, but it is a public function so that it can be called
          anywhere during debugging.

     sb->gbump(n)
          Increments gptr() by n which may be positive or negative.  No
          checks are made on whether the new value of gptr() is in bounds.

     sb->pbump(n)
          Increments pptr() by n which may be positive or negative.  No
          checks are made on whether the new value of pptr() is in bounds.

     sb->unbuffered(i), i=sb->unbuffered()
          There is a private variable known as sb's buffering state.  sb-
          >unbuffered(i) sets the value of this variable to i and sb-
          >unbuffered() returns the current value.  This state is
          independent of the actual allocation of a reserve area.  Its
          primary purpose is to control whether a reserve area is allocated
          automatically by allocate.

   Virtual Member Functions
     Virtual functions may be redefined in derived classes to specialize
     the behavior of streambufs.  This section describes the behavior that
     these virtual functions should have in any derived classes; the next
     section describes the behavior that these functions are defined to
     have in base class streambuf.

     i=sb->doallocate()
          Is called when allocate() determines that space is needed.
          doallocate() is required to call setb() to provide a reserve area
          or to return EOF if it cannot.  It is only called if
          sb->unbuffered() is zero and sb->base() is zero.

     i=overflow(c)
          Is called to consume characters.  If c is not EOF, overflow()
          also must either save c or consume it.  Usually it is called when
          the put area is full and an attempt is being made to store a new
          character, but it can be called at other times.  The normal
          action is to consume the characters between pbase() and pptr(),
          call setp() to establish a new put area, and if c!=EOF store it
          (using sputc()).  sb->overflow() should return EOF to indicate an
          error; otherwise it should return something else.

     i=sb->pbackfail(c)
          Is called when eback() equals gptr() and an attempt has been made
          to putback c.  If this situation can be dealt with (e.g., by
          repositioning an external file), pbackfail() should return c;
          otherwise it should return EOF.

     pos=sb->seekoff(off, dir, mode)
          Repositions the get and/or put pointers  (i.e., the abstract get
          and put pointers, not pptr() and gptr()).  The meanings of off
          and dir are discussed in sbuf.pub(3C).  mode specifies whether
          the put pointer (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.  A class derived from streambuf
          is not required to support repositioning.  seekoff() should
          return EOF if the class does not support repositioning.  If the
          class does support repositioning, seekoff() should return the new
          position or EOF on error.

     pos=sb->seekpos(pos, mode)
          Repositions the streambuf get and/or put pointer to pos.  mode
          specifies which pointers are affected as for seekoff().  Returns
          pos (the argument) or EOF if the class does not support
          repositioning or an error occurs.

     sb=sb->setbuf(ptr, len)
          Offers the array at ptr with len bytes to be used as a reserve
          area.  The normal interpretation is that if ptr or len are zero
          then this is a request to make the sb unbuffered.  The derived
          class may use this area or not as it chooses.  It may accept or
          ignore the request for unbuffered state as it chooses.  setbuf()
          should return sb if it honors the request.  Otherwise it should
          return 0.

     i=sb->sync()
          Is called to give the derived class a chance to look at the state
          of the areas, and synchronize them with any external
          representation.  Normally sync() should consume any characters
          that have been stored into the put area, and if possible give
          back to the source any characters in the get area that have not
          been fetched.  When sync() returns there should not be any
          unconsumed characters, and the get area should be empty.  sync()
          should return EOF if some kind of failure occurs.

     i=sb->underflow()
          Is called to supply characters for fetching, i.e., to create a
          condition in which the get area is not empty.  If it is called
          when there are characters in the get area it should return the
          first character.  If the get area is empty, it should create a
          nonempty get area and return the next character (which it should
          also leave in the get area).  If there are no more characters
          available, underflow() should return EOF and leave an empty get
          area.

     The default definitions of the virtual functions:

     i=sb->streambuf::doallocate()
          Attempts to allocate a reserve area using operator new.

     i=sb->streambuf::overflow(c)
          Is compatible with the old stream package, but that behavior is
          not considered part of the specification of the iostream package.
          Therefore, streambuf::overflow() should be treated as if it had
          undefined behavior.  That is, derived classes should always
          define it.

     i=sb->streambuf::pbackfail(c)
          Returns EOF.

     pos=sb->streambuf::seekpos(pos, mode)
          Returns sb->seekoff(streamoff(pos),ios::beg,mode).  Thus to
          define seeking in a derived class, it is frequently only
          necessary to define seekoff() and use the inherited
          streambuf::seekpos().

     pos=sb->streambuf::seekoff(off, dir, mode)
          Returns EOF.

     sb=sb->streambuf::setbuf(ptr, len)
          Will honor the request when there is no reserve area.

     i=sb->streambuf::sync()
          Returns 0 if the get area is empty and there are no unconsumed
          characters.  Otherwise it returns EOF.

     i=sb->streambuf::underflow()
          Is compatible with the old stream package, but that behavior is
          not considered part of the specification of the iostream package.
          Therefore, streambuf::underflow() should be treated as if it had
          undefined behavior.  That is, it should always be defined in
          derived classes.

CAVEATS
     The constructors are public for compatibility with the old stream
     package.  They should be protected.

     The interface for unbuffered actions is awkward.  It is difficult to
     write underflow() and overflow() virtuals that behave properly for
     unbuffered streambuf()s without special casing.  Also there is no way
     for the virtuals to react properly to multi-character gets or puts.

     Although the public interface to streambufs deals in characters and
     bytes, the interface to derived classes deals in chars.  Since a
     decision had to be made on the types of the real data pointers, it
     seemed easier to reflect that choice in the types of the protected
     members than to duplicate all the members with both plain and unsigned
     char versions.  But perhaps all these uses of char* ought to have been
     with a typedef.

     The implementation contains a variant of  setbuf() that accepts a
     third argument.  It is present only for compatibility with the old
     stream package.

SEE ALSO
     sbuf.pub(3C), streambuf(3C), ios(3C), istream(3C), ostream(3C)