File: KeyNotePseudoServerImpl.mesa
Copyright Ó 1985, 1987 by Xerox Corporation. All rights reserved.
Jack Kent January 22, 1988 10:59:07 am PST
Contents: Implementation of KeyNotePseudoServer
DIRECTORY
Basics,
FSPseudoServers,
List,
Rope,
KeyNotePseudoServer;
KeyNotePseudoServerImpl: CEDAR PROGRAM
IMPORTS Basics, FSPseudoServers, List, Rope
EXPORTS KeyNotePseudoServer = {
ROPE: TYPE = Rope.ROPE;
ServerNameReadServerList: TYPE = LIST OF ServerNameReadServerHandle;
ServerNameReadServerHandle: TYPE = REF ANY;
ServerNameReadServerHandle: TYPE = REF ServerNameReadServerObject
ServerNameReadServerObject: TYPE = RECORD [
name: ROPE,
readServer: ROPE
];
side effect is to update pseudo-server read list
RecomputeReadServerList: PUBLIC PROC [] = {
readList: ServerNameReadServerList;
LongestNamesFirst: List.CompareProc= {
RETURN[Basics.CompareInt[Rope.InlineSize[NARROW[ref2, REF ServerNameReadServerObject].readServer], Rope.InlineSize[NARROW[ref1, REF ServerNameReadServerObject].readServer]]];
};
FOR psl: FSPseudoServers.PseudoServerList ← FSPseudoServers.GetPseudoServers[], psl.rest WHILE psl # NIL DO
FOR readers: LIST OF ROPE ← psl.first.read, readers.rest WHILE readers#NIL DO
item: REF ServerNameReadServerObject ← NEW [ ServerNameReadServerObject ← [name: psl.first.server, readServer: readers.first]];
TRUSTED {readList ← List.Nconc1[readList, LOOPHOLE[item]]; };
ENDLOOP;
ENDLOOP;
now sort List so longest items are at top
pseudoServerReadList ← List.Sort[list: readList, compareProc: LongestNamesFirst];
};
SubstituteLongestPrefixWithPseudoServer: PUBLIC PROC [fileName: ROPE] RETURNS [fileNameAfterShortening: ROPE] = {
FOR psrl: ServerNameReadServerList ← pseudoServerReadList, psrl.rest WHILE psrl # NIL DO
readServerPath: REF ServerNameReadServerObject ← NARROW[psrl.first];
shortened: BOOLEAN;
shortenedName: ROPE;
[shortened: shortened, shortenedName: shortenedName] ← TryToPseudoServerShortenFileName[readServerName: readServerPath.readServer, pseudoServerName: readServerPath.name, fileName: fileName];
IF shortened THEN RETURN[shortenedName];
ENDLOOP;
RETURN[fileName];
};
TryToPseudoServerShortenFileName: PROC [readServerName: ROPE, pseudoServerName:ROPE, fileName: ROPE] RETURNS [shortened: BOOLEAN, shortenedName: ROPE] = {
fileName is something like '[Cedar]<CedarChest7.0>Documentation>Mumble.tioga'
readServerName is something like
'[Cyan]<CedarChest7.0>Documentation>'
pseudoServerName is something like '[Doc]'
fileNameHead: ROPE;
fileNameBody: ROPE;
readServerNameHead: ROPE;
readServerNameBody: ROPE;
[head: fileNameHead, body: fileNameBody] ← GetHeadAndBody[fileName];
[head: readServerNameHead, body: readServerNameBody] ← GetHeadAndBody[readServerName];
first check to see if the readServerNameBody is a prefix of the fileNameBody
IF Rope.IsPrefix[readServerNameBody, fileNameBody, FALSE] THEN {
equivalentHeads: LIST OF ROPE ← GetPseudoServers[fileNameHead];
now check to see if the readServerNameHead is the same as at least one of the equivalentHeads
FOR heads: LIST OF ROPE ← equivalentHeads, heads.rest WHILE heads#NIL DO
IF Rope.Equal[heads.first,BracketServerName[readServerNameHead]] THEN
RETURN[shortened: TRUE, shortenedName: Rope.Concat[BracketServerName[pseudoServerName],
Rope.Substr[base: fileNameBody, start: Rope.Length[readServerNameBody]]
] ];
ENDLOOP;
};
RETURN[shortened: FALSE, shortenedName: NIL];
};
GetHeadAndBody: PROC [name: ROPE] RETURNS [head: ROPE, body: ROPE] = {
endOfHead: INT ← Rope.Find[s1: name, s2: "]", pos1: 0, case: FALSE];
head ← Rope.Substr[name, 1, endOfHead-1];
body ← Rope.Substr[name, endOfHead+1];
};
BracketServerName: PROC [name: ROPE] RETURNS [bracketedName: ROPE] = {
bracketedName ← Rope.Cat[ "[", name, "]"];
};
GetPseudoServers: PROC [name: ROPE] RETURNS [servers: LIST OF ROPE] = {
servers ← FSPseudoServers.TranslateForRead[name];
IF Rope.Equal[servers.first, name] THEN RETURN[LIST[BracketServerName[name]]]
ELSE
RETURN[servers];
};
inititialize
pseudoServerReadList: ServerNameReadServerList;
RecomputeReadServerList[];
}.