<> <> <> DIRECTORY BasicTime USING [GMT, nullGMT], FS USING [Error], FSBackdoor USING [noVersion, Version], FSName USING [BangVersionFile], FSRemoteFileBackdoor USING [EnumerateForInfoProc, EnumerateForNamesProc, InfoProc], Rope USING [Compare, Concat, Equal, IsEmpty, IsPrefix, Match, ROPE, Substr], SunNFS USING [DirOpRes], SunNFSFSRemoteFile USING [caseFileNamePrefix, caseFileNamePrefixLen, CreateNameReader, CreateNameWriter, DecodeVersionFromNFSName, EachDirEntryProc, EnumerateDirectory, GetRemoteDirChild, GetRemoteDirRoot, GMTFromSunTime, LookupThruSymLinks, NameReaderObject, NameWriterObject, ReadBaseComponent, ReadDirComponent, RemoteDirObject, ReportFSError, ReportNFSError, RetractComponent, RopeFromNameWriter, ServerHandle, UnPinRemoteDir, UnPinRemoteDirPath, VersionInfo, WriteBaseComponent, WriteDirComponent] ; SunNFSFSRemoteEnumImpl: CEDAR MONITOR IMPORTS FS, FSName, Rope, SunNFSFSRemoteFile EXPORTS SunNFSFSRemoteFile ~ { OPEN SunNFSFSRemoteFile; <> GMT: TYPE ~ BasicTime.GMT; NameReader: TYPE ~ REF NameReaderObject; <> NameWriter: TYPE ~ REF NameWriterObject; <> RemoteDirHandle: TYPE ~ REF RemoteDirObject; <> ROPE: TYPE ~ Rope.ROPE; Version: TYPE ~ FSBackdoor.Version; <> initialInfoSetSize: CARDINAL _ 16; <> InfoSet: TYPE ~ REF InfoSetObject; InfoSetObject: TYPE ~ RECORD [ size: CARDINAL, info: SEQUENCE maxSize: CARDINAL OF Info ]; maxMaxSize: CARDINAL _ (CARDINAL.LAST - SIZE[InfoSetObject[0]] - 10) / SIZE[Info]; -- the '10' is just for luck InfoKind: TYPE ~ { caseHint, file, subdirectory }; Info: TYPE ~ RECORD [ name: ROPE, -- not including version part kind: InfoKind, versionNum: CARDINAL, created: GMT, bytes: INT ]; AddInfoToSet: PROC [set: InfoSet, info: Info] RETURNS [newSet: InfoSet] ~ { IF set = NIL THEN { set _ NEW[InfoSetObject[initialInfoSetSize]]; set.size _ 0 }; IF set.size < set.maxSize THEN { newSet _ set } ELSE { newSize: CARDINAL ~ MIN[2*set.maxSize, maxMaxSize]; newSet _ NEW[InfoSetObject[newSize]]; FOR i: CARDINAL IN [0 .. set.size) DO newSet.info[i] _ set.info[i]; ENDLOOP; newSet.size _ set.size; }; newSet.info[newSet.size] _ info; newSet.size _ newSet.size + 1; }; SortInfoSet: PROC [set: InfoSet] ~ { < as key ...>> left, right, p, c, cRight: CARDINAL; temp: Info; Less: PROC [i, j: CARDINAL] RETURNS [BOOL] ~ INLINE { RETURN [ SELECT Rope.Compare[set.info[i].name, set.info[j].name, FALSE] FROM less => TRUE, greater => FALSE, ENDCASE => (set.info[i].versionNum < set.info[j].versionNum) ]; }; Swap: PROC [i, j: CARDINAL] ~ INLINE { temp _ set.info[i]; set.info[i] _ set.info[j]; set.info[j] _ temp; }; IF set.size < 2 THEN RETURN; left _ set.size/2; right _ set.size - 1; DO SELECT TRUE FROM (left > 0) => { left _ left - 1 }; (right > 0) => { Swap[0, right]; right _ right - 1 }; ENDCASE => EXIT; FOR p _ left, c DO IF (c _ 2*p+1) > right THEN EXIT; IF ((cRight _ c+1) <= right) AND Less[c, cRight] THEN c _ cRight; IF Less[c, p] THEN EXIT; Swap[p, c]; ENDLOOP; ENDLOOP; }; <> EnumerationAborted: PRIVATE ERROR ~ CODE; SunNFSEnumerateForInfo: PUBLIC FSRemoteFileBackdoor.EnumerateForInfoProc -- [h: ServerHandle, pattern: ROPE, proc: InfoProc] -- ~ { dH: RemoteDirHandle; nR: NameReader; nWPath, nWSuffix: NameWriter; patternPrefix, patternUpToVersionPart: ROPE; isPattern: BOOL; versionFromPattern: Version; vI: VersionInfo; callDepth: CARDINAL _ 0; EnumerateInner: PROC ~ { set: InfoSet _ NIL; EachName: EachDirEntryProc -- [entryName: ROPE] RETURNS [continue: BOOL _ TRUE] -- ~ { <