module Data.Conduit.Network.Stream.Internal where
import Control.Applicative
import Control.Monad.Trans
import Control.Monad.Trans.Resource
import Data.Conduit
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BL
import Data.Conduit.Network.Stream.Header
newtype Stream m a = Stream { stream_base :: m a }
deriving (Monad, MonadIO, Functor, Applicative)
instance MonadTrans Stream where
lift f = Stream f
instance (MonadThrow m) => MonadThrow (Stream m) where
monadThrow e = lift $ monadThrow e
instance (MonadResource m, MonadIO m) => MonadResource (Stream m) where
liftResourceT t = lift $ liftResourceT t
encodeBS :: Monad m => Conduit ByteString (Stream m) ByteString
encodeBS = awaitForever $ \bs -> do
yield $ BS.pack (varint $ BS.length bs)
mapM_ yield $ blocks bs
where
blocks bs | BS.null bs = []
| otherwise =
let (f,r) = BS.splitAt 4096 bs
in f : blocks r
encodeLazyBS :: Monad m => Conduit (Int, BL.ByteString) (Stream m) ByteString
encodeLazyBS = awaitForever $ \(l,bs) -> do
yield $ BS.pack (varint l)
mapM_ yield $ BL.toChunks bs