-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A wrapper around a generic stream-like connection -- -- Many uses of Sockets needs a number of common functions, like a write -- queue, pushback etc. This provides such and allows code to be written -- generically for any type of connection, be a raw socket or an SSL -- connection. @package network-connection @version 0.1.1 -- | Helpful functions to deal with stream-like connections module Network.Connection -- | A BaseConnection abstracts a stream like connection. data BaseConnection BaseConnection :: (Int -> IO ByteString) -> (ByteString -> IO Int) -> IO () -> BaseConnection -- | Read, at most, the given number of bytes from the connection and -- return a ByteString of the data. EOF is signaled by an exception and a -- zero length string is never a valid return value baseRead :: BaseConnection -> Int -> IO ByteString -- | Write the given ByteString to the connection. The write may write less -- than the requested number of bytes (but must always write at least one -- byte) baseWrite :: BaseConnection -> ByteString -> IO Int -- | Close a connection baseClose :: BaseConnection -> IO () -- | Return a BaseConnection for the given socket. baseConnectionFromSocket :: Socket -> BaseConnection -- | A Connection uses the functions from a BaseConnection and wraps them a -- number of commonly needed behaviours. -- -- Firstly, a write queue is introduced so that writes can be -- non-blocking. -- -- Secondly, the Connection can manage a number of threads. Almost always -- there will be a writer thread which is taking items from the write -- queue and writing them to the BaseConnection. In addition, there can -- be zero or more other threads managed by the Connection. If a thread -- which is managed dies, by throwing an exception or otherwise, it will -- close the connection and all other managed threads will be killed. -- -- There is also the concept of pushing data back into the Connection. -- This is useful in a chain of reader functions where, for efficiency -- reasons, you would want to read large blocks at a time, but the data -- is self-deliminating so you would otherwise end up in a situation -- where you had read too much. See the pushBack function for details. data Connection -- | Create a new Connection from a BaseConnection object new :: IO () -> BaseConnection -> IO Connection -- | This creates most of a Connection, purely in the STM monad. The -- Connection returned from this must be passed to forkWriterThread, -- otherwise nothing will ever get written. newSTM :: IO () -> BaseConnection -> STM Connection -- | If you created the Connection in the STM monad using newSTM, you need -- to call this on it in order to create the thread which processes the -- outgoing queue. forkWriterThread :: Connection -> IO () -- | Run the given action, as if by forkIO, and manage the thread. If the -- given action completes or throws an exception, the connection will be -- closed and all other managed threads will be killed forkInConnection :: Connection -> IO () -> IO () -- | Close a connection close :: Connection -> IO () -- | Enqueue a ByteString to a connection. This does not block. write :: Connection -> ByteString -> STM () -- | Block until the write queue has less than the given number of bytes in -- it then enqueue a new ByteString. writeAtLowWater :: Int -> Connection -> ByteString -> STM () -- | Read some number of bytes from a connection. The size is only a hint, -- the returned data may be shorter. A zero length read is EOF read :: Connection -> Int -> IO ByteString -- | Read exactly a give number of bytes reada :: Connection -> Int -> IO ByteString -- | Unread some amount of data. It will be returned in the next call to -- read. -- -- The function pushes data to the front of the queue. Thus you need to -- push all the data base in one go, or the order of future reads will be -- wrong. -- -- This might seem like an error, but consider the case of two actions: -- the first reads 20 bytes and pushs back the last 10 of them. The -- second reads 5 bytes and pushs back the last 4. If we appended to the -- push back queue the second action would put those 4 bytes after the -- remaining 5 from the first action. pushBack :: Connection -> ByteString -> STM ()