1 {-# LANGUAGE CPP, NoImplicitPrelude, ForeignFunctionInterface #-}
3 -----------------------------------------------------------------------------
5 -- Module : Foreign.Marshal.Utils
6 -- Copyright : (c) The FFI task force 2001
7 -- License : BSD-style (see the file libraries/base/LICENSE)
9 -- Maintainer : ffi@haskell.org
10 -- Stability : provisional
11 -- Portability : portable
13 -- Utilities for primitive marshaling
15 -----------------------------------------------------------------------------
17 module Foreign.Marshal.Utils (
18 -- * General marshalling utilities
20 -- ** Combined allocation and marshalling
22 with, -- :: Storable a => a -> (Ptr a -> IO b) -> IO b
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
44 -- | (argument order: destination, source)
46 copyBytes, -- :: Ptr a -> Ptr a -> Int -> IO ()
47 moveBytes, -- :: Ptr a -> Ptr a -> Int -> IO ()
51 import Foreign.Ptr ( Ptr, nullPtr )
52 import Foreign.Storable ( Storable(poke) )
53 import Foreign.C.Types ( CSize )
54 import Foreign.Marshal.Alloc ( malloc, alloca )
56 #ifdef __GLASGOW_HASKELL__
57 import GHC.Real ( fromIntegral )
63 import Foreign.C.Types ( CInt(..) )
66 -- combined allocation and marshalling
67 -- -----------------------------------
69 -- |Allocate a block of memory and marshal a value into it
70 -- (the combination of 'malloc' and 'poke').
71 -- The size of the area allocated is determined by the 'Foreign.Storable.sizeOf'
72 -- method from the instance of 'Storable' for the appropriate type.
74 -- The memory may be deallocated using 'Foreign.Marshal.Alloc.free' or
75 -- 'Foreign.Marshal.Alloc.finalizerFree' when no longer required.
77 new :: Storable a => a -> IO (Ptr a)
84 -- |@'with' val f@ executes the computation @f@, passing as argument
85 -- a pointer to a temporarily allocated block of memory into which
86 -- @val@ has been marshalled (the combination of 'alloca' and 'poke').
88 -- The memory is freed when @f@ terminates (either normally or via an
89 -- exception), so the pointer passed to @f@ must /not/ be used after this.
91 with :: Storable a => a -> (Ptr a -> IO b) -> IO b
99 -- marshalling of Boolean values (non-zero corresponds to 'True')
100 -- -----------------------------
102 -- |Convert a Haskell 'Bool' to its numeric representation
104 fromBool :: Num a => Bool -> a
108 -- |Convert a Boolean in numeric representation to a Haskell value
110 toBool :: Num a => a -> Bool
114 -- marshalling of Maybe values
115 -- ---------------------------
117 -- |Allocate storage and marshal a storable value wrapped into a 'Maybe'
119 -- * the 'nullPtr' is used to represent 'Nothing'
121 maybeNew :: ( a -> IO (Ptr b))
122 -> (Maybe a -> IO (Ptr b))
123 maybeNew = maybe (return nullPtr)
125 -- |Converts a @withXXX@ combinator into one marshalling a value wrapped
126 -- into a 'Maybe', using 'nullPtr' to represent 'Nothing'.
128 maybeWith :: ( a -> (Ptr b -> IO c) -> IO c)
129 -> (Maybe a -> (Ptr b -> IO c) -> IO c)
130 maybeWith = maybe ($ nullPtr)
132 -- |Convert a peek combinator into a one returning 'Nothing' if applied to a
135 maybePeek :: (Ptr a -> IO b) -> Ptr a -> IO (Maybe b)
136 maybePeek peek ptr | ptr == nullPtr = return Nothing
137 | otherwise = do a <- peek ptr; return (Just a)
140 -- marshalling lists of storable objects
141 -- -------------------------------------
143 -- |Replicates a @withXXX@ combinator over a list of objects, yielding a list of
144 -- marshalled objects
146 withMany :: (a -> (b -> res) -> res) -- withXXX combinator for one object
147 -> [a] -- storable objects
148 -> ([b] -> res) -- action on list of marshalled obj.s
150 withMany _ [] f = f []
151 withMany withFoo (x:xs) f = withFoo x $ \x' ->
152 withMany withFoo xs (\xs' -> f (x':xs'))
155 -- Haskellish interface to memcpy and memmove
156 -- ------------------------------------------
158 -- |Copies the given number of bytes from the second area (source) into the
159 -- first (destination); the copied areas may /not/ overlap
161 copyBytes :: Ptr a -> Ptr a -> Int -> IO ()
162 copyBytes dest src size = do _ <- memcpy dest src (fromIntegral size)
165 -- |Copies the given number of bytes from the second area (source) into the
166 -- first (destination); the copied areas /may/ overlap
168 moveBytes :: Ptr a -> Ptr a -> Int -> IO ()
169 moveBytes dest src size = do _ <- memmove dest src (fromIntegral size)
173 -- auxilliary routines
174 -- -------------------
176 -- |Basic C routines needed for memory copying
178 foreign import ccall unsafe "string.h" memcpy :: Ptr a -> Ptr a -> CSize -> IO (Ptr a)
179 foreign import ccall unsafe "string.h" memmove :: Ptr a -> Ptr a -> CSize -> IO (Ptr a)