{-# language CPP #-}
module OpenXR.CStruct.Utils ( pokeFixedLengthByteString
, pokeFixedLengthNullTerminatedByteString
, peekByteStringFromSizedVectorPtr
, callocFixedArray
, lowerArrayPtr
, advancePtrBytes
, FixedArray
) where
import Foreign.Marshal.Alloc (callocBytes)
import Foreign.Marshal.Array (allocaArray)
import Foreign.Marshal.Utils (copyBytes)
import Foreign.Storable (peekElemOff)
import Foreign.Storable (pokeElemOff)
import Foreign.Storable (sizeOf)
import GHC.Ptr (castPtr)
import Foreign.Ptr (plusPtr)
import GHC.TypeNats (natVal)
import qualified Data.ByteString (length)
import Data.ByteString (packCString)
import Data.ByteString (packCStringLen)
import Data.ByteString (take)
import Data.ByteString (unpack)
import Data.ByteString.Unsafe (unsafeUseAsCString)
import Data.Vector (ifoldr)
import qualified Data.Vector (length)
import qualified Data.Vector.Generic ((++))
import qualified Data.Vector.Generic (empty)
import qualified Data.Vector.Generic (fromList)
import qualified Data.Vector.Generic (length)
import qualified Data.Vector.Generic (replicate)
import qualified Data.Vector.Generic (snoc)
import qualified Data.Vector.Generic (take)
import Data.Proxy (Proxy(..))
import Foreign.C.Types (CChar(..))
import Foreign.Storable (Storable)
import Foreign.Ptr (Ptr)
import GHC.TypeNats (type(<=))
import GHC.TypeNats (KnownNat)
import Data.Word (Word8)
import Data.ByteString (ByteString)
import GHC.TypeNats (Nat)
import Data.Kind (Type)
import Data.Vector (Vector)
import qualified Data.Vector.Generic (Vector)
data FixedArray (n :: Nat) (a :: Type)
pokeFixedLengthNullTerminatedByteString
:: forall n
. KnownNat n
=> Ptr (FixedArray n CChar)
-> ByteString
-> IO ()
pokeFixedLengthNullTerminatedByteString :: Ptr (FixedArray n CChar) -> ByteString -> IO ()
pokeFixedLengthNullTerminatedByteString to :: Ptr (FixedArray n CChar)
to bs :: ByteString
bs =
ByteString -> (CString -> IO ()) -> IO ()
forall a. ByteString -> (CString -> IO a) -> IO a
unsafeUseAsCString ByteString
bs ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \from :: CString
from -> do
let maxLength :: Int
maxLength = Natural -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy n -> Natural
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Natural
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n))
len :: Int
len = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
maxLength (ByteString -> Int
Data.ByteString.length ByteString
bs)
end :: Int
end = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (Int
maxLength Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1) Int
len
CString -> CString -> Int -> IO ()
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes (Ptr (FixedArray n CChar) -> CString
forall a (n :: Nat). Ptr (FixedArray n a) -> Ptr a
lowerArrayPtr Ptr (FixedArray n CChar)
to) CString
from Int
len
CString -> Int -> CChar -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff (Ptr (FixedArray n CChar) -> CString
forall a (n :: Nat). Ptr (FixedArray n a) -> Ptr a
lowerArrayPtr Ptr (FixedArray n CChar)
to) Int
end 0
pokeFixedLengthByteString
:: forall n
. KnownNat n
=> Ptr (FixedArray n Word8)
-> ByteString
-> IO ()
pokeFixedLengthByteString :: Ptr (FixedArray n Word8) -> ByteString -> IO ()
pokeFixedLengthByteString to :: Ptr (FixedArray n Word8)
to bs :: ByteString
bs = ByteString -> (CString -> IO ()) -> IO ()
forall a. ByteString -> (CString -> IO a) -> IO a
unsafeUseAsCString ByteString
bs ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \from :: CString
from -> do
let maxLength :: Int
maxLength = Natural -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy n -> Natural
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Natural
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n))
len :: Int
len = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
maxLength (ByteString -> Int
Data.ByteString.length ByteString
bs)
Ptr Word8 -> Ptr Word8 -> Int -> IO ()
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes (Ptr (FixedArray n Word8) -> Ptr Word8
forall a (n :: Nat). Ptr (FixedArray n a) -> Ptr a
lowerArrayPtr Ptr (FixedArray n Word8)
to) (CString -> Ptr Word8
forall a b. Ptr a -> Ptr b
castPtr @CChar @Word8 CString
from) Int
len
peekByteStringFromSizedVectorPtr
:: forall n
. KnownNat n
=> Ptr (FixedArray n Word8)
-> IO ByteString
peekByteStringFromSizedVectorPtr :: Ptr (FixedArray n Word8) -> IO ByteString
peekByteStringFromSizedVectorPtr p :: Ptr (FixedArray n Word8)
p = CStringLen -> IO ByteString
packCStringLen (Ptr (FixedArray n Word8) -> CString
forall a b. Ptr a -> Ptr b
castPtr Ptr (FixedArray n Word8)
p, Natural -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy n -> Natural
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Natural
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n)))
callocFixedArray
:: forall n a . (KnownNat n, Storable a) => IO (Ptr (FixedArray n a))
callocFixedArray :: IO (Ptr (FixedArray n a))
callocFixedArray = Int -> IO (Ptr (FixedArray n a))
forall a. Int -> IO (Ptr a)
callocBytes
( a -> Int
forall a. Storable a => a -> Int
sizeOf ([Char] -> a
forall a. HasCallStack => [Char] -> a
error "sizeOf evaluated its argument" :: a)
Int -> Int -> Int
forall a. Num a => a -> a -> a
* Natural -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy n -> Natural
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Natural
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n))
)
lowerArrayPtr
:: forall a n
. Ptr (FixedArray n a)
-> Ptr a
lowerArrayPtr :: Ptr (FixedArray n a) -> Ptr a
lowerArrayPtr = Ptr (FixedArray n a) -> Ptr a
forall a b. Ptr a -> Ptr b
castPtr
advancePtrBytes :: Ptr a -> Int -> Ptr a
advancePtrBytes :: Ptr a -> Int -> Ptr a
advancePtrBytes = Ptr a -> Int -> Ptr a
forall a b. Ptr a -> Int -> Ptr b
plusPtr