<<>> <> <> <> <> <<>> <> <<>> DIRECTORY Ascii, Atom, IO, IOTioga, IOTiogaPrivate, IOUtils, NodeProps, Prop, RefText, Rope, TextLooks, TiogaAccess; IOTiogaImpl: CEDAR PROGRAM IMPORTS Ascii, Atom, IO, IOUtils, NodeProps, Prop, RefText, Rope, TextLooks, TiogaAccess EXPORTS IOTioga, IOTiogaPrivate ~ BEGIN OPEN IOTioga, IOTiogaPrivate; ioTiogaOpsAtom: ATOM ~ $IOTiogaOps; AddOps: PUBLIC PROC [class: REF IO.StreamProcs, ops: Ops] ~ { IOUtils.StoreProc[class, ioTiogaOpsAtom, ops]; }; GetOps: PROC [self: STREAM] RETURNS [Ops] ~ { WITH IOUtils.LookupProc[self, ioTiogaOpsAtom] SELECT FROM ops: Ops => RETURN[ops]; ENDCASE => RETURN[noOps]; <> }; SetCharSet: PUBLIC PROC [self: STREAM, charSet: CharSet] ~ { GetOps[self].SetCharSet[self, charSet]; }; GetCharSet: PUBLIC PROC [self: STREAM] RETURNS [CharSet] ~ { RETURN[GetOps[self].GetCharSet[self]]; }; <<>> LooksFromRope: PUBLIC PROC [rope: ROPE] RETURNS [Looks] ~ { RETURN[TextLooks.RopeToLooks[rope]]; }; RopeFromLooks: PUBLIC PROC [looks: Looks] RETURNS [ROPE] ~ { RETURN[TextLooks.LooksToRope[looks]]; }; ChangeLooks: PUBLIC PROC [self: STREAM, remove, add: Looks ¬ noLooks] ~ { GetOps[self].ChangeLooks[self, remove, add]; }; <<>> GetLooks: PUBLIC PROC [self: STREAM] RETURNS [Looks] ~ { RETURN[GetOps[self].GetLooks[self]]; }; <<>> PropRem: PROC [propList: PropList, key: REF] RETURNS [PropList] ~ { RETURN[Prop.Rem[propList, key]]; }; PropGet: PUBLIC PROC [propList: PropList, key: REF] RETURNS [val: REF] ~ { RETURN[Prop.Get[propList, key]]; }; PropPut: PUBLIC PROC [propList: PropList, key: REF, val: REF] RETURNS [PropList] ~ { RETURN[Prop.Put[propList, key, val]]; }; <<>> SetCharProps: PUBLIC PROC [self: STREAM, propList: PropList] ~ { GetOps[self].SetCharProps[self, propList]; }; <<>> GetCharProps: PUBLIC PROC [self: STREAM] RETURNS [PropList] ~ { RETURN[GetOps[self].GetCharProps[self]]; }; <<>> SetNodeProp: PUBLIC PROC [self: STREAM, name: ATOM, value: REF] ~ { GetOps[self].SetNodeProp[self, name, value]; }; <<>> GetNodeProp: PUBLIC PROC [self: STREAM, name: ATOM] RETURNS [value: REF] ~ { RETURN[GetOps[self].GetNodeProp[self, name]]; }; <<>> MapNodeProps: PUBLIC PROC [self: STREAM, action: MapPropsAction] RETURNS [BOOL] ~ { RETURN[GetOps[self].MapNodeProps[self, action]]; }; <<>> FormatFromRope: PUBLIC PROC [rope: ROPE] RETURNS [format: ATOM] ~ { IF Rope.IsEmpty[rope] THEN RETURN[NIL] ELSE { scratch: REF TEXT ~ RefText.ObtainScratch[100]; text: REF TEXT ¬ scratch; action: Rope.ActionType ~ { text ¬ RefText.AppendChar[text, Ascii.Lower[c]] }; [] ¬ Rope.Map[base: rope, action: action]; format ¬ Atom.MakeAtomFromRefText[text]; RefText.ReleaseScratch[scratch]; }; }; <<>> <> <> < RETURN[Atom.GetPName[atom]];>> < RETURN[NIL];>> <<};>> <<>> nameFormat: ATOM ~ $Format; SetFormat: PUBLIC PROC [self: STREAM, format: ATOM] ~ { SetNodeProp[self, nameFormat, format]; }; GetFormat: PUBLIC PROC [self: STREAM] RETURNS [ATOM] ~ { WITH GetNodeProp[self, nameFormat] SELECT FROM format: ATOM => RETURN[format]; ENDCASE => RETURN[NIL]; }; <<>> CommentFromBool: PUBLIC PROC [bool: BOOL] RETURNS [REF] ~ { RETURN[NodeProps.ValueFromBool[bool]]; }; BoolFromComment: PUBLIC PROC [value: REF] RETURNS [BOOL] ~ { RETURN[NodeProps.BoolFromValue[value]]; }; nameComment: ATOM ~ $Comment; SetComment: PUBLIC PROC [self: STREAM, comment: BOOL] ~ { SetNodeProp[self, nameComment, CommentFromBool[comment]]; }; GetComment: PUBLIC PROC [self: STREAM] RETURNS [BOOL] ~ { RETURN[BoolFromComment[GetNodeProp[self, nameComment]]]; }; SetLevel: PUBLIC PROC [self: STREAM, level: CARDINAL] ~ { GetOps[self].SetLevel[self, level]; }; <<>> GetLevel: PUBLIC PROC [self: STREAM] RETURNS [level: CARDINAL] ~ { RETURN[GetOps[self].GetLevel[self]]; }; <<>> Break: PUBLIC PROC [self: STREAM] ~ { GetOps[self].Break[self]; }; <<>> Signal: PUBLIC SIGNAL [code: ATOM, msg: ROPE] ~ CODE; <> <<>> opsAStream: Ops ~ NEW[OpsRep ¬ [ PutChar: APutChar, SetCharSet: ASetCharSet, GetCharSet: AGetCharSet, ChangeLooks: AChangeLooks, GetLooks: AGetLooks, SetCharProps: ASetCharProps, GetCharProps: AGetCharProps, SetNodeProp: ASetNodeProp, GetNodeProp: AGetNodeProp, MapNodeProps: AMapNodeProps, SetLevel: ASetLevel, GetLevel: AGetLevel, Break: ABreak ]]; noOps: Ops ~ NEW[OpsRep ¬ [ PutChar: NoPutChar, SetCharSet: NoSetCharSet, GetCharSet: NoGetCharSet, ChangeLooks: NoChangeLooks, GetLooks: NoGetLooks, SetCharProps: NoSetCharProps, GetCharProps: NoGetCharProps, SetNodeProp: NoSetNodeProp, GetNodeProp: NoGetNodeProp, MapNodeProps: NoMapNodeProps, SetLevel: NoSetLevel, GetLevel: NoGetLevel, Break: NoBreak ]]; classAStream: REF IO.StreamProcs ~ CreateClassA[]; CreateClassA: PROC RETURNS [class: REF IO.StreamProcs] ~ { class ¬ IO.CreateStreamProcs[variety: output, class: $IOTioga, putChar: APutChar]; AddOps[class, opsAStream]; }; AStreamData: TYPE ~ REF AStreamDataRep; AStreamDataRep: TYPE ~ RECORD [ writer: TiogaAccess.Writer, char: TiogaAccess.TiogaChar, node: TiogaAccess.TiogaChar, level, prevLevel: CARDINAL ]; CreateTiogaAccessStream: PUBLIC PROC RETURNS [STREAM] ~ { nullChar: TiogaAccess.TiogaChar ~ [charSet: 0, char: '\000, looks: noLooks, format: NIL, comment: FALSE, endOfNode: FALSE, deltaLevel: 0, propList: NIL]; data: AStreamData ~ NEW[AStreamDataRep ¬ [writer: TiogaAccess.Create[], char: nullChar, node: nullChar, level: 0, prevLevel: 0]]; data.node.endOfNode ¬ TRUE; RETURN[IO.CreateStream[classAStream, data]]; }; <<>> WriterFromStream: PUBLIC PROC [self: STREAM] RETURNS [TiogaAccess.Writer] ~ { WITH self.streamData SELECT FROM data: AStreamData => RETURN[data.writer]; ENDCASE; ERROR IO.Error[NotImplementedForThisStream, self]; }; APutChar: PROC [self: STREAM, char: CHAR] ~ { data: AStreamData ~ NARROW[self.streamData]; data.char.char ¬ char; TiogaAccess.Put[data.writer, data.char]; }; NoPutChar: PROC [self: STREAM, char: CHAR] ~ { }; ASetCharSet: PROC [self: STREAM, charSet: CharSet] ~ { data: AStreamData ~ NARROW[self.streamData]; data.char.charSet ¬ charSet; }; NoSetCharSet: PROC [self: STREAM, charSet: CharSet] ~ { }; AGetCharSet: PROC [self: STREAM] RETURNS [CharSet] ~ { data: AStreamData ~ NARROW[self.streamData]; RETURN[data.char.charSet]; }; NoGetCharSet: PROC [self: STREAM] RETURNS [CharSet] ~ { RETURN[0]; }; AChangeLooks: PROC [self: STREAM, remove, add: Looks] ~ { data: AStreamData ~ NARROW[self.streamData]; data.char.looks ¬ TextLooks.ModifyLooks[old: data.char.looks, remove: remove, add: add]; }; NoChangeLooks: PROC [self: STREAM, remove, add: Looks] ~ { }; AGetLooks: PROC [self: STREAM] RETURNS [Looks] ~ { data: AStreamData ~ NARROW[self.streamData]; RETURN[data.char.looks]; }; NoGetLooks: PROC [self: STREAM] RETURNS [Looks] ~ { RETURN[TextLooks.noLooks]; }; ASetCharProps: PROC [self: STREAM, propList: PropList] ~ { data: AStreamData ~ NARROW[self.streamData]; data.char.propList ¬ propList; }; NoSetCharProps: PROC [self: STREAM, propList: PropList] ~ { }; AGetCharProps: PROC [self: STREAM] RETURNS [PropList] ~ { data: AStreamData ~ NARROW[self.streamData]; RETURN[data.char.propList]; }; NoGetCharProps: PROC [self: STREAM] RETURNS [PropList] ~ { RETURN[NIL]; }; ASetNodeProp: PROC [self: STREAM, name: ATOM, value: REF] ~ { data: AStreamData ~ NARROW[self.streamData]; data.node.propList ¬ PropPut[data.node.propList, name, value]; }; NoSetNodeProp: PROC [self: STREAM, name: ATOM, value: REF] ~ { }; AGetNodeProp: PROC [self: STREAM, name: ATOM] RETURNS [value: REF] ~ { data: AStreamData ~ NARROW[self.streamData]; RETURN[PropGet[data.node.propList, name]]; }; NoGetNodeProp: PROC [self: STREAM, name: ATOM] RETURNS [value: REF] ~ { RETURN[NIL]; }; AMapNodeProps: PROC [self: STREAM, action: MapPropsAction] RETURNS [BOOL] ~ { data: AStreamData ~ NARROW[self.streamData]; FOR list: PropList ¬ data.node.propList, list.rest UNTIL list=NIL DO WITH list.first.key SELECT FROM name: ATOM => IF action[name, list.first.val] THEN RETURN[TRUE]; ENDCASE; ENDLOOP; RETURN[FALSE]; }; NoMapNodeProps: PROC [self: STREAM, action: MapPropsAction] RETURNS [BOOL] ~ { RETURN[FALSE]; }; ASetLevel: PROC [self: STREAM, level: CARDINAL] ~ { data: AStreamData ~ NARROW[self.streamData]; IF (INT[level]-INT[data.prevLevel])>1 THEN { SIGNAL Signal[$InvalidLevel, "Invalid nesting level"]; level ¬ data.prevLevel+1; -- if RESUMEd }; data.level ¬ level; }; NoSetLevel: PROC [self: STREAM, level: CARDINAL] ~ { }; AGetLevel: PROC [self: STREAM] RETURNS [level: CARDINAL] ~ { data: AStreamData ~ NARROW[self.streamData]; RETURN[data.level]; }; NoGetLevel: PROC [self: STREAM] RETURNS [level: CARDINAL] ~ { RETURN[0]; }; ABreak: PROC [self: STREAM] ~ { data: AStreamData ~ NARROW[self.streamData]; TiogaAccess.Nest[data.writer, INT[data.level]-INT[data.prevLevel]]; TiogaAccess.Put[data.writer, data.node]; data.prevLevel ¬ data.level; }; NoBreak: PROC [self: STREAM] ~ { }; END.