Pup Network Address Formatting
PupAddressFromRope:
PUBLIC
PROC [name:
ROPE]
RETURNS [Pup.Address] = {
pAddr: Pup.Address ¬ Pup.nullAddress;
length: INT = Rope.Length[name];
net, host: CARDINAL ¬ 0;
socket: CARD ¬ 0;
IF length = 0 THEN RETURN[pAddr];
FOR i:
INT
IN [0..length)
DO
c: CHAR ¬ name.Fetch[i];
SELECT c
FROM
'# => {
IF net # 0 OR socket > LAST[BYTE] THEN Error[syntax, 0];
net ¬ host;
host ¬ socket;
socket ¬ 0;
};
IN ['0..'7] => {
-- must be octal
IF socket > LAST[CARD]/8 THEN Error[syntax, 0];
socket ¬ socket*8 + CARDINAL[c - '0];
};
ENDCASE => Error[syntax, 0];
ENDLOOP;
IF net > LAST[BYTE] THEN Error[syntax, 0];
IF host > LAST[BYTE] THEN Error[syntax, 0];
pAddr.net ¬ [net];
pAddr.host ¬ [host];
IF socket # 0 THEN pAddr.socket ¬ SocketFromCard[socket];
RETURN[pAddr];
};
PupNetFromRope:
PUBLIC
PROC [r:
ROPE]
RETURNS [Pup.Net] = {
this: CARD;
ok: BOOL;
[this, ok] ¬ PupCardFromRope[r, LAST[BYTE]];
IF ok THEN RETURN[[this]];
Error[syntax, 0];
};
PupHostFromRope:
PUBLIC
PROC [r:
ROPE]
RETURNS [Pup.Host] = {
this: CARD;
ok: BOOL;
[this, ok] ¬ PupCardFromRope[r, LAST[BYTE]];
IF ok THEN RETURN[[this]];
Error[syntax, 0];
};
PupSocketFromRope:
PUBLIC
PROC [r:
ROPE]
RETURNS [Pup.Socket] = {
this: CARD;
ok: BOOL;
[this, ok] ¬ PupCardFromRope[r, LAST[CARD]];
IF ok THEN RETURN[SocketFromCard[this]];
Error[syntax, 0];
};
RopeFromPupAddress:
PUBLIC
PROC [address: Pup.Address, format: NetFormat ¬ octal]
RETURNS [ROPE] = {
base: Base = 8;
net, host, result: ROPE;
IF format # octal THEN Error[invalidNetFormat, 0];
net ¬ RopeFromCard[address.net, base, FALSE];
host ¬ RopeFromCard[address.host, base, FALSE];
result ¬ Rope.Cat[net, "#", host, "#"];
IF address.socket # Pup.nullSocket
THEN
result ¬ result.Cat[RopeFromCard[CardFromSocket[address.socket], base, FALSE] ];
RETURN[result];
};
RopeFromPupNet:
PUBLIC
PROC[net: Pup.Net, format: NetFormat ¬ octal]
RETURNS [
ROPE] = {
IF format # octal THEN Error[invalidNetFormat, 0];
RETURN[Rope.Concat[RopeFromCard[net, 8, FALSE], "#"] ];
};
RopeFromPupHost:
PUBLIC
PROC[host: Pup.Host, format: NetFormat ¬ octal]
RETURNS [ROPE] = {
IF format # octal THEN Error[invalidNetFormat, 0];
RETURN[Rope.Concat[RopeFromCard[host,8, FALSE], "#"] ];
};
RopeFromPupSocket:
PUBLIC
PROC[socket: Pup.Socket, format: NetFormat ¬ octal]
RETURNS [ROPE] = {
IF format # octal THEN Error[invalidNetFormat, 0];
RETURN[ RopeFromCard[CardFromSocket[socket], 8, FALSE] ];
};
AppendPupAddress:
PUBLIC
PROC [to:
REF
TEXT, address: Pup.Address,
format: NetFormat ¬ octal]
RETURNS [
REF
TEXT] = {
base: Base = 8;
IF format # octal THEN Error[invalidNetFormat, 0];
to ¬ AppendCard[to, address.net, base, FALSE];
to ¬ AppendChar[to, '#];
to ¬ AppendCard[to, address.host, base, FALSE];
to ¬ AppendChar[to, '#];
IF address.socket # Pup.nullSocket
THEN
to ¬ AppendCard[to, CardFromSocket[address.socket], base, FALSE];
RETURN[to];
};
AppendPupNet:
PUBLIC
PROC [to:
REF
TEXT, net: Pup.Net,
format: NetFormat ¬ octal]
RETURNS [
REF
TEXT] = {
IF format # octal THEN Error[invalidNetFormat, 0];
to ¬ AppendCard[to, net, 8, FALSE];
RETURN[AppendChar[to, '#]];
};
AppendPupHost:
PUBLIC
PROC [to:
REF
TEXT, host: Pup.Host,
format: NetFormat ¬ octal]
RETURNS [
REF
TEXT] = {
IF format # octal THEN Error[invalidNetFormat, 0];
to ¬ AppendCard[to, host, 8, FALSE];
RETURN[AppendChar[to, '#]];
};
AppendPupSocket:
PUBLIC
PROC [to:
REF
TEXT, socket: Pup.Socket,
format: NetFormat ¬ octal]
RETURNS [
REF
TEXT] = {
IF format # octal THEN Error[invalidNetFormat, 0];
RETURN[AppendCard[to, CardFromSocket[socket], 8, FALSE] ];
};
PupCardFromRope:
PROC [r:
ROPE, max:
CARD]
RETURNS [this:
CARD, ok:
BOOL] = {
length: INT = Rope.Length[r];
this ¬ 0;
ok ¬ FALSE;
IF length = 0 THEN RETURN;
FOR i:
INT
IN [0..length)
DO
c: CHAR = r.Fetch[i];
SELECT c
FROM
'# => EXIT;
IN ['0..'7] => this ¬ this*8 + CARD[c - '0];
ENDCASE => RETURN;
ENDLOOP;
ok ¬ (this <= max);
};
SocketFromCard:
PROC [
c: CARD]
RETURNS [Pup.Socket] =
{
RETURN[LOOPHOLE[c]]};
CardFromSocket:
PROC [p: Pup.Socket]
RETURNS [
CARD] =
{
RETURN[LOOPHOLE[p]]};