-- | Arguments and return types module Foreign.LibFFI.Types ( -- * Arguments -- ** Integral types argCInt, argCUInt, argCLong, argCULong, argInt, argInt8, argInt16, argInt32, argInt64, argWord, argWord8, argWord16, argWord32, argWord64, -- ** Floating point types argCFloat, argCDouble, -- ** Various other C types argCSize, argCTime, argCChar, argCUChar, argCWchar, argPtr, argFunPtr, -- ** Strings argString, argByteString, argConstByteString, -- * Return types -- ** Integral types retVoid, retCInt, retCUInt, retCLong, retCULong, retInt, retInt8, retInt16, retInt32, retInt64, retWord, retWord8, retWord16, retWord32, retWord64, -- ** Floating point types retCFloat, retCDouble, -- ** Various other C types retCSize, retCTime, retCChar, retCUChar, retCWchar, retPtr, retFunPtr, -- ** Strings retCString, retString, retByteString, retMallocByteString ) where import Data.Int import Data.Word import qualified Data.ByteString as BS import qualified Data.ByteString.Unsafe as BSU import Foreign.C.String import Foreign.C.Types import Foreign.Marshal import Foreign.Ptr import Foreign.LibFFI.Base import Foreign.LibFFI.FFITypes argCInt :: CInt -> Arg argCInt = mkStorableArg ffi_type_sint argCUInt :: CUInt -> Arg argCUInt = mkStorableArg ffi_type_uint argCLong :: CLong -> Arg argCLong = mkStorableArg ffi_type_slong argCULong :: CULong -> Arg argCULong = mkStorableArg ffi_type_ulong -- | Note that on e.g. x86_64, Int \/= CInt argInt :: Int -> Arg argInt = mkStorableArg ffi_type_hs_int argInt8 :: Int8 -> Arg argInt8 = mkStorableArg ffi_type_sint8 argInt16 :: Int16 -> Arg argInt16 = mkStorableArg ffi_type_sint16 argInt32 :: Int32 -> Arg argInt32 = mkStorableArg ffi_type_sint32 argInt64 :: Int64 -> Arg argInt64 = mkStorableArg ffi_type_sint64 argWord :: Word -> Arg argWord = mkStorableArg ffi_type_hs_word argWord8 :: Word8 -> Arg argWord8 = mkStorableArg ffi_type_uint8 argWord16 :: Word16 -> Arg argWord16 = mkStorableArg ffi_type_uint16 argWord32 :: Word32 -> Arg argWord32 = mkStorableArg ffi_type_uint32 argWord64 :: Word64 -> Arg argWord64 = mkStorableArg ffi_type_uint64 argCFloat :: CFloat -> Arg argCFloat = mkStorableArg ffi_type_float argCDouble :: CDouble -> Arg argCDouble = mkStorableArg ffi_type_double argCSize :: CSize -> Arg argCSize = mkStorableArg ffi_type_size argCTime :: CTime -> Arg argCTime = mkStorableArg ffi_type_size argCChar :: CChar -> Arg argCChar = mkStorableArg ffi_type_schar argCUChar :: CUChar -> Arg argCUChar = mkStorableArg ffi_type_uchar argCWchar :: CWchar -> Arg argCWchar = mkStorableArg ffi_type_schar argPtr :: Ptr a -> Arg argPtr = mkStorableArg ffi_type_pointer argFunPtr :: FunPtr a -> Arg argFunPtr = mkStorableArg ffi_type_pointer {- | The string argument is passed to C as a char * pointer, which is freed afterwards. The argument should not contain zero-bytes. -} argString :: String -> Arg argString = customPointerArg newCString free -- | Like argString, but for ByteString's. argByteString :: BS.ByteString -> Arg argByteString = customPointerArg (flip BS.useAsCString return) (const $ return ()) -- | Like argByteString, but changing the string from C breaks referential transparency. argConstByteString :: BS.ByteString -> Arg argConstByteString = customPointerArg (flip BSU.unsafeUseAsCString return) (const $ return ()) retVoid :: RetType () retVoid = RetType ffi_type_void (\write -> write nullPtr >> return ()) retCInt :: RetType CInt retCInt = mkStorableRetType ffi_type_sint retCUInt :: RetType CUInt retCUInt = mkStorableRetType ffi_type_uint retCLong :: RetType CLong retCLong = mkStorableRetType ffi_type_slong retCULong :: RetType CULong retCULong = mkStorableRetType ffi_type_ulong retInt :: RetType Int retInt = mkStorableRetType ffi_type_hs_int retInt8 :: RetType Int8 retInt8 = mkStorableRetType ffi_type_sint8 retInt16 :: RetType Int16 retInt16 = mkStorableRetType ffi_type_sint16 retInt32 :: RetType Int32 retInt32 = mkStorableRetType ffi_type_sint32 retInt64 :: RetType Int64 retInt64 = mkStorableRetType ffi_type_sint64 retWord :: RetType Word retWord = mkStorableRetType ffi_type_hs_word retWord8 :: RetType Word8 retWord8 = mkStorableRetType ffi_type_uint8 retWord16 :: RetType Word16 retWord16 = mkStorableRetType ffi_type_uint16 retWord32 :: RetType Word32 retWord32 = mkStorableRetType ffi_type_uint32 retWord64 :: RetType Word64 retWord64 = mkStorableRetType ffi_type_uint64 retCFloat :: RetType CFloat retCFloat = mkStorableRetType ffi_type_float retCDouble :: RetType CDouble retCDouble = mkStorableRetType ffi_type_double retCSize :: RetType CSize retCSize = mkStorableRetType ffi_type_size retCTime :: RetType CTime retCTime = mkStorableRetType ffi_type_time retCChar :: RetType CChar retCChar = mkStorableRetType ffi_type_schar retCUChar :: RetType CUChar retCUChar = mkStorableRetType ffi_type_uchar retCWchar :: RetType CWchar retCWchar = mkStorableRetType ffi_type_schar retFunPtr :: RetType a -> RetType (FunPtr a) retFunPtr _ = mkStorableRetType ffi_type_pointer retPtr :: RetType a -> RetType (Ptr a) retPtr _ = mkStorableRetType ffi_type_pointer retCString :: RetType CString retCString = retPtr retCChar {- | Peek a String out of the returned char *. The char * is not freed. -} retString :: RetType String retString = withRetType peekCString (retPtr retCChar) {- | Like retString, but for ByteString's -} retByteString :: RetType BS.ByteString retByteString = withRetType BS.packCString (retPtr retCChar) {- | Make a ByteString out of the returned char *. The char * will be free(3)ed when the ByteString is garbage collected. -} retMallocByteString :: RetType BS.ByteString retMallocByteString = withRetType BSU.unsafePackMallocCString (retPtr retCChar)