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 -- :: !S.ByteString -> m (DecompressStream m) nextResult <- decompressNext writeIORef resultRef nextResult -- writeIORef unfetchedChunksRef nextResult -- TODO: not needed?? 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