{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Cardano.Foreign (
SizedPtr (..),
allocaSized,
memcpySized,
memsetSized,
c_memcpy,
c_memset,
) where
import Control.Monad (void)
import Data.Proxy (Proxy (..))
import Data.Void (Void)
import Data.Word (Word8)
import Foreign.C.Types (CSize (..))
import Foreign.Marshal.Alloc (allocaBytes)
import Foreign.Ptr (Ptr)
import GHC.TypeLits
newtype SizedPtr (n :: Nat) = SizedPtr (Ptr Void)
allocaSized :: forall n b. KnownNat n => (SizedPtr n -> IO b) -> IO b
allocaSized :: forall (n :: Nat) b. KnownNat n => (SizedPtr n -> IO b) -> IO b
allocaSized SizedPtr n -> IO b
k = forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
size (SizedPtr n -> IO b
k forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat). Ptr Void -> SizedPtr n
SizedPtr)
where
size :: Int
size :: Int
size = forall a. Num a => Integer -> a
fromInteger (forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (forall {k} (t :: k). Proxy t
Proxy @n))
memcpySized :: forall n. KnownNat n => SizedPtr n -> SizedPtr n -> IO ()
memcpySized :: forall (n :: Nat). KnownNat n => SizedPtr n -> SizedPtr n -> IO ()
memcpySized (SizedPtr Ptr Void
dest) (SizedPtr Ptr Void
src) = forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall a. Ptr a -> Ptr a -> CSize -> IO (Ptr ())
c_memcpy Ptr Void
dest Ptr Void
src CSize
size)
where
size :: CSize
size :: CSize
size = forall a. Num a => Integer -> a
fromInteger (forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (forall {k} (t :: k). Proxy t
Proxy @n))
memsetSized :: forall n. KnownNat n => SizedPtr n -> Word8 -> IO ()
memsetSized :: forall (n :: Nat). KnownNat n => SizedPtr n -> Word8 -> IO ()
memsetSized (SizedPtr Ptr Void
s) Word8
c = forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall a. Ptr a -> Int -> CSize -> IO (Ptr ())
c_memset Ptr Void
s (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
c) CSize
size)
where
size :: CSize
size :: CSize
size = forall a. Num a => Integer -> a
fromInteger (forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (forall {k} (t :: k). Proxy t
Proxy @n))
foreign import ccall "memcpy"
c_memcpy :: Ptr a -> Ptr a -> CSize -> IO (Ptr ())
foreign import ccall "memset"
c_memset :: Ptr a -> Int -> CSize -> IO (Ptr ())