CoreGeometryIOImpl.mesa 
Copyright © 1986 by Xerox Corporation. All rights reserved.
Bertrand Serlet December 2, 1986 12:44:28 pm PST
Barth, December 4, 1986 6:01:02 pm PST
DIRECTORY CD, CDAtomicObjects, CDCells, CDRects, CDTexts, CDSymbolicObjects, CMosB, CMosBWellDifImpl, Convert, Core, CoreIO, CoreProperties, CoreGeometry, GList, HashTable, Rope;
CoreGeometryIOImpl: CEDAR PROGRAM
IMPORTS CD, CDAtomicObjects, CDCells, CDRects, CDSymbolicObjects, CDTexts, CMosB, CMosBWellDifImpl, Convert, CoreIO, CoreProperties, GList, HashTable, Rope
SHARES CDCells, CDRects, CDTexts, CDSymbolicObjects, CoreGeometry, CMosBWellDifImpl =
BEGIN OPEN CoreIO;
The following classes are not saved even though they are loaded with CMosB. This assumes that they are not atomic objects.
CDImportsImpl $Import
CDRectsImpl $SaveRect
CDTextsImpl $RigidText, $Text
CDCurvesImpl $FilledCurve0, $Line0, $Polygon0, $Spline0
CDOpsImpl $GCollected
CDPolygonsImpl $Polygon
CDRepetitionsImpl $Repetitions
Object Class Registration
objectClassRegistry: HashTable.Table ← HashTable.Create[];
ObjectClassData: TYPE = REF ObjectClassDataRec;
ObjectClassDataRec: TYPE = RECORD [
write: ObjectClassWriteProc ← NIL,
read: ObjectClassReadProc ← NIL];
ObjectClassWriteProc: TYPE = PROC [h: Handle, me: CD.Object];
ObjectClassReadProc: TYPE = PROC [h: Handle] RETURNS [obj: CD.Object];
RegisterObjectClass: PROC [objectClass: CD.ObjectClass, write: ObjectClassWriteProc, read: ObjectClassReadProc] = {
data: ObjectClassData ← NEW[ObjectClassDataRec ← [write, read]];
IF write=NIL OR read=NIL THEN ERROR; -- if only one NIL then invariant for object write/read is broken
[] ← HashTable.Store[objectClassRegistry, objectClass.objectType, data];
};
Object Class IO Utilities
WriteInstance: PROC [h: Handle, instance: CD.Instance] = {
WriteObject[h, instance.ob];
WritePosition[h, instance.location];
WriteInt[h, instance.orientation];
WriteCDProperties[h, instance.properties];
};
ReadInstance: PROC [h: Handle] RETURNS [instance: CD.Instance] = {
instance ← NEW [CD.InstanceRep ← [ob: NIL]];
instance.ob ← ReadObject[h];
instance.location ← ReadPosition[h];
instance.orientation ← ReadInt[h];
instance.properties ← ReadCDProperties[h];
};
WriteInstanceList: PROC [h: Handle, instances: LIST OF CD.Instance] = {
WriteInt[h, GList.Length[instances]];
WHILE instances#NIL DO
WriteInstance[h, instances.first];
instances ← instances.rest;
ENDLOOP;
};
ReadInstanceList: PROC [h: Handle] RETURNS [instances: LIST OF CD.Instance ← NIL] = {
THROUGH [1 .. ReadInt[h]] DO
instances ← CONS [ReadInstance[h], instances];
ENDLOOP;
};
objectsAtom: ATOM = RegisterProperty[$CoreGeometryIOObjects, WriteObjectsProp, ReadObjectsProp];
The prop write and read procedures are only called when the hash tables are initialized for reading, never for writing.
WriteObjectsProp: PropWriteProc = {
WriteHashTable[h, NARROW[value], WriteObjectIDPair];
};
WriteObjectIDPair: HashWriteProc = {
id: ROPENARROW[key];
object: CD.Object ← NARROW[value];
WriteID[h, id];
WriteObject[h, object];
};
ReadObjectsProp: PropReadProc = {
value ← ReadHashTable[h, ReadObjectIDPair, HashTable.RopeEqual, HashTable.HashRope];
};
ReadObjectIDPair: HashReadProc = {
key ← ReadID[h];
value ← ReadObject[h];
};
A HashTable [CD.Object -> Rope ID] is stored on the handle under the key objectsAtom
CMosBObsImpl $C2DifShortCon, $C2LargeSimpleCon, $C2LargeVia, $C2LargeWellSimpleCon, $C2LTrans, $C2LWellTrans, $C2SimpleCon, $C2Trans, $C2Via, $C2WellDifShortCon, $C2WellSimpleCon, $C2WellTrans, $CLWellTrans
WriteObject: PROC [h: Handle, obj: CD.Object] = {
objects: HashTable.Table ← NARROW [CoreProperties.GetProp[h.properties, objectsAtom]];
objectID: ROPENIL;
IF objects=NIL THEN {
objects ← HashTable.Create[];
h.properties ← CoreProperties.PutProp[h.properties, objectsAtom, objects];
};
objectID ← NARROW [HashTable.Fetch[objects, obj].value];
IF objectID=NIL THEN {
classData: ObjectClassData ← NARROW[HashTable.Fetch[objectClassRegistry, obj.class.objectType].value];
objectID ← Rope.Cat["O", Convert.RopeFromInt[from: HashTable.GetSize[objects], base: 16, showRadix: FALSE]];
IF NOT HashTable.Insert[objects, obj, objectID] THEN ERROR;
WriteID[h, objectID];
WriteAtom[h, obj.class.objectType];
IF classData=NIL THEN {
IF CDAtomicObjects.IsAtomicOb[obj] THEN {
WritePosition[h, CD.InterestSize[obj]];
WriteLayer[h, obj.layer];
}
ELSE ERROR; -- no write proc and not atomic
}
ELSE classData.write[h, obj];
WriteCDProperties[h, obj.properties];
}
ELSE WriteID[h, objectID];
};
A HashTable [Rope ID -> CD.Object] is stored on the handle under the key objectsAtom
ReadObject: PROC [h: Handle] RETURNS [obj: CD.Object] = {
objects: HashTable.Table ← NARROW [CoreProperties.GetProp[h.properties, objectsAtom]];
objectID: ROPE;
IF objects=NIL THEN {
objects ← HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope];
h.properties ← CoreProperties.PutProp[h.properties, objectsAtom, objects];
};
objectID ← ReadID[h];
IF Rope.Fetch[objectID]#'O THEN ERROR;
obj ← NARROW [HashTable.Fetch[objects, objectID].value];
IF obj=NIL THEN {
classAtom: ATOM ← ReadAtom[h];
classData: ObjectClassData ← NARROW[HashTable.Fetch[objectClassRegistry, classAtom].value];
IF classData=NIL THEN {
pos: CD.Position ← ReadPosition[h];
layer: CD.Layer ← ReadLayer[h];
obj ← CDAtomicObjects.CreateAtomicOb[classAtom, pos, CMosB.cmosB, layer];
}
ELSE obj ← classData.read[h];
obj.properties ← ReadCDProperties[h];
IF NOT HashTable.Insert[objects, objectID, obj] THEN ERROR;
};
};
WritePosition: PROC [h: Handle, position: CD.Position] = {
WriteInt[h, position.x];
WriteInt[h, position.y];
};
ReadPosition: PROC [h: Handle] RETURNS [position: CD.Position] = {
position.x ← ReadInt[h];
position.y ← ReadInt[h];
};
WriteLayer: PROC [h: Handle, layer: CD.Layer] = {
WriteInt[h, layer];
};
ReadLayer: PROC [h: Handle] RETURNS [layer: CD.Layer] = {
layer ← ReadInt[h];
};
WriteCDProperties: PROC [h: Handle, properties: CD.PropList] = {
props: Core.Properties ← NIL;
WHILE properties#NIL DO
IF ISTYPE [properties.first.key, ATOM] THEN props ← CoreProperties.PutProp[props, NARROW [properties.first.key], properties.first.val];
properties ← properties.rest;
ENDLOOP;
WriteProperties[h, props];
};
ReadCDProperties: PROC [h: Handle] RETURNS [properties: CD.PropList ← NIL] = {
Consume: PROC [key: ATOM, val: REF] = {
properties ← CONS [[key, val], properties];
};
CoreProperties.Enumerate[ReadProperties[h], Consume];
};
WriteRect: PROC [h: Handle, rect: CD.Rect] = {
WriteInt[h, rect.x1]; WriteInt[h, rect.y1];
WriteInt[h, rect.x2]; WriteInt[h, rect.y2];
};
ReadRect: PROC [h: Handle] RETURNS [rect: CD.Rect] = {
rect.x1 ← ReadInt[h]; rect.y1 ← ReadInt[h];
rect.x2 ← ReadInt[h]; rect.y2 ← ReadInt[h];
};
CoreIO Object Property IO
RectPropWrite: PropWriteProc = {WriteRect[h, NARROW [value, REF CD.Rect]^]};
RectPropRead: PropReadProc = {value ← NEW [CD.Rect ← ReadRect[h]]};
PinsPropWrite: PropWriteProc = {
WITH value SELECT FROM
instance: CD.Instance => {WriteInt[h, 1]; WriteInstance[h, instance]};
instances: CoreGeometryImpl.InstanceSeq => {
WriteInt[h, instances.size];
FOR i: NAT IN [0 .. instances.size) DO WriteInstance[h, instances[i]] ENDLOOP;
};
ENDCASE => ERROR; -- hack!
};
PinsPropRead: PropReadProc = {
size: NAT ← ReadInt[h];
instances: CoreGeometryImpl.InstanceSeq ← NEW [CoreGeometryImpl.InstanceSeqRec[size]];
FOR i: NAT IN [0 .. size) DO instances[i] ← ReadInstance[h] ENDLOOP;
value ← instances;
};
GeometryPropWrite: PropWriteProc = {
WriteInstanceList[h, NARROW [value]];
};
GeometryPropRead: PropReadProc = {value ← ReadInstanceList[h]};
InstancePropWrite: PropWriteProc = {WriteInstance[h, NARROW [value]]};
InstancePropRead: PropReadProc = {value ← ReadInstance[h]};
Object Class IO
CMosBWellDifImpl $C2NDifRect, $C2PDifRect
CDRectsImpl $Rect
WriteRectangle: ObjectClassWriteProc = {
WritePosition[h, CD.InterestSize[me]];
WriteLayer[h, me.layer];
};
ReadRectangle: ObjectClassReadProc = {
sz: CD.Position = ReadPosition[h];
l: CD.Layer = ReadLayer[h];
ob: CD.Object = CDRects.CreateRect[sz, l];
RETURN [ob]
};
CDCellsImpl $Cell
WriteCell: ObjectClassWriteProc = {
cellPtr: CD.CellPtr ← NARROW [me.specificRef];
WritePosition[h, me.size];
WriteInstanceList[h, cellPtr.contents];
WriteRect[h, cellPtr.ir];
WriteRope[h, cellPtr.name];
WriteInt[h, LOOPHOLE[cellPtr.simplifyOn]];
WriteRect[h, cellPtr.dIr];
WriteAtom[h, IF cellPtr.drawBorder THEN $TRUE ELSE $FALSE];
WriteAtom[h, IF cellPtr.useDIr THEN $TRUE ELSE $FALSE];
};
ReadCell: ObjectClassReadProc = {
cellPtr: CD.CellPtr ← NEW [CD.CellRep];
obj ← NEW [CD.ObjectRep ← [class: CDCells.cellClass]];
obj.size ← ReadPosition[h];
cellPtr.contents ← ReadInstanceList[h];
cellPtr.ir ← ReadRect[h];
cellPtr.name ← ReadRope[h];
cellPtr.simplifyOn ← LOOPHOLE[ReadInt[h]];
cellPtr.dIr ← ReadRect[h];
cellPtr.drawBorder ← ReadAtom[h]=$TRUE;
cellPtr.useDIr ← ReadAtom[h]=$TRUE;
obj.specificRef ← cellPtr;
};
CDSymbolicObjectsImpl $AlignmentMarkOb, $PinOb0, $SymbolicSegment
WriteMark: ObjectClassWriteProc = {
};
ReadMark: ObjectClassReadProc = {
RETURN[CDSymbolicObjects.CreateMark[]];
};
WritePinOrSegment: ObjectClassWriteProc = {
WritePosition[h, me.size];
};
ReadPin: ObjectClassReadProc = {
RETURN [CDSymbolicObjects.CreatePin[ReadPosition[h]]]
};
ReadSegment: ObjectClassReadProc = {
p: CD.Position ← ReadPosition[h];
RETURN [CDSymbolicObjects.CreateSegment[p.y, p.x]]
};
CDTextsImpl $FlipText
WriteFlipText: ObjectClassWriteProc = {
text: CDTexts.TextPtr ← NARROW [me.specificRef];
WriteRope[h, text.text];
WriteRope[h, text.cdFont.supposedName];
WriteInt[h, text.cdFont.scaleI];
};
ReadFlipText: ObjectClassReadProc = {
text: ROPE ← ReadRope[h];
fontName: ROPE ← ReadRope[h];
scale: INT ← ReadInt[h];
font: CDTexts.CDFont ← CDTexts.MakeFont[fontName, scale];
obj ← CDTexts.CreateText[text, font];
};
Initialization
Register: PROC [decoration: CoreGeometry.Decoration] = {
[] ← RegisterProperty[decoration.irProp, RectPropWrite, RectPropRead];
[] ← RegisterProperty[decoration.pinsProp, PinsPropWrite, PinsPropRead];
[] ← RegisterProperty[decoration.geometryProp, GeometryPropWrite, GeometryPropRead];
[] ← RegisterProperty[decoration.transfProp, InstancePropWrite, InstancePropRead];
};
RegisterObjectClass[CDRects.bareRectClass, WriteRectangle, ReadRectangle];
RegisterObjectClass[CDCells.cellClass, WriteCell, ReadCell];
RegisterObjectClass[CDSymbolicObjects.markClass, WriteMark, ReadMark];
RegisterObjectClass[CDSymbolicObjects.pinClass, WritePinOrSegment, ReadPin];
RegisterObjectClass[CDSymbolicObjects.segmentClass, WritePinOrSegment, ReadSegment];
RegisterObjectClass[CMosBWellDifImpl.wndifClass, WriteRectangle, ReadRectangle];
RegisterObjectClass[CMosBWellDifImpl.wpdifClass, WriteRectangle, ReadRectangle];
RegisterObjectClass[CDTexts.textClass, WriteFlipText, ReadFlipText];
END.