machines-zlib-0.1.0: src/Data/Machine/Zlib.hs
{-# LANGUAGE NoImplicitPrelude #-}
module Data.Machine.Zlib where
import BasicPrelude
import Control.Exception (throw)
import Data.Machine
import Data.Streaming.Zlib
-- | Even though this doesn't actually do any IO, we stay in the IO monad
-- like Data.Streaming.Zlib does, to avoid any unsafe "black magic".
gunzipper :: (Functor m, MonadIO m) => ProcessT m ByteString ByteString
gunzipper = construct $ do
inflate <- liftIO . initInflate $ WindowBits 31
let go :: (Functor m, MonadIO m) => PlanT (Is ByteString) ByteString m ()
go = do
bs <- await <|> finish
popper <- liftIO <$> liftIO (feedInflate inflate bs)
exhaust (handleRes <$> popper) <|> go
handleRes PRDone = Nothing
handleRes (PRNext bs) = Just bs
handleRes (PRError e) = throw e
finish :: MonadIO m => PlanT (Is ByteString) ByteString m ByteString
finish = do
r <- liftIO $ finishInflate inflate
yield r
stop
go