PFSPrefixMapImpl.mesa
Copyright Ó 1989, 1990 by Xerox Corporation. All rights reserved.
Carl Hauser, September 13, 1989 4:29:06 pm PDT
Chauser, August 16, 1990 4:50 pm PDT
Willie-s, July 26, 1990 2:22 pm PDT
Willie-Sue, July 20, 1990 12:05:12 pm PDT
DIRECTORY
PFSNames,
PFSPrefixMap,
PFSPrefixMapExtras,
Rope
;
PFSPrefixMapImpl: CEDAR MONITOR
IMPORTS PFSNames
EXPORTS PFSPrefixMap, PFSPrefixMapExtras
= BEGIN OPEN PFSPrefixMap, PFSPrefixMapExtras;
ROPE: TYPE = Rope.ROPE;
defaultPrefixTable: PrefixTableList ← NIL;
GetMap: PUBLIC ENTRY PROC RETURNS [el: EntryList] ~
{ RETURN[ GetMapInternal[NIL] ] };
GetMapFromPTable: PUBLIC ENTRY PROC[pTable: PrefixTableList] RETURNS [el: EntryList] ~
{ RETURN[ GetMapInternal[pTable] ] };
GetMapInternal: INTERNAL PROC[pTable: PrefixTableList] RETURNS [el: EntryList] ~ {
IF pTable = NIL THEN pTable ← defaultPrefixTable;
FOR each: PrefixTableList ← pTable, each.rest WHILE each # NIL DO
el ← CONS[ [each.first.prefix, each.first.translation], el];
ENDLOOP;
};
SetMap: PUBLIC ENTRY PROC[map: EntryList] ~
{ defaultPrefixTable ← FromMapInternal[map] };
SetMapFromPTable: PUBLIC ENTRY PROC[pTable: PrefixTableList] ~
{ defaultPrefixTable ← pTable };
FromMapToPTable: PUBLIC ENTRY PROC[map: EntryList] RETURNS[PrefixTableList] ~
{ RETURN[FromMapInternal[map]] };
FromMapInternal: INTERNAL PROC[map: EntryList] RETURNS[pTable: PrefixTableList ← NIL] ~ {
FOR each: EntryList ← map, each.rest WHILE each # NIL DO
pTable ← InsertInternal[NIL, each.first.prefix, each.first.translation];
ENDLOOP;
};
Translate: PUBLIC ENTRY PROC [name: PATH] RETURNS [PATH] ~
{ RETURN[InnerTranslate[name, NIL]] };
TranslateWithPTable: PUBLIC ENTRY PROC [name: PATH, pTable: PrefixTableList ← NIL]
RETURNS [PATH] ~
{ RETURN[InnerTranslate[name, pTable]] };
InnerTranslate: INTERNAL PROC [name: PATH, pTable: PrefixTableList] RETURNS [PATH] ~ {
Translates the name. If no translation is present, returns the original name.
ENABLE UNWIND => NULL;
len: INT ← -1;
entry: PrefixTableEntry ← [];
IF pTable = NIL THEN pTable ← defaultPrefixTable;
FOR each: PrefixTableList ← pTable, each.rest WHILE each # NIL DO
matchLen: INT ← Match[name, each.first.prefix];
IF matchLen > len THEN {
len ← matchLen;
entry ← each.first;
};
ENDLOOP;
IF ( len = -1 ) THEN RETURN[ name ];
RETURN[ PFSNames.Cat[
entry.translation,
PFSNames.SubName[name~name, start~len, directory~PFSNames.IsADirectory[name]]]
];
};
TranslateAndGetHints: PUBLIC ENTRY PROC [name: PATH] RETURNS [TranslationWithHints] ~
{ RETURN[InnerTranslateAndGetHints[name, NIL]] };
TranslateAndGetHintsWithPTable: PUBLIC ENTRY PROC [name: PATH, pTable: PrefixTableList]
RETURNS [TranslationWithHints] ~
{ RETURN[InnerTranslateAndGetHints[name, pTable]] };
InnerTranslateAndGetHints: INTERNAL PROC [name: PATH, pTable: PrefixTableList]
RETURNS [TranslationWithHints] ~ {
Translates the name. If no translation is present, returns the original name.
ENABLE UNWIND => NULL;
len: INT ← -1;
translatedName: PATH;
entry: PrefixTableEntry ← [];
IF pTable = NIL THEN pTable ← defaultPrefixTable;
FOR each: PrefixTableList ← pTable, each.rest WHILE each # NIL DO
matchLen: INT ← Match[name, each.first.prefix];
IF matchLen > len THEN {
len ← matchLen;
entry ← each.first;
};
ENDLOOP;
IF ( len = -1 ) THEN RETURN[ [
translation: name,
fsName: PFSNames.ComponentRope[PFSNames.Fetch[name, 0]],
nameOnFS: PFSNames.ReplaceComponent[name: name, index: 0, new: []],
replacedPrefix: IF name.ComponentCount[]>0 THEN name.SubName[0, 1, name.IsAbsolute[], TRUE] ELSE NIL,
suppliedPrefixLen: IF name.ComponentCount[]>0 THEN 1 ELSE 0 ]
];
translatedName ← PFSNames.Cat[
entry.translation,
PFSNames.SubName[name~name, start~len, directory~PFSNames.IsADirectory[name]]];
RETURN[ [
translation: translatedName,
fsName: entry.fsName,
nameOnFS: PFSNames.ReplaceComponent[name: translatedName, index: 0, new: []],
replacedPrefix: entry.prefix,
suppliedPrefixLen: entry.suppliedPrefixLen ]
];
};
Match: PROC [name, prefix: PATH] RETURNS [matchLen: INT ← -1] ~ {
prefixLen: CARD ← PFSNames.ComponentCount[prefix];
nameLen: CARD ← PFSNames.ComponentCount[name];
IF (prefix.IsAbsolute[] # name.IsAbsolute[]) OR (nameLen < prefixLen) THEN RETURN[ -1 ];
FOR i: CARD IN [0..prefixLen) DO
IF NOT PFSNames.EqualComponents[PFSNames.Fetch[name, i], PFSNames.Fetch[prefix, i]] THEN RETURN [-1];
ENDLOOP;
RETURN[prefixLen];
};
Lookup: PUBLIC ENTRY PROC [prefix: PATH] RETURNS [PATH] ~
{ RETURN[InnerLookup[prefix, NIL]] };
LookupWithPTable: PUBLIC ENTRY PROC [prefix: PATH, pTable: PrefixTableList]
RETURNS
[PATH] ~
{ RETURN[InnerLookup[prefix, pTable]] };
InnerLookup: INTERNAL PROC [prefix: PATH, pTable: PrefixTableList] RETURNS [PATH] ~ {
... returns the PrefixTable entry for the given name ([NIL, NIL] if no such translation).
ENABLE UNWIND => NULL;
IF pTable = NIL THEN pTable ← defaultPrefixTable;
FOR each: PrefixTableList ← pTable, each.rest WHILE each # NIL DO
IF PFSNames.Equal[prefix, each.first.prefix] THEN {
RETURN[each.first.translation];
};
ENDLOOP;
RETURN [NIL];
};
Delete: PUBLIC ENTRY PROC [name: PATH] RETURNS [existing: PATH] ~
{ [existing, defaultPrefixTable] ← InnerDelete[name, NIL] };
DeleteFromPTable: PUBLIC ENTRY PROC [name: PATH, pTable: PrefixTableList]
RETURNS [existing: PATH, newPTable: PrefixTableList] ~
{ [existing, newPTable] ← InnerDelete[name, pTable] };
InnerDelete: INTERNAL PROC [name: PATH, pTable: PrefixTableList]
RETURNS [existing: PATH, newPTable: PrefixTableList] ~ {
... deletes the given prefix (if any) from the map, and returns the deleted element ([NIL, NIL] if no such element).
ENABLE UNWIND => NULL;
lag: PrefixTableList ← NIL;
IF pTable = NIL THEN pTable ← defaultPrefixTable;
newPTable ← pTable;
FOR each: PrefixTableList ← pTable, each.rest WHILE each # NIL DO
IF PFSNames.Equal[name, each.first.prefix] THEN {
IF lag = NIL THEN newPTable ← each.rest ELSE lag.rest ← each.rest;
each.rest ← NIL;
RETURN [each.first.translation, newPTable];
};
lag ← each;
ENDLOOP;
RETURN [NIL, newPTable];
};
Insert: PUBLIC ENTRY PROC [prefix: PATH, translation: PATH] ~
{ defaultPrefixTable ← InsertInternal[NIL, prefix, translation] };
InsertIntoNewPTable: PUBLIC ENTRY PROC[prefix: PATH, translation: PATH]
RETURNS[newPTable: PrefixTableList] ~
{ newPTable ← LIST[MakePrefixTableEntry[prefix, translation]]; };
InsertIntoPTable: PUBLIC ENTRY PROC[prefix: PATH, translation: PATH, pTable: PrefixTableList]
RETURNS[newPTable: PrefixTableList] ~
{ newPTable ← InsertInternal[pTable, prefix, translation] };
InsertInternal: INTERNAL PROC [pTable: PrefixTableList, prefix: PATH, translation: PATH]
RETURNS[newPTable: PrefixTableList] ~ {
... inserts the first item in the PseudoServerList into the root PseudoServerList.
ENABLE UNWIND => NULL;
IF pTable = NIL THEN newPTable ← defaultPrefixTable ELSE newPTable ← pTable;
IF prefix#NIL THEN {
lag: PrefixTableList ← NIL;
newList: PrefixTableList ← LIST[MakePrefixTableEntry[prefix, translation]];
FOR each: PrefixTableList ← newPTable, each.rest WHILE each # NIL DO
SELECT PFSNames.Compare[prefix, each.first.prefix, FALSE] FROM
less => {
Insert into the new position in the list
newList.rest ← each;
EXIT;
};
equal => {
Insert into the new position in the list, splice out old entry
newList.rest ← each.rest;
EXIT;
};
ENDCASE;
lag ← each;
ENDLOOP;
IF lag = NIL THEN newPTable ← newList ELSE lag.rest ← newList;
};
};
MakePrefixTableEntry: PROC [prefix: PATH, translation: PATH] RETURNS[PrefixTableEntry] ~ {
RETURN[ [
prefix: prefix,
translation: translation,
fsName: PFSNames.ComponentRope[PFSNames.Fetch[translation, 0]],
suppliedPrefixLen: PFSNames.ComponentCount[translation]
] ];
};
END.