streaming-commons 0.1.10.0 → 0.1.11
raw patch · 4 files changed
+56/−6 lines, 4 files
Files
- ChangeLog.md +4/−0
- Data/Streaming/Zlib.hs +30/−5
- streaming-commons.cabal +1/−1
- test/Data/Streaming/ZlibSpec.hs +21/−0
ChangeLog.md view
@@ -1,3 +1,7 @@+## 0.1.11++* `getUnusedInflated`: Return uncompressed data following compressed data [#20](https://github.com/fpco/streaming-commons/issues/20)+ ## 0.1.10 Support blaze-builder >= 0.4. Add `newByteStringBuilderRecv` to Data.Streaming.ByteString.Builder; add modules Data.Streaming.ByteString.Builder.Buffer and Data.Streaming.ByteString.Builder.Class.
Data/Streaming/Zlib.hs view
@@ -26,6 +26,7 @@ , feedInflate , finishInflate , flushInflate+ , getUnusedInflate -- * Deflate , Deflate , initDeflate@@ -51,13 +52,17 @@ import Data.ByteString.Lazy.Internal (defaultChunkSize) import Data.Typeable (Typeable) import Control.Exception (Exception)+import Data.IORef type ZStreamPair = (ForeignPtr ZStreamStruct, ForeignPtr CChar) -- | The state of an inflation (eg, decompression) process. All allocated -- memory is automatically reclaimed by the garbage collector. -- Also can contain the inflation dictionary that is used for decompression.-newtype Inflate = Inflate (ZStreamPair, Maybe S.ByteString)+data Inflate = Inflate+ ZStreamPair+ (IORef S.ByteString) -- last ByteString fed in, needed for getUnusedInflate+ (Maybe S.ByteString) -- dictionary -- | The state of a deflation (eg, compression) process. All allocated memory -- is automatically reclaimed by the garbage collector.@@ -107,7 +112,8 @@ fbuff <- mallocForeignPtrBytes defaultChunkSize withForeignPtr fbuff $ \buff -> c_set_avail_out zstr buff $ fromIntegral defaultChunkSize- return $ Inflate ((fzstr, fbuff), Nothing)+ lastBS <- newIORef S.empty+ return $ Inflate (fzstr, fbuff) lastBS Nothing -- | Initialize an inflation process with the given 'WindowBits'. -- Unlike initInflate a dictionary for inflation is set which must@@ -121,7 +127,8 @@ withForeignPtr fbuff $ \buff -> c_set_avail_out zstr buff $ fromIntegral defaultChunkSize- return $ Inflate ((fzstr, fbuff), Just bs)+ lastBS <- newIORef S.empty+ return $ Inflate (fzstr, fbuff) lastBS (Just bs) -- | Initialize a deflation process with the given compression level and -- 'WindowBits'. You will need to call 'feedDeflate' to feed uncompressed@@ -171,7 +178,14 @@ :: Inflate -> S.ByteString -> IO Popper-feedInflate (Inflate ((fzstr, fbuff), inflateDictionary)) bs = do+feedInflate (Inflate (fzstr, fbuff) lastBS inflateDictionary) bs = do+ -- Write the BS to lastBS for use by getUnusedInflate. This is+ -- theoretically unnecessary, since we could just grab the pointer from the+ -- fzstr when needed. However, in that case, we wouldn't be holding onto a+ -- reference to the ForeignPtr, so the GC may decide to collect the+ -- ByteString in the interim.+ writeIORef lastBS bs+ withForeignPtr fzstr $ \zstr -> unsafeUseAsCStringLen bs $ \(cstr, len) -> c_set_avail_in zstr cstr $ fromIntegral len@@ -229,7 +243,7 @@ -- data, you will likely have some data still sitting in the buffer. This -- function will return it to you. finishInflate :: Inflate -> IO S.ByteString-finishInflate (Inflate ((fzstr, fbuff), _)) =+finishInflate (Inflate (fzstr, fbuff) _ _) = withForeignPtr fzstr $ \zstr -> withForeignPtr fbuff $ \buff -> do avail <- c_get_avail_out zstr@@ -246,6 +260,17 @@ -- Since 0.0.3 flushInflate :: Inflate -> IO S.ByteString flushInflate = finishInflate++-- | Retrieve any data remaining after inflating. For more information on motivation, see:+--+-- <https://github.com/fpco/streaming-commons/issues/20>+--+-- Since 0.1.11+getUnusedInflate :: Inflate -> IO S.ByteString+getUnusedInflate (Inflate (fzstr, _) ref _) = do+ bs <- readIORef ref+ len <- withForeignPtr fzstr c_get_avail_in+ return $ S.drop (S.length bs - fromIntegral len) bs -- | Feed the given 'S.ByteString' to the deflater. Return a 'Popper', -- an IO action that returns the compressed data a chunk at a time.
streaming-commons.cabal view
@@ -1,5 +1,5 @@ name: streaming-commons-version: 0.1.10.0+version: 0.1.11 synopsis: Common lower-level functions needed by various streaming data libraries description: Provides low-dependency functionality commonly needed by various streaming data libraries, such as conduit and pipes. homepage: https://github.com/fpco/streaming-commons
test/Data/Streaming/ZlibSpec.hs view
@@ -6,6 +6,7 @@ import Test.Hspec.QuickCheck (prop) import Test.QuickCheck (Arbitrary (..)) +import Control.Exception (throwIO) import Data.Streaming.Zlib import Codec.Compression.Zlib import qualified Codec.Compression.GZip as Gzip@@ -218,6 +219,26 @@ output <- decompressRaw $ Raw.compress input L.all (== 10) output `shouldBe` True L.length output `shouldBe` L.length input++ it "getUnusedInflate" $ do+ let c = "This data is stored compressed."+ u = "This data isn't."+ def <- initDeflate 5 defaultWindowBits+ let loop front popper = do+ res <- popper+ case res of+ PRDone -> return front+ PRNext bs -> loop (S.append front bs) popper+ PRError e -> throwIO e++ c' <- feedDeflate def c >>= loop S.empty >>= flip loop (finishDeflate def)++ inf <- initInflate defaultWindowBits+ x <- feedInflate inf (S.append c' u) >>= loop S.empty+ y <- finishInflate inf+ S.append x y `shouldBe` c+ z <- getUnusedInflate inf+ z `shouldBe` u rawWindowBits :: WindowBits rawWindowBits = WindowBits (-15)