DIRECTORY BasicTime USING [GMT], TiogaFile USING [commentHeaderId, controlHeaderId, controlTrailerId, endNode, endOfFile, endSize, FileId, fileIdSize, IntBytes, LengthByte, rope, startNode, terminalTextNode, ThirdByte], FileReader USING [], FS USING [GetInfo, Open, OpenFile], IO USING [STREAM], RefText USING [AppendChar], Rope USING [FromRefText, ROPE, Size, Substr], RopeIO USING [FromFileC, GetRope], RopeReader USING [Create, Get, GetRope, Ref, SetPosition]; FileReaderImpl: CEDAR PROGRAM IMPORTS FS, Rope, RopeIO, RopeReader, RefText EXPORTS FileReader = BEGIN OPEN FileReader; ROPE: TYPE ~ Rope.ROPE; Open: PUBLIC PROC [fileName: ROPE, start, len: INT] RETURNS [control, comment, text: RopeReader.Ref, tiogaFile: BOOL, fh: FS.OpenFile, createDate: BasicTime.GMT] = { fh _ FS.Open[fileName]; [control, comment, text, tiogaFile, createDate] _ OpenC[fh, start, len]; }; OpenC: PUBLIC PROC [file: FS.OpenFile, start, len: INT] RETURNS [control, comment, text: RopeReader.Ref, tiogaFile: BOOL, createDate: BasicTime.GMT] = { Substr: PROC [start, len: INT] RETURNS [Rope.ROPE] = { RETURN [RopeIO.FromFileC[openFile: file, start: start, len: len]]; }; fileLen: INT; [bytes: fileLen, created: createDate] _ FS.GetInfo[file]; [control, comment, text, tiogaFile] _ DoOpen[fileLen, start, len, Substr]; }; DoOpen: PROC [size, start, len: INT, Substr: PROC [start, len: INT] RETURNS [ROPE]] RETURNS [control, comment, text: RopeReader.Ref, tiogaFile: BOOL] = { text _ RopeReader.Create[]; comment _ RopeReader.Create[]; control _ RopeReader.Create[]; tiogaFile _ TRUE; { -- for EXIT trailerLen: INT ~ TiogaFile.endSize; propsLen, textLen, fileLen, commentLen, controlLen: INT; commentStart, controlStart, trailerStart: INT; start _ MAX[0, MIN[start, size]]; len _ MAX[0, MIN[len, size-start]]; IF NOT len>trailerLen THEN GOTO FakeIt; trailerStart _ start+len-trailerLen; RopeReader.SetPosition[control, Substr[trailerStart, trailerLen]]; IF NOT ReadFileId[control, TiogaFile.controlTrailerId] THEN GOTO FakeIt; IF NOT (propsLen _ ReadLen[control]) IN [0..len-trailerLen) THEN GOTO FakeIt; IF NOT (textLen _ ReadLen[control]) IN [0..len-trailerLen) THEN GOTO FakeIt; IF NOT (fileLen _ ReadLen[control])=len THEN GOTO FakeIt; commentStart _ start+textLen; RopeReader.SetPosition[comment, Substr[commentStart, trailerStart-commentStart]]; IF NOT ReadFileId[comment, TiogaFile.commentHeaderId] THEN GOTO FakeIt; commentLen _ ReadLen[comment]; controlStart _ commentStart+commentLen; RopeReader.SetPosition[control, Substr[controlStart, trailerStart-controlStart]]; IF NOT ReadFileId[control, TiogaFile.controlHeaderId] THEN GOTO FakeIt; controlLen _ ReadLen[control]; IF NOT (textLen+commentLen+controlLen)=fileLen THEN GOTO FakeIt; RopeReader.SetPosition[text, Substr[start, textLen]]; EXITS FakeIt => { RopeReader.SetPosition[text, Substr[start, len]]; RopeReader.SetPosition[comment, NIL]; RopeReader.SetPosition[control, PhonyControl[len]]; tiogaFile _ FALSE; }; }; }; ReadFileId: PROC [rdr: RopeReader.Ref, fileId: TiogaFile.FileId] RETURNS [BOOL] = { FOR i: NAT IN [0..TiogaFile.fileIdSize) DO IF RopeReader.Get[rdr]#fileId[i] THEN RETURN[FALSE]; ENDLOOP; RETURN [TRUE]; }; ReadLen: PROC [rdr: RopeReader.Ref] RETURNS [INT] = { len: PACKED ARRAY [0..4) OF CHAR; len[0] _ RopeReader.Get[rdr]; len[1] _ RopeReader.Get[rdr]; len[2] _ RopeReader.Get[rdr]; len[3] _ RopeReader.Get[rdr]; RETURN [LOOPHOLE[len]]; }; PutInt: PROC [put: PROC [CHAR], val: INT] ~ { intBytes: TiogaFile.IntBytes ~ LOOPHOLE[val]; boundsCheck: [0..0] ~ intBytes.unused; first, second, fourth: TiogaFile.LengthByte; third: TiogaFile.ThirdByte; IF intBytes.fourth#0 THEN { fourth.data _ intBytes.fourth; first.others _ second.others _ third.others _ TRUE; }; IF intBytes.thirdTop#0 OR intBytes.thirdBottom#0 THEN { third.dataTop _ intBytes.thirdTop; third.dataBottom _ intBytes.thirdBottom; first.others _ second.others _ TRUE; }; IF intBytes.second#0 THEN { second.data _ intBytes.second; first.others _ TRUE; }; first.data _ intBytes.first; put[LOOPHOLE[first]]; IF first.others THEN { put[LOOPHOLE[second]]; IF second.others THEN { put[LOOPHOLE[third]]; IF third.others THEN { put[LOOPHOLE[fourth]] }; }; }; }; PhonyControl: PROC [len: INT] RETURNS [ROPE] = { text: REF TEXT _ NEW[TEXT[16]]; Put: PROC [c: CHAR] ~ { text _ RefText.AppendChar[text, c] }; Put[TiogaFile.startNode]; -- start root node Put[VAL[0]]; -- null type for root Put[TiogaFile.terminalTextNode]; Put[VAL[0]]; -- null type for node Put[TiogaFile.rope]; -- rope for node PutInt[Put, len]; -- length of rope for node Put[TiogaFile.endNode]; -- end of root Put[TiogaFile.endOfFile]; RETURN[Rope.FromRefText[text]]; }; FromRope: PUBLIC PROC [rope: ROPE, start: INT _ 0, len: INT _ INT.LAST] RETURNS [control, comment, text: RopeReader.Ref, tiogaFile: BOOL] = { Substr: PROC [start, len: INT] RETURNS [ROPE] = { RETURN [Rope.Substr[rope, start, len]]; }; size: INT ~ Rope.Size[rope]; start _ MAX[0, MIN[start, size]]; len _ MAX[0, MIN[len, size-start]]; [control, comment, text, tiogaFile] _ DoOpen[size, start, len, Substr]; }; FromStream: PUBLIC PROC [stream: IO.STREAM, len: INT] RETURNS [control, comment, text: RopeReader.Ref, tiogaFile: BOOL] = { rope: ROPE ~ RopeIO.GetRope[stream, len]; RETURN FromRope[rope]; }; END. ΨFileReaderImpl.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. written by Paxton. March 1981 Paxton. August 24, 1982 10:39 am Last Edited by: Maxwell, January 5, 1983 1:07 pm Russ Atkinson, July 26, 1983 5:41 pm Last Edited by: Birrell, August 23, 1983 1:29 pm Plass, March 29, 1985 4:54:11 pm PST Doug Wyatt, September 18, 1986 3:47:42 pm PDT ***** Operations for opening file **** Read from rope instead of file **** Read from IO stream ΚZ˜codešœ™Kšœ Οmœ7™BKšœ™Kšœ ™ K™0K™$K™0K™$K™-—K˜šΟk ˜ Kšœ žœžœ˜Kšœ žœ«˜ΊKšœ žœ˜Kšžœžœ˜#Kšžœžœžœ˜Kšœžœ˜Kšœžœžœ˜-Kšœžœ˜"Kšœ žœ*˜:—K˜KšΠblœžœž˜Kšžœžœ#˜-Kšžœ ˜Kšœžœžœ ˜K˜Kšžœžœžœ˜K˜Kšœ!™!K˜šΟnœžœžœ žœžœžœ5žœžœ!žœ˜₯Kšœžœ˜KšœH˜HKšœ˜K˜—š œžœžœžœžœžœ5žœžœ˜˜š  œžœžœžœžœ˜6K•StartOfExpansionD[openFile: FS.OpenFile, start: INT _ 0, len: INT _ 2147483647]šžœ<˜BKšœ˜—Kšœ žœ˜ Kšœ(žœ˜9K˜JKšœ˜K˜—š œžœžœ œžœžœžœžœžœ5žœ˜šK˜K˜K˜Kšœ žœ˜šœΟc ˜ Kšœ žœ˜$Kšœ4žœ˜8Kšœ*žœ˜.Kšœžœžœ˜!Kšœžœžœ˜#Kšžœžœžœžœ˜'Kšœ$˜$KšœB˜BKšžœžœ1žœžœ˜HKš žœžœžœžœžœ˜MKš žœžœžœžœžœ˜LKšžœžœ"žœžœ˜9Kšœ˜KšœQ˜QKšžœžœ0žœžœ˜GKšœ˜Kšœ'˜'KšœQ˜QKšžœžœ0žœžœ˜GK˜Kšžœžœ)žœžœ˜@Kšœ5˜5šžœ ˜Kšœ1˜1Kšœ žœ˜%K˜3Kšœ žœ˜K˜—Kšœ˜—Kšœ˜K˜—š  œžœ1žœžœ˜Sšžœžœžœž˜*Kšžœžœžœžœ˜4Kšžœ˜—Kšžœžœ˜Kšœ˜K˜—š œžœžœžœ˜5Kš œžœžœžœžœ˜!Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšžœžœ˜Kšœ˜K˜—š  œžœžœžœžœ˜-Kšœžœ˜-Kšœ&˜&Kšœ,˜,Kšœ˜šžœžœ˜K˜Kšœ.žœ˜3Kšœ˜—šžœžœžœ˜7K˜"K˜(Kšœžœ˜$Kšœ˜—šžœžœ˜Kšœ.žœ˜3Kšœ˜—K˜Kšœžœ ˜šžœžœ˜Kšœžœ ˜šžœžœ˜Kšœžœ ˜šžœžœ˜Kšœžœ ˜Kšœ˜—Kšœ˜—Kšœ˜—K˜K˜—š   œžœžœžœžœ˜0Kš œžœžœžœžœ˜Kš œžœžœ+˜=Kšœ‘˜,Kšœžœ‘˜"Kšœ ˜ Kšœžœ‘˜"Kšœ‘˜%Kšœ‘˜,Kšœ‘˜&Kšœ˜Kšžœ˜K˜K˜—Kšœ#™#K˜š œžœžœžœ žœ žœžœžœžœ5žœ˜š  œžœžœžœžœ˜1Kšžœ!˜'Kšœ˜—Kšœžœ˜Kšœžœžœ˜!Kšœžœžœ˜#K˜GKšœ˜K˜—Kšœ™K˜š  œžœžœ žœžœžœžœ5žœ˜{Kšœžœ˜)Kšžœ˜Kšœ˜K˜—Kšžœ˜—…—’Τ