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; 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]; }; 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]; WriteObjectsProp: PropWriteProc = { WriteHashTable[h, NARROW[value], WriteObjectIDPair]; }; WriteObjectIDPair: HashWriteProc = { id: ROPE _ NARROW[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]; }; WriteObject: PROC [h: Handle, obj: CD.Object] = { objects: HashTable.Table _ NARROW [CoreProperties.GetProp[h.properties, objectsAtom]]; objectID: ROPE _ NIL; 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]; }; 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]; }; GeometryPropWrite: PropWriteProc = { WriteInstanceList[h, NARROW [value]]; }; GeometryPropRead: PropReadProc = {value _ ReadInstanceList[h]}; InstancePropWrite: PropWriteProc = {WriteInstance[h, NARROW [value]]}; InstancePropRead: PropReadProc = {value _ ReadInstance[h]}; 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] }; 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; }; 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]] }; 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]; }; Register: PROC [decoration: CoreGeometry.Decoration] = { [] _ 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. LCoreGeometryIOImpl.mesa Copyright c 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 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 Object Class IO Utilities The prop write and read procedures are only called when the hash tables are initialized for reading, never for writing. 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 A HashTable [Rope ID -> CD.Object] is stored on the handle under the key objectsAtom 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; }; Object Class IO CMosBWellDifImpl $C2NDifRect, $C2PDifRect CDRectsImpl $Rect CDCellsImpl $Cell CDSymbolicObjectsImpl $AlignmentMarkOb, $PinOb0, $SymbolicSegment CDTextsImpl $FlipText Initialization [] _ RegisterProperty[decoration.irProp, RectPropWrite, RectPropRead]; [] _ RegisterProperty[decoration.pinsProp, PinsPropWrite, PinsPropRead]; Κ w˜– "Cedar" stylešœ™Icode– "Cedar" stylešœ Οmœ1™