Permalink
Browse files

Init

  • Loading branch information...
0 parents commit 66f85ba6f23a758b6d675fd9f1a443af5ffd3b6f maltem committed Jan 2, 2011
Showing with 148 additions and 0 deletions.
  1. +100 −0 Codec/Zlib/Enum.hs
  2. +21 −0 LICENSE
  3. +27 −0 zlib-enum.cabal
@@ -0,0 +1,100 @@
+module Codec.Zlib.Enum (
+ -- * Enumeratees
+ compress, decompress,
+ -- * Re-exported from zlib-bindings
+ WindowBits
+) where
+
+import Codec.Zlib
+import Data.Enumerator
+import Control.Monad.Trans (MonadIO, liftIO)
+import Data.ByteString (ByteString)
+import Control.Monad (join)
+
+-- |
+-- Decompress (inflate) a stream of 'ByteString's. For example:
+--
+-- > run $ enumFile "test.z" $$ decompress defaultWindowBits $$ printChunks True
+
+decompress :: MonadIO m
+ => WindowBits -- ^ Zlib parameter (see the zlib-bindings package as well as the zlib C library)
+ -> Enumeratee ByteString ByteString m ()
+decompress config step0 = do
+ inflate <- liftIO $ initInflate config
+ checkDone (continue . goInflate inflate) step0
+
+-- |
+-- Compress (deflate) a stream of 'ByteString's. The 'WindowBits' also control
+-- the format (zlib vs. gzip).
+
+compress :: MonadIO m
+ => Int -- ^ Compression level
+ -> WindowBits -- ^ Zlib parameter (see the zlib-bindings package as well as the zlib C library)
+ -> Enumeratee ByteString ByteString m ()
+compress level config step0 = do
+ deflate <- liftIO $ initDeflate level config
+ checkDone (continue . goDeflate deflate) step0
+
+goInflate :: MonadIO m
+ => Inflate
+ -- ^ Zlib state
+ -> (Stream ByteString -> Iteratee ByteString m b)
+ -- ^ Continuation to be called on the next chunk of decompressed data
+ -> (Stream ByteString)
+ -- ^ Compressed data
+ -> Iteratee ByteString m (Step ByteString m b)
+
+goInflate inflate k stream = case stream of
+ EOF -> do lastChunk <- liftIO $ finishInflate inflate
+ return $$ k (Chunks [lastChunk])
+ (Chunks []) -> continue (goInflate inflate k)
+ (Chunks (x:xs)) -> let cont k' = goInflate inflate k' (Chunks xs)
+ inflateOne = withInflateInput inflate x (return . callback k)
+ in checkDone cont $$ joinIO inflateOne
+
+-- A callback function for withInflateInput / withDeflateInput
+callback :: MonadIO m =>
+ (Stream a -> Iteratee a m b) -> IO (Maybe a) -> m (Step a m b)
+
+callback k pop = maybe done more =<< liftIO pop
+ where
+ done = return (Continue k)
+ more y = do step <- runIteratee (k (Chunks [y]))
+ case step of
+ Continue k' -> callback k' pop
+ other -> return other
+
+-- testInflate = do
+-- h <- openBinaryFile "test-out" WriteMode
+-- run $ enumFile "test.z"
+-- $$ enumInflate defaultWindowBits
+-- $$ iterHandle h
+-- hClose h
+--
+-- testDeflate = do
+-- h <- openBinaryFile "test.z" WriteMode
+-- run $ enumFile "test"
+-- $$ enumDeflate 7 defaultWindowBits
+-- $$ iterHandle h
+-- hClose h
+
+-- Conversion utility
+joinIO :: MonadIO m => IO (m (Step a m b)) -> Iteratee a m b
+joinIO = Iteratee . join . liftIO
+
+goDeflate :: MonadIO m
+ => Deflate
+ -- ^ Zlib state
+ -> (Stream ByteString -> Iteratee ByteString m b)
+ -- ^ Continuation to be called on the next chunk of compressed data
+ -> (Stream ByteString)
+ -- ^ Uncompressed data
+ -> Iteratee ByteString m (Step ByteString m b)
+
+goDeflate deflate k stream = case stream of
+ EOF -> let callFinish = finishDeflate deflate (return . callback k)
+ in return $$ joinIO callFinish
+ (Chunks []) -> continue (goDeflate deflate k)
+ (Chunks (x:xs)) -> let cont k' = goDeflate deflate k' (Chunks xs)
+ deflateOne = withDeflateInput deflate x (return . callback k)
+ in checkDone cont $$ joinIO deflateOne
@@ -0,0 +1,21 @@
+Copyright 2011 Malte Sommerkorn.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
@@ -0,0 +1,27 @@
+name: zlib-enum
+version: 0.0
+license: MIT
+license-file: LICENSE
+author: Malte Sommerkorn <malte.sommerkorn@googlemail.com>
+maintainer: Malte Sommerkorn <malte.sommerkorn@googlemail.com>
+synopsis: Enumerator interface for zlib compression
+description: zlib-enum is a stop-gap package to provide enumeratees for
+ zlib compression/decompression.
+category: Codec, Enumerator
+stability: Experimental
+cabal-version: >= 1.6
+build-type: Simple
+homepage: http://github.com/maltem/zlib-enum
+
+library
+ build-depends: base >= 4
+ , bytestring
+ , mtl >= 2
+ , enumerator >= 0.4
+ , zlib-bindings
+ exposed-modules: Codec.Zlib.Enum
+ ghc-options: -Wall
+
+source-repository head
+ type: git
+ location: git://github.com/maltem/zlib-enum.git

0 comments on commit 66f85ba

Please sign in to comment.