packages feed

zlib 0.4.0.4 → 0.5.0.0

raw patch · 6 files changed

+406/−182 lines, 6 filesdep ~base

Dependency ranges changed: base

Files

Codec/Compression/GZip.hs view
@@ -1,9 +1,9 @@ ----------------------------------------------------------------------------- -- |--- Copyright   :  (c) 2006 Duncan Coutts+-- Copyright   :  (c) 2006-2008 Duncan Coutts -- License     :  BSD-style ----- Maintainer  :  duncan.coutts@worc.ox.ac.uk+-- Maintainer  :  duncan@haskell.org -- Stability   :  provisional -- Portability :  portable (H98 + FFI) --@@ -18,8 +18,8 @@ module Codec.Compression.GZip (    -- | This module provides pure functions for compressing and decompressing-  -- streams of data represented by lazy 'ByteString's. This makes it easy to-  -- use either in memory or with disk or network IO.+  -- streams of data in the gzip format and represented by lazy 'ByteString's.+  -- This makes it easy to use either in memory or with disk or network IO.   --   -- For example a simple gzip compression program is just:   --@@ -33,19 +33,30 @@   -- > content <- fmap GZip.decompress (readFile file)   -- -  -- * Compression+  -- * Simple compression and decompression   compress,+  decompress,++  -- * Extended api with control over compression parameters   compressWith,-  CompressionLevel(..),+  decompressWith, -  -- * Decompression-  decompress+  CompressParams(..), defaultCompressParams,+  DecompressParams(..), defaultDecompressParams, +  -- ** The compression parameter types+  CompressionLevel(..),+  Method(..),+  WindowBits(..),+  MemoryLevel(..),+  CompressionStrategy(..),+   ) where  import Data.ByteString.Lazy (ByteString) -import Codec.Compression.Zlib.Internal as Internal+import qualified Codec.Compression.Zlib.Internal as Internal+import Codec.Compression.Zlib.Internal hiding (compress, decompress)   -- | Decompress a stream of data in the gzip format.@@ -66,24 +77,39 @@ -- stream before doing any IO action that depends on it. -- decompress :: ByteString -> ByteString-decompress = Internal.decompressDefault GZip+decompress = Internal.decompress GZip defaultDecompressParams  +-- | Like 'decompress' but with the ability to specify various decompression+-- parameters. Typical usage:+--+-- > decompressWith defaultCompressParams { ... }+--+decompressWith :: DecompressParams -> ByteString -> ByteString+decompressWith = Internal.decompress GZip++ -- | Compress a stream of data into the gzip format. ----- This uses the default compression level which favours a higher compression--- ratio over compression speed. Use 'compressWith' to adjust the compression--- level.+-- This uses the default compression parameters. In partiular it uses the+-- default compression level which favours a higher compression ratio over+-- compression speed, though it does not use the maximum compression level. --+-- Use 'compressWith' to adjust the compression level or other compression+-- parameters.+-- compress :: ByteString -> ByteString-compress = Internal.compressDefault GZip DefaultCompression+compress = Internal.compress GZip defaultCompressParams  --- | Like 'compress' but with an extra parameter to specify the compression--- level.+-- | Like 'compress' but with the ability to specify various compression+-- parameters. Typical usage: ----- There are a number of additional compression parameters which are rarely--- necessary to change but if you need to you can do so using 'compressFull'.+-- > compressWith defaultCompressParams { ... } ---compressWith ::CompressionLevel -> ByteString -> ByteString-compressWith = Internal.compressDefault GZip+-- In particular you can set the compression level:+--+-- > compressWith defaultCompressParams { compressLevel = BestCompression }+--+compressWith :: CompressParams -> ByteString -> ByteString+compressWith = Internal.compress GZip
Codec/Compression/Zlib.hs view
@@ -1,9 +1,9 @@ ----------------------------------------------------------------------------- -- |--- Copyright   :  (c) 2006 Duncan Coutts+-- Copyright   :  (c) 2006-2008 Duncan Coutts -- License     :  BSD-style ----- Maintainer  :  duncan.coutts@worc.ox.ac.uk+-- Maintainer  :  duncan@haskell.org -- Stability   :  provisional -- Portability :  portable (H98 + FFI) --@@ -16,26 +16,88 @@ -- ----------------------------------------------------------------------------- module Codec.Compression.Zlib (-  -  -- * Compression++  -- | This module provides pure functions for compressing and decompressing+  -- streams of data in the zlib format and represented by lazy 'ByteString's.+  -- This makes it easy to use either in memory or with disk or network IO.++  -- * Simple compression and decompression   compress,+  decompress,++  -- * Extended api with control over compression parameters   compressWith,+  decompressWith,++  CompressParams(..), defaultCompressParams,+  DecompressParams(..), defaultDecompressParams,++  -- ** The compression parameter types   CompressionLevel(..),-  -  -- * Decompression-  decompress+  Method(..),+  WindowBits(..),+  MemoryLevel(..),+  CompressionStrategy(..),    ) where  import Data.ByteString.Lazy (ByteString) -import Codec.Compression.Zlib.Internal as Internal+import qualified Codec.Compression.Zlib.Internal as Internal+import Codec.Compression.Zlib.Internal hiding (compress, decompress) ++-- | Decompress a stream of data in the zlib format.+--+-- There are a number of errors that can occur. In each case an exception will+-- be thrown. The possible error conditions are:+--+-- * if the stream does not start with a valid gzip header+--+-- * if the compressed stream is corrupted+--+-- * if the compressed stream ends permaturely+--+-- Note that the decompression is performed /lazily/. Errors in the data stream+-- may not be detected until the end of the stream is demanded (since it is+-- only at the end that the final checksum can be checked). If this is+-- important to you, you must make sure to consume the whole decompressed+-- stream before doing any IO action that depends on it.+-- decompress :: ByteString -> ByteString-decompress = Internal.decompressDefault Zlib+decompress = Internal.decompress Zlib defaultDecompressParams ++-- | Like 'decompress' but with the ability to specify various decompression+-- parameters. Typical usage:+--+-- > decompressWith defaultCompressParams { ... }+--+decompressWith :: DecompressParams -> ByteString -> ByteString+decompressWith = Internal.decompress Zlib+++-- | Compress a stream of data into the zlib format.+--+-- This uses the default compression parameters. In partiular it uses the+-- default compression level which favours a higher compression ratio over+-- compression speed, though it does not use the maximum compression level.+--+-- Use 'compressWith' to adjust the compression level or other compression+-- parameters.+-- compress :: ByteString -> ByteString-compress = Internal.compressDefault Zlib DefaultCompression+compress = Internal.compress Zlib defaultCompressParams -compressWith ::CompressionLevel -> ByteString -> ByteString-compressWith = Internal.compressDefault Zlib++-- | Like 'compress' but with the ability to specify various compression+-- parameters. Typical usage:+--+-- > compressWith defaultCompressParams { ... }+--+-- In particular you can set the compression level:+--+-- > compressWith defaultCompressParams { compressLevel = BestCompression }+--+compressWith :: CompressParams -> ByteString -> ByteString+compressWith = Internal.compress Zlib
Codec/Compression/Zlib/Internal.hs view
@@ -1,9 +1,10 @@+{-# LANGUAGE CPP #-} ----------------------------------------------------------------------------- -- |--- Copyright   :  (c) 2006-2007 Duncan Coutts+-- Copyright   :  (c) 2006-2008 Duncan Coutts -- License     :  BSD-style ----- Maintainer  :  duncan.coutts@worc.ox.ac.uk+-- Maintainer  :  duncan@haskell.org -- Stability   :  provisional -- Portability :  portable (H98 + FFI) --@@ -12,20 +13,23 @@ ----------------------------------------------------------------------------- module Codec.Compression.Zlib.Internal ( -  -- * Compression and decompression-  compressDefault,-  decompressDefault,+  -- * Compression+  compress,+  CompressParams(..),+  defaultCompressParams,++  -- * Decompression+  decompress,+  DecompressParams(..),+  defaultDecompressParams,++  -- * The compression parameter types   Stream.Format(..),   Stream.CompressionLevel(..),--  -- * The same but with the full set of parameters-  compressFull,-  decompressFull,   Stream.Method(..),   Stream.WindowBits(..),   Stream.MemoryLevel(..),   Stream.CompressionStrategy(..),-   ) where  import Prelude hiding (length)@@ -42,64 +46,111 @@ import qualified Codec.Compression.Zlib.Stream as Stream import Codec.Compression.Zlib.Stream (Stream) -compressDefault-  :: Stream.Format-  -> Stream.CompressionLevel-  -> L.ByteString-  -> L.ByteString-compressDefault format compressionLevel =-  compressFull format-               compressionLevel-               Stream.Deflated-               Stream.DefaultWindowBits-               Stream.DefaultMemoryLevel-               Stream.DefaultStrategy+-- | The full set of parameters for compression. The defaults are+-- 'defaultCompressParams'.+--+-- The 'compressBufferSize' is the size of the first output buffer containing+-- the compressed data. If you know an approximate upper bound on the size of+-- the compressed data then setting this parameter can save memory. The default+-- compression output buffer size is @16k@. If your extimate is wrong it does+-- not matter too much, the default buffer size will be used for the remaining+-- chunks.+--+data CompressParams = CompressParams {+  compressLevel       :: Stream.CompressionLevel,+  compressMethod      :: Stream.Method,+  compressWindowBits  :: Stream.WindowBits,+  compressMemoryLevel :: Stream.MemoryLevel,+  compressStrategy    :: Stream.CompressionStrategy,+  compressBufferSize  :: Int+} -decompressDefault-  :: Stream.Format-  -> L.ByteString-  -> L.ByteString-decompressDefault format =-  decompressFull format-                 Stream.DefaultWindowBits+-- | The full set of parameters for decompression. The defaults are+-- 'defaultDecompressParams'.+--+-- The 'decompressBufferSize' is the size of the first output buffer,+-- containing the uncompressed data. If you know an exact or approximate upper+-- bound on the size of the decompressed data then setting this parameter can+-- save memory. The default decompression output buffer size is @32k@. If your+-- extimate is wrong it does not matter too much, the default buffer size will+-- be used for the remaining chunks.+--+-- One particular use case for setting the 'decompressBufferSize' is if you+-- know the exact size of the decompressed data and want to produce a strict+-- 'Data.ByteString.ByteString'. The compression and deccompression functions+-- use lazy 'Data.ByteString.Lazy.ByteString's but if you set the+-- 'decompressBufferSize' correctly then you can generate a lazy+-- 'Data.ByteString.Lazy.ByteString' with exactly one chunk, which can be+-- converted to a strict 'Data.ByteString.ByteString' in @O(1)@ time using+-- @'Data.ByteString.concat' . 'Data.ByteString.Lazy.toChunks'@.+--+data DecompressParams = DecompressParams {+  decompressWindowBits :: Stream.WindowBits,+  decompressBufferSize :: Int+} -{-# NOINLINE compressFull #-}-compressFull+-- | The default set of parameters for compression. This is typically used with+-- the @compressWith@ function with specific paramaters overridden.+--+defaultCompressParams :: CompressParams+defaultCompressParams = CompressParams {+  compressLevel       = Stream.DefaultCompression,+  compressMethod      = Stream.Deflated,+  compressWindowBits  = Stream.DefaultWindowBits,+  compressMemoryLevel = Stream.DefaultMemoryLevel,+  compressStrategy    = Stream.DefaultStrategy,+  compressBufferSize  = defaultCompressBufferSize+}++-- | The default set of parameters for decompression. This is typically used with+-- the @compressWith@ function with specific paramaters overridden.+--+defaultDecompressParams :: DecompressParams+defaultDecompressParams = DecompressParams {+  decompressWindowBits = Stream.DefaultWindowBits,+  decompressBufferSize = defaultDecompressBufferSize+}++-- | The default chunk sizes for the output of compression and decompression+-- are 16k and 32k respectively (less a small accounting overhead).+--+defaultCompressBufferSize, defaultDecompressBufferSize :: Int+#ifdef BYTESTRING_IN_BASE+defaultCompressBufferSize   = 16 * 1024 - 16+defaultDecompressBufferSize = 32 * 1024 - 16+#else+defaultCompressBufferSize   = 16 * 1024 - L.chunkOverhead+defaultDecompressBufferSize = 32 * 1024 - L.chunkOverhead+#endif++{-# NOINLINE compress #-}+compress   :: Stream.Format-  -> Stream.CompressionLevel-  -> Stream.Method-  -> Stream.WindowBits-  -> Stream.MemoryLevel-  -> Stream.CompressionStrategy+  -> CompressParams   -> L.ByteString   -> L.ByteString-compressFull format compLevel method bits memLevel strategy input =+compress format+  (CompressParams compLevel method bits memLevel strategy initChunkSize)+  input =   L.fromChunks $ Stream.run $ do     Stream.deflateInit format compLevel method bits memLevel strategy     case L.toChunks input of-      [] -> fillBuffers []+      [] -> fillBuffers 20 [] --gzip header is 20 bytes, others even smaller       S.PS inFPtr offset length : chunks -> do         Stream.pushInputBuffer inFPtr offset length-        fillBuffers chunks+        fillBuffers initChunkSize chunks    where-  outChunkSize :: Int-#ifdef BYTESTRING_IN_BASE-  outChunkSize = 16 * 1024 - 16-#else-  outChunkSize = 16 * 1024 - L.chunkOverhead-#endif-     -- we flick between two states:     --   * where one or other buffer is empty     --       - in which case we refill one or both     --   * where both buffers are non-empty     --       - in which case we compress until a buffer is empty -  fillBuffers ::-      [S.ByteString]-   -> Stream [S.ByteString]-  fillBuffers inChunks = do+  fillBuffers :: Int+              -> [S.ByteString]+              -> Stream [S.ByteString]+  fillBuffers outChunkSize inChunks = do     Stream.consistencyCheck      -- in this state there are two possabilities:@@ -145,9 +196,10 @@         outputBufferFull <- Stream.outputBufferFull         if outputBufferFull           then do (outFPtr, offset, length) <- Stream.popOutputBuffer-                  outChunks <- Stream.unsafeInterleave (fillBuffers inChunks)+                  outChunks <- Stream.unsafeInterleave+                    (fillBuffers defaultCompressBufferSize inChunks)                   return (S.PS outFPtr offset length : outChunks)-          else do fillBuffers inChunks+          else do fillBuffers defaultCompressBufferSize inChunks        Stream.StreamEnd -> do         inputBufferEmpty <- Stream.inputBufferEmpty@@ -163,39 +215,32 @@       Stream.NeedDict    -> fail "NeedDict is impossible!"  -{-# NOINLINE decompressFull #-}-decompressFull+{-# NOINLINE decompress #-}+decompress   :: Stream.Format-  -> Stream.WindowBits+  -> DecompressParams   -> L.ByteString   -> L.ByteString-decompressFull format bits input =+decompress format (DecompressParams bits initChunkSize) input =   L.fromChunks $ Stream.run $ do     Stream.inflateInit format bits     case L.toChunks input of-      [] -> fillBuffers []+      [] -> fillBuffers 4 [] --always an error anyway       S.PS inFPtr offset length : chunks -> do         Stream.pushInputBuffer inFPtr offset length-        fillBuffers chunks+        fillBuffers initChunkSize chunks    where-  outChunkSize :: Int-#ifdef BYTESTRING_IN_BASE-  outChunkSize = 32 * 1024 - 16-#else-  outChunkSize = 32 * 1024 - L.chunkOverhead-#endif-     -- we flick between two states:     --   * where one or other buffer is empty     --       - in which case we refill one or both     --   * where both buffers are non-empty     --       - in which case we compress until a buffer is empty -  fillBuffers ::-      [S.ByteString]-   -> Stream [S.ByteString]-  fillBuffers inChunks = do+  fillBuffers :: Int+              -> [S.ByteString]+              -> Stream [S.ByteString]+  fillBuffers outChunkSize inChunks = do      -- in this state there are two possabilities:     --   * no outbut buffer space is available@@ -239,9 +284,10 @@         outputBufferFull <- Stream.outputBufferFull         if outputBufferFull           then do (outFPtr, offset, length) <- Stream.popOutputBuffer-                  outChunks <- Stream.unsafeInterleave (fillBuffers inChunks)+                  outChunks <- Stream.unsafeInterleave+                    (fillBuffers defaultDecompressBufferSize inChunks)                   return (S.PS outFPtr offset length : outChunks)-          else do fillBuffers inChunks+          else do fillBuffers defaultDecompressBufferSize inChunks        Stream.StreamEnd -> do         -- Note that there may be input bytes still available if the stream
Codec/Compression/Zlib/Raw.hs view
@@ -1,10 +1,10 @@ ----------------------------------------------------------------------------- -- |--- Copyright   :  (c) 2006 Duncan Coutts+-- Copyright   :  (c) 2006-2008 Duncan Coutts -- License     :  BSD-style ----- Maintainer  :  duncan.coutts@worc.ox.ac.uk--- Stability   :  experimental+-- Maintainer  :  duncan@haskell.org+-- Stability   :  provisional -- Portability :  portable (H98 + FFI) -- -- Compression and decompression of data streams in the raw deflate format.@@ -17,25 +17,39 @@ ----------------------------------------------------------------------------- module Codec.Compression.Zlib.Raw (   -  -- * Compression+  -- * Simple compression and decompression   compress,+  decompress,++  -- * Extended api with control over compression parameters   compressWith,+  decompressWith,++  CompressParams(..), defaultCompressParams,+  DecompressParams(..), defaultDecompressParams,++  -- ** The compression parameter types   CompressionLevel(..),-  -  -- * Decompression-  decompress-  +  Method(..),+  WindowBits(..),+  MemoryLevel(..),+  CompressionStrategy(..),+   ) where  import Data.ByteString.Lazy (ByteString) -import Codec.Compression.Zlib.Internal as Internal+import qualified Codec.Compression.Zlib.Internal as Internal+import Codec.Compression.Zlib.Internal hiding (compress, decompress)  decompress :: ByteString -> ByteString-decompress = Internal.decompressDefault Raw+decompress = Internal.decompress Raw defaultDecompressParams +decompressWith :: DecompressParams -> ByteString -> ByteString+decompressWith = Internal.decompress Raw+ compress :: ByteString -> ByteString-compress = Internal.compressDefault Raw DefaultCompression+compress = Internal.compress Raw defaultCompressParams -compressWith ::CompressionLevel -> ByteString -> ByteString-compressWith = Internal.compressDefault Raw+compressWith :: CompressParams -> ByteString -> ByteString+compressWith = Internal.compress Raw
Codec/Compression/Zlib/Stream.hsc view
@@ -1,11 +1,11 @@-{-# OPTIONS_GHC -fno-warn-missing-methods #-}+{-# LANGUAGE ForeignFunctionInterface #-} ----------------------------------------------------------------------------- -- | -- Copyright   :  (c) 2006-2008 Duncan Coutts -- License     :  BSD-style ----- Maintainer  :  duncan.coutts@worc.ox.ac.uk--- Stability   :  experimental+-- Maintainer  :  duncan@haskell.org+-- Stability   :  provisional -- Portability :  portable (H98 + FFI) -- -- Zlib wrapper layer@@ -58,11 +58,16 @@   ) where  import Foreign+         ( Word8, Ptr, nullPtr, plusPtr, peekByteOff, pokeByteOff, mallocBytes+         , ForeignPtr, FinalizerPtr, newForeignPtr_, addForeignPtrFinalizer+	 , finalizeForeignPtr, withForeignPtr, touchForeignPtr+	 , unsafeForeignPtrToPtr, unsafePerformIO ) import Foreign.C+         ( CInt, CUInt, CChar, CString, withCAString, peekCAString ) #ifdef BYTESTRING_IN_BASE-import Data.ByteString.Base+import Data.ByteString.Base (nullForeignPtr) #else-import Data.ByteString.Internal+import Data.ByteString.Internal (nullForeignPtr) #endif import System.IO.Unsafe (unsafeInterleaveIO) import System.IO (hPutStrLn, stderr)@@ -370,12 +375,12 @@                 --   'BuferError' is not fatal, and 'inflate' can be called                 --   again with more input and more output space to continue. -instance Enum Status where-  toEnum (#{const Z_OK})         = Ok-  toEnum (#{const Z_STREAM_END}) = StreamEnd-  toEnum (#{const Z_NEED_DICT})  = NeedDict-  toEnum (#{const Z_BUF_ERROR})  = BufferError-  toEnum other = error ("unexpected zlib status: " ++ show other)+toStatus :: CInt -> Status+toStatus (#{const Z_OK})         = Ok+toStatus (#{const Z_STREAM_END}) = StreamEnd+toStatus (#{const Z_NEED_DICT})  = NeedDict+toStatus (#{const Z_BUF_ERROR})  = BufferError+toStatus other = error ("unexpected zlib status: " ++ show other)  failIfError :: CInt -> Stream () failIfError errno@@ -387,7 +392,7 @@ getErrorMessage errno = do   msgPtr <- withStreamPtr (#{peek z_stream, msg})   if msgPtr /= nullPtr-    then unsafeLiftIO (peekCString msgPtr)+    then unsafeLiftIO (peekCAString msgPtr)     else return $ case errno of       #{const Z_ERRNO}         -> "file error"       #{const Z_STREAM_ERROR}  -> "stream error"@@ -403,54 +408,89 @@   | Finish --  | Block -- only available in zlib 1.2 and later, uncomment if you need it. -instance Enum Flush where-  fromEnum NoFlush   = #{const Z_NO_FLUSH}-  fromEnum SyncFlush = #{const Z_SYNC_FLUSH}-  fromEnum FullFlush = #{const Z_FULL_FLUSH}-  fromEnum Finish    = #{const Z_FINISH}---  fromEnum Block     = #{const Z_BLOCK}+fromFlush :: Flush -> CInt+fromFlush NoFlush   = #{const Z_NO_FLUSH}+fromFlush SyncFlush = #{const Z_SYNC_FLUSH}+fromFlush FullFlush = #{const Z_FULL_FLUSH}+fromFlush Finish    = #{const Z_FINISH}+--  fromFlush Block     = #{const Z_BLOCK} +-- | The format used for compression or decompression. There are three+-- variations.+-- data Format =-    GZip       -- ^ Encode or decode with the gzip header format.-  | Zlib       -- ^ Encode or decode with the zlib header format.-  | Raw        -- ^ Encode or decode a raw data stream without any header.-  | GZipOrZlib -- ^ Enable zlib or gzip decoding with automatic header-               --   detection. This only makes sense for decompression.+    GZip -- ^ The gzip format uses a header with a checksum and some optional+         -- meta-data about the compressed file. It is intended primarily for+         -- compressing individual files but is also sometimes used for network+         -- protocols such as HTTP. The format is described in detail in RFC+         -- #1952 <http://www.ietf.org/rfc/rfc1952.txt> +  | Zlib -- | The zlib format uses a minimal header with a checksum but no+         -- other meta-data. It is especially designed for use in network+         -- protocols. The format is described in detail in RFC #1950+         -- <http://www.ietf.org/rfc/rfc1950.txt>++  | Raw  -- | The \'raw\' format is just the compressed data stream without any+         -- additional header, meta-data or data-integrity checksum. The format+         -- is described in detail in RFC #1951+         -- <http://www.ietf.org/rfc/rfc1951.txt>++  | GZipOrZlib -- ^ This is not a format as such. It enabled zlib or gzip+               -- decoding with automatic header detection. This only makes+               -- sense for decompression.+  deriving Eq+ -- | The compression method-data Method = Deflated -- ^ \'Deflate\' is the only one supported in this-                       -- version of zlib.+--+data Method = Deflated -- ^ \'Deflate\' is the only method supported in this+                       -- version of zlib. Indeed it is likely to be the only+                       -- method that ever will be supported. -instance Enum Method where-  fromEnum Deflated = #{const Z_DEFLATED}+fromMethod :: Method -> CInt+fromMethod Deflated = #{const Z_DEFLATED} --- | Control amount of compression. This is a trade-off between the amount--- of compression and the time and memory required to do the compression.+-- | The compression level parameter controls the amount of compression. This+-- is a trade-off between the amount of compression and the time required to do+-- the compression.+-- data CompressionLevel =      DefaultCompression   -- ^ The default compression level is 6 (that is, -                         --   biased towards high compression at expense of speed).+                         --   biased towards higher compression at expense of+			 -- speed).   | NoCompression        -- ^ No compression, just a block copy.   | BestSpeed            -- ^ The fastest compression method (less compression)    | BestCompression      -- ^ The slowest compression method (best compression).   | CompressionLevel Int -- ^ A specific compression level between 1 and 9. -instance Enum CompressionLevel where-  fromEnum DefaultCompression = -1-  fromEnum NoCompression      = 0-  fromEnum BestSpeed          = 1-  fromEnum BestCompression    = 9-  fromEnum (CompressionLevel n)-           | n >= 1 && n <= 9 = n+fromCompressionLevel :: CompressionLevel -> CInt+fromCompressionLevel DefaultCompression   = -1+fromCompressionLevel NoCompression        = 0+fromCompressionLevel BestSpeed            = 1+fromCompressionLevel BestCompression      = 9+fromCompressionLevel (CompressionLevel n)+           | n >= 1 && n <= 9 = fromIntegral n            | otherwise        = error "CompressLevel must be in the range 1..9" +-- | This specifies the size of the compression window. Larger values of this+-- parameter result in better compression at the expense of higher memory+-- usage.+--+-- The compression window size is the value of the the window bits raised to+-- the power 2. The window bits must be in the range @8..15@ which corresponds+-- to compression window sizes of 256b to 32Kb. The default is 15 which is also+-- the maximum size.+--+-- The total amount of memory used depends on the window bits and the+-- 'MemoryLevel'. See the 'MemoryLevel' for the details.+-- data WindowBits = DefaultWindowBits                 | WindowBits Int -windowBits :: Format -> WindowBits-> Int+windowBits :: Format -> WindowBits-> CInt windowBits format bits = (formatModifier format) (checkWindowBits bits)   where checkWindowBits DefaultWindowBits = 15         checkWindowBits (WindowBits n)-          | n >= 8 && n <= 15 = n+          | n >= 8 && n <= 15 = fromIntegral n           | otherwise         = error "WindowBits must be in the range 8..15"         formatModifier Zlib       = id         formatModifier GZip       = (+16)@@ -458,23 +498,41 @@         formatModifier Raw        = negate  -- | The 'MemoryLevel' parameter specifies how much memory should be allocated--- for the internal compression state.+-- for the internal compression state. It is a tradoff between memory usage,+-- compression ratio and compression speed. Using more memory allows faster+-- compression and a better compression ratio. --+-- The total amount of memory used for compression depends on the 'WindowBits'+-- and the 'MemoryLevel'. For decompression it depends only on the+-- 'WindowBits'. The totals are given by the functions:+--+-- > compressTotal windowBits memLevel = 4 * 2^windowBits + 512 * 2^memLevel+-- > decompressTotal windowBits = 2^windowBits+--+-- For example, for compression with the default @windowBits = 15@ and+-- @memLevel = 8@ uses @256Kb@. So for example a network server with 100+-- concurrent compressed streams would use @25Mb@. The memory per stream can be+-- halved (at the cost of somewhat degraded and slower compressionby) by+-- reducing the @windowBits@ and @memLevel@ by one.+--+-- Decompression takes less memory, the default @windowBits = 15@ corresponds+-- to just @32Kb@.+-- data MemoryLevel =     DefaultMemoryLevel -- ^ The default. (Equivalent to @'MemoryLevel' 8@)   | MinMemoryLevel     -- ^ Use minimum memory. This is slow and reduces the                        --   compression ratio. (Equivalent to @'MemoryLevel' 1@)   | MaxMemoryLevel     -- ^ Use maximum memory for optimal compression speed.                        --   (Equivalent to @'MemoryLevel' 9@)-  | MemoryLevel Int    -- ^ Use a specific level in the range 1..9+  | MemoryLevel Int    -- ^ Use a specific level in the range @1..9@ -instance Enum MemoryLevel where-  fromEnum DefaultMemoryLevel = 8-  fromEnum MinMemoryLevel     = 1-  fromEnum MaxMemoryLevel     = 9-  fromEnum (MemoryLevel n)-           | n >= 1 && n <= 9 = n-           | otherwise        = error "MemoryLevel must be in the range 1..9"+fromMemoryLevel :: MemoryLevel -> CInt+fromMemoryLevel DefaultMemoryLevel = 8+fromMemoryLevel MinMemoryLevel     = 1+fromMemoryLevel MaxMemoryLevel     = 9+fromMemoryLevel (MemoryLevel n)+         | n >= 1 && n <= 9 = fromIntegral n+         | otherwise        = error "MemoryLevel must be in the range 1..9"   -- | The strategy parameter is used to tune the compression algorithm.@@ -505,12 +563,12 @@                     --   allowing for a simpler decoder for special applications. -} -instance Enum CompressionStrategy where-  fromEnum DefaultStrategy = #{const Z_DEFAULT_STRATEGY}-  fromEnum Filtered        = #{const Z_FILTERED}-  fromEnum HuffmanOnly     = #{const Z_HUFFMAN_ONLY}---  fromEnum RLE             = #{const Z_RLE}---  fromEnum Fixed           = #{const Z_FIXED}+fromCompressionStrategy :: CompressionStrategy -> CInt+fromCompressionStrategy DefaultStrategy = #{const Z_DEFAULT_STRATEGY}+fromCompressionStrategy Filtered        = #{const Z_FILTERED}+fromCompressionStrategy HuffmanOnly     = #{const Z_HUFFMAN_ONLY}+--fromCompressionStrategy RLE             = #{const Z_RLE}+--fromCompressionStrategy Fixed           = #{const Z_FIXED}  withStreamPtr :: (Ptr StreamState -> IO a) -> Stream a withStreamPtr f = do@@ -552,6 +610,7 @@  inflateInit :: Format -> WindowBits -> Stream () inflateInit format bits = do+  checkFormatSupported format   err <- withStreamState $ \zstream ->     c_inflateInit2 zstream (fromIntegral (windowBits format bits))   failIfError err@@ -565,29 +624,30 @@             -> CompressionStrategy             -> Stream () deflateInit format compLevel method bits memLevel strategy = do+  checkFormatSupported format   err <- withStreamState $ \zstream ->     c_deflateInit2 zstream-                  (fromIntegral (fromEnum compLevel))-                  (fromIntegral (fromEnum method))-                  (fromIntegral (windowBits format bits))-                  (fromIntegral (fromEnum memLevel))-                  (fromIntegral (fromEnum strategy))+                  (fromCompressionLevel compLevel)+                  (fromMethod method)+                  (windowBits format bits)+                  (fromMemoryLevel memLevel)+                  (fromCompressionStrategy strategy)   failIfError err   getStreamState >>= unsafeLiftIO . addForeignPtrFinalizer c_deflateEnd  inflate_ :: Flush -> Stream Status inflate_ flush = do   err <- withStreamState $ \zstream ->-    c_inflate zstream (fromIntegral (fromEnum flush))+    c_inflate zstream (fromFlush flush)   failIfError err-  return (toEnum (fromIntegral err))+  return (toStatus err)  deflate_ :: Flush -> Stream Status deflate_ flush = do   err <- withStreamState $ \zstream ->-    c_deflate zstream (fromIntegral (fromEnum flush))+    c_deflate zstream (fromFlush flush)   failIfError err-  return (toEnum (fromIntegral err))+  return (toStatus err)  -- | This never needs to be used as the stream's resources will be released -- automatically when no longer needed, however this can be used to release@@ -597,6 +657,18 @@ finalise :: Stream () finalise = getStreamState >>= unsafeLiftIO . finalizeForeignPtr +checkFormatSupported :: Format -> Stream ()+checkFormatSupported format = do+  version <- unsafeLiftIO (peekCAString =<< c_zlibVersion)+  case version of+    ('1':'.':'1':'.':_)+       | format == GZip+      || format == GZipOrZlib+      -> fail $ "version 1.1.x of the zlib C library does not support the"+             ++ " 'gzip' format via the in-memory api, only the 'raw' and "+	     ++ " 'zlib' formats."+    _ -> return ()+ ---------------------- -- The foreign imports @@ -621,7 +693,7 @@  c_inflateInit2 :: StreamState -> CInt -> IO CInt c_inflateInit2 z n =-  withCString #{const_str ZLIB_VERSION} $ \versionStr ->+  withCAString #{const_str ZLIB_VERSION} $ \versionStr ->     c_inflateInit2_ z n versionStr (#{const sizeof(z_stream)} :: CInt)  foreign import ccall unsafe "zlib.h inflate"@@ -640,7 +712,7 @@ c_deflateInit2 :: StreamState                -> CInt -> CInt -> CInt -> CInt -> CInt -> IO CInt c_deflateInit2 z a b c d e =-  withCString #{const_str ZLIB_VERSION} $ \versionStr ->+  withCAString #{const_str ZLIB_VERSION} $ \versionStr ->     c_deflateInit2_ z a b c d e versionStr (#{const sizeof(z_stream)} :: CInt)  foreign import ccall unsafe "zlib.h deflate"@@ -648,3 +720,6 @@  foreign import ccall unsafe "zlib.h &deflateEnd"   c_deflateEnd :: FinalizerPtr StreamState++foreign import ccall unsafe "zlib.h zlibVersion"+  c_zlibVersion :: IO CString
zlib.cabal view
@@ -1,5 +1,5 @@ name:            zlib-version:         0.4.0.4+version:         0.5.0.0 copyright:       (c) 2006-2008 Duncan Coutts license:         BSD3 license-file:    LICENSE@@ -36,6 +36,7 @@                    Codec.Compression.Zlib.Internal   other-modules:   Codec.Compression.Zlib.Stream   extensions:      CPP, ForeignFunctionInterface+  build-depends: base < 5   if flag(bytestring-in-base)     -- bytestring was in base-2.0 and 2.1.1     build-depends: base >= 2.0 && < 2.2