BCDery>BCDeryImpl.Mesa
Last Edited by: Spreitzer, March 1, 1984 9:06:04 pm PST
DIRECTORY BcdDefs, BCDery, FS, IO, ListerUtils, Rope, TimeStamp;
BCDeryImpl: CEDAR PROGRAM
IMPORTS FS, IO, ListerUtils
EXPORTS BCDery =
BEGIN OPEN BCDery;
EnumerateFiles: PUBLIC PROC [bcd: RefBCD ← NIL, bcdFileName: ROPE, to: PROC [name: ROPE, version: VersionStamp]] RETURNS [ferSure: RefBCD] = TRUSTED
BEGIN
fti: BcdDefs.FTIndex ← BcdDefs.FTIndex.FIRST;
inStream: IO.STREAMFS.StreamOpen[bcdFileName, $read];
inner: PROC [ptr: LONG POINTER] = TRUSTED {
tb: BcdDefs.Base = LOOPHOLE[ptr];
ssb: BcdDefs.NameString = LOOPHOLE[ptr + ferSure.ssOffset];
ftb: BcdDefs.Base = tb + ferSure.ftOffset;
UNTIL fti = ferSure.ftLimit DO
SELECT fti FROM
BcdDefs.FTNull => NULL;
BcdDefs.FTSelf => NULL;
ENDCASE => {
ftr: LONG POINTER TO BcdDefs.FTRecord = @ftb[fti];
name: ROPE = NameToRope[ftr.name, ssb];
to[name: name, version: ftr.version]};
fti ← fti + BcdDefs.FTRecord.SIZE;
IF LOOPHOLE[fti, CARDINAL] > LOOPHOLE[ferSure.ftLimit, CARDINAL] THEN ERROR;
ENDLOOP};
ferSure ← IF bcd # NIL THEN bcd ELSE ListerUtils.ReadBcd[bcdFileName];
ListerUtils.WithPages[inStream, ferSure, 0, ferSure.nPages, inner];
inStream.Close[];
END;
NameToRope: PROC [n: BcdDefs.NameRecord, ssb: BcdDefs.NameString] RETURNS [ROPE] = TRUSTED {
CharSeq: TYPE = RECORD[PACKED SEQUENCE COMPUTED CARDINAL OF CHAR];
ss: LONG POINTER TO CharSeq = LOOPHOLE[ssb];
index: CARDINAL = n+3;
len: CARDINAL = ss[index]-0C;
ros: IO.STREAM = IO.ROS[];
FOR i: NAT IN [index+1..index+len] DO
IO.PutChar[ros, ss[i]];
ENDLOOP;
RETURN [IO.RopeFromROS[ros]];
};
END.