<> <> <> <> <> <<>> <> <> <<>> DIRECTORY IO USING [STREAM], Rope USING [ROPE], XNS USING [Address, Socket], 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.>> <> BYTE: TYPE ~ [0..100H); <> Milliseconds: TYPE ~ LONG CARDINAL; waitForever: Milliseconds ~ 1800000; -- 1/2 hour of milliseconds dontWait: Milliseconds ~ 0; SubSequenceType: TYPE ~ XNSSPPTypes.SubSequenceType; AttentionType: TYPE ~ [0..100H); <> Listener: TYPE ~ REF ListenerObject; ListenerObject: TYPE; FilterProc: TYPE = PROC [remote: XNS.Address] RETURNS [accept: BOOL]; ListenerProc: TYPE = PROC [stream: IO.STREAM, remote: XNS.Address]; CreateListener: PROC [ socket: XNS.Socket, worker: ListenerProc, getTimeout, putTimeout: Milliseconds _ waitForever, 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.>> <> <> <<>> DestroyListener: PROC [Listener]; <> <> <> Create: PROC [remote: XNS.Address, getTimeout: Milliseconds _ waitForever, putTimeout: Milliseconds _ waitForever] RETURNS [IO.STREAM]; <> <> 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: LONG 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]; <> }.