AddressTranslationImpl.mesa - used to maniputlate various fields of the NetworkAddress
Copyright © 1985 by Xerox Corporation. All rights reserved.
AOF: January 30, 1981 10:38 AM
Russ Atkinson (RRA) February 2, 1985 4:17:47 pm PST
DIRECTORY
AddressTranslation USING [Field],
Socket USING [AssignNetworkAddress],
NSAddress USING [HostNumber, broadcastHostNumber, NetworkAddress, SocketNumber, nullNetworkAddress, NetworkNumber, nullNetworkNumber, GetProcessorID],
PrincOpsUtils USING [BITAND, BITNOT, BITOR, BITSHIFT];
AddressTranslationImpl: PROGRAM
IMPORTS PrincOpsUtils, Socket, NSAddress
EXPORTS AddressTranslation = BEGIN
This module implements the address translation interface. It translates strings to internal records, and internal records to strings.
All numbers are in octal.
<network address> := <net>#<host>#<socket>
<system element> := <net>#<host>#
<network number> := <net>
<net> := {a 32 bit number} | <empty>
<host> := <broadcast> | <Dmachine>
<broadcast> := *
<Dmachine> := {48 bit processor ID}
<socket> := {16 bit number}
Local constants, types and variables
NSAddressElement: PUBLIC TYPE = NSAddress.NetworkAddress;
NetworkAddress: PUBLIC TYPE = NSAddress.NetworkAddress;
Procedures (in alphabetical order)
AddCharacterToString: PUBLIC PROCEDURE [c: CHARACTER, s: STRING] =
BEGIN
IF s.length < s.maxlength THEN {s[s.length] ← c; s.length ← s.length+1}
ELSE ERROR StringOverflow;
END;
AppendMyHostNumber: PUBLIC PROCEDURE [s: STRING] =
BEGIN
Adds ASCII represenation of the local host number to the string 's.' If the host number is null, then at least on '0' will be in the string.
c: CHARACTER;
noSuppress: BOOLEANFALSE;
timesToShift: CARDINAL = ((SIZE [NSAddress.HostNumber]*16)+2)/3;
shift: INTEGERSIZE [NSAddress.HostNumber] MOD 3;
hN: NSAddress.HostNumber ← NSAddress.GetProcessorID [];
IF shift = 0 THEN shift ← 3;
THROUGH [0..timesToShift) DO
c ← ShiftFieldLeft [@hN, SIZE [NSAddress.HostNumber], shift, 0]+'0;
shift ← 3;
IF (noSuppress ← noSuppress OR c#'0) THEN AddCharacterToString [c, s];
ENDLOOP;
IF ~noSuppress THEN AddCharacterToString ['0, s];
AddCharacterToString ['#, s];
END;
AppendMyNetworkNumber: PUBLIC PROCEDURE [s: STRING] =
BEGIN
lnA: NSAddress.NetworkAddress ← Socket.AssignNetworkAddress [];
AppendNetworkNumber [s, LOOPHOLE [lnA, NetworkAddress].net];
END;
AppendNetworkAddress: PUBLIC PROCEDURE
[s: STRING, nA: NetworkAddress] =
BEGIN
Adds ASCII represenation of the client specified network address to the string 's.' If the network address is null, then at least on '0' will be in the string for each of the three positions.
c: CHARACTER;
shift: INTEGER ← 1;
noSuppress: BOOLEANFALSE;
AppendNSAddressElement [s, nA];
THROUGH [0..6) DO
c ← ShiftFieldLeft [@nA.socket, 1, shift, 0]+'0;
shift ← 3;
IF (noSuppress ← noSuppress OR c#'0) THEN AddCharacterToString [c, s];
ENDLOOP;
IF ~noSuppress THEN AddCharacterToString ['0, s];
END;
AppendNetworkNumber: PUBLIC PROCEDURE
[s: STRING, net: NSAddress.NetworkNumber] =
BEGIN
Adds ASCII represenation of the local network number to the string 's.' If the network number is null, then at least on '0' will be in the string.
c: CHARACTER;
noSuppress: BOOLEANFALSE;
timesToShift: CARDINAL = ((SIZE [NSAddress.NetworkNumber]*16)+2)/3;
shift: INTEGERSIZE [NSAddress.NetworkNumber] MOD 3;
IF shift = 0 THEN shift ← 3;
THROUGH [0..timesToShift) DO
c ← ShiftFieldLeft [@net, SIZE [NSAddress.NetworkNumber], shift, 0]+'0;
shift ← 3;
IF (noSuppress ← noSuppress OR c#'0) THEN AddCharacterToString [c, s];
ENDLOOP;
IF ~noSuppress THEN AddCharacterToString ['0, s];
AddCharacterToString ['#, s];
END;
AppendNSAddressElement: PUBLIC PROCEDURE
[s: STRING, sE: NSAddressElement] =
BEGIN
Adds ASCII represenation of the client specified system element to the string 's.' If the system element is null, then at least on '0' will be in the string for each of the two fields.
c: CHARACTER;
noSuppress: BOOLEANFALSE;
timesToShift: CARDINAL = ((SIZE [NSAddress.HostNumber]*16)+2)/3;
shift: INTEGERSIZE [NSAddress.HostNumber] MOD 3;
IF shift = 0 THEN shift ← 3;
AppendNetworkNumber [s, sE.net];
THROUGH [0..timesToShift) DO
c ← ShiftFieldLeft [@sE.host, SIZE [NSAddress.HostNumber], shift, 0]+'0;
shift ← 3;
IF (noSuppress ← noSuppress OR c#'0) THEN AddCharacterToString [c, s];
ENDLOOP;
IF ~noSuppress THEN AddCharacterToString ['0, s];
AddCharacterToString ['#, s];
END;
BadSyntax: PUBLIC ERROR [field: AddressTranslation.Field] = CODE;
ShiftFieldLeft: PROCEDURE
[ptr: POINTER, len: CARDINAL, shift: INTEGER, new: CARDINAL]
RETURNS [lost: CARDINAL] =
Shift field pointed to by "ptr" and of length (words) "len" left "shift" places. Save the bits lost off the left end in "lost" and add bits "new" to right end of field.
BEGIN
saveMask: UNSPECIFIED = PrincOpsUtils.BITNOT [PrincOpsUtils.BITSHIFT [177777B, -shift]];
ptr ← ptr+len; lost ← 0;
THROUGH [0..len) DO
ptr ← ptr-1;
lost ← PrincOpsUtils.BITAND [ptr^, saveMask];
ptr^ ← PrincOpsUtils.BITSHIFT [ptr^, shift];
ptr^ ← PrincOpsUtils.BITOR [ptr^, new];
new ← lost ← PrincOpsUtils.BITSHIFT [lost, shift-16];
ENDLOOP;
END;
StringOverflow: PUBLIC ERROR = CODE;
StringToNetworkAddress: PUBLIC PROCEDURE [s: STRING]
RETURNS [nA: NetworkAddress] =
string must be in the following format:
<network address> := <net>#<host>#<socket> | #<host>#<socket>
<net> may be defaulted and the assumed value will be the primary net number.
<host> may NOT be defaulted.
<socket> may NOT be defaulted.
BEGIN
sI: CARDINAL;
field: {net, host, socket} ← net;
nA ← StringToNSAddressElement [s];
FOR sI IN [0..s.length) DO
SELECT field FROM
net, host => --These are handled be StringToNSAddressElement
BEGIN
IF s[sI] = '# THEN field ← SUCC [field];
END;
socket =>
BEGIN
IF PrincOpsUtils.BITAND [nA.socket, 160000B] # 0
OR s[sI] NOT IN ['0..'8) THEN GOTO syntax;
nA.socket ← LOOPHOLE[PrincOpsUtils.BITOR [PrincOpsUtils.BITSHIFT [LOOPHOLE[nA.socket], 3], s[sI]-'0]];
END;
ENDCASE;
ENDLOOP;
EXITS
syntax => ERROR BadSyntax [socket];
END;
StringToNetworkNumber: PUBLIC PROCEDURE [s: STRING]
RETURNS [nN: NSAddress.NetworkNumber] =
string must be in the following format:
<network address> := <net>#
<net> may be defaulted and the assumed value will be the primary net number.
BEGIN
sI: CARDINAL ← 0;
ptrToNet: POINTER ← @nN;
nN ← NSAddress.nullNetworkNumber;
FOR sI IN [0..s.length) DO
IF s[sI] = '# THEN
BEGIN
lnA: NSAddress.NetworkAddress ← Socket.AssignNetworkAddress [];
IF nN = NSAddress.nullNetworkNumber THEN
nN ← LOOPHOLE [lnA, NetworkAddress].net;
RETURN;
END;
IF (ShiftFieldLeft [ptrToNet, SIZE [NSAddress.NetworkNumber], 3, s[sI]-'0] # 0)
OR (s[sI] NOT IN ['0..'8)) THEN EXIT;
ENDLOOP;
ERROR BadSyntax [net];
END;
StringToNSAddressElement: PUBLIC PROCEDURE [s: STRING]
RETURNS [sE: NSAddressElement] =
string must be in the following format:
<network address> := <net>#<host># | #<host>#
<net> may be defaulted and the assumed value will be the primary net number.
<host> may NOT be defaulted, but may be one of four formats
BEGIN
sI: CARDINAL;
defined: BOOLEANFALSE;
size: CARDINAL = SIZE [NSAddress.HostNumber];
field: {net, host, socket} ← net;
sE ← NSAddress.nullNetworkAddress;
sE.net ← StringToNetworkNumber [s];
FOR sI IN [0..s.length) DO
IF s[sI] = '# THEN field ← SUCC [field] ELSE
SELECT field FROM
net => NULL; --This is already been handled by StringToNetworkNumber
host =>
BEGIN
IF ~defined AND (s[sI] = '*)
THEN sE.host ← NSAddress.broadcastHostNumber
ELSE IF (s[sI] NOT IN ['0..'8)) OR (ShiftFieldLeft [@sE.host, size, 3, s[sI]-'0] # 0)
THEN GO TO syntax;
defined ← TRUE;
END;
socket => RETURN; --Socket is assumed null for NSAddressElement
ENDCASE;
ENDLOOP;
EXITS syntax => ERROR BadSyntax [host];
END;
END.
LOG
Time: June 9, 1980 1:50 PM By: AOF Action: created file.
Time: July 8, 1980 12:35 PM By: AOF Action: Forced at least one '0' on null fields. Eliminated two superflous routines..
Time: July 8, 1980 3:52 PM By: AOF Action: Removed TRAILING ZERO SUPPRESSION "feature."
Time: July 29, 1980 12:12 PM By: AOF Action: SIGNALs => ERRORs
Time: January 30, 1981 10:38 AM By: AOF Action: Ripped out unsupported code