zlib 0.6.2.2 → 0.6.2.3
raw patch · 5 files changed
+148/−51 lines, 5 filesdep ~basedep ~bytestringdep ~tastynew-uploader
Dependency ranges changed: base, bytestring, tasty
Files
- Codec/Compression/Zlib/ByteStringCompat.hs +54/−0
- Codec/Compression/Zlib/Internal.hs +43/−42
- changelog +4/−0
- test/Test.hs +22/−1
- zlib.cabal +25/−8
+ Codec/Compression/Zlib/ByteStringCompat.hs view
@@ -0,0 +1,54 @@+-- Lifted from the text package, with light editing:+-- Data.Text.Internal.ByteStringCompat++{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE MagicHash #-}+module Codec.Compression.Zlib.ByteStringCompat (mkBS, withBS) where++import Data.ByteString.Internal (ByteString (..))+import Data.Word (Word8)+import Foreign.ForeignPtr (ForeignPtr)++#if MIN_VERSION_base(4,10,0)+import GHC.ForeignPtr (plusForeignPtr)+#else+import GHC.ForeignPtr (ForeignPtr(ForeignPtr))+import GHC.Types (Int (..))+import GHC.Prim (plusAddr#)+#endif++mkBS :: ForeignPtr Word8 -> Int -> Int -> ByteString+#if MIN_VERSION_bytestring(0,11,0)+mkBS dfp o n = BS (plusForeignPtr dfp o) n+#else+mkBS dfp o n = PS dfp o n+#endif+{-# INLINE mkBS #-}++withBS :: ByteString -> (ForeignPtr Word8 -> Int -> r) -> r+#if MIN_VERSION_bytestring(0,11,0)+withBS (BS !sfp !slen) kont = kont sfp slen+#else+withBS (PS !sfp !soff !slen) kont = kont (plusForeignPtr sfp soff) slen+#endif+{-# INLINE withBS #-}++#if !MIN_VERSION_base(4,10,0)+-- |Advances the given address by the given offset in bytes.+--+-- The new 'ForeignPtr' shares the finalizer of the original,+-- equivalent from a finalization standpoint to just creating another+-- reference to the original. That is, the finalizer will not be+-- called before the new 'ForeignPtr' is unreachable, nor will it be+-- called an additional time due to this call, and the finalizer will+-- be called with the same address that it would have had this call+-- not happened, *not* the new address.+plusForeignPtr :: ForeignPtr a -> Int -> ForeignPtr b+plusForeignPtr (ForeignPtr addr guts) (I# offset) = ForeignPtr (plusAddr# addr offset) guts+{-# INLINE [0] plusForeignPtr #-}+{-# RULES+"ByteString plusForeignPtr/0" forall fp .+ plusForeignPtr fp 0 = fp+ #-}+#endif
Codec/Compression/Zlib/Internal.hs view
@@ -92,6 +92,7 @@ import GHC.IO (noDuplicate) import qualified Codec.Compression.Zlib.Stream as Stream+import Codec.Compression.Zlib.ByteStringCompat (mkBS, withBS) import Codec.Compression.Zlib.Stream (Stream) -- | The full set of parameters for compression. The defaults are@@ -471,13 +472,12 @@ \chunk -> do Stream.deflateInit format compLevel method bits memLevel strategy setDictionary mdict- case chunk of- _ | S.null chunk ->- fillBuffers 20 --gzip header is 20 bytes, others even smaller-- S.PS inFPtr offset length -> do- Stream.pushInputBuffer inFPtr offset length- fillBuffers initChunkSize+ withBS chunk $ \inFPtr length ->+ if length == 0+ then fillBuffers 20 --gzip header is 20 bytes, others even smaller+ else do+ Stream.pushInputBuffer inFPtr 0 length+ fillBuffers initChunkSize where -- we flick between two states:@@ -507,11 +507,11 @@ Stream.pushOutputBuffer outFPtr 0 outChunkSize if inputBufferEmpty- then return $ CompressInputRequired $ \chunk ->- case chunk of- _ | S.null chunk -> drainBuffers True- S.PS inFPtr offset length -> do- Stream.pushInputBuffer inFPtr offset length+ then return $ CompressInputRequired $ flip withBS $ \inFPtr length ->+ if length == 0+ then drainBuffers True+ else do+ Stream.pushInputBuffer inFPtr 0 length drainBuffers False else drainBuffers False @@ -534,7 +534,7 @@ outputBufferFull <- Stream.outputBufferFull if outputBufferFull then do (outFPtr, offset, length) <- Stream.popOutputBuffer- let chunk = S.PS outFPtr offset length+ let chunk = mkBS outFPtr offset length return $ CompressOutputAvailable chunk $ do fillBuffers defaultCompressBufferSize else do fillBuffers defaultCompressBufferSize@@ -545,7 +545,7 @@ outputBufferBytesAvailable <- Stream.outputBufferBytesAvailable if outputBufferBytesAvailable > 0 then do (outFPtr, offset, length) <- Stream.popOutputBuffer- let chunk = S.PS outFPtr offset length+ let chunk = mkBS outFPtr offset length Stream.finalise return $ CompressOutputAvailable chunk (return CompressStreamEnd) else do Stream.finalise@@ -607,25 +607,25 @@ Stream.inflateReset else assert outputBufferFull $ Stream.inflateInit format bits- case chunk of- _ | S.null chunk -> do- -- special case to avoid demanding more input again- -- always an error anyway- when outputBufferFull $ do- let outChunkSize = 1- outFPtr <- Stream.unsafeLiftIO (S.mallocByteString outChunkSize)- Stream.pushOutputBuffer outFPtr 0 outChunkSize- drainBuffers True-- S.PS inFPtr offset length -> do- Stream.pushInputBuffer inFPtr offset length- -- Normally we start with no output buffer (so counts as full) but- -- if we're resuming then we'll usually still have output buffer- -- space available- assert (if not resume then outputBufferFull else True) $ return ()- if outputBufferFull- then fillBuffers initChunkSize- else drainBuffers False+ withBS chunk $ \inFPtr length ->+ if length == 0+ then do+ -- special case to avoid demanding more input again+ -- always an error anyway+ when outputBufferFull $ do+ let outChunkSize = 1+ outFPtr <- Stream.unsafeLiftIO (S.mallocByteString outChunkSize)+ Stream.pushOutputBuffer outFPtr 0 outChunkSize+ drainBuffers True+ else do+ Stream.pushInputBuffer inFPtr 0 length+ -- Normally we start with no output buffer (so counts as full) but+ -- if we're resuming then we'll usually still have output buffer+ -- space available+ assert (if not resume then outputBufferFull else True) $ return ()+ if outputBufferFull+ then fillBuffers initChunkSize+ else drainBuffers False where -- we flick between two states:@@ -657,11 +657,12 @@ if inputBufferEmpty then return $ DecompressInputRequired $ \chunk ->- case chunk of- _ | S.null chunk -> drainBuffers True- S.PS inFPtr offset length -> do- Stream.pushInputBuffer inFPtr offset length- drainBuffers False+ withBS chunk $ \inFPtr length ->+ if length == 0+ then drainBuffers True+ else do+ Stream.pushInputBuffer inFPtr 0 length+ drainBuffers False else drainBuffers False @@ -682,7 +683,7 @@ outputBufferFull <- Stream.outputBufferFull if outputBufferFull then do (outFPtr, offset, length) <- Stream.popOutputBuffer- let chunk = S.PS outFPtr offset length+ let chunk = mkBS outFPtr offset length return $ DecompressOutputAvailable chunk $ do fillBuffers defaultDecompressBufferSize else do fillBuffers defaultDecompressBufferSize@@ -695,7 +696,7 @@ if inputBufferEmpty then do finish (DecompressStreamEnd S.empty) else do (inFPtr, offset, length) <- Stream.popRemainingInputBuffer- let inchunk = S.PS inFPtr offset length+ let inchunk = mkBS inFPtr offset length finish (DecompressStreamEnd inchunk) Stream.Error code msg -> case code of@@ -714,7 +715,7 @@ outputBufferBytesAvailable <- Stream.outputBufferBytesAvailable if outputBufferBytesAvailable > 0 then do (outFPtr, offset, length) <- Stream.popOutputBuffer- return (DecompressOutputAvailable (S.PS outFPtr offset length) (return end))+ return (DecompressOutputAvailable (mkBS outFPtr offset length) (return end)) else return end setDictionary :: Stream.DictionaryHash -> Maybe S.ByteString@@ -902,7 +903,7 @@ tryFollowingStream :: S.ByteString -> Stream.State s -> ST s (DecompressStream (ST s))- tryFollowingStream chunk zstate = + tryFollowingStream chunk zstate = case S.length chunk of 0 -> return $ DecompressInputRequired $ \chunk' -> case S.length chunk' of 0 -> finaliseStreamEnd S.empty zstate
changelog view
@@ -1,5 +1,9 @@ See also http://pvp.haskell.org/faq +0.6.2.3 Emily Pillmore <emilypi@cohomolo.gy> February 2021++ * Add support for bytestring-0.11.0.0+ 0.6.2.2 Julian Ospald <hasufell@posteo.de> August 2020 * Bump bundled zlib to 1.2.11, fixes #26
test/Test.hs view
@@ -22,6 +22,9 @@ import qualified Data.ByteString.Char8 as BS.Char8 import qualified Data.ByteString.Lazy as BL import qualified Data.ByteString as BS+#if !MIN_VERSION_bytestring(0,11,0)+import qualified Data.ByteString.Internal as BS+#endif import System.IO #if !(MIN_VERSION_base(4,6,0)) import Prelude hiding (catch)@@ -38,7 +41,8 @@ testProperty "concatenated gzip members" prop_gzip_concat, testProperty "multiple gzip members, boundaries (all 2-chunks)" prop_multiple_members_boundary2, testProperty "multiple gzip members, boundaries (all 3-chunks)" prop_multiple_members_boundary3,- testProperty "prefixes of valid stream detected as truncated" prop_truncated+ testProperty "prefixes of valid stream detected as truncated" prop_truncated,+ testProperty "compress works with BSes with non-zero offset" prop_compress_nonzero_bs_offset ], testGroup "unit tests" [ testCase "simple gzip case" test_simple_gzip,@@ -135,6 +139,23 @@ (\err -> case err of TruncatedInput -> True; _ -> False) shortStrings = sized $ \sz -> resize (sz `div` 6) arbitrary++prop_compress_nonzero_bs_offset :: BS.ByteString+ -> Int+ -> Property+prop_compress_nonzero_bs_offset original to_drop =+ to_drop > 0 &&+ BS.length original > to_drop ==>+ let input = BS.drop to_drop original+#if MIN_VERSION_bytestring(0,11,0)+ dropped = to_drop+#else+ (BS.PS _ptr dropped _length) = input+#endif+ input' = BL.pack $ BS.unpack input -- BL.fromStrict is only available since bytestring-0.10.4.0+ compressed = compress gzipFormat defaultCompressParams input'+ decompressed = decompress gzipFormat defaultDecompressParams compressed+ in dropped == to_drop && decompressed == input' test_simple_gzip :: Assertion
zlib.cabal view
@@ -1,12 +1,12 @@ cabal-version: >= 1.10 name: zlib-version: 0.6.2.2+version: 0.6.2.3 copyright: (c) 2006-2016 Duncan Coutts license: BSD3 license-file: LICENSE author: Duncan Coutts <duncan@community.haskell.org>-maintainer: Duncan Coutts <duncan@community.haskell.org>+maintainer: Duncan Coutts <duncan@community.haskell.org>, Andrew Lelechenko <andrew.lelechenko@gmail.com>, Emily Pillmore <emilypi@cohomolo.gy>, Herbert Valerio Riedel <hvr@gnu.org> bug-reports: https://github.com/haskell/zlib/issues category: Codec synopsis: Compression and decompression in the gzip and zlib formats@@ -21,8 +21,20 @@ tasks and for the few cases where more control is needed it provides access to the full zlib feature set. build-type: Simple-tested-with: GHC ==7.0.4, GHC ==7.2.2, GHC ==7.4.2, GHC ==7.6.3, GHC ==7.8.4, GHC ==7.10.3, GHC ==8.0.1, GHC==8.0.2, GHC ==8.2.2, GHC ==8.4.4, GHC==8.6.5, GHC==8.8.3, GHC==8.10.1 +tested-with: GHC == 7.0.4+ , GHC == 7.2.2+ , GHC == 7.4.2+ , GHC == 7.6.3+ , GHC == 7.8.4+ , GHC == 7.10.3+ , GHC == 8.0.2+ , GHC == 8.2.2+ , GHC == 8.4.4+ , GHC == 8.6.5+ , GHC == 8.8.4+ , GHC == 8.10.3+ extra-source-files: changelog -- zlib C sources (for Windows) cbits/crc32.h cbits/inffast.h cbits/inflate.h@@ -63,22 +75,27 @@ Codec.Compression.Zlib, Codec.Compression.Zlib.Raw, Codec.Compression.Zlib.Internal- other-modules: Codec.Compression.Zlib.Stream+ other-modules: Codec.Compression.Zlib.Stream,+ Codec.Compression.Zlib.ByteStringCompat+ if impl(ghc < 7) default-language: Haskell98 default-extensions: PatternGuards else default-language: Haskell2010+ other-extensions: CPP, ForeignFunctionInterface, RankNTypes, BangPatterns, DeriveDataTypeable if impl(ghc >= 7.2) other-extensions: DeriveGeneric if impl(ghc >= 7.6) other-extensions: CApiFFI- build-depends: base >= 4 && < 4.15,- bytestring >= 0.9 && < 0.11- if impl(ghc >= 7.2 && < 7.6)++ build-depends: base >= 4 && < 4.16,+ bytestring >= 0.9 && < 0.12+ if impl(ghc >= 7.0 && < 8.0.3) build-depends: ghc-prim+ includes: zlib.h ghc-options: -Wall -fwarn-tabs if flag(non-blocking-ffi)@@ -111,7 +128,7 @@ default-language: Haskell2010 build-depends: base, bytestring, zlib, QuickCheck == 2.*,- tasty >= 0.8 && < 1.3,+ tasty >= 0.8 && < 1.5, tasty-quickcheck >= 0.8 && < 0.11, tasty-hunit >= 0.8 && < 0.11 ghc-options: -Wall