<> <> DIRECTORY Atom, IO, IOUtils, Rope, StructuredStreams, UnparserBuffer; StructuredStreamsImpl: CEDAR PROGRAM IMPORTS IO, IOUtils, UB:UnparserBuffer EXPORTS StructuredStreams SHARES IO = BEGIN ROPE: TYPE = Rope.ROPE; PropList: TYPE = Atom.PropList; SSData: TYPE = REF SSDataRec; SSDataRec: TYPE = RECORD [ ubh: UB.Handle]; used: CARDINAL _ 0; SSProcs: REF IO.StreamProcs _ IO.CreateStreamProcs[ variety: output, class: $StructuredStream, putChar: PutChar, flush: Flush, close: Close]; pfProcs: IOUtils.PFProcs = IOUtils.CopyPFProcs[NIL]; Create: PUBLIC PROC [onTopOf: UB.Handle] RETURNS [ss: IO.STREAM] = BEGIN ssd: SSData _ NEW [SSDataRec _ [ubh: onTopOf]]; UB.Init[ssd.ubh]; ss _ IO.CreateStream[streamProcs: SSProcs, streamData: ssd, backingStream: WITH onTopOf.output SELECT FROM so: UB.BufferOutput.stream => so.stream, ao: UB.BufferOutput.access => NIL, ENDCASE => ERROR ]; [] _ IOUtils.SetPFProcs[ss, pfProcs]; END; IsAnSS: PUBLIC PROC [s: IO.STREAM] RETURNS [BOOLEAN] = BEGIN IF s.streamData = NIL THEN RETURN [FALSE]; RETURN [ISTYPE[s.streamData, SSData]]; END; GetHandle: PUBLIC PROC [ss: IO.STREAM] RETURNS [UB.Handle] = BEGIN IF ss.streamData = NIL THEN RETURN [NIL]; WITH ss.streamData SELECT FROM ssd: SSData => RETURN [ssd.ubh]; ENDCASE => RETURN [NIL]; END; Strip: PUBLIC PROC [ss: IO.STREAM] RETURNS [IO.STREAM] = BEGIN IF ss.streamData = NIL THEN RETURN [ss]; WITH ss.streamData SELECT FROM ssd: SSData => WITH ssd.ubh.output SELECT FROM so: UB.BufferOutput.stream => RETURN [so.stream]; ao: UB.BufferOutput.access => RETURN [NIL]; ENDCASE => ERROR; ENDCASE => RETURN [ss]; END; CloseThrough: PUBLIC PROC [self: IO.STREAM] = BEGIN IF NOT IsAnSS[self] THEN self.Close[] ELSE { ssd: SSData = NARROW[self.streamData]; self.Close[]; WITH ssd.ubh.output SELECT FROM so: UB.BufferOutput.stream => so.stream.Close[]; ao: UB.BufferOutput.access => NULL; ENDCASE => ERROR; }; END; Begin: PUBLIC PROC [ss: IO.STREAM] = { IF IsAnSS[ss] THEN NARROW[ss.streamData, SSData].ubh.Setb[]; }; End: PUBLIC PROC [ss: IO.STREAM] = { IF IsAnSS[ss] THEN NARROW[ss.streamData, SSData].ubh.Endb[]; }; Bp: PUBLIC PROC [ss: IO.STREAM, cond: UB.BreakCondition, offset: INTEGER, sep: ROPE _ NIL] = { IF IsAnSS[ss] THEN { ssd: SSData _ NARROW[ss.streamData]; ssd.ubh.Bp[cond, offset, sep]; } ELSE ss.PutRope[sep]; }; ChangeMargin: PUBLIC PROC [ss: IO.STREAM, newMargin: INTEGER _ 69] = { IF IsAnSS[ss] THEN BEGIN ssd: SSData _ NARROW[ss.streamData]; ssd.ubh.margin _ newMargin; END; }; PutChar: PROC [self: IO.STREAM, char: CHAR] = { ssd: SSData = NARROW[self.streamData]; IF char = IO.CR THEN ssd.ubh.Newlineb[0] ELSE ssd.ubh.Charb[char]; }; PrintLFormat: PROC [stream: IO.STREAM, val: IO.Value, format: IOUtils.Format, char: CHAR] --IOUtils.PFCodeProc-- = { ssd: SSData = NARROW[stream.streamData]; WITH val SELECT FROM x: rope IO.Value => ssd.ubh.Looksb[x.value]; ENDCASE => ERROR IO.Error[PFTypeMismatch, stream]; }; PrintPFormat: PROC [stream: IO.STREAM, val: IO.Value, format: IOUtils.Format, char: CHAR] --IOUtils.PFCodeProc-- = { ssd: SSData = NARROW[stream.streamData]; WITH val SELECT FROM x: refAny IO.Value => TRUSTED { mv: REF ANY = LOOPHOLE[x.value]; IF mv = NIL OR ISTYPE[mv, PropList] THEN ssd.ubh.CharPropsb[NARROW[mv]] ELSE ERROR IO.Error[PFTypeMismatch, stream]; }; ENDCASE => ERROR IO.Error[PFTypeMismatch, stream]; }; PrintNFormat: PROC [stream: IO.STREAM, val: IO.Value, format: IOUtils.Format, char: CHAR] --IOUtils.PFCodeProc-- = { ssd: SSData = NARROW[stream.streamData]; WITH val SELECT FROM x: refAny IO.Value => TRUSTED { mv: REF ANY = LOOPHOLE[x.value]; IF mv = NIL OR ISTYPE[mv, PropList] THEN ssd.ubh.NodePropsb[NARROW[mv]] ELSE ERROR IO.Error[PFTypeMismatch, stream]; }; x: boolean IO.Value => ssd.ubh.NodeCommentb[x.value]; x: atom IO.Value => ssd.ubh.NodeFormatb[x.value]; ENDCASE => ERROR IO.Error[PFTypeMismatch, stream]; }; Flush: PROC [self: IO.STREAM] = {IF self.backingStream # NIL THEN IO.Flush[self.backingStream]}; Close: PROC [self: IO.STREAM, abort: BOOL _ FALSE] = BEGIN IOUtils.AmbushStream[self: self, streamProcs: IOUtils.closedStreamProcs, streamData: NIL]; END; Start: PROC = { [] _ IOUtils.SetPFCodeProc[pfProcs, 'l, PrintLFormat]; [] _ IOUtils.SetPFCodeProc[pfProcs, 'p, PrintPFormat]; [] _ IOUtils.SetPFCodeProc[pfProcs, 'n, PrintNFormat]; }; Start[]; END.