module Codec.Zlib.Enum (
compress, decompress,
WindowBits, defaultWindowBits
) where
import Codec.Zlib
import Data.Enumerator as E
import Control.Monad.Trans (MonadIO, liftIO)
import Data.ByteString (ByteString)
import Control.Monad (join)
joinIO :: MonadIO m => IO (m (Step a m b)) -> Iteratee a m b
joinIO = Iteratee . join . liftIO
enumLoop :: Monad m =>
((Stream b -> Iteratee b m c) -> Iteratee b m c)
-> (a -> (Stream b -> Iteratee b m c) -> Iteratee b m c)
-> Enumeratee a b m c
enumLoop done more = checkDone loop where
loop k = do maybe_x <- E.head
case maybe_x of
Nothing -> return $$ done k
Just x -> checkDone loop $$ more x k
decompress :: MonadIO m
=> WindowBits
-> Enumeratee ByteString ByteString m ()
decompress config step0 = do
inflate <- liftIO $ initInflate config
let done k = do lastChunk <- liftIO $ finishInflate inflate
k (Chunks [lastChunk])
more x k = joinIO $ withInflateInput inflate x (return . callback k)
enumLoop done more step0
compress :: MonadIO m
=> Int
-> WindowBits
-> Enumeratee ByteString ByteString m ()
compress level config step0 = do
deflate <- liftIO $ initDeflate level config
let done k = joinIO $ finishDeflate deflate (return . callback k)
more x k = joinIO $ withDeflateInput deflate x (return . callback k)
enumLoop done more step0
callback :: MonadIO m =>
(Stream a -> Iteratee a m b) -> IO (Maybe a) -> m (Step a m b)
callback k pop = maybe done more =<< liftIO pop
where
done = return (Continue k)
more y = do step <- runIteratee (k (Chunks [y]))
case step of
Continue k' -> callback k' pop
other -> return other