{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Foreign.Marshal.Utils (
with,
new,
fromBool,
toBool,
maybeNew,
maybeWith,
maybePeek,
withMany,
copyBytes,
moveBytes,
) where
import Data.Maybe
import Foreign.Ptr ( Ptr, nullPtr )
import Foreign.Storable ( Storable(poke) )
import Foreign.C.Types ( CSize(..) )
import Foreign.Marshal.Alloc ( malloc, alloca )
import GHC.Real ( fromIntegral )
import GHC.Num
import GHC.Base
new :: Storable a => a -> IO (Ptr a)
new val =
do
ptr <- malloc
poke ptr val
return ptr
with :: Storable a => a -> (Ptr a -> IO b) -> IO b
with val f =
alloca $ \ptr -> do
poke ptr val
res <- f ptr
return res
fromBool :: Num a => Bool -> a
fromBool False = 0
fromBool True = 1
toBool :: (Eq a, Num a) => a -> Bool
toBool = (/= 0)
maybeNew :: ( a -> IO (Ptr b))
-> (Maybe a -> IO (Ptr b))
maybeNew = maybe (return nullPtr)
maybeWith :: ( a -> (Ptr b -> IO c) -> IO c)
-> (Maybe a -> (Ptr b -> IO c) -> IO c)
maybeWith = maybe ($ nullPtr)
maybePeek :: (Ptr a -> IO b) -> Ptr a -> IO (Maybe b)
maybePeek peek ptr | ptr == nullPtr = return Nothing
| otherwise = do a <- peek ptr; return (Just a)
withMany :: (a -> (b -> res) -> res)
-> [a]
-> ([b] -> res)
-> res
withMany _ [] f = f []
withMany withFoo (x:xs) f = withFoo x $ \x' ->
withMany withFoo xs (\xs' -> f (x':xs'))
copyBytes :: Ptr a -> Ptr a -> Int -> IO ()
copyBytes dest src size = do _ <- memcpy dest src (fromIntegral size)
return ()
moveBytes :: Ptr a -> Ptr a -> Int -> IO ()
moveBytes dest src size = do _ <- memmove dest src (fromIntegral size)
return ()
foreign import ccall unsafe "string.h" memcpy :: Ptr a -> Ptr a -> CSize -> IO (Ptr a)
foreign import ccall unsafe "string.h" memmove :: Ptr a -> Ptr a -> CSize -> IO (Ptr a)