cinvoke-0.1: Foreign/CInvoke/Types.hs
{- | Arguments and return types.
Note that functions for 'Int' and 'Word' are not provided here, as Haskell merely defines that
'Int' is a \"fixed-precision integer type with at least the range [-2^29 .. 2^29-1]\",
and 'Word' is an \"unsigned integral type, with the same size as 'Int'\".
(As both types are instances of 'Storable', the user may easily define them himself when determined useful.)
Note also that on e.g. Linux x86_64, 'Int' \/= 'CInt'.
-}
module Foreign.CInvoke.Types (
-- * Arguments
-- ** Integral types
argCShort,
argCUShort,
argCInt,
argCUInt,
argCLong,
argCULong,
argCLLong,
argCULLong,
argInt8,
argInt16,
argInt32,
argInt64,
argWord8,
argWord16,
argWord32,
argWord64,
-- ** Floating point types
argCFloat,
argCDouble,
-- ** Various other C types
argCSize,
argCTime,
argCChar,
argCSChar,
argCUChar,
argCWchar,
argPtr,
argFunPtr,
-- ** Strings
argString,
argByteString,
argConstByteString,
-- * Return types
-- ** Integral types
retVoid,
retCShort,
retCUShort,
retCInt,
retCUInt,
retCLong,
retCULong,
retCLLong,
retCULLong,
retInt8,
retInt16,
retInt32,
retInt64,
retWord8,
retWord16,
retWord32,
retWord64,
-- ** Floating point types
retCFloat,
retCDouble,
-- ** Various other C types
retCSize,
retCTime,
retCChar,
retCSChar,
retCUChar,
retCWchar,
retPtr,
retFunPtr,
-- ** Strings
retCString,
retString,
retByteString,
retMallocByteString
) where
import Control.Monad
import Data.List
import Data.Char
import Data.Int
import Data.Word
import Foreign.C.Types
import Foreign.Ptr
import Foreign.Storable
import Foreign.C.String
import Foreign.Marshal
import qualified Data.ByteString as BS
import qualified Data.ByteString.Unsafe as BSU
import Foreign.CInvoke.Base
argCShort = mkStorableArg :: CShort -> Arg
argCUShort = mkStorableArg :: CUShort -> Arg
argCInt = mkStorableArg :: CInt -> Arg
argCUInt = mkStorableArg :: CUInt -> Arg
argCLong = mkStorableArg :: CLong -> Arg
argCULong = mkStorableArg :: CULong -> Arg
argCLLong = mkStorableArg :: CLLong -> Arg
argCULLong = mkStorableArg :: CULLong -> Arg
argInt8 = mkStorableArg :: Int8 -> Arg
argInt16 = mkStorableArg :: Int16 -> Arg
argInt32 = mkStorableArg :: Int32 -> Arg
argInt64 = mkStorableArg :: Int64 -> Arg
argWord8 = mkStorableArg :: Word8 -> Arg
argWord16 = mkStorableArg :: Word16 -> Arg
argWord32 = mkStorableArg :: Word32 -> Arg
argWord64 = mkStorableArg :: Word64 -> Arg
argCFloat = mkStorableArg :: CFloat -> Arg
argCDouble = mkStorableArg :: CDouble -> Arg
argCSize = mkStorableArg :: CSize -> Arg
argCTime = mkStorableArg :: CTime -> Arg
argCChar = mkStorableArg :: CChar -> Arg
argCSChar = mkStorableArg :: CSChar -> Arg
argCUChar = mkStorableArg :: CUChar -> Arg
argCWchar = mkStorableArg :: CWchar -> Arg
argPtr = mkStorableArg :: Ptr a -> Arg
argFunPtr = mkStorableArg :: FunPtr a -> Arg
{- | 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 = mkPointerArg newCString free
-- | Like 'argString', but for 'ByteString''s.
argByteString :: BS.ByteString -> Arg
argByteString = mkPointerArg (flip BS.useAsCString return) (const $ return ())
-- | Like 'argByteString', but changing the string from C breaks referential transparency.
argConstByteString :: BS.ByteString -> Arg
argConstByteString = mkPointerArg (flip BSU.unsafeUseAsCString return) (const $ return ())
retVoid :: RetType ()
retVoid = RetType (\write -> write 0 nullPtr >> return ())
retCShort = mkStorableRetType :: RetType CShort
retCUShort = mkStorableRetType :: RetType CUShort
retCInt = mkStorableRetType :: RetType CInt
retCUInt = mkStorableRetType :: RetType CUInt
retCLong = mkStorableRetType :: RetType CLong
retCULong = mkStorableRetType :: RetType CULong
retCLLong = mkStorableRetType :: RetType CLLong
retCULLong = mkStorableRetType :: RetType CULLong
retInt8 = mkStorableRetType :: RetType Int8
retInt16 = mkStorableRetType :: RetType Int16
retInt32 = mkStorableRetType :: RetType Int32
retInt64 = mkStorableRetType :: RetType Int64
retWord8 = mkStorableRetType :: RetType Word8
retWord16 = mkStorableRetType :: RetType Word16
retWord32 = mkStorableRetType :: RetType Word32
retWord64 = mkStorableRetType :: RetType Word64
retCFloat = mkStorableRetType :: RetType CFloat
retCDouble = mkStorableRetType :: RetType CDouble
retCSize = mkStorableRetType :: RetType CSize
retCTime = mkStorableRetType :: RetType CTime
retCChar = mkStorableRetType :: RetType CChar
retCSChar = mkStorableRetType :: RetType CSChar
retCUChar = mkStorableRetType :: RetType CUChar
retCWchar = mkStorableRetType :: RetType CWchar
retFunPtr :: RetType a -> RetType (FunPtr a)
retFunPtr _ = mkStorableRetType
retPtr :: RetType a -> RetType (Ptr a)
retPtr _ = mkStorableRetType
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)