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 53 54 55 56 57 58 59 60
|
There is only one additional public member: tt(setField(field const
&)). This member defines the size of the next field to extract. Its
parameter is a reference to a tt(field) class, a em(manipulator class)
defining the width of the next field.
Since a tt(field &) is mentioned in tt(Fistream)'s interface, tt(field)
must be declared before tt(Fistream)'s interface starts. The class tt(field)
itself is simple and declares tt(Fistream) as its friend. It has two data
members: tt(d_width) specifies the width of the next field, and tt(d_newWidth)
which is set to tt(true) if tt(d_width)'s value should actually be used. If
tt(d_newWidth) is false, tt(Fistream) returns to its standard extraction
mode. The class tt(field) has two constructors: a default
constructor, setting tt(d_newWidth) to tt(false), and a second constructor
expecting the width of the next field to extract as its value. Here is the
class tt(field):
verbinclude(//FIELD examples/fistream/fistream.h)
Since tt(field) declares tt(Fistream) as its friend, tt(setField) may
inspect tt(field)'s members directly.
Time to return to tt(setField). This function expects a reference to a
tt(field) object, initialized in one of three different ways:
itemization(
itt(field()): When tt(setField)'s argument is a tt(field) object
constructed by its default constructor the next extraction will use
the same field width as the previous extraction.
itt(field(0)): When this tt(field) object is used as tt(setField)'s
argument, fixed-sized field extraction stops, and the tt(Fistream)
acts like any standard tt(istream) object again.
itt(field(x)): When the tt(field) object itself is initialized by a
non-zero size_t value tt(x), then the next field width is tt(x)
characters wide. The preparation of such a field is left to
tt(setBuffer), tt(Fistream)'s only private member.
)
Here is tt(setField)'s implementation:
verbinclude(//SETFIELD examples/fistream/fistream.cc)
The private member tt(setBuffer) defines a buffer of tt(d_width + 1)
characters and uses tt(read) to fill the buffer with tt(d_width)
characters. The buffer is an NTBS. This buffer is used to initialize the
tt(d_iss) member. tt(Fistream)'s tt(rdbuf) member is used to extract the
tt(d_str)'s data via the tt(Fistream) object itself:
verbinclude(//SETBUFFER examples/fistream/fistream.cc)
Although tt(setField) could be used to configure tt(Fistream) to use or
not to use fixed-sized field extraction, using manipulators is probably
preferable. To allow tt(field) objects to be used as manipulators an
overloaded extraction operator was defined. This extraction operator accepts
tt(istream &) and a tt(field const &) objects. Using this extraction
operator, statements like
verb(fis >> field(2) >> x >> field(0);)
are possible (assuming tt(fis) is a tt(Fistream) object). Here is the
overloaded oprshift(), as well as its declaration:
verbinclude(//OPEX examples/fistream/fistream.cc)
Declaration:
verbinclude(//OPEX examples/fistream/fistream.h)
Finally, an example. The following program uses a tt(Fistream) object to
url-decode url-encoded information appearing at its standard input:
verbinclude(//MAIN examples/fistream/main.cc)
|