diff options
author | Joe Crayne <joe@jerkface.net> | 2019-03-31 21:23:57 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2019-03-31 21:23:57 -0400 |
commit | 86169b961457dfcf77af1400fcc4c95ee17886af (patch) | |
tree | ee7f69278c43ab2f22e9641e57c459be5e0991f3 | |
parent | 6001fb63aaa1cdce1c672a2cf8dfd83bf82e3ecc (diff) |
Provided instance to use ForeignPtr as a struct.
-rw-r--r-- | src/Data/Primitive/Struct.hs | 16 |
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 #-} | ||
11 | module Data.Primitive.Struct where | 12 | module Data.Primitive.Struct where |
12 | 13 | ||
13 | import Control.Monad.Primitive | 14 | import Control.Monad.Primitive |
@@ -16,6 +17,7 @@ import Data.Primitive.ByteArray.Util | |||
16 | import Data.Primitive.Types | 17 | import Data.Primitive.Types |
17 | import Data.Tagged | 18 | import Data.Tagged |
18 | import Data.Typeable | 19 | import Data.Typeable |
20 | import Foreign.ForeignPtr | ||
19 | import Foreign.Ptr | 21 | import Foreign.Ptr |
20 | import Foreign.Storable | 22 | import Foreign.Storable |
21 | import GHC.TypeLits | 23 | import GHC.TypeLits |
@@ -110,3 +112,17 @@ withPointer :: Struct IO base tag -> (Ptr tag -> IO x) -> IO x | |||
110 | withPointer (Struct (Offset off) ary) f = do | 112 | withPointer (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 | |||
116 | data ForeignStruct tag = ForeignStruct | ||
117 | { fsPtr :: !(ForeignPtr tag) | ||
118 | , fsOffset :: !Int | ||
119 | } | ||
120 | |||
121 | instance 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) | ||