packages feed

call-haskell-from-anything 1.0.1.0 → 1.1.0.0

raw patch · 3 files changed

+38/−21 lines, 3 filesdep +data-msgpackdep +storable-endiandep −msgpackdep −vectordep ~template-haskellPVP ok

version bump matches the API change (PVP)

Dependencies added: data-msgpack, storable-endian

Dependencies removed: msgpack, vector

Dependency ranges changed: template-haskell

API changes (from Hackage documentation)

- FFI.Anything.TypeUncurry.DataKinds: (:::) :: a -> TypeList l -> TypeList (a : l)
- FFI.Anything.TypeUncurry.DataKinds: Nil :: TypeList '[]
- FFI.Anything.TypeUncurry.Msgpack: instance (Data.MessagePack.Object.MessagePack a, FFI.Anything.TypeUncurry.Msgpack.MessagePackRec l) => FFI.Anything.TypeUncurry.Msgpack.MessagePackRec (a : l)
- FFI.Anything.TypeUncurry.Msgpack: instance (FFI.Anything.TypeUncurry.Msgpack.MessagePackRec l, FFI.Anything.TypeUncurry.DataKinds.ParamLength l) => Data.MessagePack.Object.MessagePack (FFI.Anything.TypeUncurry.DataKinds.TypeList l)
+ FFI.Anything.TypeUncurry.DataKinds: [:::] :: a -> TypeList l -> TypeList (a : l)
+ FFI.Anything.TypeUncurry.DataKinds: [Nil] :: TypeList '[]
+ FFI.Anything.TypeUncurry.Msgpack: instance (Data.MessagePack.Class.MessagePack a, FFI.Anything.TypeUncurry.Msgpack.MessagePackRec l) => FFI.Anything.TypeUncurry.Msgpack.MessagePackRec (a : l)
+ FFI.Anything.TypeUncurry.Msgpack: instance (FFI.Anything.TypeUncurry.Msgpack.MessagePackRec l, FFI.Anything.TypeUncurry.DataKinds.ParamLength l) => Data.MessagePack.Class.MessagePack (FFI.Anything.TypeUncurry.DataKinds.TypeList l)
- FFI.Anything.TypeUncurry.Msgpack: fromObjectRec :: MessagePackRec l => Vector Object -> Maybe (TypeList l)
+ FFI.Anything.TypeUncurry.Msgpack: fromObjectRec :: (MessagePackRec l, Monad m) => [Object] -> m (TypeList l)
- FFI.Anything.TypeUncurry.Msgpack: getTypeListFromMsgpackArray :: (MessagePackRec l, ParamLength l) => Object -> Maybe (TypeList l)
+ FFI.Anything.TypeUncurry.Msgpack: getTypeListFromMsgpackArray :: forall m l. (MessagePackRec l, ParamLength l, Monad m) => Object -> m (TypeList l)

Files

