1 % -----------------------------------------------------------------------------
2 % $Id: PrelMarshalUtils.lhs,v 1.3 2001/05/18 16:54:05 simonmar Exp $
4 % (c) The FFI task force, 2000
7 Utilities for primitive marshaling
10 {-# OPTIONS -fno-implicit-prelude #-}
12 module PrelMarshalUtils (
14 -- combined allocation and marshalling
16 withObject, -- :: Storable a => a -> (Ptr a -> IO b) -> IO b
17 {- FIXME: should be `with' -}
18 new, -- :: Storable a => a -> IO (Ptr a)
20 -- marshalling of Boolean values (non-zero corresponds to `True')
22 fromBool, -- :: Num a => Bool -> a
23 toBool, -- :: Num a => a -> Bool
25 -- marshalling of Maybe values
27 maybeNew, -- :: ( a -> IO (Ptr a))
28 -- -> (Maybe a -> IO (Ptr a))
29 maybeWith, -- :: ( a -> (Ptr b -> IO c) -> IO c)
30 -- -> (Maybe a -> (Ptr b -> IO c) -> IO c)
31 maybePeek, -- :: (Ptr a -> IO b )
32 -- -> (Ptr a -> IO (Maybe b))
34 -- marshalling lists of storable objects
36 withMany, -- :: (a -> (b -> res) -> res) -> [a] -> ([b] -> res) -> res
38 -- Haskellish interface to memcpy and memmove
39 -- (argument order: destination, source)
41 copyBytes, -- :: Ptr a -> Ptr a -> Int -> IO ()
42 moveBytes -- :: Ptr a -> Ptr a -> Int -> IO ()
45 #ifdef __GLASGOW_HASKELL__
46 import PrelPtr ( Ptr, nullPtr )
47 import PrelStorable ( Storable(poke,destruct) )
48 import PrelCTypesISO ( CSize )
49 import PrelMarshalAlloc ( malloc, alloca )
52 import PrelReal ( fromIntegral )
57 -- combined allocation and marshalling
58 -- -----------------------------------
60 -- allocate storage for a value and marshal it into this storage
62 new :: Storable a => a -> IO (Ptr a)
69 -- allocate temporary storage for a value and marshal it into this storage
71 -- * see the life time constraints imposed by `alloca'
73 {- FIXME: should be called `with' -}
74 withObject :: Storable a => a -> (Ptr a -> IO b) -> IO b
83 -- marshalling of Boolean values (non-zero corresponds to `True')
84 -- -----------------------------
86 -- convert a Haskell Boolean to its numeric representation
88 fromBool :: Num a => Bool -> a
92 -- convert a Boolean in numeric representation to a Haskell value
94 toBool :: Num a => a -> Bool
98 -- marshalling of Maybe values
99 -- ---------------------------
101 -- allocate storage and marshall a storable value wrapped into a `Maybe'
103 -- * the `nullPtr' is used to represent `Nothing'
105 maybeNew :: ( a -> IO (Ptr a))
106 -> (Maybe a -> IO (Ptr a))
107 maybeNew = maybe (return nullPtr)
109 -- converts a withXXX combinator into one marshalling a value wrapped into a
112 maybeWith :: ( a -> (Ptr b -> IO c) -> IO c)
113 -> (Maybe a -> (Ptr b -> IO c) -> IO c)
114 maybeWith = maybe ($ nullPtr)
116 -- convert a peek combinator into a one returning `Nothing' if applied to a
119 maybePeek :: (Ptr a -> IO b) -> Ptr a -> IO (Maybe b)
120 maybePeek peek ptr | ptr == nullPtr = return Nothing
121 | otherwise = do a <- peek ptr; return (Just a)
124 -- marshalling lists of storable objects
125 -- -------------------------------------
127 -- replicates a withXXX combinator over a list of objects, yielding a list of
128 -- marshalled objects
130 withMany :: (a -> (b -> res) -> res) -- withXXX combinator for one object
131 -> [a] -- storable objects
132 -> ([b] -> res) -- action on list of marshalled obj.s
134 withMany _ [] f = f []
135 withMany withFoo (x:xs) f = withFoo x $ \x' ->
136 withMany withFoo xs (\xs' -> f (x':xs'))
139 -- Haskellish interface to memcpy and memmove
140 -- ------------------------------------------
142 -- copies the given number of bytes from the second area (source) into the
143 -- first (destination); the copied areas may *not* overlap
145 copyBytes :: Ptr a -> Ptr a -> Int -> IO ()
146 copyBytes dest src size = memcpy dest src (fromIntegral size)
148 -- copies the given number of elements from the second area (source) into the
149 -- first (destination); the copied areas *may* overlap
151 moveBytes :: Ptr a -> Ptr a -> Int -> IO ()
152 moveBytes dest src size = memmove dest src (fromIntegral size)
155 -- auxilliary routines
156 -- -------------------
158 -- basic C routines needed for memory copying
160 foreign import unsafe memcpy :: Ptr a -> Ptr a -> CSize -> IO ()
161 foreign import unsafe memmove :: Ptr a -> Ptr a -> CSize -> IO ()