DIRECTORY FileReader, PropertyTypes, Rope, RopeIO, RopeFrom, FileOps, RopeReader, IO, CIFS, Directory, File, System; FileReaderImpl: CEDAR PROGRAM IMPORTS Rope, RopeFrom, RopeIO, RopeReader, CIFS, Directory EXPORTS FileReader = BEGIN OPEN FileReader; InterDoc: PUBLIC SIGNAL [doc: ROPE] = CODE; -- raised by following procs Open: PUBLIC PROC [fileName: ROPE, start, len: Offset, okToMapFile: BOOLEAN] RETURNS [control, comment, text: RopeReader.Ref, tiogaFile: BOOL, fh: CIFS.OpenFile, createDate: System.GreenwichMeanTime] = { file: File.Capability _ CIFS.GetFC[fh _ CIFS.Open[fileName, CIFS.read]]; [control,comment,text,tiogaFile,createDate] _ OpenC[file,start,len,okToMapFile] }; IsInterDoc: PROC [textRope: ROPE] RETURNS [BOOLEAN] = { interdocHeader: ROPE = "{Interdoc/Interchange/"; RETURN [RopeReader.EqSubstrs[textRope,interdocHeader, 0,0,Rope.Size[interdocHeader]]] }; OpenC: PUBLIC PROC [file: File.Capability, start, len: Offset, okToMapFile: BOOLEAN] RETURNS [control, comment, text: RopeReader.Ref, tiogaFile: BOOL, createDate: System.GreenwichMeanTime] = TRUSTED { Substr: PROC [start,len: Offset] RETURNS [Rope.ROPE] = TRUSTED { RETURN [RopeFrom.File[file,start,len,TRUE,fileLen,okToMapFile]] }; fileLen: Offset; interdoc: ROPE; Directory.GetProperty[file: file, property: PropertyTypes.tByteLength, propertyValue: DESCRIPTOR[@fileLen, SIZE[Offset]]]; Directory.GetProperty[file: file, property: PropertyTypes.tCreateDate, propertyValue: DESCRIPTOR[@createDate, SIZE[System.GreenwichMeanTime]]]; [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] = { OPEN FileOps; FOR i:NAT IN [0..fileIdSize) DO IF RopeReader.Get[control] # 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] = { OPEN RopeReader; start: PACKED ARRAY [0..3] OF CHARACTER; start[0] _ Get[rdr]; start[1] _ Get[rdr]; start[2] _ Get[rdr]; start[3] _ Get[rdr]; RETURN [LOOPHOLE[start]] }; ReadControlTrailerId: PROC [control: RopeReader.Ref] RETURNS [BOOLEAN] = { OPEN FileOps; FOR i:NAT IN [0..fileIdSize) DO IF RopeReader.Get[control] # controlTrailerId[i] THEN RETURN[FALSE]; ENDLOOP; RETURN [TRUE] }; PhonyControl: PROC [len: Offset] RETURNS [r: ROPE] = { OPEN FileOps; first, second, fourth: LengthByte; third: ThirdByte; lenBytes: IntBytes _ LOOPHOLE[len]; r _ RopeFrom.Character[startNode]; -- start root node r _ RopeFrom.FlatAppendByte[r,0]; -- null type for root r _ RopeFrom.FlatAppendChar[r,terminalTextNode]; r _ RopeFrom.FlatAppendByte[r,0]; -- null type for node r _ RopeFrom.FlatAppendChar[r,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,endNode]; -- end of root r _ RopeFrom.FlatAppendChar[r,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.Handle, 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 -- last written by Paxton. August 24, 1982 10:39 am Last Edited by: Maxwell, January 5, 1983 1:07 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 ÊÚ˜JšÏc™Jš!™!Jš3™3J™0J˜JšÏk ˜ J˜ J˜J˜J˜J˜ J˜J˜ Jšžœ˜Jšžœ˜J˜ J˜Jšœ˜J˜šœž ˜Jšžœ%žœ ˜;Jšžœ ˜—Jšž˜Jšžœ ˜J˜Jš$™$J˜š œ žœžœžœžœ˜HJ™PJ™—šÏnœžœžœ žœ˜6Jšœ žœ˜šžœ5žœ˜AJšœžœ4˜<—Jšœžœ žœžœ˜HJšœS˜SJ˜—š Ÿ œžœ žœžœžœ˜7Jšœžœ˜0šžœ/˜5J˜"J˜——šŸœžœžœ:žœ˜Tšžœ5ž˜AJšœ(žœ˜1—š Ÿœžœžœžœžœ˜@Jšžœžœ˜B—J˜Jšœ žœ˜˜FJšœž œ žœ ˜3—šœF˜FJšœž œžœ˜H—J˜MJšžœ žœžœžœ˜2J˜—š ŸœžœŸœžœžœžœ˜ZJšžœ4žœ žœ˜UJ˜šŸœžœ˜Jšœ žœ˜#Jšžœžœ˜0šžœ˜Jšœ žœ˜J˜&J˜5J˜——Jšœ ˜ J˜8Jšœ žœ˜Jšœžœ˜J˜Jšœ žœ˜Jšœžœžœ˜!Jšœžœžœ˜#J˜J˜J˜J˜Jšžœžœžœ˜#J˜