1 % -----------------------------------------------------------------------------
2 % $Id: PrelMarshalUtils.lhs,v 1.1 2001/01/11 17:25:57 simonmar Exp $
4 % (c) The FFI task force, 2000
7 Utilities for primitive marshaling
10 module PrelMarshalUtils (
12 -- combined allocation and marshalling
14 withObject, -- :: Storable a => a -> (Ptr a -> IO b) -> IO b
15 {- FIXME: should be `with' -}
16 new, -- :: Storable a => a -> IO (Ptr a)
18 -- marshalling of Boolean values (non-zero corresponds to `True')
20 fromBool, -- :: Num a => Bool -> a
21 toBool, -- :: Num a => a -> Bool
23 -- marshalling of Maybe values
25 maybeNew, -- :: ( a -> IO (Ptr a))
26 -- -> (Maybe a -> IO (Ptr a))
27 maybeWith, -- :: ( a -> (Ptr b -> IO c) -> IO c)
28 -- -> (Maybe a -> (Ptr b -> IO c) -> IO c)
29 maybePeek, -- :: (Ptr a -> IO b )
30 -- -> (Ptr a -> IO (Maybe b))
32 -- marshalling lists of storable objects
34 withMany, -- :: (a -> (b -> res) -> res) -> [a] -> ([b] -> res) -> res
36 -- Haskellish interface to memcpy and memmove
37 -- (argument order: destination, source)
39 copyBytes, -- :: Ptr a -> Ptr a -> Int -> IO ()
40 moveBytes -- :: Ptr a -> Ptr a -> Int -> IO ()
43 import Monad ( liftM )
45 import PrelPtr ( Ptr, nullPtr )
46 import PrelStorable ( Storable (poke) )
47 import PrelCTypesISO ( CSize )
48 import PrelMarshalAlloc ( malloc, alloca )
51 -- combined allocation and marshalling
52 -- -----------------------------------
54 -- allocate storage for a value and marshal it into this storage
56 new :: Storable a => a -> IO (Ptr a)
63 -- allocate temporary storage for a value and marshal it into this storage
65 -- * see the life time constraints imposed by `alloca'
67 {- FIXME: should be called `with' -}
68 withObject :: Storable a => a -> (Ptr a -> IO b) -> IO b
69 withObject val f = alloca $ \ptr -> do poke ptr val; f ptr
72 -- marshalling of Boolean values (non-zero corresponds to `True')
73 -- -----------------------------
75 -- convert a Haskell Boolean to its numeric representation
77 fromBool :: Num a => Bool -> a
81 -- convert a Boolean in numeric representation to a Haskell value
83 toBool :: Num a => a -> Bool
87 -- marshalling of Maybe values
88 -- ---------------------------
90 -- allocate storage and marshall a storable value wrapped into a `Maybe'
92 -- * the `nullPtr' is used to represent `Nothing'
94 maybeNew :: ( a -> IO (Ptr a))
95 -> (Maybe a -> IO (Ptr a))
96 maybeNew = maybe (return nullPtr)
98 -- converts a withXXX combinator into one marshalling a value wrapped into a
101 maybeWith :: ( a -> (Ptr b -> IO c) -> IO c)
102 -> (Maybe a -> (Ptr b -> IO c) -> IO c)
103 maybeWith = maybe ($ nullPtr)
105 -- convert a peek combinator into a one returning `Nothing' if applied to a
108 maybePeek :: (Ptr a -> IO b) -> Ptr a -> IO (Maybe b)
109 maybePeek peek ptr | ptr == nullPtr = return Nothing
110 | otherwise = liftM Just $ peek ptr
113 -- marshalling lists of storable objects
114 -- -------------------------------------
116 -- replicates a withXXX combinator over a list of objects, yielding a list of
117 -- marshalled objects
119 withMany :: (a -> (b -> res) -> res) -- withXXX combinator for one object
120 -> [a] -- storable objects
121 -> ([b] -> res) -- action on list of marshalled obj.s
123 withMany _ [] f = f []
124 withMany withFoo (x:xs) f = withFoo x $ \x' ->
125 withMany withFoo xs (\xs' -> f (x':xs'))
128 -- Haskellish interface to memcpy and memmove
129 -- ------------------------------------------
131 -- copies the given number of bytes from the second area (source) into the
132 -- first (destination); the copied areas may *not* overlap
134 copyBytes :: Ptr a -> Ptr a -> Int -> IO ()
135 copyBytes dest src size = memcpy dest src (fromIntegral size)
137 -- copies the given number of elements from the second area (source) into the
138 -- first (destination); the copied areas *may* overlap
140 moveBytes :: Ptr a -> Ptr a -> Int -> IO ()
141 moveBytes dest src size = memmove dest src (fromIntegral size)
144 -- auxilliary routines
145 -- -------------------
147 -- basic C routines needed for memory copying
149 foreign import unsafe memcpy :: Ptr a -> Ptr a -> CSize -> IO ()
150 foreign import unsafe memmove :: Ptr a -> Ptr a -> CSize -> IO ()