1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
Several complexities might be encountered when overriding tt(underflow)
especially when buffers must repeatedly be refreshed and loaded. They are:
itemization(
it() How to keep track of the over-all current offset?
it() The actions performed by tt(underflow) and tt(overflow).
it() Should tt(uflow) be overridden?
it() Which members are called by which stream read/write requests?
it() Overriding tt(xsgetn).
it() Overriding tt(xsputn).
)
figure(polymorphism/buffers)
(Multi-buffer I/O handling)
(BuffersFig)
Figure ref(BuffersFig) shows a situation where multiple buffers are used: the
device's information is made available in a buffer which is processed and
managed by the derived tt(streambuf) class. In this figure the following
variables are introduced:
itemization(
itt(offset) is the device's current position. Its lower limit is 0,
and for all practical purposes there is no upper limit.
itt(maxEnd), however, is the device's current physical maximum offset
value. Such a physical maximum may not exist, but it em(does) exist if,
e.g., a physical buffer in memory is used which cannot contain more
than a fixed number of bytes. In those cases tt(maxEnd) is set to that
maximum value, representing the offset just beyond the highest offset
where a byte may be written to the device;
itt(getEnd) is the current maximum number of characters that can be read
from the device. With a newly defined device its value is 0 (zero),
but once bytes are written to the device tt(getEnd) is updated to the
position just beyond to the highest ever offset where a byte was
written. When disk-files are used tt(getEnd) would be equal to the
file's size;
it() All of the device's information cannot at once be made available in
the tt(streambuf's) buffer. Instead it is split up in blocks of a
fixed size. The device's offset of the first byte of such a
block is available in tt(bufBeg), and the offset just beyond the last
byte of such a block is available in tt(bufEnd); tt(bufEnd) never
exceeds tt(maxEnd).
)
This section covers how such multi-buffer data can be handled by tt(iostream)
objects: streams supporting reading em(and) writing. Such streams offer
tt(seekg) and tt(seekp) members, but the device's offset position applies to
both tt(seekg) and tt(seekp): after either tt(seekg) or tt(seekp) reading and
writing both start at the position defined by either of these two seek
members. Furthermore, when switching between reading and writing no
tt(seekg/seekp) call is required: by default new read or write requests
continue at the device's current offset, set by the last read, write, or seek
request.
|