-- 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.