module Codec.Zlib.Enum (
compress, decompress, gzip, ungzip,
WindowBits (..), defaultWindowBits, ZlibException
) where
import Codec.Zlib
import Data.Enumerator as E
import qualified Data.Enumerator.List as EL
import Control.Monad.Trans.Class (lift)
import Control.Monad.IO.Class (MonadIO, liftIO)
import Data.ByteString (ByteString)
gzip :: MonadIO m => Enumeratee ByteString ByteString m a
gzip = compress 1 (WindowBits 31)
ungzip :: MonadIO m => Enumeratee ByteString ByteString m a
ungzip = decompress (WindowBits 31)
decompress
:: MonadIO m
=> WindowBits
-> Enumeratee ByteString ByteString m a
decompress config inner = do
inf <- liftIO $ initInflate config
decompress' inf inner
decompress' :: MonadIO m => Inflate -> Enumeratee ByteString ByteString m b
decompress' inf (Continue k) = do
x <- EL.head
case x of
Nothing -> do
chunk <- liftIO $ finishInflate inf
lift $ runIteratee $ k $ Chunks [chunk]
Just bs -> do
chunks <- liftIO $ (feedInflate inf bs >>= callback)
step <- lift $ runIteratee $ k $ Chunks chunks
decompress' inf step
decompress' _ step = return step
compress
:: MonadIO m
=> Int
-> WindowBits
-> Enumeratee ByteString ByteString m a
compress level config inner = do
def <- liftIO $ initDeflate level config
compress' def inner
compress' :: MonadIO m => Deflate -> Enumeratee ByteString ByteString m b
compress' def (Continue k) = do
x <- EL.head
case x of
Nothing -> do
chunks <- liftIO $ callback (finishDeflate def)
lift $ runIteratee $ k $ Chunks chunks
Just bs -> do
chunks <- liftIO $ (feedDeflate def bs >>= callback)
step <- lift $ runIteratee $ k $ Chunks chunks
compress' def step
compress' _ step = return step
callback :: Monad m => m (Maybe a) -> m [a]
callback pop = go id where
go front = do
x <- pop
case x of
Nothing -> return $ front []
Just y -> go (front . (:) y)