1 {-# OPTIONS -fno-implicit-prelude #-}
2 -----------------------------------------------------------------------------
4 -- Module : Foreign.Marshal.Utils
5 -- Copyright : (c) The FFI task force 2001
6 -- License : BSD-style (see the file libraries/core/LICENSE)
8 -- Maintainer : ffi@haskell.org
9 -- Stability : provisional
10 -- Portability : portable
12 -- $Id: Utils.hs,v 1.4 2002/04/24 16:31:44 simonmar Exp $
14 -- Utilities for primitive marshaling
16 -----------------------------------------------------------------------------
18 module Foreign.Marshal.Utils (
20 -- combined allocation and marshalling
22 withObject, -- :: Storable a => a -> (Ptr a -> IO b) -> IO b
23 {- FIXME: should be `with' -}
24 new, -- :: Storable a => a -> IO (Ptr a)
26 -- marshalling of Boolean values (non-zero corresponds to `True')
28 fromBool, -- :: Num a => Bool -> a
29 toBool, -- :: Num a => a -> Bool
31 -- marshalling of Maybe values
33 maybeNew, -- :: ( a -> IO (Ptr a))
34 -- -> (Maybe a -> IO (Ptr a))
35 maybeWith, -- :: ( a -> (Ptr b -> IO c) -> IO c)
36 -- -> (Maybe a -> (Ptr b -> IO c) -> IO c)
37 maybePeek, -- :: (Ptr a -> IO b )
38 -- -> (Ptr a -> IO (Maybe b))
40 -- marshalling lists of storable objects
42 withMany, -- :: (a -> (b -> res) -> res) -> [a] -> ([b] -> res) -> res
44 -- Haskellish interface to memcpy and memmove
45 -- (argument order: destination, source)
47 copyBytes, -- :: Ptr a -> Ptr a -> Int -> IO ()
48 moveBytes -- :: Ptr a -> Ptr a -> Int -> IO ()
53 #ifdef __GLASGOW_HASKELL__
54 import Foreign.Ptr ( Ptr, nullPtr )
55 import GHC.Storable ( Storable(poke) )
56 import Foreign.C.TypesISO ( CSize )
57 import Foreign.Marshal.Alloc ( malloc, alloca )
59 import GHC.Real ( fromIntegral )
64 -- combined allocation and marshalling
65 -- -----------------------------------
67 -- allocate storage for a value and marshal it into this storage
69 new :: Storable a => a -> IO (Ptr a)
76 -- allocate temporary storage for a value and marshal it into this storage
78 -- * see the life time constraints imposed by `alloca'
80 {- FIXME: should be called `with' -}
81 withObject :: Storable a => a -> (Ptr a -> IO b) -> IO b
89 -- marshalling of Boolean values (non-zero corresponds to `True')
90 -- -----------------------------
92 -- convert a Haskell Boolean to its numeric representation
94 fromBool :: Num a => Bool -> a
98 -- convert a Boolean in numeric representation to a Haskell value
100 toBool :: Num a => a -> Bool
104 -- marshalling of Maybe values
105 -- ---------------------------
107 -- allocate storage and marshall a storable value wrapped into a `Maybe'
109 -- * the `nullPtr' is used to represent `Nothing'
111 maybeNew :: ( a -> IO (Ptr a))
112 -> (Maybe a -> IO (Ptr a))
113 maybeNew = maybe (return nullPtr)
115 -- converts a withXXX combinator into one marshalling a value wrapped into a
118 maybeWith :: ( a -> (Ptr b -> IO c) -> IO c)
119 -> (Maybe a -> (Ptr b -> IO c) -> IO c)
120 maybeWith = maybe ($ nullPtr)
122 -- convert a peek combinator into a one returning `Nothing' if applied to a
125 maybePeek :: (Ptr a -> IO b) -> Ptr a -> IO (Maybe b)
126 maybePeek peek ptr | ptr == nullPtr = return Nothing
127 | otherwise = do a <- peek ptr; return (Just a)
130 -- marshalling lists of storable objects
131 -- -------------------------------------
133 -- replicates a withXXX combinator over a list of objects, yielding a list of
134 -- marshalled objects
136 withMany :: (a -> (b -> res) -> res) -- withXXX combinator for one object
137 -> [a] -- storable objects
138 -> ([b] -> res) -- action on list of marshalled obj.s
140 withMany _ [] f = f []
141 withMany withFoo (x:xs) f = withFoo x $ \x' ->
142 withMany withFoo xs (\xs' -> f (x':xs'))
145 -- Haskellish interface to memcpy and memmove
146 -- ------------------------------------------
148 -- copies the given number of bytes from the second area (source) into the
149 -- first (destination); the copied areas may *not* overlap
151 copyBytes :: Ptr a -> Ptr a -> Int -> IO ()
152 copyBytes dest src size = memcpy dest src (fromIntegral size)
154 -- copies the given number of elements from the second area (source) into the
155 -- first (destination); the copied areas *may* overlap
157 moveBytes :: Ptr a -> Ptr a -> Int -> IO ()
158 moveBytes dest src size = memmove dest src (fromIntegral size)
161 -- auxilliary routines
162 -- -------------------
164 -- basic C routines needed for memory copying
166 foreign import ccall unsafe memcpy :: Ptr a -> Ptr a -> CSize -> IO ()
167 foreign import ccall unsafe memmove :: Ptr a -> Ptr a -> CSize -> IO ()