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/base/LICENSE)
8 -- Maintainer : ffi@haskell.org
9 -- Stability : provisional
10 -- Portability : portable
12 -- Utilities for primitive marshaling
14 -----------------------------------------------------------------------------
16 module Foreign.Marshal.Utils (
17 -- * General marshalling utilities
19 -- ** Combined allocation and marshalling
21 withObject, -- :: Storable a => a -> (Ptr a -> IO b) -> IO b
22 {- FIXME: should be `with' -}
23 new, -- :: Storable a => a -> IO (Ptr a)
25 -- ** Marshalling of Boolean values (non-zero corresponds to 'True')
27 fromBool, -- :: Num a => Bool -> a
28 toBool, -- :: Num a => a -> Bool
30 -- ** Marshalling of Maybe values
32 maybeNew, -- :: ( a -> IO (Ptr a))
33 -- -> (Maybe a -> IO (Ptr a))
34 maybeWith, -- :: ( a -> (Ptr b -> IO c) -> IO c)
35 -- -> (Maybe a -> (Ptr b -> IO c) -> IO c)
36 maybePeek, -- :: (Ptr a -> IO b )
37 -- -> (Ptr a -> IO (Maybe b))
39 -- ** Marshalling lists of storable objects
41 withMany, -- :: (a -> (b -> res) -> res) -> [a] -> ([b] -> res) -> res
43 -- ** Haskellish interface to memcpy and memmove
45 -- | (argument order: destination, source)
46 copyBytes, -- :: Ptr a -> Ptr a -> Int -> IO ()
47 moveBytes -- :: Ptr a -> Ptr a -> Int -> IO ()
52 #ifdef __GLASGOW_HASKELL__
53 import Foreign.Ptr ( Ptr, nullPtr )
54 import GHC.Storable ( Storable(poke) )
55 import Foreign.C.TypesISO ( CSize )
56 import Foreign.Marshal.Alloc ( malloc, alloca )
58 import GHC.Real ( fromIntegral )
63 -- combined allocation and marshalling
64 -- -----------------------------------
66 -- |Allocate storage for a value and marshal it into this storage
68 new :: Storable a => a -> IO (Ptr a)
75 -- |Allocate temporary storage for a value and marshal it into this storage
77 -- * see the life time constraints imposed by 'alloca'
79 {- FIXME: should be called `with' -}
80 withObject :: Storable a => a -> (Ptr a -> IO b) -> IO b
88 -- marshalling of Boolean values (non-zero corresponds to 'True')
89 -- -----------------------------
91 -- |Convert a Haskell 'Bool' to its numeric representation
93 fromBool :: Num a => Bool -> a
97 -- |Convert a Boolean in numeric representation to a Haskell value
99 toBool :: Num a => a -> Bool
103 -- marshalling of Maybe values
104 -- ---------------------------
106 -- |Allocate storage and marshall a storable value wrapped into a 'Maybe'
108 -- * the 'nullPtr' is used to represent 'Nothing'
110 maybeNew :: ( a -> IO (Ptr a))
111 -> (Maybe a -> IO (Ptr a))
112 maybeNew = maybe (return nullPtr)
114 -- |Converts a @withXXX@ combinator into one marshalling a value wrapped into a
117 maybeWith :: ( a -> (Ptr b -> IO c) -> IO c)
118 -> (Maybe a -> (Ptr b -> IO c) -> IO c)
119 maybeWith = maybe ($ nullPtr)
121 -- |Convert a peek combinator into a one returning 'Nothing' if applied to a
124 maybePeek :: (Ptr a -> IO b) -> Ptr a -> IO (Maybe b)
125 maybePeek peek ptr | ptr == nullPtr = return Nothing
126 | otherwise = do a <- peek ptr; return (Just a)
129 -- marshalling lists of storable objects
130 -- -------------------------------------
132 -- |Replicates a @withXXX@ combinator over a list of objects, yielding a list of
133 -- marshalled objects
135 withMany :: (a -> (b -> res) -> res) -- withXXX combinator for one object
136 -> [a] -- storable objects
137 -> ([b] -> res) -- action on list of marshalled obj.s
139 withMany _ [] f = f []
140 withMany withFoo (x:xs) f = withFoo x $ \x' ->
141 withMany withFoo xs (\xs' -> f (x':xs'))
144 -- Haskellish interface to memcpy and memmove
145 -- ------------------------------------------
147 -- |Copies the given number of bytes from the second area (source) into the
148 -- first (destination); the copied areas may /not/ overlap
150 copyBytes :: Ptr a -> Ptr a -> Int -> IO ()
151 copyBytes dest src size = memcpy dest src (fromIntegral size)
153 -- |Copies the given number of elements from the second area (source) into the
154 -- first (destination); the copied areas /may/ overlap
156 moveBytes :: Ptr a -> Ptr a -> Int -> IO ()
157 moveBytes dest src size = memmove dest src (fromIntegral size)
160 -- auxilliary routines
161 -- -------------------
163 -- |Basic C routines needed for memory copying
165 foreign import ccall unsafe memcpy :: Ptr a -> Ptr a -> CSize -> IO ()
166 foreign import ccall unsafe memmove :: Ptr a -> Ptr a -> CSize -> IO ()