DIRECTORY BasicTime USING [GMT], FileOps USING [commentHeaderId, controlHeaderId, controlTrailerId, endNode, endOfFile, endSize, 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, EqSubstrs, 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, interdoc: ROPE] = { fh _ FS.Open[fileName]; [control,comment,text,tiogaFile,createDate,interdoc] _ OpenC[fh,start,len]; }; IsInterDoc: PROC [textRope: ROPE] RETURNS [BOOL] = { interdocHeader: ROPE = "{Interdoc/Interchange/"; RETURN [ RopeReader.EqSubstrs[textRope,interdocHeader,0,0,Rope.Size[interdocHeader]]] }; OpenC: PUBLIC PROC [file: FS.OpenFile, start, len: INT] RETURNS [ control, comment, text: RopeReader.Ref, tiogaFile: BOOL, createDate: BasicTime.GMT, interdoc: ROPE] = { 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,interdoc,tiogaFile] _ DoOpen[fileLen,start,len,Substr]; }; DoOpen: PROC [totLen, start, len: INT, Substr: PROC [start,len: INT] RETURNS [ROPE]] RETURNS [control, comment, text: RopeReader.Ref, interdoc: ROPE, tiogaFile: BOOL] = { FakeFile: PROC = { textRope: ROPE _ Substr[start,len]; IF IsInterDoc[textRope] THEN interdoc _ textRope ELSE { tiogaFile _ FALSE; RopeReader.SetPosition[text,textRope]; RopeReader.SetPosition[control,PhonyControl[len]] }; }; { -- for EXIT commentStart,end,commentLen,controlLen,propsLen: INT; endSize: NAT = FileOps.endSize; endRope: Rope.ROPE; tiogaFile _ TRUE; start _ MAX[0,MIN[start,totLen]]; len _ MAX[0,MIN[len,totLen-start]]; end _ start+len; text _ RopeReader.Create[]; comment _ RopeReader.Create[]; control _ RopeReader.Create[]; IF len <= endSize THEN GOTO FakeIt; RopeReader.SetPosition[control,Substr[end-endSize,endSize]]; IF ~ReadControlTrailerId[control] THEN GOTO FakeIt; IF (propsLen _ ReadLen[control]) NOT IN [0..len-endSize) THEN GOTO FakeIt; IF (commentStart _ ReadLen[control]) NOT IN [0..len-endSize) THEN GOTO FakeIt; IF ReadLen[control] # len THEN GOTO FakeIt; endRope _ Substr[start+commentStart,len-commentStart]; -- comment and control RopeReader.SetPosition[comment,endRope]; IF ~ReadCommentHeaderId[comment] THEN GOTO FakeIt; commentLen _ ReadLen[comment]; RopeReader.SetPosition[control,endRope,commentLen]; IF ~ReadControlHeaderId[control] THEN GOTO FakeIt; controlLen _ ReadLen[control]; IF commentStart+commentLen+controlLen # len THEN GOTO FakeIt; RopeReader.SetPosition[text,Substr[start,commentStart]] EXITS FakeIt => FakeFile[] }}; ReadControlHeaderId: PROC [control: RopeReader.Ref] RETURNS [BOOL] = { FOR i:NAT IN [0..FileOps.fileIdSize) DO IF RopeReader.Get[control] # FileOps.controlHeaderId[i] THEN RETURN[FALSE]; ENDLOOP; RETURN [TRUE]; }; ReadCommentHeaderId: PROC [comment: RopeReader.Ref] RETURNS [BOOL] = { FOR i:NAT IN [0..FileOps.fileIdSize) DO IF RopeReader.Get[comment] # FileOps.commentHeaderId[i] THEN RETURN[FALSE]; ENDLOOP; RETURN [TRUE]; }; ReadLen: PROC [rdr: RopeReader.Ref] RETURNS [INT] = { start: PACKED ARRAY [0..3] OF CHAR; start[0] _ RopeReader.Get[rdr]; start[1] _ RopeReader.Get[rdr]; start[2] _ RopeReader.Get[rdr]; start[3] _ RopeReader.Get[rdr]; RETURN [LOOPHOLE[start]]; }; ReadControlTrailerId: PROC [control: RopeReader.Ref] RETURNS [BOOL] = { FOR i:NAT IN [0..FileOps.fileIdSize) DO IF RopeReader.Get[control] # FileOps.controlTrailerId[i] THEN RETURN[FALSE]; ENDLOOP; RETURN [TRUE]; }; PhonyControl: PROC [len: INT] RETURNS [r: ROPE] = { first, second, fourth: FileOps.LengthByte; third: FileOps.ThirdByte; lenBytes: FileOps.IntBytes _ LOOPHOLE[len]; text: REF TEXT _ NEW[TEXT[16]]; Append: PROC [c: CHAR] ~ { text _ RefText.AppendChar[text, c]; }; Append[FileOps.startNode]; -- start root node Append[VAL[0]]; -- null type for root Append[FileOps.terminalTextNode]; Append[VAL[0]]; -- null type for node Append[FileOps.rope]; -- rope for node IF lenBytes.fourth # 0 THEN { fourth.data _ lenBytes.fourth; first.others _ second.others _ third.others _ TRUE; }; IF lenBytes.thirdTop # 0 OR lenBytes.thirdBottom # 0 THEN { third.dataTop _ lenBytes.thirdTop; third.dataBottom _ lenBytes.thirdBottom; first.others _ second.others _ TRUE; }; IF lenBytes.second # 0 THEN { second.data _ lenBytes.second; first.others _ TRUE; }; first.data _ lenBytes.first; Append[LOOPHOLE[first]]; IF first.others THEN { Append[LOOPHOLE[second]]; IF second.others THEN { Append[LOOPHOLE[third]]; IF third.others THEN { Append[LOOPHOLE[fourth]] }}}; Append[FileOps.endNode]; -- end of root Append[FileOps.endOfFile]; r _ Rope.FromRefText[text]; }; FromRope: PUBLIC PROC [rope: ROPE, start, len: INT] RETURNS [control, comment, text: RopeReader.Ref, tiogaFile: BOOL, interdoc: ROPE] = { Substr: PROC [start,len: INT] RETURNS [ROPE] = { RETURN [Rope.Substr[rope,start,len]]; }; [control,comment,text,interdoc,tiogaFile] _ DoOpen[Rope.Size[rope],start,len,Substr]; }; FromStream: PUBLIC PROC [stream: IO.STREAM, len: INT] RETURNS [control, comment, text: RopeReader.Ref, tiogaFile: BOOL, interdoc: ROPE] = { rope: ROPE _ RopeIO.GetRope[stream,len]; [control,comment,text,tiogaFile,interdoc] _ FromRope[rope,0,Rope.Size[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, August 28, 1986 4:22:53 pm PDT ***** Operations for opening file length of rope for node **** Read from rope instead of file **** Read from IO stream Κ˜codešœ™Kšœ Οmœ7™BKšœ™Kšœ ™ K™0K™$K™0K™$K™*—K˜šΟk ˜ Kšœ žœžœ˜Kšœžœ£˜°Kšœ žœ˜Kšžœžœ˜#Kšžœžœžœ˜Kšœžœ˜Kšœžœžœ˜-Kšœžœ˜"Kšœ žœ5˜E—K˜KšΠblœžœž˜Kšžœžœ#˜-Kšžœ ˜Kšœžœžœ ˜K˜Kšžœžœžœ˜K˜Kšœ!™!K˜š Οnœžœžœ žœžœ˜3šžœ5žœ˜AKšœžœ!žœ žœ˜?—Kšœžœ˜KšœK˜KKšœ˜K˜—š   œžœ žœžœžœ˜4Kšœžœ˜0šžœ˜KšœO˜OK˜——š  œžœžœžœžœ˜7šžœ˜ Kšœ3žœ˜8Kšœžœ žœ˜.—š  œžœžœžœžœ˜6K•StartOfExpansionD[openFile: FS.OpenFile, start: INT _ 0, len: INT _ 2147483647]šžœ<˜BKšœ˜—Kšœ žœ˜ Kšœ(žœ˜9K˜MKšœ˜K˜—š œžœžœ œžœ žœžœžœ˜TKšžœ4žœ žœ˜UK˜š œžœ˜Kšœ žœ˜#šžœ˜Kšžœ˜šžœ˜Kšœ žœ˜K˜&K˜1K˜——˜K˜——KšœΟc ˜ Kšœ1žœ˜5Kšœ žœ˜Kšœžœ˜K˜Kšœ žœ˜Kšœžœžœ˜!Kšœžœžœ˜#K˜K˜K˜K˜Kšžœžœžœ˜#K˜