+++ /dev/null
-{-# OPTIONS_GHC -fno-implicit-prelude #-}
------------------------------------------------------------------------------
--- |
--- Module : Foreign.Marshal.Utils
--- Copyright : (c) The FFI task force 2001
--- License : BSD-style (see the file libraries/base/LICENSE)
---
--- Maintainer : ffi@haskell.org
--- Stability : provisional
--- Portability : portable
---
--- Utilities for primitive marshaling
---
------------------------------------------------------------------------------
-
-module Foreign.Marshal.Utils (
- -- * General marshalling utilities
-
- -- ** Combined allocation and marshalling
- --
- with, -- :: Storable a => a -> (Ptr a -> IO b) -> IO b
- new, -- :: Storable a => a -> IO (Ptr a)
-
- -- ** Marshalling of Boolean values (non-zero corresponds to 'True')
- --
- fromBool, -- :: Num a => Bool -> a
- toBool, -- :: Num a => a -> Bool
-
- -- ** Marshalling of Maybe values
- --
- maybeNew, -- :: ( a -> IO (Ptr a))
- -- -> (Maybe a -> IO (Ptr a))
- maybeWith, -- :: ( a -> (Ptr b -> IO c) -> IO c)
- -- -> (Maybe a -> (Ptr b -> IO c) -> IO c)
- maybePeek, -- :: (Ptr a -> IO b )
- -- -> (Ptr a -> IO (Maybe b))
-
- -- ** Marshalling lists of storable objects
- --
- withMany, -- :: (a -> (b -> res) -> res) -> [a] -> ([b] -> res) -> res
-
- -- ** Haskellish interface to memcpy and memmove
- -- | (argument order: destination, source)
- --
- copyBytes, -- :: Ptr a -> Ptr a -> Int -> IO ()
- moveBytes, -- :: Ptr a -> Ptr a -> Int -> IO ()
-) where
-
-import Data.Maybe
-import Foreign.Ptr ( Ptr, nullPtr )
-import Foreign.Storable ( Storable(poke) )
-import Foreign.C.Types ( CSize )
-import Foreign.Marshal.Alloc ( malloc, alloca )
-
-#ifdef __GLASGOW_HASKELL__
-import GHC.IOBase
-import GHC.Real ( fromIntegral )
-import GHC.Num
-import GHC.Base
-#endif
-
-#ifdef __NHC__
-import Foreign.C.Types ( CInt(..) )
-#endif
-
--- combined allocation and marshalling
--- -----------------------------------
-
--- |Allocate a block of memory and marshal a value into it
--- (the combination of 'malloc' and 'poke').
--- The size of the area allocated is determined by the 'Foreign.Storable.sizeOf'
--- method from the instance of 'Storable' for the appropriate type.
---
--- The memory may be deallocated using 'Foreign.Marshal.Alloc.free' or
--- 'Foreign.Marshal.Alloc.finalizerFree' when no longer required.
---
-new :: Storable a => a -> IO (Ptr a)
-new val =
- do
- ptr <- malloc
- poke ptr val
- return ptr
-
--- |@'with' val f@ executes the computation @f@, passing as argument
--- a pointer to a temporarily allocated block of memory into which
--- @val@ has been marshalled (the combination of 'alloca' and 'poke').
---
--- The memory is freed when @f@ terminates (either normally or via an
--- exception), so the pointer passed to @f@ must /not/ be used after this.
---
-with :: Storable a => a -> (Ptr a -> IO b) -> IO b
-with val f =
- alloca $ \ptr -> do
- poke ptr val
- res <- f ptr
- return res
-
-
--- marshalling of Boolean values (non-zero corresponds to 'True')
--- -----------------------------
-
--- |Convert a Haskell 'Bool' to its numeric representation
---
-fromBool :: Num a => Bool -> a
-fromBool False = 0
-fromBool True = 1
-
--- |Convert a Boolean in numeric representation to a Haskell value
---
-toBool :: Num a => a -> Bool
-toBool = (/= 0)
-
-
--- marshalling of Maybe values
--- ---------------------------
-
--- |Allocate storage and marshall a storable value wrapped into a 'Maybe'
---
--- * the 'nullPtr' is used to represent 'Nothing'
---
-maybeNew :: ( a -> IO (Ptr a))
- -> (Maybe a -> IO (Ptr a))
-maybeNew = maybe (return nullPtr)
-
--- |Converts a @withXXX@ combinator into one marshalling a value wrapped
--- into a 'Maybe', using 'nullPtr' to represent 'Nothing'.
---
-maybeWith :: ( a -> (Ptr b -> IO c) -> IO c)
- -> (Maybe a -> (Ptr b -> IO c) -> IO c)
-maybeWith = maybe ($ nullPtr)
-
--- |Convert a peek combinator into a one returning 'Nothing' if applied to a
--- 'nullPtr'
---
-maybePeek :: (Ptr a -> IO b) -> Ptr a -> IO (Maybe b)
-maybePeek peek ptr | ptr == nullPtr = return Nothing
- | otherwise = do a <- peek ptr; return (Just a)
-
-
--- marshalling lists of storable objects
--- -------------------------------------
-
--- |Replicates a @withXXX@ combinator over a list of objects, yielding a list of
--- marshalled objects
---
-withMany :: (a -> (b -> res) -> res) -- withXXX combinator for one object
- -> [a] -- storable objects
- -> ([b] -> res) -- action on list of marshalled obj.s
- -> res
-withMany _ [] f = f []
-withMany withFoo (x:xs) f = withFoo x $ \x' ->
- withMany withFoo xs (\xs' -> f (x':xs'))
-
-
--- Haskellish interface to memcpy and memmove
--- ------------------------------------------
-
--- |Copies the given number of bytes from the second area (source) into the
--- first (destination); the copied areas may /not/ overlap
---
-copyBytes :: Ptr a -> Ptr a -> Int -> IO ()
-copyBytes dest src size = do memcpy dest src (fromIntegral size)
- return ()
-
--- |Copies the given number of bytes from the second area (source) into the
--- first (destination); the copied areas /may/ overlap
---
-moveBytes :: Ptr a -> Ptr a -> Int -> IO ()
-moveBytes dest src size = do memmove dest src (fromIntegral size)
- return ()
-
-
--- auxilliary routines
--- -------------------
-
--- |Basic C routines needed for memory copying
---
-foreign import ccall unsafe "string.h" memcpy :: Ptr a -> Ptr a -> CSize -> IO (Ptr a)
-foreign import ccall unsafe "string.h" memmove :: Ptr a -> Ptr a -> CSize -> IO (Ptr a)