<> <> <> <> 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 <> <> << := ##>> << := ##>> << := >> << := {a 32 bit number} | >> << := | >> << := *>> << := {48 bit processor ID}>> << := {16 bit number}>> <> 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] = <> << := ## | ##>> << may be defaulted and the assumed value will be the primary net number.>> << may NOT be defaulted.>> << 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] = <> << := #>> << 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] = <> << := ## | ##>> << may be defaulted and the assumed value will be the primary net number.>> << may NOT be defaulted, but may be one of four formats>> 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