Providing Inserters and Extractors for User-Defined Types
For some user-defined types, inserters and extractors may already exist; for
such types, we only need check that the routines
have the required semantics before
we ``hook'' them into G2++ via attributes or defaults.
For other user-defined types,
however, it will be necessary to write the inserters
and extractors ourselves.
According to
List(C++),
for example:
friend ostream& operator<<(ostream& os,List< >& x);
Inserts an ASCII representation of x into os.
The representation consists of (1) an open
parenthesis followed by (2) the elements
of x separated by commas followed by (3) a close parenthesis.
Since the output consists entirely of printable characters, this operator is
acceptable and we may omit the get attribute when defining USER
type List.
List(C++)
does not
specify an extractor, however, so we would need to provide one ourselves.
For simplicity, let's go back to the Time example.
Since
Time provides an inserter but not an extractor, we have two choices:
-
Provide an extractor compatible with the existing inserter;
That is, one that reads the external representation created
by the existing inserter;
-
Provide a brand-new pair of functions that use some new external
representation.
First consider the issue of external representation. Besides the basic G2++
requirement (printable ASCII characters only)
there are also the following desiderata:
Environment independence-
Two environments may wish to communicate by exchanging records containing
values of type T.
It is only realistic to assume
that, in addition to the normal
evolution occurring independently within the two
environments (hardware, operating system, data views),
the code implementing type
T will also be evolving independently.
The external
representation chosen for T should therefore be
as immune as possible to the effects of such evolution.
For example, representing a value by its ASCII-fied core image
may be fast, but is certainly a bad idea since it locks
both environments into using the same
(1) machine architecture and (2) implementation
of class T.
Visibility-
If the data in G2 records is semantically meaningful to a human
reader, records can be inspected, manipulated,
and even created by human users using
text editors or other tools.
Reports can be readily formatted using standard UNIX
text processing tools.
This would argue for a representation natural to humans.
Two external representations come to mind:
2:30:27 PM January 1, 1989 EST-
This external representation the advantage of extreme visibility.
It is environment-independent to the extent that the
Time(C++)
function make_time() can parse strings in a wide variety of formats
(American, European, etc.).
Since make_time() cannot handle timezone
names embedded in the text, however,
communication would be restricted to environments
located within the same timezone.
3879637-
(an integer value representing the number of seconds elapsed since
January 1, 1970 at 0h, GMT).
This external representation is not very meaningful
to humans, but it is environment-independent,
since it is a universal representation
of absolute time.
It also has the advantage of speed over the first representation,
which requires parsing.
After considering these tradeoffs, we will choose the second representation.
Since the existing Time inserter produces the first
representation, we will supply
put and get attributes naming two functions,
to be declared in a file called Timeio.h:
usr.g
Time USER
.header Time.h # class definition
.header Timeio.h # inserter, extractor
.put Tput # inserter
.get Tget # extractor
.null Time::MIN
Timeio.h
#include <Time.h>
#include <iostream.h>
ostream& Tput(ostream& os,const Time& t);
istream& Tget(istream& is,Time& t);
Next, we write the operation definitions, which turn out to be surprisingly
simple:
Timeio.c
#include "Timeio.h"
ostream& Tput(ostream& os,const Time& t){
os << t.make_time_t();
return os;
}
istream& Tget(istream& is,Time& t){
long x;
is >> x;
t=make_time(x);
return is;
}
Next topic:
Strings Containing Nonprintable Characters
Previous topic:
Null Values
© 2005 The SCO Group, Inc. All rights reserved.
SCO OpenServer Release 6.0.0 -- 02 June 2005