{-# 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 -> ConduitT i SN.Message m ()
sourceSocket socket len = loop
where
loop = do
(bs, addr) <- lift $ liftIO $ recvFrom socket len
yield (SN.Message bs addr) >> loop
sinkSocket :: MonadIO m => Socket -> ConduitT ByteString o m ()
sinkSocket = sinkSocketHelper (\sock bs -> void $ send sock bs)
sinkAllSocket :: MonadIO m => Socket -> ConduitT ByteString o m ()
sinkAllSocket = sinkSocketHelper sendAll
sinkToSocket :: MonadIO m => Socket -> ConduitT SN.Message o m ()
sinkToSocket = sinkSocketHelper (\sock (SN.Message bs addr) -> void $ sendTo sock bs addr)
sinkAllToSocket :: MonadIO m => Socket -> ConduitT SN.Message o m ()
sinkAllToSocket = sinkSocketHelper (\sock (SN.Message bs addr) -> sendAllTo sock bs addr)
sinkSocketHelper :: MonadIO m => (Socket -> a -> IO ())
-> Socket
-> ConduitT a o m ()
sinkSocketHelper act socket = loop
where
loop = await >>= maybe
(return ())
(\a -> lift (liftIO $ act socket a) >> loop)
{-# INLINE sinkSocketHelper #-}