-- 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
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;
-- ***** Operations for opening file
InterDoc: PUBLIC SIGNAL [doc: ROPE] = CODE; -- raised by following procs
This is a silly hack to reduce the size of the return records to keep them SAFE.
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
-- length of 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]};
-- **** Read from rope instead of file
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] };
-- **** Read from IO stream
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]] };
-- **** Miscellaneous
Start: PUBLIC PROC = {
};
END.