summaryrefslogtreecommitdiff
path: root/src/Data/Primitive/ByteArray/Util.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Data/Primitive/ByteArray/Util.hs')
-rw-r--r--src/Data/Primitive/ByteArray/Util.hs71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/Data/Primitive/ByteArray/Util.hs b/src/Data/Primitive/ByteArray/Util.hs
new file mode 100644
index 0000000..83a2e7d
--- /dev/null
+++ b/src/Data/Primitive/ByteArray/Util.hs
@@ -0,0 +1,71 @@
1{-# LANGUAGE DataKinds #-}
2{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE KindSignatures #-}
5{-# LANGUAGE MagicHash #-}
6{-# LANGUAGE MultiParamTypeClasses #-}
7{-# LANGUAGE ScopedTypeVariables #-}
8{-# LANGUAGE TypeFamilies #-}
9{-# LANGUAGE TypeOperators #-}
10{-# LANGUAGE CPP #-}
11module Data.Primitive.ByteArray.Util where
12
13import GHC.Exts (Ptr(..))
14import GHC.TypeLits
15import Control.Monad.Primitive
16import qualified Data.ByteString as B
17import qualified Data.ByteString.Unsafe as B
18import Data.Primitive.Addr
19import Data.Primitive.Types
20import Data.Primitive.ByteArray
21import Data.Word
22import Foreign.Ptr
23
24newtype Offset (n :: Nat) = Offset Int
25
26offset :: KnownNat n => Offset n
27offset = let k = Offset $ fromIntegral $ natVal k in k
28
29(+.) :: Offset j -> Offset k -> Offset (j + k)
30Offset j +. Offset k = Offset (j + k)
31
32
33type family SizeOf a :: Nat
34
35class IsMultipleOf (n::Nat) (k::Nat)
36
37instance n ~ (q * k) => IsMultipleOf n k
38
39writeAtByte :: ( Prim a
40 , PrimMonad m
41#if __GLASGOW_HASKELL__ >= 802
42 , IsMultipleOf n (SizeOf a)
43#endif
44 ) => MutableByteArray (PrimState m) -> Offset n -> a -> m ()
45writeAtByte buf (Offset offset) a = writeByteArray buf (div offset $ (sizeOf a)) a
46{-# INLINE writeAtByte #-}
47
48readAtByte :: forall a m n.
49 ( Prim a
50 , PrimMonad m
51#if __GLASGOW_HASKELL__ >= 802
52 , IsMultipleOf n (SizeOf a)
53#endif
54 ) => MutableByteArray (PrimState m) -> Offset n -> m a
55readAtByte buf (Offset offset) = readByteArray buf (div offset $ (sizeOf (undefined :: a)))
56{-# INLINE readAtByte #-}
57
58writeStringAt :: PrimMonad m => MutableByteArray s -> Int -> B.ByteString -> m (Ptr a)
59writeStringAt src o bsname = do
60 (p,cnt) <- unsafeIOToPrim $ B.unsafeUseAsCStringLen bsname return
61 let nptr = ptr (mutableByteArrayContents src) `plusPtr` o
62 copyAddr (adr nptr) (adr p) cnt
63 writeOffAddr (adr nptr) cnt (0 :: Word8)
64 return nptr
65
66ptr :: Addr -> Ptr a
67ptr (Addr a) = Ptr a
68
69adr :: Ptr a -> Addr
70adr (Ptr a) = Addr a
71