CoreGeometryIOImpl.mesa 
Copyright Ó 1986, 1987 by Xerox Corporation. All rights reserved.
Bertrand Serlet May 5, 1988 5:42:00 pm PDT
Barth, December 4, 1986 6:01:02 pm PST
DIRECTORY
BrineIO,
CD, CDAtomicObjects, CDCells, CDPrivate, CDRects, CDRoutingObjects, CDTexts, CDSymbolicObjects,
Core, CoreIO, CoreProperties, CoreGeometry, CoreGeometryBackdoor,
GList, IO, PW, RefTab, RefTabExtras, Rope;
CoreGeometryIOImpl: CEDAR PROGRAM
IMPORTS BrineIO, CD, CDAtomicObjects, CDCells, CDPrivate, CDRects, CDSymbolicObjects, CDRoutingObjects, CDTexts, CoreIO, CoreGeometry, CoreGeometryBackdoor, CoreProperties, GList, PW, RefTab, RefTabExtras, Rope
EXPORTS CoreGeometryBackdoor
SHARES CDCells, CDRects, CDTexts, CDSymbolicObjects, CoreGeometry =
BEGIN OPEN BrineIO, CoreIO, CoreGeometry, CoreGeometryBackdoor;
The following classes are not saved even though they are loaded with CMosB. This assumes that they are not atomic objects.
CDImportsImpl $Import
CDRepetitionsImpl $Repetitions
CDRectsImpl $SaveRect
CDCurvesImpl $FilledCurve0, $Line0, $Polygon0, $Spline0
CDOpsImpl $GCollected
CDPolygonsImpl $Polygon
Object Class Registration
STREAM: TYPE = IO.STREAM;
objectClassRegistry: RefTab.Ref ← RefTab.Create[];
ObjectClassData: TYPE = REF ObjectClassDataRec;
ObjectClassDataRec: TYPE = RECORD [
write: ObjectClassWriteProc ← NIL,
read: ObjectClassReadProc ← NIL];
ObjectClassWriteProc: TYPE = PROC [stream: STREAM, me: CD.Object];
ObjectClassReadProc: TYPE = PROC [stream: STREAM] RETURNS [obj: CD.Object];
RegisterObjectClass: PUBLIC 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
[] ← RefTab.Store[objectClassRegistry, objectClass.objectType, data];
};
Low Level IO Utilities
WritePosition: PUBLIC PROC [stream: STREAM, position: CD.Position] = {
WriteInt[stream, position.x];
WriteInt[stream, position.y];
};
ReadPosition: PUBLIC PROC [stream: STREAM] RETURNS [position: CD.Position] = {
position.x ← ReadInt[stream];
position.y ← ReadInt[stream];
};
WriteRect: PUBLIC PROC [stream: STREAM, rect: CD.Rect] = {
WriteInt[stream, rect.x1]; WriteInt[stream, rect.y1];
WriteInt[stream, rect.x2]; WriteInt[stream, rect.y2];
};
ReadRect: PUBLIC PROC [stream: STREAM] RETURNS [rect: CD.Rect] = {
rect.x1 ← ReadInt[stream]; rect.y1 ← ReadInt[stream];
rect.x2 ← ReadInt[stream]; rect.y2 ← ReadInt[stream];
};
WriteTechnology: PUBLIC PROC [stream: STREAM, technology: CD.Technology] = {
WriteAtom[stream, IF technology=NIL THEN $NILTechnology ELSE technology.key];
};
ReadTechnology: PUBLIC PROC [stream: STREAM] RETURNS [technology: CD.Technology] = {
atom: ATOM ← ReadAtom[stream];
technology ← IF atom=$NILTechnology THEN NIL ELSE CD.FetchTechnology[atom];
};
WriteLayer: PUBLIC PROC [stream: STREAM, layer: CD.Layer] = {
WriteTechnology[stream, CDPrivate.layers[layer].technology];
WriteAtom[stream, CD.LayerKey[layer]];
};
ReadLayer: PUBLIC PROC [stream: STREAM] RETURNS [layer: CD.Layer] = {
technology: CD.Technology ← ReadTechnology[stream];
layer ← CD.FetchLayer[technology, ReadAtom[stream]];
};
WriteOrient: PUBLIC PROC [stream: STREAM, orient: CD.Orientation] = {
WriteInt[stream, ORD[orient]];
};
ReadOrient: PUBLIC PROC [stream: STREAM] RETURNS [orient: CD.Orientation] = {
aux: NAT ← ReadInt[stream];
orient ← VAL [aux];
};
WriteTrans: PUBLIC PROC [stream: STREAM, trans: CD.Transformation] = {
WritePosition[stream, trans.off];
WriteOrient[stream, trans.orient];
};
ReadTrans: PUBLIC PROC [stream: STREAM] RETURNS [trans: CD.Transformation] = {
off: CD.Position ← ReadPosition[stream];
trans ← [off, ReadOrient[stream]];
};
WriteCDProperties: PUBLIC PROC [stream: STREAM, 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[stream, props];
};
ReadCDProperties: PUBLIC PROC [stream: STREAM] RETURNS [properties: CD.PropList ← NIL] = {
Consume: PROC [key: ATOM, val: REF] = {
properties ← CONS [[key, val], properties];
};
CoreProperties.Enumerate[ReadProperties[stream], Consume];
};
Object Class IO Utilities
WriteCDInstance: PUBLIC PROC [stream: STREAM, instance: CD.Instance] = {
WriteObject[stream, instance.ob];
WriteTrans[stream, instance.trans];
WriteCDProperties[stream, instance.properties];
};
ReadCDInstance: PUBLIC PROC [stream: STREAM] RETURNS [instance: CD.Instance] = {
instance ← NEW [CD.InstanceRep ← [ob: ReadObject[stream]]];
instance.trans ← ReadTrans[stream];
instance.properties ← ReadCDProperties[stream];
};
WriteCDInstances: PUBLIC PROC [stream: STREAM, instances: LIST OF CD.Instance] = {
WriteInt[stream, GList.Length[instances]];
WHILE instances#NIL DO
WriteCDInstance[stream, instances.first];
instances ← instances.rest;
ENDLOOP;
};
ReadCDInstances: PUBLIC PROC [stream: STREAM] RETURNS [instances: LIST OF CD.Instance ← NIL] = {
THROUGH [1 .. ReadInt[stream]] DO
instances ← CONS [ReadCDInstance[stream], instances];
ENDLOOP;
};
WriteInstance: PUBLIC PROC [stream: STREAM, instance: Instance] = {
WriteObject[stream, instance.obj];
WriteTrans[stream, instance.trans];
};
ReadInstance: PUBLIC PROC [stream: STREAM] RETURNS [instance: Instance] = {
obj: CD.Object ← ReadObject[stream];
instance ← [obj, ReadTrans[stream]];
};
WriteInstances: PUBLIC PROC [stream: STREAM, instances: Instances] = {
WriteInt[stream, Length[instances]];
WHILE instances#NIL DO
WriteInstance[stream, instances.first];
instances ← instances.rest;
ENDLOOP;
};
ReadInstances: PUBLIC PROC [stream: STREAM] RETURNS [instances: Instances ← NIL] = {
THROUGH [0 .. ReadInt[stream]) DO
instances ← CONS [ReadInstance[stream], instances];
ENDLOOP;
};
WriteObjectRef: PROC [stream: STREAM, ref: REF] = {WriteObject[stream, NARROW [ref]]};
ReadObjectRef: PROC [stream: STREAM] RETURNS [ref: REF] = {ref ← ReadObject[stream]};
CMosBObsImpl $C2DifShortCon, $C2LargeSimpleCon, $C2LargeVia, $C2LargeWellSimpleCon, $C2LTrans, $C2LWellTrans, $C2SimpleCon, $C2Trans, $C2Via, $C2WellDifShortCon, $C2WellSimpleCon, $C2WellTrans, $CLWellTrans
WriteObject: PUBLIC PROC [stream: STREAM, obj: CD.Object] = {
objects: RefTab.Ref ← GetRefTab[stream, $CoreGeometryIOObjects];
objectID: ROPE ← objectID ← NARROW [RefTab.Fetch[objects, obj].val];
IF objectID=NIL THEN {
classData: ObjectClassData ← NARROW[RefTab.Fetch[objectClassRegistry, obj.class.objectType].val];
objectID ← MakeID["O", RefTab.GetSize[objects]];
IF NOT RefTab.Insert[objects, obj, objectID] THEN ERROR;
WriteID[stream, objectID];
WriteAtom[stream, obj.class.objectType];
IF classData=NIL THEN {
IF CDAtomicObjects.IsAtomicOb[obj] THEN {
WriteTechnology[stream, obj.class.technology];
WritePosition[stream, CD.InterestSize[obj]];
WriteLayer[stream, obj.layer];
}
ELSE ERROR; -- no write proc and not atomic
}
ELSE classData.write[stream, obj];
WriteCDProperties[stream, obj.properties];
}
ELSE WriteID[stream, objectID];
};
ReadObject: PUBLIC PROC [stream: STREAM] RETURNS [obj: CD.Object] = {
objects: RefTab.Ref ← GetRefTab[stream, $CoreGeometryIOObjects, RefTabExtras.EqualRope, RefTabExtras.HashRope];
objectID: ROPE ← ReadID[stream];
IF Rope.Fetch[objectID]#'O THEN ERROR;
obj ← NARROW [RefTab.Fetch[objects, objectID].val];
IF obj=NIL THEN {
classAtom: ATOM ← ReadAtom[stream];
classData: ObjectClassData ← NARROW [RefTab.Fetch[objectClassRegistry, classAtom].val];
IF classData=NIL THEN {
technology: CD.Technology ← ReadTechnology[stream];
pos: CD.Position ← ReadPosition[stream];
layer: CD.Layer ← ReadLayer[stream];
obj ← CDAtomicObjects.CreateAtomicOb[classAtom, pos, technology, layer];
}
ELSE obj ← classData.read[stream];
obj.properties ← ReadCDProperties[stream];
IF NOT RefTab.Insert[objects, objectID, obj] THEN ERROR;
};
};
CoreIO Object Property IO
PinsInstancesPropWrite: PropWriteProc = {
count: INT ← 0;
Incr: EachInstanceProc = {count ← count+1};
Write: EachInstanceProc = {WriteInstance[stream, instance]};
[] ← RawEnumeratePins[prop, value, Incr];
WriteInt[stream, count];
[] ← RawEnumeratePins[prop, value, Write];
};
GeometryInstancesPropWrite: PropWriteProc = {
count: INT ← 0;
Incr: EachInstanceProc = {count ← count+1};
Write: EachInstanceProc = {WriteInstance[stream, instance]};
[] ← RawEnumerateGeometry[prop, value, Incr];
WriteInt[stream, count];
[] ← RawEnumeratePins[prop, value, Write];
};
InstancesPropRead: PropReadProc = {
value ← ReadInstances[stream];
};
ObjectPropWrite: PropWriteProc = {WriteObject[stream, NARROW [value]]};
ObjectPropRead: PropReadProc = {value ← ReadObject[stream]};
TransPropWrite: PropWriteProc = {WriteTrans[stream, NARROW [value, REF CD.Transformation]^]};
TransPropRead: PropReadProc = {value ← NEW [CD.Transformation ← ReadTrans[stream]]};
WriteObjectsProp: PropWriteProc = {
WriteRefTab[stream, NARROW [value], WriteIDRef, WriteObjectRef];
};
ReadObjectsProp: PropReadProc = {
value ← ReadRefTab[stream, ReadIDRef, ReadObjectRef, RefTabExtras.EqualRope, RefTabExtras.HashRope];
};
Object Class IO
CMosBWellDifImpl $C2NDifRect, $C2PDifRect; CDRectsImpl $Rect
WriteRectangle: ObjectClassWriteProc = {
WritePosition[stream, CD.InterestSize[me]];
WriteLayer[stream, me.layer];
};
ReadRectangle: ObjectClassReadProc = {
sz: CD.Position = ReadPosition[stream];
l: CD.Layer = ReadLayer[stream];
ob: CD.Object = CDRects.CreateRect[sz, l];
RETURN [ob]
};
CDCellsImpl $Cell
WriteCell: ObjectClassWriteProc = {
ConsInstance: CDCells.InstEnumerator = {insts ← CONS [inst, insts]};
insts: LIST OF CD.Instance ← NIL;
cellPtr: CD.CellSpecific ← NARROW [me.specific];
[] ← CDCells.EnumerateInstances[me, ConsInstance];
WriteRect[stream, me.bbox];
WriteCDInstances[stream, insts];
WriteRect[stream, cellPtr.ir];
WriteReal[stream, cellPtr.simplifyOn];
WriteBool[stream, cellPtr.drawBorder];
WriteBool[stream, cellPtr.specifiedIr];
};
ReadCell: ObjectClassReadProc = {
cellPtr: CD.CellSpecific ← NEW [CD.CellRep];
obj ← NEW [CD.ObjectRep ← [class: CDCells.pCellClass]];
obj.bbox ← ReadRect[stream];
cellPtr.contents ← ReadCDInstances[stream];
cellPtr.ir ← ReadRect[stream];
cellPtr.simplifyOn ← ReadReal[stream];
cellPtr.drawBorder ← ReadBool[stream];
cellPtr.specifiedIr ← ReadBool[stream];
obj.specific ← cellPtr;
CDCells.ToSequenceMode[obj];
};
PW $AbutX $AbutY
WriteAbut: ObjectClassWriteProc = {
Write: PW.EachSubObjectProc = {WriteObject[stream, subObject]};
WriteRect[stream, me.bbox];
WriteBool[stream, me.class=PW.abutXClass];
WriteInt[stream, PW.CountSubObjects[me]];
[] ← PW.EnumerateSubObjects[me, Write];
};
ReadAbut: ObjectClassReadProc = {
bbox: CD.Rect ← ReadRect[stream];
inX: BOOL ← ReadBool[stream];
size: INT ← ReadInt[stream];
subObjects: LIST OF CD.Object ← NIL;
THROUGH [0 .. size) DO subObjects ← CONS [ReadObject[stream], subObjects] ENDLOOP;
obj ← (IF inX THEN PW.CreateNewAbutX ELSE PW.CreateNewAbutY)[NARROW [GList.Reverse[subObjects]]];
IF obj.bbox#bbox THEN ERROR;
};
PW $Rotation
WriteRotation: ObjectClassWriteProc = {
specific: PW.RotationSpecific = NARROW [me.specific];
WriteObject[stream, specific.obj];
WriteOrient[stream, specific.orientation];
};
ReadRotation: ObjectClassReadProc = {
sub: CD.Object ← ReadObject[stream];
orient: CD.Orientation ← ReadOrient[stream];
obj ← PW.CreateRotation[sub, orient];
};
CDRoutingObjects $RoutingClass
WriteRouting: ObjectClassWriteProc = {
routing: CDRoutingObjects.RoutingSpecific ← NARROW [me.specific];
WriteRect[stream, me.bbox];
WriteInt[stream, routing.size];
WriteRect[stream, routing.ir];
WriteReal[stream, routing.scaleHint];
FOR i: NAT IN [0 .. routing.size) DO
node: CDRoutingObjects.Node = routing[i];
WriteInt[stream, node.size];
WriteCDProperties[stream, node.properties];
FOR j: NAT IN [0 .. node.size) DO
WriteObject[stream, node[j].object];
WritePosition[stream, node[j].position];
ENDLOOP;
ENDLOOP;
};
ReadRouting: ObjectClassReadProc = {
bbox: CD.Rect ← ReadRect[stream];
size: NATNAT [ReadInt[stream]];
routing: CDRoutingObjects.RoutingSpecific ← NEW [CDRoutingObjects.RoutingRep[size]];
routing.ir ← ReadRect[stream];
routing.scaleHint ← ReadReal[stream];
FOR i: NAT IN [0 .. size) DO
nb: NATNAT [ReadInt[stream]];
node: CDRoutingObjects.Node = NEW [CDRoutingObjects.NodeRep[nb]];
node.properties ← ReadCDProperties[stream];
FOR j: NAT IN [0 .. nb) DO
object: CD.Object ← ReadObject[stream];
node[j] ← [object: object, position: ReadPosition[stream]];
ENDLOOP;
routing[i] ← node;
ENDLOOP;
obj ← NEW [CD.ObjectRep ← [class: CDRoutingObjects.routingClass, specific: routing, bbox: bbox]];
};
PW $Tiling
TileArrayRec: TYPE = RECORD [c: SEQUENCE sizeY: NAT OF REF TileLinesRec];
TileLinesRec: TYPE = RECORD [c: SEQUENCE sizeX: NAT OF CD.Object];
WriteTiling: ObjectClassWriteProc = {
sizeX, sizeY: NAT;
[sizeX, sizeY] ← PW.GetTilingSize[me];
WriteRect[stream, me.bbox];
WriteInt[stream, sizeX];
WriteInt[stream, sizeY];
FOR y: NAT IN [0 .. sizeY) DO
FOR x: NAT IN [0 .. sizeX) DO WriteObject[stream, PW.GetTile[me, x, y]] ENDLOOP;
ENDLOOP;
};
ReadTiling: ObjectClassReadProc = {
Tiles: PROC [x, y: NAT] RETURNS [CD.Object] = {RETURN [tileArray[y][x]]};
bbox: CD.Rect ← ReadRect[stream];
sizeX: NATNAT [ReadInt[stream]];
sizeY: NATNAT [ReadInt[stream]];
tileArray: REF TileArrayRec ← NEW [TileArrayRec[sizeY]];
FOR y: NAT IN [0 .. sizeY) DO
tileArray[y] ← NEW [TileLinesRec[sizeX]];
FOR x: NAT IN [0 .. sizeX) DO tileArray[y][x] ← ReadObject[stream] ENDLOOP;
ENDLOOP;
obj ← PW.CreateTiling[sizeX, sizeY, Tiles];
IF obj.bbox#bbox THEN ERROR;
};
PW $Indirect
WriteIndirect: ObjectClassWriteProc = {
indirect: CD.Object ← NARROW [me.specific];
WriteRect[stream, me.bbox];
WriteObject[stream, indirect];
};
ReadIndirect: ObjectClassReadProc = {
bbox: CD.Rect ← ReadRect[stream];
indirect: CD.Object ← ReadObject[stream];
IF indirect.bbox#bbox THEN ERROR;
obj ← PW.CreateIndirect[indirect];
};
CDSymbolicObjectsImpl $AlignmentMarkOb, $PinOb0, $SymbolicSegment
WriteMark: ObjectClassWriteProc = {
};
ReadMark: ObjectClassReadProc = {
RETURN[CDSymbolicObjects.CreateMark[]];
};
WriteSegment: ObjectClassWriteProc = {
WritePosition[stream, CD.InterestSize[me]];
};
ReadSegment: ObjectClassReadProc = {
p: CD.Position ← ReadPosition[stream];
RETURN [CDSymbolicObjects.CreateSegment[p.y, p.x]]
};
WritePin: ObjectClassWriteProc = {
WritePosition[stream, CD.InterestSize[me]];
};
ReadPin: ObjectClassReadProc = {
RETURN [CDSymbolicObjects.CreatePin[ReadPosition[stream]]]
};
CDTextsImpl $FlipText, $RigidText
WriteText: ObjectClassWriteProc = {
text: CDTexts.TextSpecific ← NARROW [me.specific];
WriteRope[stream, text.text];
WriteRope[stream, text.cdFont.supposedName];
WriteInt[stream, text.cdFont.scaleI];
};
ReadText: ObjectClassReadProc = {
text: ROPE ← ReadRope[stream];
fontName: ROPE ← ReadRope[stream];
scale: INT ← ReadInt[stream];
font: CDTexts.CDFont ← CDTexts.MakeFont[fontName, scale];
obj ← CDTexts.Create[text, font];
};
Hack for Pins (one more time!)
WriteLayerRef: PropWriteProc = {
WriteLayer[stream, NARROW [value, CDPrivate.LayerRef].number];
};
ReadLayerRef: PropReadProc = {
value ← CDPrivate.layers[ReadLayer[stream]];
};
Initialization
RegisterDecorationIO: PUBLIC PROC [decoration: Decoration] = {
[] ← RegisterProperty[decoration.objectProp, ObjectPropWrite, ObjectPropRead];
[] ← RegisterProperty[decoration.pinsProp, PinsInstancesPropWrite, InstancesPropRead];
[] ← RegisterProperty[decoration.geometryProp, GeometryInstancesPropWrite, InstancesPropRead];
[] ← RegisterProperty[decoration.transProp, TransPropWrite, TransPropRead];
};
[] ← RegisterProperty[$layerOfPin, WriteLayerRef, ReadLayerRef];
RegisterObjectClass[CDRects.bareRectClass, WriteRectangle, ReadRectangle];
RegisterObjectClass[CDRects.wellRectClass, WriteRectangle, ReadRectangle];
RegisterObjectClass[CDCells.pCellClass, WriteCell, ReadCell];
RegisterObjectClass[PW.abutXClass, WriteAbut, ReadAbut];
RegisterObjectClass[PW.abutYClass, WriteAbut, ReadAbut];
RegisterObjectClass[PW.rotationClass, WriteRotation, ReadRotation];
RegisterObjectClass[CDRoutingObjects.routingClass, WriteRouting, ReadRouting];
RegisterObjectClass[PW.tilingClass, WriteTiling, ReadTiling];
RegisterObjectClass[PW.indirectClass, WriteIndirect, ReadIndirect];
RegisterObjectClass[CDSymbolicObjects.markClass, WriteMark, ReadMark];
RegisterObjectClass[CDSymbolicObjects.segmentClass, WriteSegment, ReadSegment];
RegisterObjectClass[CDSymbolicObjects.pinClass, WritePin, ReadPin];
RegisterObjectClass[CDTexts.flipTextClass, WriteText, ReadText];
RegisterObjectClass[CDTexts.rigidTextClass, WriteText, ReadText];
END.