pipes-zlib 0.2.0.0 → 0.3.0
raw patch · 4 files changed
+117/−101 lines, 4 filesdep ~pipes
Dependency ranges changed: pipes
Files
- PEOPLE +1/−0
- pipes-zlib.cabal +6/−6
- src/Control/Proxy/Zlib.hs +0/−95
- src/Pipes/Zlib.hs +110/−0
PEOPLE view
@@ -4,3 +4,4 @@ Renzo Carbonara Paolo Capriotti+Oliver Charles
pipes-zlib.cabal view
@@ -1,5 +1,5 @@ name: pipes-zlib-version: 0.2.0.0+version: 0.3.0 license: BSD3 license-file: LICENSE Copyright: Copyright (c) Paolo Capriotti 2012,@@ -11,8 +11,8 @@ bug-reports: https://github.com/k0001/pipes-zlib/issues category: Pipes, Compression build-type: Simple-synopsis: Pipes to deal with zlib compressed data.-description: Pipes to deal with zlib compressed data.+synopsis: Zlib compression and decompression for Pipes streams+description: Zlib compression and decompression for Pipes streams cabal-version: >=1.8 extra-source-files: README.md PEOPLE @@ -22,11 +22,11 @@ library hs-source-dirs: src- exposed-modules: Control.Proxy.Zlib+ exposed-modules: Pipes.Zlib build-depends: base (>= 4.5 && < 5.0) , transformers (>= 0.2 && < 0.4)- , pipes (>= 3.3 && < 3.4)+ , pipes (>= 4.0 && < 4.1) , bytestring (>= 0.9.2.1) , zlib (>= 0.5 && < 0.7) , zlib-bindings (>= 0.1 && < 0.2)- ghc-options: -Wall+ ghc-options: -Wall -O2
− src/Control/Proxy/Zlib.hs
@@ -1,95 +0,0 @@--- | This module exports utilities to compress and decompress @pipes@ streams--- using the zlib compression codec.--module Control.Proxy.Zlib (- -- * Streams- decompressD- , compressD-- -- * Compression level- -- $ccz-re-export- , ZC.defaultCompression- , ZC.noCompression- , ZC.bestSpeed- , ZC.bestCompression- , ZC.compressionLevel-- -- * Window size- -- $ccz-re-export- , ZC.defaultWindowBits- , ZC.windowBits- ) where--import qualified Codec.Zlib as Z-import qualified Codec.Compression.Zlib as ZC-import Control.Monad (forever, unless)-import Control.Monad.Trans.Class (lift)-import Control.Proxy ((>->))-import qualified Control.Proxy as P-import qualified Data.ByteString as B-import Data.Traversable (mapM)-import Prelude hiding (mapM)-------------------------------------------------------------------------------------- | Decompress bytes flowing downstream using the given 'Z.WindowBits'.------ See the "Codec.Zlib" module for details about this values.-decompressD- :: P.Proxy p- => Z.WindowBits- -> () -> P.Pipe p B.ByteString B.ByteString IO r-decompressD config () = P.runIdentityP . forever $ do- inf <- lift (Z.initInflate config)- popper <- lift . Z.feedInflate inf =<< P.request ()- (P.unitD >-> fromPopperS popper) ()- bs <- lift (Z.finishInflate inf)- unless (B.null bs) $ P.respond bs---- | Compress bytes flowing downstream.------ See the "Codec.Zlib" module for details about these values.-compressD- :: P.Proxy p- => ZC.CompressionLevel- -> Z.WindowBits- -> () -> P.Pipe p B.ByteString B.ByteString IO r-compressD level config () = P.runIdentityP loop where- loop = forever $ do- def <- lift (Z.initDeflate level' config)- popper <- lift . Z.feedDeflate def =<< P.request ()- (P.unitD >-> fromPopperS popper) ()- mapM P.respond =<< lift (Z.finishDeflate def)- level' = fromCompressionLevel level-------------------------------------------------------------------------------------- $ccz-re-export------ The following are re-exported from "Codec.Compression.Zlib" for your--- convenience.------------------------------------------------------------------------------------- Internal stuff---- | Produce values from the given 'Z.Poppler' until exhausted.-fromPopperS :: P.Proxy p => Z.Popper -> () -> P.Producer p B.ByteString IO ()-fromPopperS pop () = P.runIdentityP loop where- loop = do- mbs <- lift pop- case mbs of- Nothing -> return ()- Just bs -> P.respond bs >> loop---- We need this function until the @zlib@ library hides the--- 'ZC.CompressionLevel' constructors in future version 0.7.-fromCompressionLevel :: ZC.CompressionLevel -> Int-fromCompressionLevel level = case level of- ZC.DefaultCompression -> -1- ZC.NoCompression -> 0- ZC.BestSpeed -> 1- ZC.BestCompression -> 9- ZC.CompressionLevel n- | n >= 0 && n <= 9 -> fromIntegral n- _ -> error "CompressLevel must be in the range 1..9"-
+ src/Pipes/Zlib.hs view
@@ -0,0 +1,110 @@+{-# LANGUAGE RankNTypes #-}++-- | This module exports utilities to compress and decompress @pipes@ streams+-- using the zlib compression codec.++module Pipes.Zlib (+ -- * Streams+ decompress+ , compress++ -- * Compression level+ -- $ccz-re-export+ , ZC.defaultCompression+ , ZC.noCompression+ , ZC.bestSpeed+ , ZC.bestCompression+ , ZC.compressionLevel++ -- * Window size+ -- $ccz-re-export+ , ZC.defaultWindowBits+ , ZC.windowBits+ ) where++import qualified Codec.Zlib as Z+import qualified Codec.Compression.Zlib as ZC+import Control.Monad (forever)+import Pipes+import qualified Data.ByteString as B++--------------------------------------------------------------------------------++-- | Decompress bytes flowing downstream.+--+-- See the "Codec.Compression.Zlib" module for details about 'Z.WindowBits'.+decompress :: MonadIO m => ZC.WindowBits -> Pipe B.ByteString B.ByteString m r+decompress config = forever $ do+ inf <- liftIO (Z.initInflate config)+ a <- awaitNonEmpty+ popper <- liftIO (Z.feedInflate inf a)+ fromPopper popper+ bs <- liftIO (Z.finishInflate inf)+ if B.null bs+ then return ()+ else yield bs+{-# INLINABLE decompress #-}++-- | Compress bytes flowing downstream.+--+-- See the "Codec.Compression.Zlib" module for details about+-- 'ZC.CompressionLevel' and 'ZC.WindowBits'.+compress+ :: MonadIO m+ => ZC.CompressionLevel -> ZC.WindowBits -> Pipe B.ByteString B.ByteString m r+compress level config = forever $ do+ def <- liftIO (Z.initDeflate level' config)+ a <- awaitNonEmpty+ popper <- liftIO (Z.feedDeflate def a)+ fromPopper popper+ mbs <- liftIO (Z.finishDeflate def)+ case mbs of+ Just bs -> yield bs+ Nothing -> return ()+ where+ level' = fromCompressionLevel level+{-# INLINABLE compress #-}++--------------------------------------------------------------------------------++-- $ccz-re-export+--+-- The following are re-exported from "Codec.Compression.Zlib" for your+-- convenience.++--------------------------------------------------------------------------------+-- Internal stuff++awaitNonEmpty :: Monad m => Consumer' B.ByteString m B.ByteString+awaitNonEmpty = loop+ where+ loop = do+ bs <- await+ if B.null bs+ then loop+ else return bs+{-# INLINABLE awaitNonEmpty #-}++-- | Produce values from the given 'Z.Poppler' until exhausted.+fromPopper :: MonadIO m => Z.Popper -> Producer' B.ByteString m ()+fromPopper pop = loop+ where+ loop = do+ mbs <- liftIO pop+ case mbs of+ Nothing -> return ()+ Just bs -> yield bs >> loop+{-# INLINABLE fromPopper #-}++-- We need this function until the @zlib@ library hides the+-- 'ZC.CompressionLevel' constructors in future version 0.7.+fromCompressionLevel :: ZC.CompressionLevel -> Int+fromCompressionLevel level = case level of+ ZC.DefaultCompression -> -1+ ZC.NoCompression -> 0+ ZC.BestSpeed -> 1+ ZC.BestCompression -> 9+ ZC.CompressionLevel n+ | n >= 0 && n <= 9 -> fromIntegral n+ _ -> error "CompressLevel must be in the range 1..9"+