From 062db545636881f694e6c0c1eaef1eb973da1b0d Mon Sep 17 00:00:00 2001 From: Joe Crayne Date: Sun, 28 Oct 2018 23:58:22 -0400 Subject: Send empty bytestrings as null pointer. --- haskell/Data/VCDIFF.hs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/haskell/Data/VCDIFF.hs b/haskell/Data/VCDIFF.hs index c48eb1a..6b95ede 100644 --- a/haskell/Data/VCDIFF.hs +++ b/haskell/Data/VCDIFF.hs @@ -47,7 +47,7 @@ import Data.Text.Encoding import Data.Word import Foreign.C.Types import Foreign.C.String -import Foreign.ForeignPtr (withForeignPtr) +import Foreign.ForeignPtr (withForeignPtr,touchForeignPtr) import Foreign.Ptr import Foreign.Concurrent import Foreign.Storable @@ -67,6 +67,9 @@ data Stream m = Stream , streamSource :: MutVar (PrimState m) (Maybe (Source m)) } +keepAlive srcvar s = do + seq srcvar $ seq s $ return () -- Keep array s alive until the ffi functions finish. +{-# NOINLINE keepAlive #-} -- The xd3_config structure is used to initialize a stream - all data -- is copied into stream so config may be a temporary variable. See @@ -84,7 +87,7 @@ config_stream cfg = do xd3_abort_stream sptr xd3_close_stream sptr xd3_free_stream sptr - seq srcvar $ seq s $ return () -- Keep array s alive until the ffi functions finish. + keepAlive srcvar s fp <- newForeignPtr sptr finalize return Stream { streamArray = s @@ -149,8 +152,12 @@ pokeCurrentBlock stream blk = do withByteString :: PrimBase m => B.ByteString -> (Ptr b -> Usize_t -> m a) -> m a withByteString d act = let (fp,off,len) = B.toForeignPtr d - in unsafeIOToPrim $ withForeignPtr fp $ \ptr -> unsafePrimToIO $ do - act (ptr `plusPtr` off) (fromIntegral len) + in do ptr <- unsafeIOToPrim $ withForeignPtr fp $ return + a <- case fromIntegral len of + 0 -> act nullPtr 0 + l -> act (ptr `plusPtr` off) l + unsafeIOToPrim $ touchForeignPtr fp + return a xdelta :: (PrimBase m, Monoid u) => XDeltaMethods m u -> (Stream m -> m ErrorCode) -> [B.ByteString] -> m u xdelta x xxcode_input ds = do -- cgit v1.2.3