NetworkNameImpl.mesa
Copyright Ó 1991, 1992 by Xerox Corporation. All rights reserved.
Demers, May 23, 1990 7:52 am PDT
DIRECTORY
NetworkName,
RefTab,
Rope
;
NetworkNameImpl: CEDAR MONITOR
IMPORTS RefTab
EXPORTS NetworkName
~ {
OPEN NN: NetworkName;
Types
ROPE: TYPE ~ Rope.ROPE;
Global Variables
regTab: RefTab.Ref ¬ RefTab.Create[];
Exported to NetworkName
Error: PUBLIC ERROR[codes: LIST OF ATOM, msg: ROPE] ~ CODE;
broadcastHostName: PUBLIC ROPE ¬ "*";
AddressFromName: PUBLIC PROC [family: ATOM, name: ROPE, portHint: ROPE, components: NN.Components, serviceFlavor: ATOM] RETURNS [addr: ROPE, responderFlavor: ATOM]
~ {
errorCodes: LIST OF ATOM ¬ LIST[$noService];
errorRope: ROPE ¬ "requested service not registered";
regs: LIST OF NN.Registration ¬ NARROW[RefTab.Fetch[regTab, family].val];
r: NN.Registration;
FOR regs ¬ regs, regs.rest WHILE regs # NIL DO
r ¬ regs.first;
IF (serviceFlavor = NIL) OR (r.flavor = serviceFlavor) THEN {
ENABLE Error => IF regs.rest # NIL
THEN { errorCodes ¬ codes; errorRope ¬ msg; LOOP }
ELSE REJECT;
responderFlavor ¬ r.flavor;
addr ¬ r.addressFromName[r, name, portHint, components];
RETURN;
};
ENDLOOP;
ERROR Error[errorCodes, errorRope];
};
NameFromAddress: PUBLIC PROC [family: ATOM, addr: ROPE, components: NN.Components, serviceFlavor: ATOM ¬ NIL] RETURNS [name: ROPE, responderFlavor: ATOM]
~ {
errorCodes: LIST OF ATOM ¬ LIST[$noService];
errorRope: ROPE ¬ "requested service not registered";
regs: LIST OF NN.Registration ¬ NARROW[RefTab.Fetch[regTab, family].val];
r: NN.Registration;
FOR regs ¬ regs, regs.rest WHILE regs # NIL DO
r ¬ regs.first;
IF (serviceFlavor = NIL) OR (r.flavor = serviceFlavor) THEN {
ENABLE Error => IF regs.rest # NIL
THEN { errorCodes ¬ codes; errorRope ¬ msg; LOOP }
ELSE REJECT;
IF r.nameFromAddress = NIL
THEN { errorCodes ¬ LIST[$notImplemented]; errorRope ¬ "address-to-name translation not implemented by service"; LOOP };
responderFlavor ¬ r.flavor;
name ¬ r.nameFromAddress[r, addr, components];
RETURN;
};
ENDLOOP;
ERROR Error[errorCodes, errorRope];
};
EnumerateFamilies: PUBLIC PROC [eachFamily: NN.EachFamilyProc] ~ {
EachPair: RefTab.EachPairAction -- [key, val] RETURNS[quit] -- ~ {
regs: LIST OF NN.Registration ¬ NARROW[val];
IF (regs # NIL) AND (regs.first # NIL)
THEN quit ¬ NOT eachFamily[regs.first.family]
ELSE quit ¬ FALSE;
};
[] ¬ RefTab.Pairs[regTab, EachPair];
};
Register: PUBLIC PROC [family: ATOM, proc: NN.RegistrationCallbackProc] ~ {
deleted: NN.Registration ¬ EntryRegister[family, proc];
IF (deleted # NIL) AND (deleted.destroy # NIL) THEN deleted.destroy[deleted];
};
EntryRegister: ENTRY PROC [family: ATOM, proc: NN.RegistrationCallbackProc] RETURNS [deleted: NN.Registration ¬ NIL] ~ {
ENABLE UNWIND => NULL;
UpdateActionForRegister: RefTab.UpdateAction -- [found, val] RETURNS [op {none, store, delete}, new] -- ~ {
list, this, prev: LIST OF NN.Registration;
action: NN.RegistrationAction -- {continue, abort, insert, replace, delete} -- ;
newReg: NN.Registration;
list ¬ NARROW[val];
this ¬ list; prev ¬ NIL;
WHILE this # NIL DO
[action, newReg] ¬ proc[this.first];
SELECT action FROM
continue => {
NULL;
};
abort => {
RETURN [none, NIL];
};
insert => {
this.rest ¬ CONS[this.first, this.rest]; this.first ¬ newReg;
RETURN [none, NIL];
};
replace => {
this.first ¬ newReg;
RETURN [none, NIL];
};
delete => {
deleted ¬ this.first;
IF prev # NIL THEN { prev.rest ¬ this.rest; RETURN [none, NIL] };
IF this.rest # NIL THEN RETURN [store, this.rest];
RETURN [delete, NIL];
};
ENDCASE => ERROR;
prev ¬ this; this ¬ this.rest;
ENDLOOP;
[action, newReg] ¬ proc[NIL];
SELECT action FROM
continue, abort => {
RETURN [none, NIL];
};
insert => {
IF prev = NIL THEN {
newRegList: LIST OF NN.Registration ¬ LIST[newReg];
RETURN [store, newRegList];
};
prev.rest ¬ CONS[newReg, prev.rest];
RETURN [none, NIL];
};
ENDCASE => ERROR;
};
RefTab.Update[regTab, family, UpdateActionForRegister];
};
}.