Types
ROPE: TYPE ~ Rope.ROPE;
Address: TYPE ~ Arpa.Address;
nullAddress: Address ~ Arpa.nullAddress;
Port: TYPE ~ ArpaUDP.Port;
nullPort: Port ~ ArpaUDP.nullPort;
UnsafeBlock: TYPE ~ Basics.UnsafeBlock;
Handle: TYPE ~ REF Object;
Object: TYPE;
Server: TYPE ~ REF ServerObject;
ServerObject: TYPE;
Conversation: TYPE ~ SunRPCAuth.Conversation;
Clients
StartCall:
PROC [h: Handle, c: Conversation, pgm, version, proc:
CARD];
Prepare to serialize the arguments.
On return, h is ready to put the arguments with PutXXX[h, ...].
SendCallAndReceiveReply:
PROC [h: Handle, timeoutMsec:
CARD, retries:
CARD]
RETURNS [remoteAddress: Address, remotePort: Port];
Send the arguments and wait for the reply.
On return, h is ready to get the results with GetXXX[h].
! Error[<any>]
ReceiveAnotherReply:
PROC [h: Handle, timeoutMsec:
CARD]
RETURNS [remoteAddress: Address, remotePort: Port];
Wait for another reply. Used for broadcast-based protocols.
On return, h is ready to get the results with GetXXX[h].
! Error[$timeout | $protocolError | $wrongRPCVersion | $wrongProg | $wrongProgVersion]
ReleaseReply:
PROC [h: Handle];
Free some resources associated with the handle.
The next StartCall[h] or Destroy[h] does an implicit ReleaseReply[h] if you forgot it.
Servers
ServerProc:
TYPE ~
PROC [h: Handle, c: Conversation, proc:
CARD, clientData:
REF]
RETURNS [doReply:
BOOL, replyTimeToLive:
CARDINAL];
On entry, h is ready to get the arguments with GetXXX[h].
If doReply=FALSE, no reply message will be sent.
The value of replyTimeToLive is the number of seconds the reply message will be kept around by the SunRPC package for duplicate handling.
StartReply:
PROC [h: Handle];
On return, h is ready to put the results with PutXXX[h, ...].
A ServerProc may raise Error[...] either before or after calling StartReply[...]; the ServerProc will be unwound and an appropriate reply will be sent to the client.
A ServerProc may raise Error[$abortWithoutReturn], causing no reply message to be sent.
Serializing / Deserializing
BytesRemaining:
PROC [h: Handle]
RETURNS [bytes:
CARDINAL];
Return number of bytes remaining to be read by GetXXX[h].
GetByte: PROC [h: Handle] RETURNS [byte: BYTE];
SkipBytes: PROC [h: Handle, bytes: CARDINAL];
GetAlign: PROC [h: Handle];
GetH: PROC [h: Handle] RETURNS [hword: Basics.HWORD];
GetCard16:
PROC [h: Handle]
RETURNS [card16:
CARD16] ~
INLINE {
RETURN [Basics.Card16FromH[GetH[h]]] };
GetInt16:
PROC [h: Handle]
RETURNS [int16:
INT16] ~
INLINE {
RETURN [LOOPHOLE[Basics.Card16FromH[GetH[h]]]] };
GetF: PROC [h: Handle] RETURNS [fword: Basics.FWORD];
GetCard32:
PROC [h: Handle]
RETURNS [card32:
CARD32] ~
INLINE {
RETURN [Basics.Card32FromF[GetF[h]]] };
GetInt32:
PROC [h: Handle]
RETURNS [int32:
INT32] ~
INLINE {
RETURN [LOOPHOLE[Basics.Card32FromF[GetF[h]]]] };
UnsafeGetBlock: UNSAFE PROC [h: Handle, block: UnsafeBlock];
GetBlock: PROC [h: Handle, block: REF TEXT, startIndex: CARDINAL ← 0, count: CARDINAL ← CARDINAL.LAST];
GetRefText: PROC [h: Handle] RETURNS [refText: REF TEXT];
GetEphemeralRefText:
PROC [h: Handle, oldBuffer:
REF
TEXT ←
NIL]
RETURNS [newBuffer:
REF
TEXT];
Reuse "oldBuffer" if it's long enough; otherwise allocate a new one with RefText.ObtainScratch.
GetRope: PROC [h: Handle] RETURNS [ROPE];
PutByte: PROC [h: Handle, byte: BYTE];
PutAlign: PROC [h: Handle, padValue: BYTE ← 0];
PutH: PROC [h: Handle, hword: Basics.HWORD];
PutCard16:
PROC [h: Handle, card16:
CARD16] ~
INLINE {
PutH[h, Basics.HFromCard16[card16]] };
PutInt16:
PROC [h: Handle, int16:
INT16] ~
INLINE {
PutH[h, Basics.HFromCard16[LOOPHOLE[int16]]] };
PutF: PROC [h: Handle, fword: Basics.FWORD];
PutCard32:
PROC [h: Handle, card32:
CARD32] ~
INLINE {
PutF[h, Basics.FFromCard32[card32]] };
PutInt32:
PROC [h: Handle, int32:
INT32] ~
INLINE {
PutF[h, Basics.FFromCard32[LOOPHOLE[int32]]] };
UnsafePutBlock: UNSAFE PROC [h: Handle, block: UnsafeBlock];
PutBlock: PROC [h: Handle, block: REF READONLY TEXT, startIndex: CARDINAL ← 0, count: CARDINAL ← CARDINAL.LAST];
PutRefText: PROC [h: Handle, refText: REF READONLY TEXT];
PutRope: PROC [h: Handle, rope: ROPE];
}...