DIRECTORY Ascii, Atom, BasicTime, Convert, IO, RefTab, RefTabExtras, Rope, BrineIO; BrineIOImpl: CEDAR PROGRAM IMPORTS Atom, BasicTime, Convert, IO, RefTab, RefTabExtras, Rope EXPORTS BrineIO = BEGIN OPEN BrineIO; ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; PutSpace: PROC [stream: STREAM] = INLINE {IO.PutChar[stream, Ascii.SP]}; ReadInt: PUBLIC PROC [stream: STREAM] RETURNS [int: INT] = { int _ IO.GetInt[stream]; }; WriteInt: PUBLIC PROC [stream: STREAM, int: INT] = { IO.Put1[stream, IO.int[int]]; PutSpace[stream]; }; ReadBool: PUBLIC PROC [stream: STREAM] RETURNS [bool: BOOL] = { bool _ ReadInt[stream]#0; }; WriteBool: PUBLIC PROC [stream: STREAM, bool: BOOL] = { WriteInt[stream, IF bool THEN 1 ELSE 0]; }; ReadReal: PUBLIC PROC [stream: STREAM] RETURNS [real: REAL] = { real _ IO.GetReal[stream]; }; WriteReal: PUBLIC PROC [stream: STREAM, real: REAL] = { IO.Put1[stream, IO.real[real]]; PutSpace[stream]; }; ReadGMT: PUBLIC PROC [stream: STREAM] RETURNS [gmt: BasicTime.GMT] = { gmt _ BasicTime.FromNSTime[LOOPHOLE [ReadInt[stream], CARD]]; }; WriteGMT: PUBLIC PROC [stream: STREAM, gmt: BasicTime.GMT] = { WriteInt[stream, LOOPHOLE [BasicTime.ToNSTime[gmt], INT]]; }; ReadAtom: PUBLIC PROC [stream: STREAM] RETURNS [atom: ATOM] = { atomIDTable: RefTab.Ref _ GetRefTab[stream, $BrineIOAtomTable, RefTabExtras.EqualRope, RefTabExtras.HashRope]; atomID: ROPE _ ReadID[stream]; IF Rope.Fetch[atomID]#'A THEN ERROR; atom _ NARROW [RefTab.Fetch[atomIDTable, atomID].val]; IF atom=NIL THEN { atom _ IO.GetAtom[stream]; IF NOT RefTab.Insert[atomIDTable, atomID, atom] THEN ERROR; }; }; WriteAtom: PUBLIC PROC [stream: STREAM, atom: ATOM] = { atomIDTable: RefTab.Ref _ GetRefTab[stream, $BrineIOAtomTable]; atomID: ROPE _ NARROW [RefTab.Fetch[atomIDTable, atom].val]; IF atomID=NIL THEN { atomID _ MakeID["A", RefTab.GetSize[atomIDTable]]; IF NOT RefTab.Insert[atomIDTable, atom, atomID] THEN ERROR; WriteID[stream, atomID]; IO.Put1[stream, IO.atom[atom]]; PutSpace[stream]; } ELSE WriteID[stream, atomID]; }; ReadID: PUBLIC PROC [stream: STREAM] RETURNS [id: ROPE] = { id _ IO.GetID[stream]; }; WriteID: PUBLIC PROC [stream: STREAM, id: ROPE] = { IO.PutRope[stream, id]; PutSpace[stream]; }; ReadRope: PUBLIC PROC [stream: STREAM] RETURNS [rope: ROPE] = { ropeIDTable: RefTab.Ref _ GetRefTab[stream, $BrineIORopeTable, RefTabExtras.EqualRope, RefTabExtras.HashRope]; ropeID: ROPE _ ReadID[stream]; IF Rope.Fetch[ropeID]#'R THEN ERROR; rope _ NARROW [RefTab.Fetch[ropeIDTable, ropeID].val]; IF rope=NIL THEN { rope _ IO.GetRopeLiteral[stream]; IF NOT RefTab.Insert[ropeIDTable, ropeID, rope] THEN ERROR; }; }; doubleQuote: CHAR = '"; backSlash: CHAR = '\\; doubleQuoteRope: ROPE = Rope.FromChar[doubleQuote]; WriteRope: PUBLIC PROC [stream: STREAM, rope: ROPE] = { ropeIDTable: RefTab.Ref _ GetRefTab[stream, $BrineIORopeTable]; ropeID: ROPE _ NARROW [RefTab.Fetch[ropeIDTable, rope].val]; IF ropeID=NIL THEN { ropeID _ MakeID["R", RefTab.GetSize[ropeIDTable]]; IF NOT RefTab.Insert[ropeIDTable, rope, ropeID] THEN ERROR; WriteID[stream, ropeID]; IO.PutChar[stream, doubleQuote]; WHILE NOT Rope.IsEmpty[rope] DO index: INT _ Rope.Find[rope, doubleQuoteRope]; IF index<0 THEN {IO.PutRope[stream, rope]; rope _ NIL} ELSE { IO.PutRope[stream, rope, 0, index]; IO.PutChar[stream, backSlash]; IO.PutChar[stream, doubleQuote]; rope _ Rope.Substr[rope, index+1]; }; ENDLOOP; IO.PutChar[stream, doubleQuote]; PutSpace[stream]; } ELSE WriteID[stream, ropeID]; }; ReadAtomRef: PUBLIC PROC [stream: STREAM] RETURNS [REF] = {RETURN [ReadAtom[stream]]}; WriteAtomRef: PUBLIC PROC [stream: STREAM, ref: REF] = {WriteAtom[stream, NARROW [ref]]}; ReadIDRef: PUBLIC PROC [stream: STREAM] RETURNS [REF] = {RETURN [ReadID[stream]]}; WriteIDRef: PUBLIC PROC [stream: STREAM, ref: REF] = {WriteID[stream, NARROW [ref]]}; ReadRopeRef: PUBLIC PROC [stream: STREAM] RETURNS [REF] = {RETURN [ReadRope[stream]]}; WriteRopeRef: PUBLIC PROC [stream: IO.STREAM, ref: REF] = {WriteRope[stream, NARROW [ref]]}; ReadRopes: PUBLIC PROC [stream: STREAM] RETURNS [ropes: LIST OF ROPE] = { count: INT _ ReadInt[stream]; lor: LIST OF ROPE _ NIL; FOR c: INT IN [0 .. count) DO lor _ CONS [ReadRope[stream], lor]; ENDLOOP; FOR rl: LIST OF ROPE _ lor, rl.rest UNTIL rl=NIL DO ropes _ CONS [rl.first, ropes]; ENDLOOP; }; WriteRopes: PUBLIC PROC [stream: STREAM, ropes: LIST OF ROPE] = { count: INT _ 0; FOR rl: LIST OF ROPE _ ropes, rl.rest UNTIL rl=NIL DO count _ count + 1; ENDLOOP; WriteInt[stream, count]; FOR rl: LIST OF ROPE _ ropes, rl.rest UNTIL rl=NIL DO WriteRope[stream, rl.first]; ENDLOOP; }; ReadRefTab: PUBLIC PROC [stream: STREAM, readKey, readVal: ReadRefProc, equal: RefTab.EqualProc _ NIL, hash: RefTab.HashProc _ NIL] RETURNS [table: RefTab.Ref] = { size: INT _ ReadInt[stream]; table _ RefTab.Create[mod: (size/2)*2+1, equal: equal, hash: hash]; THROUGH [0 .. size) DO key: REF _ readKey[stream]; val: REF _ readVal[stream]; IF NOT RefTab.Insert[table, key, val] THEN ERROR; ENDLOOP; }; WriteRefTab: PUBLIC PROC [stream: STREAM, table: RefTab.Ref, writeKey, writeVal: WriteRefProc] = { HashPair: RefTab.EachPairAction = {writeKey[stream, key]; writeVal[stream, val]}; WriteInt[stream, RefTab.GetSize[table]]; IF RefTab.Pairs[table, HashPair] THEN ERROR; }; MakeID: PUBLIC PROC [prefix: ROPE, int: INT] RETURNS [ROPE] = { RETURN [Rope.Cat[prefix, Convert.RopeFromInt[from: int, base: 16, showRadix: FALSE]]]; }; GetRefTab: PUBLIC PROC [stream: STREAM, key: ATOM, equal: RefTab.EqualProc _ NIL, hash: RefTab.HashProc _ NIL] RETURNS [table: RefTab.Ref] = { table _ NARROW [Atom.GetPropFromList[stream.propList, key]]; IF table#NIL THEN RETURN; table _ RefTab.Create[equal: equal, hash: hash]; stream.propList _ Atom.PutPropOnList[stream.propList, key, table]; }; END. €BrineIOImpl.mesa Copyright Σ 1988 by Xerox Corporation. All rights reversed. Created by Bertrand Serlet May 4, 1988 11:15:43 pm PDT Bertrand Serlet May 7, 1988 4:33:58 pm PDT Prerequisites Basic Read/Write Functions We use Put1 instead of PutF to be faster. we cannot use IO.PutF that truncates long ropes, and we have to beware of "! Composite Read/Write Functions Utilities Κή– "cedar" style˜codešœ™Kšœ<™Kšœœœ˜:K˜K˜—š žœœœ œœœ˜?Kšœn˜nKšœœ˜Kšœœœ˜$Kšœœ)˜6šœœœ˜Kšœœ˜Kšœœ*œœ˜;K˜—K˜K˜—š ž œœœ œœ˜7Kšœ?˜?Kšœœœ'˜<šœœœ˜Kšœ2˜2Kšœœ*œœ˜;Kšœ˜Kšœœ˜1K˜—Kšœ˜K˜K˜—š žœœœ œœœ˜;Kšœœ˜K˜K˜—š žœœœ œœ˜3Kšœ'˜)K˜K˜—š žœœœ œœœ˜?Kšœn˜nKšœœ˜Kšœœœ˜$Kšœœ)˜6šœœœ˜Kšœœ˜!Kšœœ*œœ˜;K˜—K˜K˜—Kšœ œ˜Kšœ œ˜šœœ˜3K˜—š ž œœœ œœ˜7Kšœ?˜?Kšœœœ'˜<šœœœ˜Kšœ2˜2Kšœœ*œœ˜;Kšœ˜Kšœ˜ Kšœœ<™Lšœœ˜Kšœœ$˜.šœ ˜ Kšœœœ˜+Kšœ˜Kšœ!˜#Kšœ˜Kšœ˜ Kšœ"˜"K˜—Kšœ˜—Kšœ˜ Kšœ˜K˜—Kšœ˜K˜——™Kš ž œ œ œœœœ˜VKš ž œ œ œœœ ˜YKš ž œ œ œœœœ˜RKš ž œ œ œœœ ˜UKš ž œ œ œœœœ˜Vš ž œ œ œœœœ ˜\K˜—šž œœœ œœ œœœ˜IKšœœ˜Kš œœœœœ˜šœœœ˜Kšœœ˜#Kšœ˜—š œœœœœœ˜3Kšœœ˜Kšœ˜—K˜K˜—šž œœœ œ œœœ˜AKšœœ˜š œœœœœœ˜5Kšœ˜Kšœ˜—Kšœ˜š œœœœœœ˜5Kšœ˜Kšœ˜—K˜K˜—šž œœœ œ;œœœ˜£Kšœœ˜KšœC˜Cšœ ˜Kšœœ˜Kšœœ˜Kšœœ œœ˜1Kšœ˜—K˜K˜—šž œœœ œ:˜bKšžœI˜QKšœ(˜(Kšœœœ˜,K˜——™ š žœ œ œœœœ˜?KšœGœ˜VK˜K˜—šž œœœ œœœœœ˜ŽKšœœ.˜