<> <> <> DIRECTORY Basics, FS, IO, IODefs, LayerFileDefs, PartitionDefs, Rope; LayerFile: CEDAR PROGRAM IMPORTS FS, IO, IODefs, PartitionDefs, Rope EXPORTS LayerFileDefs = BEGIN OPEN PartitionDefs; <> <> <> <> StartStripe: CARDINAL = 7; EndStripe: CARDINAL = 8; EndBuffer: CARDINAL = 9; EndDrawing: CARDINAL = 4; EBESStreamStateRef: TYPE = REF EBESStreamState; EBESStreamState: TYPE = RECORD [ dest: IO.STREAM, eor: BOOL, buf: REF TEXT]; ebesStreamProcs: REF IO.StreamProcs = IO.CreateStreamProcs[ variety: output, class: $EBESOutputStream, unsafePutBlock: PutEBESBlock, flush: FlushEBES, close: CloseEBES ]; EBESOpen: PROC [ dest: IO.STREAM, eor: BOOL _ TRUE ] RETURNS [ self: IO.STREAM ] = BEGIN state: EBESStreamStateRef = NEW[EBESStreamState _ [dest: dest, eor: eor, buf: NEW[TEXT[2048]]]]; state.buf.length _ 0; self _ IO.CreateStream[ streamProcs: ebesStreamProcs, streamData: state ]; END; PutEBESBlock: PROC [ self: IO.STREAM, block: IO.UnsafeBlock ] = TRUSTED BEGIN state: EBESStreamStateRef = NARROW[self.streamData]; FlushEBESIfNecessary[state, block.count]; FOR i: INT IN [0..block.count) DO CharArrayPtr: TYPE = LONG POINTER TO PACKED ARRAY [0..0) OF CHAR; state.buf[state.buf.length+i] _ LOOPHOLE[block.base, CharArrayPtr][block.startIndex+i]; ENDLOOP; state.buf.length _ state.buf.length+block.count; END; FlushEBESIfNecessary: PROC [state: EBESStreamStateRef, newBytes: NAT] = INLINE BEGIN IF state.buf.maxLength0 THEN BEGIN IF state.eor THEN BEGIN IF state.buf.length+2<=state.buf.maxLength THEN TRUSTED BEGIN -- append an end-of-record command to the buffer endRec: PACKED ARRAY [0..2) OF CHAR = LOOPHOLE[endRecord]; state.buf[state.buf.length] _ endRec[0]; state.buf[state.buf.length+1] _ endRec[1]; state.buf.length _ state.buf.length+2; END ELSE ERROR; -- can't terminate buffer properly END; FOR i: CARDINAL IN [state.buf.length..state.buf.maxLength) DO state.buf[i] _ 000C; -- pad out with 0's ENDLOOP; state.buf.length _ state.buf.maxLength; state.dest.PutBlock[state.buf]; END; state.buf.length _ 0; END; CloseEBES: PROC [ self: IO.STREAM, abort: BOOL _ FALSE ] = BEGIN state: EBESStreamStateRef = NARROW[self.streamData]; self.Flush[]; state.dest.Close[]; END; word: REF CARDINAL _ NEW[CARDINAL]; WriteCmd: PROCEDURE [Word: CARDINAL] = { WriteWord[Word] }; WriteWord: PROCEDURE [Word: CARDINAL] = BEGIN word^ _ Word; TRUSTED {mebesLayerFile.UnsafePutBlock[[LOOPHOLE[word], 0, Basics.bytesPerWord*SIZE[CARDINAL]]]}; END; WriteHeaderRecord: PROCEDURE [ PatternName, PatternDate, PatternMask: Rope.ROPE, PatternSizeX, PatternSizeY: CARDINAL, MebesUnitsPerMicron: CARDINAL] = <> <> <> BEGIN stripeHeight: INT = 256; -- in EBES units maxStripes: INT = 255; maskHeight: INT = maxStripes*stripeHeight; maskWidth: INT = 32768; Date: TYPE = PACKED ARRAY [0..6) OF CHAR _ ALL[' ]; <> FileName: TYPE = PACKED ARRAY [0..12) OF CHAR _ ALL[' ]; <<[9] must be '. , [10] is column ['A..'Z], [11] is row ['A..'Z]>> StartDrawing: TYPE = MACHINE DEPENDENT RECORD [ nFields (0: 0..7): [0..256) _ 2, addressCode (0: 8..15): [0..6], cx (1): CARDINAL[0..maskWidth], -- 0 is illegal cy (2): CARDINAL[0..maskHeight], -- 0 is illegal moDayYr (3): Date, field1Size (6): CARDINAL _ 6, patternFileName (7): FileName, field2Size (13): CARDINAL _ 2, maskInfo (14): PACKED ARRAY [0..4) OF CHAR _ ALL[' ] ]; startDrawing: REF StartDrawing _ NEW[StartDrawing _ [ addressCode: MebesUnitsPerMicron/2*3, cx: PatternSizeX, cy: PatternSizeY ]]; FOR i: [0..6) IN [0..6) DO startDrawing.moDayYr[i] _ Rope.Fetch[PatternDate, i] ENDLOOP; FOR i: [0..12) IN [0..12) DO startDrawing.patternFileName[i] _ Rope.Fetch[PatternName, i] ENDLOOP; FOR i: [0..4) IN [0..4) DO startDrawing.maskInfo[i] _ Rope.Fetch[PatternMask, i] ENDLOOP; TRUSTED {mebesLayerFile.UnsafePutBlock[[LOOPHOLE[startDrawing], 0, Basics.bytesPerWord*SIZE[StartDrawing]]]}; END; object: REF TEXT _ NEW[TEXT[50]]; WriteStripe: PROCEDURE [Stripe: PartitionDefs.stripeNumber, Layer: PartitionDefs.layerNumber] = <> BEGIN s: IO.STREAM _ PartitionDefs.ReadPartitionCreate[Stripe, Layer]; objectNumber: INT _ 0; IF s=NIL THEN RETURN; WriteCmd[StartStripe + 256*(Stripe + 1)]; -- Write out stripe header DO -- Loop reading and writing objects [] _ PartitionDefs.ReadObject[s, object ! IO.EndOfStream => EXIT]; mebesLayerFile.PutBlock[object]; objectNumber _ objectNumber+1; IF objectNumber MOD 1000 = 0 THEN IODefs.PostIt[IO.PutFR["Writing object %g of stripe %g on layer file...", IO.int[objectNumber], IO.int[Stripe]]]; ENDLOOP; WriteCmd[EndStripe]; -- Write end of stripe END; mebesLayerFile: IO.STREAM _ NIL; MakeLayerFile: PUBLIC PROCEDURE [ DiskFileName: Rope.ROPE, Layer: PartitionDefs.layerNumber, PatternName, PatternDate, PatternMask: Rope.ROPE, PatternSizeX, PatternSizeY: CARDINAL, MebesUnitsPerMicron: CARDINAL] = BEGIN Stripe: PartitionDefs.stripeNumber; mebesLayerFile _ EBESOpen[FS.StreamOpen[fileName: DiskFileName, accessOptions: $create]]; WriteHeaderRecord[ PatternName, PatternDate, PatternMask, PatternSizeX, PatternSizeY, MebesUnitsPerMicron]; FOR Stripe IN PartitionDefs.stripeNumber DO WriteStripe[Stripe, Layer]; ENDLOOP; WriteCmd[EndDrawing]; mebesLayerFile.Close[]; mebesLayerFile _ NIL; END; END.