module Foreign.C.Structs.Utils (
next, fmax, sizeof
) where
import Foreign.Storable (Storable, peek, sizeOf, alignment)
import Foreign.Marshal (alloca)
import Foreign.Ptr (Ptr, plusPtr, alignPtr)
sizeof :: [Int] -> [Int] -> Int
sizeof :: [Int] -> [Int] -> Int
sizeof as :: [Int]
as@(Int
_:[Int]
alignments) (Int
s:[Int]
sizes) = Int -> [Int] -> [Int] -> Int
sizeof' Int
s [Int]
alignments [Int]
sizes
where
sizeof' :: Int -> [Int] -> [Int] -> Int
sizeof' Int
s [] [] = Int
s Int -> Int -> Int
forall t. Integral t => t -> t -> t
`pad` [Int] -> Int
forall a. Integral a => [a] -> a
fmax [Int]
as
sizeof' Int
x (Int
a:[Int]
as) (Int
s:[Int]
ss) = let
s' :: Int
s' = Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
s
in Int -> [Int] -> [Int] -> Int
sizeof' (Int
s' Int -> Int -> Int
forall t. Integral t => t -> t -> t
`pad` Int
a) [Int]
as [Int]
ss
pad :: t -> t -> t
pad t
x t
a
| t
x t -> t -> t
forall t. Integral t => t -> t -> t
`mod` t
a t -> t -> Bool
forall a. Eq a => a -> a -> Bool
== t
0 = t
x
| Bool
otherwise = t -> t -> t
pad (t
xt -> t -> t
forall a. Num a => a -> a -> a
+t
1) t
a
next :: (Storable a, Storable b, Storable c) => Ptr a -> b -> IO (Ptr c)
next :: Ptr a -> b -> IO (Ptr c)
next Ptr a
ptr b
x = (Ptr c -> IO (Ptr c)) -> IO (Ptr c)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr c -> IO (Ptr c)) -> IO (Ptr c))
-> (Ptr c -> IO (Ptr c)) -> IO (Ptr c)
forall a b. (a -> b) -> a -> b
$ Ptr a -> b -> Ptr c -> IO (Ptr c)
forall a b c.
(Storable a, Storable b, Storable c) =>
Ptr a -> b -> Ptr c -> IO (Ptr c)
next' Ptr a
ptr b
x
where
next' :: (Storable a, Storable b, Storable c) => Ptr a -> b -> Ptr c -> IO (Ptr c)
next' :: Ptr a -> b -> Ptr c -> IO (Ptr c)
next' Ptr a
ptr b
x Ptr c
ptr_x = do
let ptr_y :: Ptr b
ptr_y = Ptr a -> Int -> Ptr b
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr a
ptr (Int -> Ptr b) -> Int -> Ptr b
forall a b. (a -> b) -> a -> b
$ b -> Int
forall a. Storable a => a -> Int
sizeOf b
x
c
y <- Ptr c -> IO c
forall a. Storable a => Ptr a -> IO a
peek Ptr c
ptr_x
Ptr c -> IO (Ptr c)
forall (m :: * -> *) a. Monad m => a -> m a
return (Ptr c -> IO (Ptr c)) -> Ptr c -> IO (Ptr c)
forall a b. (a -> b) -> a -> b
$ Ptr c -> Int -> Ptr c
forall a. Ptr a -> Int -> Ptr a
alignPtr Ptr c
forall b. Ptr b
ptr_y (Int -> Ptr c) -> Int -> Ptr c
forall a b. (a -> b) -> a -> b
$ c -> Int
forall a. Storable a => a -> Int
alignment c
y
fmax :: Integral a => [a] -> a
fmax :: [a] -> a
fmax = (a -> a -> a) -> a -> [a] -> a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> a -> a
forall a. Ord a => a -> a -> a
max a
0