module Potoki.Zlib.Fetch (
runGzip,
withCounter,
) where
import Potoki.Zlib.Prelude
import Potoki.Core.Fetch
import Potoki.Core.Consume
import qualified Codec.Compression.Zlib.Internal as A
withConsumeHook :: Consume a b -> (a -> IO ()) -> Consume a b
withConsumeHook (Consume consume) hook =
Consume $ \ (Fetch fetchIO) -> consume $ Fetch $ do
fetch <- fetchIO
case fetch of
Nothing -> return Nothing
Just val -> Just val <$ hook val
withCounter :: Consume a b -> (Int -> IO ()) -> Consume a b
withCounter consume int2IO =
do
counterVar <- liftIO $ newIORef 0
withConsumeHook consume $ \_ -> do
modifyIORef' counterVar succ
readIORef counterVar >>= int2IO
runGzip :: IORef [ByteString]
-> IORef (A.DecompressStream IO)
-> Fetch ByteString
-> Fetch (Either A.DecompressError ByteString)
runGzip unfetchedChunksRef resultRef (Fetch oldFetchIO) =
Fetch $ do
let
interpretResult resultIO = do
result <- resultIO
case result of
A.DecompressInputRequired nextResult -> do
newResult <- do
oldFetch <- oldFetchIO
return $ case oldFetch of
Nothing -> nextResult mempty
Just val -> nextResult val
interpretResult newResult
A.DecompressOutputAvailable decompressOutput decompressNext -> do
nextResult <- decompressNext
writeIORef resultRef nextResult
return (Just (Right decompressOutput))
A.DecompressStreamEnd _ ->
return Nothing
A.DecompressStreamError err ->
return (Just (Left err))
unfetchedChunks <- readIORef unfetchedChunksRef
case unfetchedChunks of
headChunk : unfetchedChunksTail -> do
writeIORef unfetchedChunksRef unfetchedChunksTail
return (Just (Right headChunk))
_ -> interpretResult $ readIORef resultRef