* For information about this program, contact Blair MacIntyre * (bm@cs.columbia.edu) or Steven Feiner (feiner@cs.columbia.edu) * at the Computer Science Dept., Columbia University, * 1214 Amsterdam Ave. Mailstop 0401, New York, NY, 10027. * * Copyright (C) 1995, 1996 by The Trustees of Columbia University in the * City of New York. Blair MacIntyre, Computer Science Department. *
ConvertPacking is a module that provides assistance in converting
a data value from one representation to another, where the
representations are represented by RTPacking.Ts.
When an instance of ConvertPacking.T is initialized, an internal
program is created describing how to convert an instance of type
typecode from memory format from to memory format to.
When a conversion is desired, convert should be called. The
first parameter to convert is the address of the data area to be
filled in. It should be an address of the sort returned by
RTHeap.GetDataAdr(ref). The remaining two parameters are used
during the conversion process. The first is called to acquire data
from the source. The second is used to fill in references: it is
up to the caller to provide a suitable reference each time getRef
is called.
UNSAFE INTERFACEConvertPacking ; IMPORT RTPacking, PklAction, Thread, Rd, Wr; EXCEPTION Error(TEXT); CONST Brand = "ConvertPacking 1.0"; TYPE T <: Public; Public = OBJECT METHODS init(typecode: INTEGER; from: RTPacking.T; local: RTPacking.T; VAR (*OUT*) nDim, fromEltPack, toEltPack: INTEGER): T RAISES {Error}; getDim(VAR (*OUT*) nDim, fromEltPack, toEltPack: INTEGER); convertRead(dest: ADDRESS; v: ReadVisitor; number: INTEGER): ADDRESS RAISES {Error, Rd.EndOfFile, Rd.Failure, Thread.Alerted}; write(src: ADDRESS; v: WriteVisitor; number: INTEGER): ADDRESS RAISES {Error, Wr.Failure, Thread.Alerted}; print(); printProgram(); END;
convert() will uses the visitor v to fill in the data area
pointed to be dest. dest should point to the beginning of the
data address of a traced reference type with typecode typecode.
If typecode is an Open Array type, then the resulting converter
will be set up to convert one instance of the open array element.
Furthermore, init and getDim will return the number of
dimensions and element packing of the open array. It is up to the
caller to call convert the appropriate number of times with the
correct address each time.
convert will call v.readData each time it needs some data from
the conversion source, v.skipData to skip a number of data bytes
from the source and v.readRef to obtain a reference. It returns
the next address after the block of data filled in by the
conversion.
write will write out a reference in the analogous manner to
convert, without doing any conversions. It assumes the local
data format is the local packing passed to init.
TYPE ReadVisitor <: RVPublic;
RVPublic = OBJECT METHODS
readData(VAR data: ARRAY OF CHAR) RAISES
{Rd.EndOfFile, Rd.Failure, Thread.Alerted};
skipData(length: INTEGER) RAISES
{Rd.EndOfFile, Rd.Failure, Thread.Alerted};
readRef(type: RefType): REFANY RAISES
{Error, Rd.EndOfFile, Rd.Failure, Thread.Alerted};
END;
When v.readData is called, the array data should be filled in with
bytes from the conversion source. When v.skipData is called,
length data bytes in the conversion source should be skipped
over.
TYPE WriteVisitor <: WVPublic;
WVPublic = OBJECT METHODS
writeData(VAR data: ARRAY OF CHAR) RAISES
{Wr.Failure, Thread.Alerted};
skipData(length: INTEGER) RAISES
{Wr.Failure, Thread.Alerted};
writeRef(type: RefType; ref: REFANY) RAISES
{Error, Wr.Failure, Thread.Alerted};
END;
When v.writeData is called, the array data should be writen
output destination. When v.skipData is called,
length data bytes in the destination should be skipped
over.
TYPE
RefType = PklAction.RefType; (* => {Ref, UntracedRef, Proc} *)
v.readRef or v.writeRef is called each time the convertRead
or write methods (respectively) hit a reference data entry that
needs to be dealt with. Because of the way Pickling works, the
single RefType parameter is sufficient for the unpickling code to
obtain the required reference.
PROCEDURE New(typecode: INTEGER; from: RTPacking.T; local: RTPacking.T;
VAR (*OUT*) nDim, fromEltPack, toEltPack: INTEGER): T
RAISES {Error};
Same as NEW(T).init(typecode, from, to, nDim, fromEltPack, toEltPack);
These are the data conversions we currently support.
TYPE
Kind = {Copy, Swap, Copy32to64, Copy64to32, Swap32to64, Swap64to32};
PROCEDURE GetWordKind(from: RTPacking.T; local: RTPacking.T): Kind;
The result is good for all ordinal types except LONGINT.
PROCEDURE GetLongintKind(from: RTPacking.T; local: RTPacking.T): Kind;
The result is good only for LONGINT.
END ConvertPacking.