.\" '\" tep .\" to invoke 'tbl', 'eqn', 'pic' in the proper order .\" .\" @(#)sbufprot.3 1.1 93/04/27 SMI; .\" .TH SBUFPROT 3CC4 "06 February 1996" .\" .SH NAME sbufprot \- protected interface of the stream buffer base class .SH SYNOPSIS .LP .nf .ft B #include .sp .5v typedef long streampos; typedef long streamoff; .sp .5v 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 }; // \fIsee \fBios\fR(3CC4)\fI for remainder ...\fB } ; 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(); }; .ft R .fi .\" .SH DESCRIPTION .LP The public interface of \fBstreambuf\fRs is described in \fBsbufpub\fR(3CC4). Here we discuss the protected interface, necessary to derive a usable buffer class. The \fBstreambuf\fR 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 .BR filebuf (3CC4), .BR ssbuf (3CC4), .BR stdiobuf (3CC4). .LP Generally speaking, the non-virtual functions described here are not intended to be over-ridden; they provide low-level buffer-management functions. .LP 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 example, a buffer class which has no input source need not do anything on .I underflow except return .BR "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 .B streambuf version to ensure that other functions which depend on this behavior will continue to work. .\" .PP Each of the protected member functions of streambuf uses locking to help in making streambuf work correctly in a multi-threaded environment. .PP 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 .B _unlocked appended to the function name. .PP .SS "Constructors and assignment" .TP .B "streambuf()" This constructor creates an empty buffer for an empty input stream. .TP .B "streambuf(ptr, len)" This constructor creates an empty buffer, or \fIreserve\fR area (see below) using the \fBlen\fR bytes beginning at the location pointed to by \fBptr\fR. .TP .BI "streambuf(streambuf&)" " // private" .ti -.5i .BI "operator= (streambuf&)" " // private" .br The copy constructor and assignment operator are private and not implemented to ensure that a \fBstreambuf\fR cannot be copied. You don't want to copy a \fBstreambuf\fR, but rather pass around pointers to one. .\" .SS "The get, put, and reserve areas" The buffer of a .B streambuf may be considered to have three parts: the \fIget\fI area, the \fIput\fI area, and the \fIreserve\fI area (which is the same as the buffer area). The get area contains the characters immediately available 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. .LP 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 helpful to view it as pointing ``just before'' it. This establishes a correspondence to the abstraction described in .BR sbufpub (3CC4), .\" .SS "Non-virtual functions for examining pointers" .TP .B "char* ptr = sbuf.base()" Returns a pointer to the beginning of the reserve area. .TP .B "char* ptr = sbuf.ebuf()" Returns a pointer just past the end of the reserve area. The space from \fBbase()\fR through \fBebuf()\-1\fR is the reserve area. If \fBebuf()==base()\fR, the stream is unbuffered. .TP .B "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 characters immediately available are from \fBgptr()\fR through \fBegptr()\-1\fR. If \fBegptr()<=gptr()\fR, no characters are available. .TP .B "char* ptr = sbuf.egptr()" Returns a pointer just past the end of the get area, the maximum possible value for \fBgptr()\fR. .TP .B "char* ptr = sbuf.eback()" Returns the lowest possible value for \fBgptr()\fR. The space from \fBeback()\fR through \fBgptr()\-1\fR is available for putting characters back (backing up the get pointer). If \fBeback()==gptr()\fR, an attempted putback operation might fail. .TP .B "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). .TP .B "char* ptr = sbuf.pbase()" Returns the a pointer to the beginning of the space available for the put area, the lowest possible value for \fBpptr()\fR. The area from \fBpbase()\fR through \fBpptr()\-1\fR represents characters which have been stored in the buffer but not yet consumed. .TP .B "char* ptr = sbuf.epptr()" Returns a pointer just past the end of the put area, the maximum possible value for \fBpptr()\fR. The space from \fBpptr()\fR through \fBepptr()\fR is immediately available for storing characters without a flush operation. .\" .SS "Non-virtual functions for setting pointers" .LP 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. .TP .B "sbuf.setb(buf, end, del)" Establishes the reserve area (the buffer). Sets \fBbase()\fR to \fBbuf\fR and \fBebuf()\fR to \fBend\fR. If \fBdel\fR is non-zero, the buffer will be \fBdelete\fRd whenever \fBbase()\fR is changed by another call to \fBsetb()\fR, or when the streambuf destructor is invoked. If \fBdel\fR is zero, the buffer will not be deleted automatically by these functions. .TP .B "sbuf.setg(back, g, eg)" Establishes the get area. Sets \fBeback()\fR to \fBback\fR, \fBgptr()\fR to \fBg\fR, and \fBegptr()\fR to \fBeg\fR. .TP .B "sbuf.setp(p, ep)" Establishes the put area. Sets \fBpptr()\fR to \fBp\fR and \fBepptr()\fR to \fBep\fR. .\" .SS "Other non-virtual functions" .TP .B "int i = sbuf.allocate()" This function is not called by any non-virtual member of \fBstreambuf\fR. 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 \fBstreambuf\fR is marked unbuffered. Otherwise, it attempts the allocation by calling the virtual function \fBdoallocate()\fR. It returns 1 on success, \fBEOF\fR on failure. See below for \fBunbuffered()\fR and \fBdoallocate()\fR. .TP .B "int i = sbuf.blen()" Returns the size in \fBchar\fRs of the reserve area, \fBebuf()\-base()\fR. .TP .B "sbuf.gbump(n)" Add \fBn\fR, a signed quantity, to the get pointer, without any validity checks. .TP .B "sbuf.pbump(n)" Add \fBn\fR, a signed quantity, to the put pointer, without any validity checks. .TP .B "int i = sbuf.unbuffered()" .ti -.5i .B "sbuf.unbuffered(i)" .br A \fBstreambuf\fR 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 \fBallocate()\fR 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 \fBi\fR is nonzero, clears it otherwise. .TP .B "dpb()" Writes all the state variables of the \fBstreambuf\fR 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. .\" .SS "Virtual functions" .LP 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 documents the default behavior of the base class versions of these functions. .TP .B "int i = sbuf.doallocate()" This function is called by \fBallocate\fR when \fBunbuffered()\fR is zero and \fBbase()\fR is zero. It attempts to make a buffer of suitable size available. On success it must call \fBsetb\fR to establish the reserve area, then return a value greater than zero. On failure it returns \fBEOF\fR. The default behavior is to allocate a buffer using \fBnew\fR. .TP .B "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 \fBc\fR is not \fBEOF\fR, \fBoverflow\fR must either store or consume the character, following those already in the put area. It returns \fBEOF\fR on error, any other value on success. .sp .5v The default behavior of the base class version is undefined, so each derived class must define its own \fBoverflow\fR. The normal action for a derived class version is to consume the characters in the put area (those between \fBpbase()\fR and \fBpptr()\fR), call \fBsetp()\fR to set up a new put area, then store \fBc\fR (using \fBsputc()\fR) if it is not \fBEOF\fR. .TP .B "int i = sbuf.pbackfail(c)" This function is called when an attempt is made to put back the character \fBc\fR and there is no space in the putback area; that is, \fBeback()==gptr()\fR. If this situation can be handled, such as by repositioning an external device, the derived class version of \fBpbackfail\fR should do so and return \fBc\fR. If the character cannot be put back for whatever reason, it should return \fBEOF\fR. The default behavior of the base class version is to return \fBEOF\fR. .TP .B "streampos pos = sbuf.seekoff(off, dir, mode)" See \fBsbufpub\fR(3CC4) for a description of the parameters, return value, and purpose of this function. The abstract get and put pointers, as opposed to \fBgptr()\fR and \fBpptr()\fR specifically, are modified by this function if possible. A derived class version should return \fBEOF\fR 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 \fBEOF\fR. .TP .B "streampos pos2 = sbuf.seekpos(pos, mode)" See \fBsbufpub\fR(3CC4) for a description of the parameters, return value, and purpose of this function. The abstract get and put pointers, as opposed to \fBgptr()\fR and \fBpptr()\fR specifically, are modified by this function if possible. The default behavior of the base class version is just to return the value of .ti +.5i .B "sbuf.seekoff( (streamoff)pos, ios::beg, mode )" .br This means that it is usually only necessary to implement \fBseekoff\fR in a derived class, and inherit the base class \fBseekpos\fR. .TP .B "streambuf* sb = sbuf.setbuf(ptr, len)" A call of this function is a request to use the array of \fBlen\fR bytes starting at the location pointed to by \fBptr\fR as the buffer area. Setting \fBptr\fR to zero or \fBlen\fR 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 \fBsbuf\fR if it accepts the request, \fBEOF\fR otherwise. The default behavior of the base class version is to honor the request if there is no reserve area. .TP .B "int i = sbuf.sync()" This function synchronizes the \fBstreambuf\fR with its actual stream of characters. The derived class version should flush any characters in the put area to their final destination, and if possible give back any characters in the input buffer to their source. It should return \fBEOF\fR 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 (\fBin_avail()\fR and \fBout_waiting()\fR are both zero), and return \fBEOF\fR otherwise. .TP .B "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 \fBEOF\fR. The default behavior of the base class version is undefined, so each derived class must define its own \fBunderflow\fR. .\" .SH "SEE ALSO" .LP .na .BR ios.intro (3CC4), .BR filebuf (3CC4), .BR ios (3CC4), .BR sbufpub (3CC4), .BR ssbuf (3CC4), .BR stdiobuf (3CC4), .TP .I C++ Library Reference .TP Chapter 3, "The Classic \fIiostream\fR Library", .TP Chapter 4, "Using Classic \fIiostream\fR in a Multithreaded Environment." .\" .TZ ????