DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 
G2++ Tutorial - G2++(3C++)

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(3C++), for example:

   friend ostream& operator<<(ostream& os,List<GREEK SMALL LETTER TAU >& 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(3C++) 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:

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(3C++) 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

© 2004 The SCO Group, Inc. All rights reserved.
UnixWare 7 Release 7.1.4 - 27 April 2004