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 NSAddressElement: PUBLIC TYPE = NSAddress.NetworkAddress; NetworkAddress: PUBLIC TYPE = NSAddress.NetworkAddress; 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 c: CHARACTER; noSuppress: BOOLEAN _ FALSE; timesToShift: CARDINAL = ((SIZE [NSAddress.HostNumber]*16)+2)/3; shift: INTEGER _ SIZE [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 c: CHARACTER; shift: INTEGER _ 1; noSuppress: BOOLEAN _ FALSE; 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 c: CHARACTER; noSuppress: BOOLEAN _ FALSE; timesToShift: CARDINAL = ((SIZE [NSAddress.NetworkNumber]*16)+2)/3; shift: INTEGER _ SIZE [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 c: CHARACTER; noSuppress: BOOLEAN _ FALSE; timesToShift: CARDINAL = ((SIZE [NSAddress.HostNumber]*16)+2)/3; shift: INTEGER _ SIZE [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] = 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] = 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] = 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] = BEGIN sI: CARDINAL; defined: BOOLEAN _ FALSE; 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 ~AddressTranslationImpl.mesa - used to maniputlate various fields of the NetworkAddress Copyright c 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 This module implements the address translation interface. It translates strings to internal records, and internal records to strings. All numbers are in octal. := ## := ## := := {a 32 bit number} | := | := * := {48 bit processor ID} := {16 bit number} Local constants, types and variables Procedures (in alphabetical order) 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. 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. 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. 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. 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. string must be in the following format: := ## | ## may be defaulted and the assumed value will be the primary net number. may NOT be defaulted. may NOT be defaulted. string must be in the following format: := # may be defaulted and the assumed value will be the primary net number. string must be in the following format: := ## | ## may be defaulted and the assumed value will be the primary net number. may NOT be defaulted, but may be one of four formats Κ ˜codešœV™VKšœ Οmœ1™