{-# LANGUAGE RankNTypes #-}
module Data.Conduit.Network.UDP
(
SN.Message (..)
, sourceSocket
, sinkSocket
, sinkAllSocket
, sinkToSocket
, sinkAllToSocket
, SN.HostPreference
) where
import Data.Conduit
import Network.Socket (Socket)
import Network.Socket.ByteString (recvFrom, send, sendAll, sendTo, sendAllTo)
import Data.ByteString (ByteString)
import Control.Monad.IO.Class (MonadIO (liftIO))
import Control.Monad (void)
import Control.Monad.Trans.Class (lift)
import qualified Data.Streaming.Network as SN
sourceSocket :: MonadIO m => Socket -> Int -> Producer m SN.Message
sourceSocket socket len = loop
where
loop = do
(bs, addr) <- lift $ liftIO $ recvFrom socket len
yield (SN.Message bs addr) >> loop
sinkSocket :: MonadIO m => Socket -> Consumer ByteString m ()
sinkSocket = sinkSocketHelper (\sock bs -> void $ send sock bs)
sinkAllSocket :: MonadIO m => Socket -> Consumer ByteString m ()
sinkAllSocket = sinkSocketHelper sendAll
sinkToSocket :: MonadIO m => Socket -> Consumer SN.Message m ()
sinkToSocket = sinkSocketHelper (\sock (SN.Message bs addr) -> void $ sendTo sock bs addr)
sinkAllToSocket :: MonadIO m => Socket -> Consumer SN.Message m ()
sinkAllToSocket = sinkSocketHelper (\sock (SN.Message bs addr) -> sendAllTo sock bs addr)
sinkSocketHelper :: MonadIO m => (Socket -> a -> IO ())
-> Socket
-> Consumer a m ()
sinkSocketHelper act socket = loop
where
loop = await >>= maybe
(return ())
(\a -> lift (liftIO $ act socket a) >> loop)
{-# INLINE sinkSocketHelper #-}