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.