summaryrefslogtreecommitdiff
path: root/haskell/Data/Primitive/ByteArray/Util.hs
blob: 17762866455df9e3c414a8e497a5c98a530564d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
{-# LANGUAGE DataKinds             #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE KindSignatures        #-}
{-# LANGUAGE MagicHash             #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables   #-}
{-# LANGUAGE TypeFamilies          #-}
{-# LANGUAGE TypeOperators         #-}
module Data.Primitive.ByteArray.Util where

import GHC.TypeLits
import Control.Monad.Primitive
import Data.Primitive.Types
import Data.Primitive.ByteArray

newtype Offset (n :: Nat) = Offset Int

offset :: KnownNat n => Offset n
offset = let k = Offset $ fromIntegral $ natVal k in k

(+.) :: Offset j -> Offset k -> Offset (j + k)
Offset j +. Offset k = Offset (j + k)


type family SizeOf a :: Nat

class IsMultipleOf (n::Nat) (k::Nat)

instance n ~ (q * k) => IsMultipleOf n k

writeAtByte :: ( Prim a
               , PrimMonad m
               , IsMultipleOf n (SizeOf a)
               ) => MutableByteArray (PrimState m) -> Offset n -> a -> m ()
writeAtByte buf (Offset offset) a = writeByteArray buf (div offset $ (sizeOf a)) a
{-# INLINE writeAtByte #-}

readAtByte :: forall a m n.
               ( Prim a
               , PrimMonad m
               , IsMultipleOf n (SizeOf a)
               ) => MutableByteArray (PrimState m) -> Offset n -> m a
readAtByte buf (Offset offset) = readByteArray buf (div offset $ (sizeOf (undefined :: a)))
{-# INLINE readAtByte #-}