-- file FileTableImpl.mesa -- last edited by Lewis on 6-Jan-82 17:56:02 -- last edited by Satterthwaite, December 27, 1982 9:43 am DIRECTORY BcdDefs USING [BCD, FTIndex, FTRecord, FTSelf, NameRecord, VersionStamp], CIFS: TYPE USING [OpenFile, Close, Error, GetFC, Open, read], ConvertUnsafe: TYPE USING [ToRope], Error USING [ErrorFile, WrongFileVersion], FileTable: TYPE USING [], PackagerDefs USING [globalData, nullSourceIndex], SourceBcd USING [bcdBases, bcdLimits, SubStringForName], Space: TYPE USING [ Handle, nullHandle, virtualMemory, CopyIn, Create, Delete, Error, LongPointer, Map], String USING [AppendString, AppendSubString, SubString, SubStringDescriptor]; FileTableImpl: PROGRAM IMPORTS CIFS, ConvertUnsafe, Error, PackagerDefs, SourceBcd, Space, String EXPORTS FileTable = BEGIN FTIndex: TYPE = BcdDefs.FTIndex; SubStringDescriptor: TYPE = String.SubStringDescriptor; SubString: TYPE = String.SubString; UnknownFile: PUBLIC ERROR [fti: FTIndex] = CODE; maxFiles: NAT = (FTIndex.LAST-FTIndex.FIRST)/BcdDefs.FTRecord.SIZE + 1; FileSequence: TYPE = RECORD [SEQUENCE length: [0..maxFiles] OF CIFS.OpenFile]; BitSequence: TYPE = RECORD [PACKED SEQUENCE length: [0..maxFiles] OF BOOL]; nullFile: CIFS.OpenFile = NIL; fileArray: REF FileSequence _ NIL; -- REF so GC can find OpenFile objects fileStampChecked: LONG POINTER TO BitSequence _ NIL; headerSeg: Space.Handle _ Space.nullHandle; header: LONG POINTER TO BcdDefs.BCD _ NIL; Build: PUBLIC PROC = { OPEN BcdDefs; numFiles: NAT; fileNameString: STRING _ [100]; ftiNameDesc: SubStringDescriptor; ftiName: SubString _ @ftiNameDesc; saveIndex: CARDINAL = PackagerDefs.globalData.textIndex; i: CARDINAL; PackagerDefs.globalData.textIndex _ PackagerDefs.nullSourceIndex; -- allocate file handle array numFiles _ IndexForFti[SourceBcd.bcdLimits.ft]; fileArray _ --PackagerDefs.globalData.zone.--NEW[FileSequence[numFiles]]; fileStampChecked _ PackagerDefs.globalData.zone.NEW[BitSequence[numFiles]]; FOR i IN [0..numFiles) DO fileArray[i] _ nullFile; fileStampChecked[i] _ FALSE; ENDLOOP; -- enter file names into symtab (if not already there) to speed file lookup i _ 0; FOR fti: FTIndex _ FIRST[FTIndex], fti+SIZE[FTRecord] UNTIL fti = SourceBcd.bcdLimits.ft DO SourceBcd.SubStringForName[ftiName, SourceBcd.bcdBases.ftb[fti].name]; fileNameString.length _ 0; String.AppendSubString[fileNameString, ftiName]; FOR j: CARDINAL IN [0..fileNameString.length) DO IF fileNameString[j] = '. THEN EXIT; REPEAT FINISHED => String.AppendString[fileNameString, ".bcd"L]; ENDLOOP; fileArray[i] _ CIFS.Open[ConvertUnsafe.ToRope[fileNameString], CIFS.read ! CIFS.Error => TRUSTED {CONTINUE}]; i _ i + 1; ENDLOOP; headerSeg _ Space.Create[size: 1, parent: Space.virtualMemory]; headerSeg.Map[]; header _ headerSeg.LongPointer[]; PackagerDefs.globalData.textIndex _ saveIndex}; IndexForFti: PROC [fti: FTIndex] RETURNS [CARDINAL] = INLINE { RETURN[ LOOPHOLE[fti,CARDINAL]/SIZE[BcdDefs.FTRecord] ]}; Destroy: PUBLIC PROC = { IF headerSeg # Space.nullHandle THEN { Space.Delete[headerSeg]; headerSeg _ Space.nullHandle}; IF fileArray # NIL THEN { FOR i: CARDINAL IN [0..fileArray.length) DO IF fileArray[i] # nullFile THEN{ CIFS.Close[fileArray[i]]; fileArray[i] _ nullFile}; ENDLOOP; --PackagerDefs.globalData.zone.--FREE[@fileArray]}}; HandleForFile: PUBLIC PROC [fti: FTIndex] RETURNS [file: CIFS.OpenFile_nullFile] = { -- copies into non-GC storage are ok index: CARDINAL; IF fti = BcdDefs.FTSelf THEN file _ PackagerDefs.globalData.sourceBcdFile ELSE { index _ IndexForFti[fti]; IF index >= fileArray.length OR (file _ fileArray[index]) = nullFile THEN ERROR UnknownFile[fti]; IF ~fileStampChecked[index] THEN { BEGIN headerSeg.CopyIn[window: [file: file.GetFC, base: 1] ! Space.Error => {GO TO fail}]; IF header.version # SourceBcd.bcdBases.ftb[fti].version THEN Error.WrongFileVersion[ class: error, fti: fti, requiredVersion: SourceBcd.bcdBases.ftb[fti].version, actualVersion: header.version]; EXITS fail => { Error.ErrorFile[class: error, fti: fti, s: "cannot be opened"L]; ERROR UnknownFile[fti]}; END; fileStampChecked[index] _ TRUE}}; RETURN}; END.