<> <> <> <> <> <> <<>> <> <> <<>> DIRECTORY IO USING [STREAM], Rope USING [ROPE], XNS USING [Address, Socket, unknownSocket], XNSSPPTypes USING [SubSequenceType]; XNSStream: CEDAR DEFINITIONS ~ { <> <> <<>> <> <> <> <<>> <> <<>> <> <<(1) the usual client-server interaction usies Create[...] at the client end and CreateListener at the server end.>> <<(2) rendezvous uses a yet-to-be-determined mechanism.>> <> <> Milliseconds: TYPE ~ CARD32; waitForever: Milliseconds ~ 1800000; -- 1/2 hour of milliseconds dontWait: Milliseconds ~ 0; SubSequenceType: TYPE ~ XNSSPPTypes.SubSequenceType; AttentionType: TYPE ~ BYTE; <> Listener: TYPE ~ REF ListenerObject; ListenerObject: TYPE; FilterProc: TYPE = PROC [remote: XNS.Address, clientData: REF] RETURNS [accept: BOOL]; ListenerProc: TYPE = PROC [stream: IO.STREAM, remote: XNS.Address, clientData: REF]; CreateListener: PROC [ socket: XNS.Socket ¬ XNS.unknownSocket, worker: ListenerProc, getTimeout, putTimeout: Milliseconds ¬ waitForever, clientData: REF ¬ NIL, filter: FilterProc ¬ NIL, -- NIL => Accept all requests echoFilter: FilterProc ¬ NIL] -- NIL => Answer all echos RETURNS [Listener]; <> <<1) Checking for duplicates. >> <<2) Calling the client's filter. Returning FALSE will reject the connection. >> <<3) Creating a stream with the specified timeouts.>> <<4) FORKing a new instance of worker to interact with the new stream.>> <<5) Detaching the new process.>> <> <> <<>> GetLocalFromListener: PROC [listener: Listener] RETURNS [local: XNS.Address]; DestroyListener: PROC [Listener]; <> <> <> Create: PROC [remote: XNS.Address, getTimeout: Milliseconds ¬ waitForever, putTimeout: Milliseconds ¬ waitForever] RETURNS [IO.STREAM]; <> <> GetLocal: PROC [self: IO.STREAM] RETURNS [local: XNS.Address]; GetRemote: PROC [self: IO.STREAM] RETURNS [remote: XNS.Address]; GetTimeouts: PROC [self: IO.STREAM] RETURNS [getTimeout, putTimeout: Milliseconds]; SetTimeouts: PROC [self: IO.STREAM, getTimeout, putTimeout: Milliseconds ¬ waitForever]; <> <> <<>> SetSSType: PROC [self: IO.STREAM, ssType: SubSequenceType]; <> <> <> <> <<>> SendEndOfMessage: PROC [self: IO.STREAM]; <> <> <> <<>> SendAttention: PROC [self: IO.STREAM, attentionType: AttentionType]; <> <> <> <> <<>> SendClose: PROC [self: IO.STREAM] RETURNS [ok: BOOL]; <> <> <<>> SendCloseReply: PROC [self: IO.STREAM] RETURNS [ok: BOOL]; <> <> <<>> SendNow: PROC [self: IO.STREAM]; <> <> <<>> FlushInput: PROC [self: IO.STREAM, wait: BOOL ¬ FALSE] RETURNS [bytesSkipped: CARDINAL]; <> <> <> <> <<>> WaitAttention: PROC [self: IO.STREAM, waitTimeout: Milliseconds ¬ waitForever] RETURNS [AttentionType]; <> <> State: TYPE ~ { open, ssTypeChange, endOfMessage, attention }; GetStatus: PROC [self: IO.STREAM, reset: BOOL ¬ TRUE] RETURNS [state: State, ssType: SubSequenceType, attentionType: AttentionType]; <> <> <> Timeout: SIGNAL; <> <> CloseReason: TYPE = { notClosed, unknown, localClose, noResponse, noRoute, remoteReject, remoteClose, timeout }; ConnectionClosed: ERROR [why: CloseReason, text: Rope.ROPE]; <> }.