[Haskell-cafe] How to define Storable instance for data constructor with storable vectors
Sanket Agrawal
sanket.agrawal at gmail.com
Wed Dec 21 23:21:10 CET 2011
I am trying to write a union data structure which can store vectors - a
simplified definition of data structure is below:
---------------------
-- V is Data.Vector.Storable
data Elems = I {-# UNPACK #-} !GHC.Int.Int32
| S {-# UNPACK #-} !GHC.Int.Int32 {-# UNPACK #-} !(Ptr CChar)
| T {-# UNPACK #-} !(V.Vector Elems)
---------------------
What I can't figure out is how to store Vector elements when defining
Storable instance for Elems type - the main stumbling block is that my
approach requires defining a Storable instance of ForeignPtr. Snippets of
code below:
---------------------
instance Storable Elems where
sizeOf _ = ...
alignment _ = ...
{-# INLINE poke #-}
poke p x = case x of
...
T x -> do
poke (castPtr p :: Ptr Word8) 3 -- store a tag for data
constructor T. We will check it when doing peek
let (fp,_,n) = V.unsafeToForeignPtr x
poke (castPtr p1) n
poke (castPtr (p1 `plusPtr` 8)) fp
where p1 = (castPtr p :: Ptr Word8) `plusPtr` 1 -- get pointer to
start of the element. First byte is type of element
{-# INLINE peek #-}
peek p = do
let p1 = (castPtr p::Ptr Word8) `plusPtr` 1 -- get pointer to
start of the element. First byte is type of element
t <- peek (castPtr p::Ptr Word8)
case t of
.... -- handle all data constructors except T here
_ -> do
x <- peek (castPtr p1 :: Ptr Int)
y <- peek (castPtr (p1 `plusPtr` 8) :: Ptr (ForeignPtr
Elems))
return (T (V.unsafeFromForeignPtr y 0 x)) -- return
vector elements
---------------------
If I use above approach, I will need to define Storable instance of
ForeignPtr for Elems data type. Is it possible to define peek/poke
operations for storing vectors, using something other than ForeignPtr? I
prefer using ForeignPtr because it has finalizer associated with it. I
guess it might be possible to store Ptr through withForeignPtr, but then
how do you convert back from the Ptr to Vector in peek?
If storing the ForeignPtr is a cleaner approach, how would Storable
definition for ForeignPtr look like? GHC code for ForeignPtr seems to
export only ForeignPtr constructor.
I am aware above code is not portable (e.g., assumption that Int is 8
bytes). That is not really an issue because I am writing code for a very
specific platform. If there is a library defined somewhere which has
already dealt with similar issue, I will very much appreciate pointers.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20111221/e7b33d56/attachment.htm>
More information about the Haskell-Cafe
mailing list