definition module StdChannels // ******************************************************************************** // Clean Standard TCP library, version 1.2.2 // // StdChannels defines operations on channels // Author: Martin Wierich // Modified: 15 October 2001 for Clean 2.0 (Peter Achten) // ******************************************************************************** from StdMaybe import :: Maybe from StdOverloaded import class toString, class == from tcp import class ChannelEnv, class FileEnv, class TimeEnv, class Ids, instance TimeEnv World, instance Ids World from iostate import :: PSt instance ChannelEnv World // ******************************************************************************** // receive channels // ******************************************************************************** class Receive ch where receive_MT :: !(Maybe Timeout) !*(ch .a) !*env -> (!TimeoutReport, !Maybe .a, !*(ch .a), !*env) | ChannelEnv env receiveUpTo :: !Int !*(ch .a) !*env -> (![.a], !*(ch .a), !*env) | ChannelEnv env available :: !*(ch .a) !*env -> (!Bool, !*(ch .a), !*env) | ChannelEnv env eom :: !*(ch .a) !*env -> (!Bool, !*(ch .a), !*env) | ChannelEnv env /* receive_MT tries to receive on a channel. This function will block until data can be received, eom becomes true, or the timeout expires. receiveUpTo max ch env receives messages on a channel until available becomes False or max messages have been received. available polls on a channel whether some data is ready to be received. If the returned Boolean is True, then a following receive_MT will not block and return TR_Success. eom ("end of messages") polls on a channel whether data can't be received anymore. */ class closeRChannel ch :: !*(ch .a) !*env -> *env | ChannelEnv env // Closes the channel // ******************************************************************************** // send channels // ******************************************************************************** class Send ch where send_MT :: !(Maybe Timeout) !.a !*(ch .a) !*env -> (!TimeoutReport, !Int, !*(ch .a), !*env) | ChannelEnv env nsend_MT :: !(Maybe Timeout) ![.a] !*(ch .a) !*env -> (!TimeoutReport, !Int, !*(ch .a), !*env) | ChannelEnv env flushBuffer_MT :: !(Maybe Timeout) !*(ch .a) !*env -> (!TimeoutReport, !Int, !*(ch .a), !*env) | ChannelEnv env closeChannel_MT :: !(Maybe Timeout) !*(ch .a) !*env -> (!TimeoutReport, !Int, !*env) | ChannelEnv env abortConnection :: !*(ch .a) !*env -> *env | ChannelEnv env disconnected :: !*(ch .a) !*env -> (!Bool, !*(ch .a), !*env) | ChannelEnv env bufferSize :: !*(ch .a) -> (!Int, !*(ch .a)) /* send_MT mbTimeout a ch env adds the data a to the channels internal buffer and tries to send this buffer. nsend_MT mbTimeout l ch env adds the data l to the channels internal buffer and tries to send this buffer. flushBuffer_MT tries to send the channels internal buffer. closeSChannel_MT first tries to send the channels internal buffer and then closes the channel. abortConnection will cause an abortive disconnect (sent data can be lost). disconnected polls on a channel, whether data can't be sent anymore. If the returned Boolean is True, then a following send_MT will not block and return TR_NoSuccess. bufferSize returns the size of the channels internal buffer in bytes. The integer value that is returned by send_MT, nsend_MT, flushBuffer_MT, and closeSChannel_MT is the number of sent bytes. */ // ******************************************************************************** // miscellaneous // ******************************************************************************** class MaxSize ch where setMaxSize :: !Int !*(ch .a) -> *(ch .a) getMaxSize :: !*(ch .a) -> (!Int, !*(ch .a)) clearMaxSize :: !*(ch .a) -> *(ch .a) // Set, get, or clear the maximum size of the data that can be received :: DuplexChannel sChannel rChannel a = { sChannel:: sChannel a , rChannel:: rChannel a } :: TimeoutReport = TR_Expired | TR_Success | TR_NoSuccess :: Timeout :== Int // timeout in ticks :: ReceiveMsg m = Received m | EOM // Receiving "EOM" automatically closes the receiver :: SendEvent = Sendable | Disconnected // Receiving "Disconnected" automatically closes the receiver instance == TimeoutReport instance toString TimeoutReport // ******************************************************************************** // derived functions // ******************************************************************************** nreceive_MT :: !(Maybe Timeout) !Int !*(ch .a) !*env -> (!TimeoutReport, ![.a],!*(ch .a),!*env) | Receive ch & ChannelEnv env /* nreceive_MT mbTimeout n ch env tries to call receive_MT n times. If the result is (tReport, l, ch2, env2), then the following holds: tReport==TR_Succes <=> length l==n tReport==TR_NoSuccess => length l (!.a, !*(ch .a), !*env) | ChannelEnv env & Receive ch nreceive :: !Int !*(ch .a) !*env -> (![.a], !*(ch .a), !*env) | ChannelEnv env & Receive ch /* The following three send functions call their "_MT" counterpart with no timeout. */ send :: !.a !*(ch .a) !*env -> (!*(ch .a), !*env) | ChannelEnv env & Send ch nsend :: ![.a] !*(ch .a) !*env -> (!*(ch .a), !*env) | ChannelEnv env & Send ch closeChannel :: !*(ch .a) !*env -> *env | ChannelEnv env & Send ch /* The following two send functions call their "_MT" counterpart with timeout == 0. "NB" is a shorthand for "non blocking" */ send_NB :: !.a !*(ch .a) !*env -> (!*(ch .a), !*env) | ChannelEnv env & Send ch flushBuffer_NB :: !*(ch .a) !*env -> (!*(ch .a), !*env) | ChannelEnv env & Send ch