Oberon || Library || Module Index || Search Engine || Definition || Module
TYPE ObjectTable = POINTER TO ObjectTableRec; TYPE ObjectTableRec = RECORD (Disciplines.ObjectRec) END;
CONST corruptedInput = 0; readFailed = 1; CONST typeGuardFailure = 2; unknownObject = 3; CONST writeFailed = 4; errors = 5; TYPE ErrorCode = SHORTINT; (* corruptedInput ... *) TYPE ErrorEvent = POINTER TO ErrorEventRec; TYPE ErrorEventRec = RECORD (Events.EventRec) s: Streams.Stream; code: ErrorCode; otype, guard: Services.Type; modname, name: ConstStrings.String; END; VAR error: Events.EventType; VAR errormsg: ARRAY errors OF Events.Message;
PROCEDURE CreateTable(VAR table: ObjectTable); PROCEDURE Add(table: ObjectTable; object: PersistentObjects.Object; modname, name: ConstStrings.String); PROCEDURE Insert(table: ObjectTable; object: PersistentObjects.Object; modname: ConstStrings.String; VAR name: ConstStrings.String); PROCEDURE Lookup(table: ObjectTable; modname, name: ConstStrings.String; VAR object: PersistentObjects.Object) : BOOLEAN; PROCEDURE GetObjects(table: ObjectTable; it: Iterators.Iterator); PROCEDURE InTab(table: ObjectTable; modname: ConstStrings.String) : BOOLEAN;
PROCEDURE Init(s: Streams.Stream; modname: ConstStrings.String; table: ObjectTable); PROCEDURE GetParams(s: Streams.Stream; VAR modname: ConstStrings.String; VAR table: ObjectTable);
PROCEDURE Read(s: Streams.Stream; VAR object: PersistentObjects.Object) : BOOLEAN; PROCEDURE GuardedRead(s: Streams.Stream; guard: Services.Type; VAR object: PersistentObjects.Object) : BOOLEAN; PROCEDURE Write(s: Streams.Stream; object: PersistentObjects.Object; modname, name: ConstStrings.String) : BOOLEAN;
Graphs are written module-wise: Open an individual stream for each module, call Init for it, and invoke Write for a root object of that module. Root objects have the property that all other objects of that module can be reached from them without crossing module boundaries.
On reading, modules have to be read in topological order by invoking Read or GuardedRead for each of the root objects on each individual stream representing a module. An object table allows to resolve references across module boundaries by storing all objects read so far by their module and object names.
Note that ModularizedStructures does not store any information (using PersistentDisciplines or whatever) about module and/or object names at the objects itself. Instead these names must be explicitly passed to Write, and the reading marshalling procedures are expected to add objects to the object table. This avoids redundancy and gives more flexibility in allowing objects to be used in more than one context of ModularizedStructures. It is recommended to put support for this in an application-dependent persistent object type. An example for this is CompilerObjects.
Not all objects belonging to a modularized graph need to be named and read or written using ModularizedStructures. This is necessary only for objects that are possibly referenced across module boundaries. Objects that are referenced by multiple modules but not saved and restored using ModularizedStructures will be duplicated.
CreateTable creates an object table that stores persistent objects by their module and object name. Object tables are later associated by Init with a stream that represents a module, and used (but not maintained) by Read and GuardedRead.
Add adds object to table with the given module and object name. Module names do not have to be registered before, they come into existence when they are mentioned first. Insert works like Add but generates an unique name for it. Lookup allows to access objects of a table by their module and object name. GetObjects returns an iterator that allows to iterate through all objects of an object table. InTab returns TRUE if objects of module modname are included in the table.
Init associates a stream with a module name and a table. There is only one such association active for a stream and multiple calls of Init allow to change an association. Note that the object table parameter may be NIL if neither Read nor GuardedRead will be called for that stream. GetParams returns the parameters passed earlier to Init. Note that GetParams must not be called if Init has not been called before.
Read and GuardedRead work like their counterparts in LinearizedStructures but support references across modules if referenced objects are to be found in the object table associated with s. Write writes a reference of object (if modname is non-NIL and not equal to the module associated with s), or the object itself using LinearizedStructures otherwise.
Oberon || Library || Module Index || Search Engine || Definition || Module