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] ~ { 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] ~ { 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] ~ { 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] ~ { 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] ~ { 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 => { newList.rest _ each; EXIT; }; equal => { 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. *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 Translates the name. If no translation is present, returns the original name. Translates the name. If no translation is present, returns the original name. ... returns the PrefixTable entry for the given name ([NIL, NIL] if no such translation). ... deletes the given prefix (if any) from the map, and returns the deleted element ([NIL, NIL] if no such element). ... inserts the first item in the PseudoServerList into the root PseudoServerList. Insert into the new position in the list Insert into the new position in the list, splice out old entry Κ g˜codešœ™K™BK™.K™$K™#K™)—˜šΟk ˜ K˜ K˜ K˜K˜K˜——headšœœ˜Kšœ ˜Kšœ!˜(Kšœ œ"˜.K˜Kšœœœ˜K˜—šœ&œ˜*K˜—šΟnœœ œœ˜3Kšœœœ˜"K˜—š žœœœœœ˜VKšœœ˜%K˜—šžœœœœ˜RKšœ œœ˜1šœ+œœ˜AKšœœ3˜Kšœ ˜ K˜—š žœœœœœ˜MKšœœ˜!K˜—š žœœœœœ˜Yšœ"œœ˜8Kšœœ-˜HKšœ˜—K˜K˜—šž œœœœœœœ˜;šœœœ˜&K˜——šžœœœœœœœœ˜dšœœ!˜)K˜——š žœœœœœœ˜VKšœN™NKšœœœ˜Kšœœ˜Kšœ˜Kšœ œœ˜1šœ+œœ˜AKšœ œ˜/šœœ˜K˜Kšœ˜Kšœ˜—Kšœ˜—Kšœœœ ˜$Kšœv˜|K˜K˜—š žœœœœœœ˜UKšœœ!œ˜1K˜—š žœœœœœœ˜xKšœœ,˜4K˜—š žœœœœœ˜qKšœN™NKšœœœ˜Kšœœ˜Kšœ˜Kšœ˜Kšœ œœ˜1šœ+œœ˜AKšœ œ˜/šœœ˜K˜Kšœ˜Kšœ˜—Kšœ˜—šœœœ˜Kšœ˜Kšœ8˜8KšœC˜CKš œœœ'œœ˜eKšœœœœ˜=Kšœ˜—Kšœ‚˜‚šœ˜ Kšœ˜Kšœ˜KšœM˜MKšœ˜Kšœ,˜,Kšœ˜—K˜K˜—š žœœœœ œ ˜AKšœ œ#˜2Kšœ œ!˜.Kšœ,œœœ˜Yšœœœ˜ KšœœNœœ˜eKšœ˜—Kšœ ˜K˜—K˜šžœœœœ œœœ˜9Kšœœœ˜%K˜—šžœœœœ œœœ˜\Kšœœ ˜(K˜—š ž œœœ œœœ˜UKšœ6 œ™YKšœœœ˜Kšœ œœ˜1šœ+œœ˜Ašœ+œ˜3Kšœ˜Kšœ˜—Kšœ˜—Kšœœ˜ K˜K™—šžœœœœœœ œ˜AKšœ5œ˜˜ Kšœ(™(Kšœ˜Kšœ˜K˜—˜ Kšœ>™>Kšœ˜Kšœ˜K˜—Kšœ˜—Kšœ ˜ Kšœ˜—Kšœœœœ˜>K˜—K˜K˜—š žœœ œœœ˜Zšœ˜ Kšœ˜Kšœ˜Kšœ?˜?Kšœ7˜7Kšœ˜—Kšœ˜K˜K˜—Kšœ˜K˜—…—Ί'K