ArpaNameSupportImpl.mesa
Copyright © 1987 by Xerox Corporation. All rights reserved.
John Larson, October 30, 1987 5:16:58 pm PST
DIRECTORY
Arpa,
ArpaNameSupport,
Ascii USING [Digit],
IO USING [PutFR],
Rope USING [Cat, Equal, Fetch, InlineFetch, IsEmpty, Length, ROPE, Substr];
ArpaNameSupportImpl: CEDAR PROGRAM
IMPORTS Ascii, IO, Rope
EXPORTS ArpaNameSupport =
BEGIN
ROPE: TYPE = Rope.ROPE;
AddressInList: PUBLIC PROC [addresses: LIST OF Arpa.Address, address: Arpa.Address]
RETURNS [yes: BOOL] = {
FOR list: LIST OF Arpa.Address ← addresses, list.rest UNTIL list = NIL DO
IF list.first = address THEN RETURN [TRUE];
ENDLOOP;
RETURN[FALSE]; };
CountAddresses: PUBLIC PROC [addresses: LIST OF Arpa.Address] RETURNS [count: INT𡤀] = {
FOR list: LIST OF Arpa.Address ← addresses, list.rest UNTIL list = NIL DO
count ← count +1;
ENDLOOP;
};
AppendUniqueAddress: PUBLIC PROC [address: Arpa.Address, addresses: LIST OF Arpa.Address ← NIL]
RETURNS [new: LIST OF Arpa.Address] = {
IF addresses = NIL THEN RETURN[LIST[address]];
new ← addresses;
DO
IF addresses.first = address THEN RETURN;
IF addresses.rest = NIL THEN { addresses.rest ← LIST[address]; RETURN; };
addresses ← addresses.rest;
ENDLOOP; };
AppendUniqueRope: PUBLIC PROC [ropes: LIST OF ROPE, name: ROPE]
RETURNS [new: LIST OF ROPE] = {
IF ropes = NIL THEN RETURN[LIST[name]];
new ← ropes;
DO
IF Rope.Equal[ropes.first, name, FALSE] THEN RETURN;
IF ropes.rest = NIL THEN { ropes.rest ← LIST[name]; RETURN; };
ropes ← ropes.rest;
ENDLOOP; };
AddressToRope: PUBLIC PROC [address: Arpa.Address, brackets: BOOLTRUE] RETURNS [rope: Rope.ROPE] = {
rope ← IO.PutFR["%g.%g.%g.%g",
[cardinal[address.a]], [cardinal[address.b]], [cardinal[address.c]], [cardinal[address.d]]];
IF brackets THEN rope ← Rope.Cat["[", rope, "]"];
};
IsAddressRope: PUBLIC PROC [rope: ROPE] RETURNS [BOOL] = {
firstChar: CHAR;
length: INT ← Rope.Length[rope];
IF Rope.IsEmpty[rope] THEN RETURN[FALSE];
firstChar Rope.Fetch[rope, 0];
IF length > 2 AND (firstChar = '[ OR Ascii.Digit[firstChar]) THEN RETURN[TRUE];
RETURN[FALSE];};
AddressRopeToQueryRope: PUBLIC PROC [addrRope: ROPE] RETURNS [queryRope: ROPE] = {
addr: Arpa.Address ← RopeToAddress[addrRope];
IF ~IsAddressRope[addrRope] THEN RETURN[NIL];
addr ← RopeToAddress[addrRope];
IF addr = Arpa.nullAddress THEN RETURN[NIL];
queryRope ← AddressToQueryRope[addr];
};
AddressToQueryRope: PUBLIC PROC [addr: Arpa.Address] RETURNS [queryRope: ROPE] = {
queryRope ← IO.PutFR["%G.%G.%G.%G.IN-ADDR.ARPA", [integer[addr.d]], [integer[addr.c]], [integer[addr.b]], [integer[addr.a]]];
};
StripBrackets: PUBLIC PROC [inRope: ROPE] RETURNS [outRope: ROPE] = {
firstChar: CHAR;
length: INT ← Rope.Length[inRope];
IF Rope.IsEmpty[inRope] THEN RETURN[NIL];
firstChar Rope.Fetch[inRope, 0];
IF length > 2 AND firstChar = '[ THEN outRope ← Rope.Substr[inRope, 1, length-2]
ELSE outRope ← inRope;
};
RopeToAddress: PUBLIC PROC [rope: ROPE] RETURNS [address: Arpa.Address𡤊rpa.nullAddress] = {
len: CARDINAL;
i: CARDINAL ← 0;
AtEnd: PROC RETURNS [BOOL] ~ INLINE { RETURN [i >= len] };
GetChar: PROC RETURNS [c: CHAR] ~ INLINE { c ← Rope.InlineFetch[rope, i]; i ← i + 1 };
Skip: PROC [c: CHAR] ~ INLINE { IF (i < len) AND (Rope.InlineFetch[rope, i] = c) THEN i ← i + 1 };
AToI: PROC RETURNS [n: CARDINAL ← 0] ~ {
DO
c: CHAR;
IF AtEnd[] THEN RETURN;
IF NOT Ascii.Digit[c ← GetChar[]] THEN RETURN;
n ← n * 10 + (c - '0);
ENDLOOP;
};
IF rope = NIL THEN RETURN[Arpa.nullAddress];
len Rope.Length[rope];
Skip['[]; IF AtEnd[] THEN RETURN[Arpa.nullAddress];
address.a ← AToI[];
Skip['.]; IF AtEnd[] THEN RETURN[Arpa.nullAddress];
address.b ← AToI[];
Skip['.]; IF AtEnd[] THEN RETURN[Arpa.nullAddress];
address.c ← AToI[];
Skip['.]; IF AtEnd[] THEN RETURN[Arpa.nullAddress];
address.d ← AToI[];
RETURN[address];
};
Tailed: PUBLIC PROC [body, tail: ROPE] RETURNS [match: BOOL] = {
bodyLength: INT = Rope.Length[body];
tailLength: INT = Rope.Length[tail];
back: ROPE;
IF bodyLength <= tailLength THEN RETURN[FALSE];
back ← Rope.Substr[body, bodyLength-tailLength, tailLength];
IF ~Rope.Equal[back, tail, FALSE] THEN RETURN[FALSE];
RETURN[TRUE]; };
StripTail: PUBLIC PROC [body, tail: ROPE] RETURNS [new: ROPE] = {
bodyLength: INT = body.Length[];
tailLength: INT = tail.Length[];
RETURN[Rope.Substr[body, 0, bodyLength - tailLength]]};
END.