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.STREAM ← FS.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.