The member tt(overflow) is called then the stream's write buffer is empty or
exhausted. The member tt(underflow) is called then the stream's read buffer is
empty or exhausted.

In both cases a new buffer (from tt(bufBeg) to tt(bufEnd)) is computed
containing tt(offset). But tt(offset) depends on the streambuf's state. When
called in the tt(SEEK) state tt(offset) is up-to-date; when called in the
tt(WRITE) state the offset is at the last-used write offset; when called in
the tt(READ) state the current offset is at the end of the current read
buffer. 

When called in the tt(SEEK) state the read and write buffers are already
empty. When called in the tt(READ) state the actual offset is determined and
the read buffer is reset to ensure that tt(underflow) is called at the next
read operation.

Likewise, when called in the tt(WRITE) state the write buffer is reset to
ensure that tt(overflow) is called at the next write request. 

Both tt(underflow) and tt(overflow) therefore start by determining the current
offset, computing the corresponding buffer boundaries. The member tt(getOffset)
is called by both tt(underflow) and tt(overflow). Here's its skeleton
implementation: 
    verbinclude(-a examples/getoffset.cc)

The member tt(bufLimits) simply ensures that tt(offset) is located inside a
buffer: 
    verbinclude(-a examples/buflimits.cc)

The member tt(overflow) returns tt(EOF) or initializes a new read
buffer. Since tt(overflow) is guaranteed to be called when writing is
requested from states tt(SEEK) and tt(READ) it calls tt(getOffset) to obtain
the current absolute offset and the corresponding tt(bufBeg) en tt(bufEnd)
values. Writing can only be used if tt(offset < maxEnd). If so, a new write
buffer is installed whose tt(pptr()) points at the tt(offset) position in the
physical device. After calling tt(setp) tt(overflow) em(must) return tt(ch) on
success. Here's tt(overflow's) skeleton:
    verbinclude(-a examples/overflow.cc)

The member tt(underflow) returns tt(EOF) or initializes a new read
buffer. Since tt(underflow) is guaranteed to be called when reading is
requested from states tt(SEEK) and tt(WRITE) it calls, like tt(overflow),
tt(getOffset) to obtain the current absolute offset as well as the
matching tt(bufBeg) en tt(bufEnd) values. Reading can only be used if
tt(offset < getEnd). If so, a new read buffer is installed whose tt(gptr())
points at the tt(offset) position in the physical device.

As with tt(overflow), after calling tt(setg) it's em(essential) that the first
available character (i.e., tt(*gptr())) is returned. If not and the buffer
contains just one character then that character might not be processed by
tt(underflow's) caller. Here's tt(underflow's) skeleton:
    verbinclude(-a examples/underflow.cc)



