{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE Trustworthy #-}
module Pipes.Brotli
(
compress
, decompress
, compressWith
, Brotli.defaultCompressParams
, Brotli.CompressParams
, Brotli.compressLevel
, Brotli.compressWindowSize
, Brotli.compressMode
, Brotli.compressSizeHint
, Brotli.CompressionLevel(..)
, Brotli.CompressionWindowSize(..)
, Brotli.CompressionMode(..)
, decompressWith
, Brotli.defaultDecompressParams
, Brotli.DecompressParams
, Brotli.decompressDisableRingBufferReallocation
) where
import Pipes
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import qualified Codec.Compression.Brotli as Brotli
decompress :: forall m r. MonadIO m
=> Producer ByteString m r
-> Producer ByteString m (Producer ByteString m r)
decompress = decompressWith Brotli.defaultDecompressParams
decompressWith :: forall m r. MonadIO m
=> Brotli.DecompressParams
-> Producer ByteString m r
-> Producer ByteString m (Producer ByteString m r)
decompressWith params prod0 = liftIO (Brotli.decompressIO params) >>= go prod0
where
go :: Producer ByteString m r
-> Brotli.DecompressStream IO
-> Producer ByteString m (Producer ByteString m r)
go prod s@(Brotli.DecompressInputRequired more) = do
mx <- lift $ next prod
case mx of
Right (x, prod')
| BS.null x -> go prod' s
| otherwise -> liftIO (more x) >>= go prod'
Left r -> liftIO (more BS.empty) >>= go (return r)
go prod (Brotli.DecompressOutputAvailable output cont) = do
yield output
liftIO cont >>= go prod
go prod (Brotli.DecompressStreamEnd leftover) =
return (yield leftover >> prod)
go _prod (Brotli.DecompressStreamError ecode) =
fail $ "Pipes.Brotli.decompress: error (" ++ Brotli.showBrotliDecoderErrorCode ecode ++ ")"
compress :: forall m r. MonadIO m
=> Producer ByteString m r
-> Producer ByteString m r
compress = compressWith Brotli.defaultCompressParams
compressWith :: forall m r. MonadIO m
=> Brotli.CompressParams
-> Producer ByteString m r
-> Producer ByteString m r
compressWith params prod0 = liftIO (Brotli.compressIO params) >>= go prod0
where
go :: Producer ByteString m r
-> Brotli.CompressStream IO
-> Producer ByteString m r
go prod s@(Brotli.CompressInputRequired _flush more) = do
mx <- lift $ next prod
case mx of
Right (x, prod')
| BS.null x -> go prod' s
| otherwise -> liftIO (more x) >>= go prod'
Left r -> liftIO (more BS.empty) >>= go (return r)
go prod (Brotli.CompressOutputAvailable output cont) = do
yield output
liftIO cont >>= go prod
go prod Brotli.CompressStreamEnd =
prod