call-haskell-from-anything.cabal view
@@ -1,5 +1,5 @@ name:          call-haskell-from-anything-version:       1.0.1.0+version:       1.1.0.0 license:       MIT author:        Niklas Hambüchen (mail@nh2.me) maintainer:    Niklas Hambüchen (mail@nh2.me)@@ -11,7 +11,7 @@ synopsis:      Call Haskell functions from other languages via serialization and dynamic libraries description:   FFI via serialisation. See https://github.com/nh2/call-haskell-from-anything for details. stability:     experimental-tested-with:   GHC==7.10.3+tested-with:   GHC==8.0.2 cabal-version: >= 1.10 homepage:      https://github.com/nh2/call-haskell-from-anything bug-reports:   https://github.com/nh2/call-haskell-from-anything/issues@@ -39,10 +39,10 @@   build-depends:       base >= 4.8 && < 5     , bytestring >= 0.10.0.0-    , msgpack >= 1.0.0-    , template-haskell+    , data-msgpack >= 0.0.10+    , storable-endian >= 0.2.6+    , template-haskell >= 2.11.0     , mtl >= 2.1.2-    , vector   ghc-options:     -Wall -fwarn-unused-imports @@ -59,7 +59,7 @@     -- Packages that already have version bounds in the library:     , base     , bytestring-    , msgpack+    , data-msgpack     , mtl   ghc-options:     -- For building TemplateHaskell with cabal and -dynamic, we have to disable -dynamic sometimes
src/FFI/Anything/TH.hs view
@@ -32,7 +32,7 @@ deriveCallable funName exportedName = do   info <- reify funName   case info of-    VarI name typ _mDec _fixity -> do+    VarI name typ _mDec -> do       let _nameString   = nameBase name           signatureList = parameters typ           paramTypes    = init signatureList
src/FFI/Anything/TypeUncurry/Msgpack.hs view
@@ -32,12 +32,16 @@ import           Data.ByteString (ByteString) import qualified Data.ByteString as BS import qualified Data.ByteString.Lazy as BSL+import           Data.ByteString.Unsafe (unsafeUseAsCStringLen)+import           Data.Int (Int64) import           Data.Maybe (fromMaybe) import qualified Data.MessagePack as MSG import           Data.Proxy-import           Data.Vector (Vector)-import qualified Data.Vector as V+import           Data.Storable.Endian (peekBE, pokeBE) import           Foreign.C+import           Foreign.Marshal.Alloc (mallocBytes)+import           Foreign.Marshal.Utils (copyBytes)+import           Foreign.Ptr (castPtr, plusPtr)  import FFI.Anything.TypeUncurry @@ -47,23 +51,23 @@ -- We need this because we have to call 'parseArray' at the top-level -- 'MSG.MessagePack' instance, but not at each function argument step. class MessagePackRec l where-  fromObjectRec :: Vector MSG.Object -> Maybe (TypeList l)+  fromObjectRec :: (Monad m) => [MSG.Object] -> m (TypeList l)  -- | When no more types need to be unpacked, we are done. instance MessagePackRec '[] where-  fromObjectRec v | V.null v = Just Nil-  fromObjectRec _            = Nothing+  fromObjectRec v | null v = pure Nil+  fromObjectRec _          = fail "fromObjectRec: passed object is not expected []"  -- | Unpack one type by just parsing the next element. instance (MSG.MessagePack a, MessagePackRec l) => MessagePackRec (a ': l) where-  fromObjectRec v | not (V.null v) = (:::) <$> MSG.fromObject (V.head v) <*> fromObjectRec (V.tail v)-  fromObjectRec _                  = Nothing+  fromObjectRec (x:xs) = (:::) <$> MSG.fromObject x <*> fromObjectRec xs+  fromObjectRec _      = fail "fromObjectRec: passed object is not expected (x:xs)"  -- | Parses a tuple of arbitrary size ('TypeList's) from a MessagePack array.-getTypeListFromMsgpackArray :: forall l . (MessagePackRec l, ParamLength l) => MSG.Object -> Maybe (TypeList l)+getTypeListFromMsgpackArray :: forall m l . (MessagePackRec l, ParamLength l, Monad m) => MSG.Object -> m (TypeList l) getTypeListFromMsgpackArray obj = case obj of-    MSG.ObjectArray v | V.length v == len -> fromObjectRec v-    _                                     -> Nothing+    MSG.ObjectArray v | length v == len -> fromObjectRec v+    _                                   -> fail "getTypeListFromMsgpackArray: wrong object length"   where     len = paramLength (Proxy :: Proxy l) @@ -114,6 +118,17 @@   Just args -> Just $ BSL.toStrict . MSG.pack <$> (translate f $ args)  +-- | O(n). Makes a copy of the ByteString's contents into a malloc()ed area.+-- You need to free() the returned string when you're done with it.+byteStringToMallocedCStringWith64bitLength :: ByteString -> IO CString+byteStringToMallocedCStringWith64bitLength bs =+  unsafeUseAsCStringLen bs $ \(ptr, len) -> do+    targetPtr <- mallocBytes (8 + len)+    pokeBE (castPtr targetPtr) (fromIntegral len :: Int64)+    copyBytes (targetPtr `plusPtr` 8) ptr len+    return targetPtr++ -- * Exporting  -- TODO implement via byteStringToCStringFunIO?@@ -121,9 +136,10 @@ -- for use in the FFI. byteStringToCStringFun :: (ByteString -> ByteString) -> CString -> IO CString byteStringToCStringFun f cs = do-  cs_bs <- BS.packCString cs+  msgLength :: Int64 <- peekBE (castPtr cs)+  cs_bs <- BS.packCStringLen (cs `plusPtr` 8, fromIntegral msgLength)   let res_bs = f cs_bs-  res_cs <- BS.useAsCString res_bs return+  res_cs <- byteStringToMallocedCStringWith64bitLength res_bs   return res_cs  @@ -131,9 +147,10 @@ -- for use in the FFI. byteStringToCStringFunIO :: (ByteString -> IO ByteString) -> CString -> IO CString byteStringToCStringFunIO f cs = do-  cs_bs <- BS.packCString cs+  msgLength :: Int64 <- peekBE (castPtr cs)+  cs_bs <- BS.packCStringLen (cs `plusPtr` 8, fromIntegral msgLength)   res_bs <- f cs_bs-  res_cs <- BS.useAsCString res_bs return+  res_cs <- byteStringToMallocedCStringWith64bitLength res_bs   return res_cs