summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2018-10-23 22:23:56 -0400
committerJoe Crayne <joe@jerkface.net>2018-10-23 22:23:56 -0400
commit94ab26f229bc59e8e917e0e67484b0b833fb0fa8 (patch)
tree6b108785d0112c8ce5b91da46efb5537ef117966
parentd62577cf423148a2a07eac33377003802e7e70d6 (diff)
withByteString (wrapper on withForeignPtr)
-rw-r--r--haskell/Data/XDelta.hsc49
1 files changed, 32 insertions, 17 deletions
diff --git a/haskell/Data/XDelta.hsc b/haskell/Data/XDelta.hsc
index 113959b..d276a8d 100644
--- a/haskell/Data/XDelta.hsc
+++ b/haskell/Data/XDelta.hsc
@@ -59,11 +59,15 @@ foreign import ccall "xdelta3.h xd3_abort_stream" xd3_abort_stream :: Ptr Xd3Str
59foreign import ccall "xdelta3.h xd3_close_stream" xd3_close_stream :: Ptr Xd3Stream -> IO ErrorCode 59foreign import ccall "xdelta3.h xd3_close_stream" xd3_close_stream :: Ptr Xd3Stream -> IO ErrorCode
60 60
61 61
62writeCompressorConfig :: PrimMonad m =>
63 MutableByteArray (PrimState m) -> Int -> CompressorConfig -> m ()
62writeCompressorConfig c o sec = do 64writeCompressorConfig c o sec = do
63 writeAtByte c (o + #{offset xd3_sec_cfg,ngroups}) (ngroups sec) 65 writeAtByte c (o + #{offset xd3_sec_cfg,ngroups}) (ngroups sec)
64 writeAtByte c (o + #{offset xd3_sec_cfg,sector_size}) (sector_size sec) 66 writeAtByte c (o + #{offset xd3_sec_cfg,sector_size}) (sector_size sec)
65 writeAtByte c (o + #{offset xd3_sec_cfg,inefficient}) (inefficient sec) 67 writeAtByte c (o + #{offset xd3_sec_cfg,inefficient}) (inefficient sec)
66 68
69writeMatcher :: PrimMonad m =>
70 MutableByteArray (PrimState m) -> Int -> StringMatcher -> m ()
67writeMatcher c o sm = do 71writeMatcher c o sm = do
68 -- handled elsewhere: const char *name; <- smName :: String 72 -- handled elsewhere: const char *name; <- smName :: String
69 writeAtByte c (o + #{offset xd3_smatcher, string_match }) (smStringMatch sm) 73 writeAtByte c (o + #{offset xd3_smatcher, string_match }) (smStringMatch sm)
@@ -75,7 +79,10 @@ writeMatcher c o sm = do
75 writeAtByte c (o + #{offset xd3_smatcher, max_lazy }) (smMaxLazy sm) 79 writeAtByte c (o + #{offset xd3_smatcher, max_lazy }) (smMaxLazy sm)
76 writeAtByte c (o + #{offset xd3_smatcher, long_enough }) (smLongEnough sm) 80 writeAtByte c (o + #{offset xd3_smatcher, long_enough }) (smLongEnough sm)
77 81
82ptr :: Addr -> Ptr a
78ptr (Addr a) = Ptr a 83ptr (Addr a) = Ptr a
84
85adr :: Ptr a -> Addr
79adr (Ptr a) = Addr a 86adr (Ptr a) = Addr a
80 87
81-- The xd3_config structure is used to initialize a stream - all data 88-- The xd3_config structure is used to initialize a stream - all data
@@ -134,12 +141,13 @@ config_stream cfg = do
134 XD3_SUCCESS -> return $ c `seq` Right stream 141 XD3_SUCCESS -> return $ c `seq` Right stream
135 ecode -> return $ Left ecode 142 ecode -> return $ Left ecode
136 143
144writeStringAt :: PrimMonad m => MutableByteArray s -> Int -> B.ByteString -> m (Ptr a)
137writeStringAt src o bsname = do 145writeStringAt src o bsname = do
138 (p,cnt) <- unsafeIOToPrim $ B.unsafeUseAsCStringLen bsname return 146 (p,cnt) <- unsafeIOToPrim $ B.unsafeUseAsCStringLen bsname return
139 let nptr = ptr (mutableByteArrayContents src) `plusPtr` o 147 let nptr = ptr (mutableByteArrayContents src) `plusPtr` o
140 copyAddr (adr nptr) (adr p) cnt 148 copyAddr (adr nptr) (adr p) cnt
141 writeOffAddr (adr nptr) cnt (0 :: Word8) 149 writeOffAddr (adr nptr) cnt (0 :: Word8)
142 return nptr 150 return nptr
143 151
144data Xd3Source 152data Xd3Source
145 153
@@ -222,8 +230,9 @@ foreign import ccall "xdelta3.h xd3_errstring" xd3_errstring :: Ptr Xd3Stream ->
222 230
223-- | Gives some extra information about the latest library error, if any 231-- | Gives some extra information about the latest library error, if any
224-- is known. 232-- is known.
225errorString stream = unsafeIOToPrim $ withForeignPtr (streamPtr stream) $ \stream -> do 233errorString :: PrimMonad m => Stream m -> m String
226 cstring <- xd3_errstring stream 234errorString stream = unsafeIOToPrim $ do
235 cstring <- xd3_errstring (ptr $ mutableByteArrayContents $ streamArray stream)
227 peekCString cstring 236 peekCString cstring
228 237
229pokeCurrentBlock :: PrimMonad m => Stream m -> CurrentBlock -> m () 238pokeCurrentBlock :: PrimMonad m => Stream m -> CurrentBlock -> m ()
@@ -235,20 +244,27 @@ pokeCurrentBlock stream (CurrentBlock no sz ptr) = do
235 writeAtByte src #{offset xd3_source, curblk} ptr 244 writeAtByte src #{offset xd3_source, curblk} ptr
236 245
237 246
247withByteString :: PrimBase m => B.ByteString -> (Ptr b -> Usize_t -> m a) -> m a
248withByteString d act =
249 let (fp,off,len) = B.toForeignPtr d
250 in unsafeIOToPrim $ withForeignPtr fp $ \ptr -> unsafePrimToIO $ do
251 act (ptr `plusPtr` off) (fromIntegral len)
252
238xdelta :: (PrimBase m, Monoid u) => XDeltaMethods m u -> (Stream m -> IO ErrorCode) -> [B.ByteString] 253xdelta :: (PrimBase m, Monoid u) => XDeltaMethods m u -> (Stream m -> IO ErrorCode) -> [B.ByteString]
239 -> m (Either ErrorCode u) 254 -> m u
240xdelta x xxcode_input ds = do 255xdelta x xxcode_input ds = do
241 mstream <- config_stream (xConfig x) 256 mstream <- config_stream (xConfig x)
242 forM mstream $ \stream -> do 257 either (\e _ -> xOnError x e "config_stream failed")
258 (flip ($))
259 mstream $ \stream -> do
243 set_source stream "xdelta" (xBlockSize x) (xBlockSize x) 260 set_source stream "xdelta" (xBlockSize x) (xBlockSize x)
244 let go withBlk (d:ds) = do 261 let go withBlk (d:ds) = do
245 let (fp,off,len) = B.toForeignPtr d 262 let (fp,off,len) = B.toForeignPtr d
246 eof = null ds 263 eof = null ds
247 when eof $ setFlush stream True 264 when eof $ setFlush stream True
248 unsafeIOToPrim $ withForeignPtr fp $ \indata0 -> do 265 withByteString d $ \indata len -> do
249 let indata = indata0 `plusPtr` off 266 avail_input stream indata len
250 avail_input stream indata (fromIntegral len) 267 go2 withBlk eof ds
251 unsafePrimToIO $ go2 withBlk eof ds
252 go2 withBlk eof ds = do 268 go2 withBlk eof ds = do
253 ret <- withBlk $ unsafeIOToPrim $ xxcode_input stream 269 ret <- withBlk $ unsafeIOToPrim $ xxcode_input stream
254 case ret of 270 case ret of
@@ -260,10 +276,9 @@ xdelta x xxcode_input ds = do
260 XD3_GETSRCBLK -> do 276 XD3_GETSRCBLK -> do
261 Just n <- requestedBlockNumber stream 277 Just n <- requestedBlockNumber stream
262 let blk = xGetSource x n 278 let blk = xGetSource x n
263 withBlk' act = let (fp,off,len) = B.toForeignPtr blk 279 withBlk' act = withByteString blk $ \p len -> do
264 in unsafeIOToPrim $ withForeignPtr fp $ \p -> unsafePrimToIO $ do 280 pokeCurrentBlock stream $ CurrentBlock n len p
265 pokeCurrentBlock stream $ CurrentBlock n (fromIntegral len) (plusPtr p off) 281 act
266 act
267 go2 withBlk' eof ds 282 go2 withBlk' eof ds
268 XD3_GOTHEADER -> go2 withBlk eof ds -- No 283 XD3_GOTHEADER -> go2 withBlk eof ds -- No
269 XD3_WINSTART -> go2 withBlk eof ds -- action 284 XD3_WINSTART -> go2 withBlk eof ds -- action