DIRECTORY BasicTime, FileOps, FileReader, FS, Rope, RopeIO, RopeFrom, IO, RopeReader; FileReaderImpl: CEDAR PROGRAM IMPORTS FS, Rope, RopeFrom, RopeIO, RopeReader EXPORTS FileReader = BEGIN OPEN FileReader; InterDoc: PUBLIC SIGNAL [doc: ROPE] = CODE; -- raised by following procs Open: PUBLIC PROC [fileName: ROPE, start, len: Offset] 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]; }; IsInterDoc: PROC [textRope: ROPE] RETURNS [BOOLEAN] = { interdocHeader: ROPE = "{Interdoc/Interchange/"; RETURN [ RopeReader.EqSubstrs[textRope,interdocHeader,0,0,Rope.Size[interdocHeader]]] }; OpenC: PUBLIC PROC [file: FS.OpenFile, start, len: Offset] RETURNS [ control, comment, text: RopeReader.Ref, tiogaFile: BOOL, createDate: BasicTime.GMT] = TRUSTED { Substr: PROC [start,len: Offset] RETURNS [Rope.ROPE] = TRUSTED { RETURN [RopeFrom.File[file,start,len,TRUE,fileLen]]; }; fileLen: Offset; interdoc: ROPE; [bytes: fileLen, created: createDate] _ FS.GetInfo[file]; [control,comment,text,interdoc,tiogaFile] _ DoOpen[fileLen,start,len,Substr]; IF interdoc#NIL THEN SIGNAL InterDoc[interdoc]; }; DoOpen: PROC [totLen, start, len: Offset, Substr: PROC [start,len: Offset] 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: Offset; 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 [BOOLEAN] = { 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 [BOOLEAN] = { 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 [Offset] = { 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: Offset] RETURNS [r: ROPE] = { first, second, fourth: FileOps.LengthByte; third: FileOps.ThirdByte; lenBytes: FileOps.IntBytes _ LOOPHOLE[len]; r _ RopeFrom.Character[FileOps.startNode]; -- start root node r _ RopeFrom.FlatAppendByte[r,0]; -- null type for root r _ RopeFrom.FlatAppendChar[r,FileOps.terminalTextNode]; r _ RopeFrom.FlatAppendByte[r,0]; -- null type for node r _ RopeFrom.FlatAppendChar[r,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; r _ RopeFrom.FlatAppendByte[r,first]; IF first.others THEN { r _ RopeFrom.FlatAppendByte[r,second]; IF second.others THEN { r _ RopeFrom.FlatAppendByte[r,third]; IF third.others THEN { r _ RopeFrom.FlatAppendByte[r,fourth] }}}; r _ RopeFrom.FlatAppendChar[r,FileOps.endNode]; -- end of root r _ RopeFrom.FlatAppendChar[r,FileOps.endOfFile]; }; FromRope: PUBLIC PROC [rope: ROPE, start, len: Offset] RETURNS [control, comment, text: RopeReader.Ref, tiogaFile: BOOL] = { Substr: PROC [start,len: Offset] RETURNS [ROPE] = { RETURN [Rope.Substr[rope,start,len]]; }; interdoc: ROPE; [control,comment,text,interdoc,tiogaFile] _ DoOpen[Rope.Size[rope],start,len,Substr]; IF interdoc#NIL THEN SIGNAL InterDoc[interdoc]; }; FromStream: PUBLIC PROC [stream: IO.STREAM, len: Offset] RETURNS [control, comment, text: RopeReader.Ref, tiogaFile: BOOL] = { rope: ROPE _ RopeIO.GetRope[stream,len]; [control,comment,text,tiogaFile] _ FromRope[rope,0,Rope.Size[rope]]; }; Start: PUBLIC PROC = { }; END. ÎFileReaderImpl.Mesa 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 -- ***** Operations for opening file This is a silly hack to reduce the size of the return records to keep them SAFE. -- length of rope for node -- **** Read from rope instead of file -- **** Read from IO stream -- **** Miscellaneous Ê ˜šÏc™Jš™Jš ™ J™0J™$—J™0šÏk ˜ Jšœ ˜ Jšœ˜J˜ Jšžœ˜J˜J˜J˜ Jšžœ˜Jšœ ˜ —J˜šœž ˜Jšžœžœ$˜.Jšžœ ˜Jšœž œ ˜—J˜Jš$™$J˜š œ žœžœžœžœ˜HJ™PJ™—šÏnœžœžœ žœ˜6šžœ5žœ˜AJšœžœ!žœ˜/—Jšœ˜JšœB˜BJšœ˜J˜—š Ÿ œžœ žœžœžœ˜7Jšœžœ˜0šžœ˜JšœO˜OJ˜——šŸœžœžœžœ˜:šžœ˜ Jšœ3žœ˜8Jšœžœžœ˜&—š Ÿœžœžœžœžœ˜@Jšžœžœ ˜4Jšœ˜—J˜Jšœ žœ˜Jšœ(žœ˜9J˜MJšžœ žœžœžœ˜/Jšœ˜J˜—š ŸœžœŸœžœžœžœ˜ZJšžœ4žœ žœ˜UJ˜šŸœžœ˜Jšœ žœ˜#šžœ˜Jšžœ˜šžœ˜Jšœ žœ˜J˜&J˜1J˜——˜J˜——Jšœ ˜ J˜8Jšœ žœ˜Jšœžœ˜J˜Jšœ žœ˜Jšœžœžœ˜!Jšœžœžœ˜#J˜J˜J˜J˜Jšžœžœžœ˜#J˜Jšœ1˜1J˜J˜—Jš&™&J˜šŸœžœž˜Jšœžœ˜ Jšžœ5žœ˜EšŸœžœžœžœ˜3Jšžœ˜%Jšœ˜—Jšœ žœ˜J˜UJšžœ žœžœžœ˜/Jšœ˜J˜—Jš™J˜šŸ œžœžœ ž œ˜8Jšžœ5žœ˜EJšœžœ˜(JšœD˜DJšœ˜J˜—Jš™J˜šŸœžœžœ˜J˜J˜—Jšžœ˜J˜—…—ÄŸ