PFSPrefixMapImpl.mesa
Copyright Ó 1989, 1990, 1991 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, February 19, 1992 4:45 pm PST
Willie-Sue, July 20, 1990 12:05:12 pm PDT
Michael Plass, August 22, 1991 1:21 pm PDT
DIRECTORY
PFSNames,
PFSPrefixMap,
ProcessProps,
Rope
;
PFSPrefixMapImpl:
CEDAR
MONITOR
IMPORTS PFSNames, ProcessProps
EXPORTS PFSPrefixMap
= BEGIN OPEN PFSPrefixMap;
ROPE: TYPE = Rope.ROPE;
defaultPrefixTable: PrefixTableList ¬
NIL;
DefaultPrefixTable:
PROC
RETURNS [PrefixTableList] ~ {
WITH ProcessProps.GetProp[$PrefixTableList]
SELECT
FROM
p: PrefixTableList => RETURN [p];
ENDCASE;
RETURN [defaultPrefixTable]
};
GetMap:
PUBLIC
ENTRY
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[each.first.prefix, each.first.translation, NIL];
ENDLOOP;
};
Translate:
PUBLIC
ENTRY
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, pTable: PrefixTableList]
RETURNS [PrefixTableEntry] ~ {
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, 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, 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;
newPTable ¬ IF pTable = NIL THEN defaultPrefixTable ELSE pTable;
FOR each: PrefixTableList ¬ newPTable, 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;
IF ( pTable = NIL ) THEN defaultPrefixTable ¬ newPTable;
RETURN [each.first.translation, newPTable];
};
lag ¬ each;
ENDLOOP;
RETURN [NIL, newPTable];
};
InsertIntoNewPTable:
PUBLIC
ENTRY
PROC[prefix:
PATH, translation:
PATH]
RETURNS[newPTable: PrefixTableList] ~
{ newPTable ¬ LIST[MakePrefixTableEntry[prefix, translation]]; };
Insert:
PUBLIC
ENTRY
PROC [prefix:
PATH, translation:
PATH, pTable: PrefixTableList]
RETURNS[newPTable: PrefixTableList] ~ {
newPTable ¬ InsertInternal[prefix, translation, pTable];
IF pTable = NIL THEN defaultPrefixTable ¬ newPTable;
RETURN[newPTable];
};
InsertInternal:
INTERNAL
PROC [prefix:
PATH, translation:
PATH, pTable: PrefixTableList]
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.