summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-03-31 21:23:57 -0400
committerJoe Crayne <joe@jerkface.net>2019-03-31 21:23:57 -0400
commit86169b961457dfcf77af1400fcc4c95ee17886af (patch)
treeee7f69278c43ab2f22e9641e57c459be5e0991f3
parent6001fb63aaa1cdce1c672a2cf8dfd83bf82e3ecc (diff)
Provided instance to use ForeignPtr as a struct.
-rw-r--r--src/Data/Primitive/Struct.hs16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/Data/Primitive/Struct.hs b/src/Data/Primitive/Struct.hs
index 154b750..705e65d 100644
--- a/src/Data/Primitive/Struct.hs
+++ b/src/Data/Primitive/Struct.hs
@@ -8,6 +8,7 @@
8{-# LANGUAGE TypeApplications #-} 8{-# LANGUAGE TypeApplications #-}
9{-# LANGUAGE TypeFamilies #-} 9{-# LANGUAGE TypeFamilies #-}
10{-# LANGUAGE TypeOperators #-} 10{-# LANGUAGE TypeOperators #-}
11{-# LANGUAGE UndecidableInstances #-}
11module Data.Primitive.Struct where 12module Data.Primitive.Struct where
12 13
13import Control.Monad.Primitive 14import Control.Monad.Primitive
@@ -16,6 +17,7 @@ import Data.Primitive.ByteArray.Util
16import Data.Primitive.Types 17import Data.Primitive.Types
17import Data.Tagged 18import Data.Tagged
18import Data.Typeable 19import Data.Typeable
20import Foreign.ForeignPtr
19import Foreign.Ptr 21import Foreign.Ptr
20import Foreign.Storable 22import Foreign.Storable
21import GHC.TypeLits 23import GHC.TypeLits
@@ -110,3 +112,17 @@ withPointer :: Struct IO base tag -> (Ptr tag -> IO x) -> IO x
110withPointer (Struct (Offset off) ary) f = do 112withPointer (Struct (Offset off) ary) f = do
111 x <- f (ptr (mutableByteArrayContents ary) `plusPtr` off) 113 x <- f (ptr (mutableByteArrayContents ary) `plusPtr` off)
112 seq ary $ return x 114 seq ary $ return x
115
116data ForeignStruct tag = ForeignStruct
117 { fsPtr :: !(ForeignPtr tag)
118 , fsOffset :: !Int
119 }
120
121instance IsStruct IO ForeignStruct where
122 type BaseOffset ForeignStruct = TypeError (Text "ForeignStruct has no type-level offset information.")
123 type NestedStruct IO ForeignStruct j t = ForeignStruct t
124 setField (ForeignStruct fptr base) (Field (Offset o)) val = withForeignPtr fptr $ \ptr -> do
125 poke (castPtr $ ptr `plusPtr` o `plusPtr` base) $ PrimStorable val
126 getField (ForeignStruct fptr base) (Field (Offset o)) = withForeignPtr fptr $ \ptr -> do
127 getPrimStorable <$> peek (castPtr $ ptr `plusPtr` o `plusPtr` base)
128 nestedField (ForeignStruct fptr base) (Field (Offset o)) _ = ForeignStruct (castForeignPtr fptr) (base + o)