Commit d66534a4 authored by simonmar's avatar simonmar
Browse files

[project @ 2002-05-09 13:13:28 by simonmar]

Add documentation Haddock-style
parent f9efc410
......@@ -9,13 +9,16 @@
-- Stability : provisional
-- Portability : portable
--
-- This module defines foreign pointers, i.e. addresses with associated
-- finalizers.
-- The 'ForeignPtr' type and operations. This module is part of the
-- Foreign Function Interface (FFI) and will usually be imported via
-- the "Foreign" module.
--
-----------------------------------------------------------------------------
module Foreign.ForeignPtr
( ForeignPtr, -- abstract, instance of: Eq
(
-- * Finalised data pointers
ForeignPtr, -- abstract, instance of: Eq
, newForeignPtr -- :: Ptr a -> IO () -> IO (ForeignPtr a)
, addForeignPtrFinalizer -- :: ForeignPtr a -> IO () -> IO ()
, withForeignPtr -- :: ForeignPtr a -> (Ptr a -> IO b) -> IO b
......@@ -39,7 +42,24 @@ import GHC.Err
INSTANCE_TYPEABLE1(ForeignPtr,foreignPtrTc,"ForeignPtr")
#ifdef __GLASGOW_HASKELL__
-- |The type 'ForeignPtr' represents references to objects that are
-- maintained in a foreign language, i.e., that are not part of the
-- data structures usually managed by the Haskell storage manager.
-- The essential difference between 'ForeignPtr's and vanilla memory
-- references of type @Ptr a@ is that the former may be associated
-- with /finalisers/. A finaliser is a routine that is invoked when
-- the Haskell storage manager detects that - within the Haskell heap
-- and stack - there are no more references left that are pointing to
-- the 'ForeignPtr'. Typically, the finaliser will, then, invoke
-- routines in the foreign language that free the resources bound by
-- the foreign object.
--
-- The 'ForeignPtr' is parameterised in the same way as 'Ptr'. The
-- type argument of 'ForeignPtr' should normally be an instance of
-- class 'Storable'.
--
data ForeignPtr a = ForeignPtr ForeignObj#
instance CCallable (ForeignPtr a)
eqForeignPtr :: ForeignPtr a -> ForeignPtr a -> Bool
......@@ -50,12 +70,24 @@ instance Eq (ForeignPtr a) where
p /= q = not (eqForeignPtr p q)
newForeignPtr :: Ptr a -> IO () -> IO (ForeignPtr a)
-- ^Turns a plain memory reference into a foreign object
-- by associating a finaliser - given by the monadic operation
-- - with the reference. The finaliser will be executed after
-- the last reference to the foreign object is dropped. Note
-- that there is no guarantee on how soon the finaliser is
-- executed after the last reference was dropped; this depends
-- on the details of the Haskell storage manager. The only
-- guarantee is that the finaliser runs before the program
-- terminates.
newForeignPtr p finalizer
= do fObj <- mkForeignPtr p
addForeignPtrFinalizer fObj finalizer
return fObj
addForeignPtrFinalizer :: ForeignPtr a -> IO () -> IO ()
-- ^This function adds another finaliser to the given
-- foreign object. No guarantees are made on the order in
-- which multiple finalisers for a single object are run.
addForeignPtrFinalizer (ForeignPtr fo) finalizer =
IO $ \s -> case mkWeak# fo () finalizer s of { (# s1, w #) -> (# s1, () #) }
......@@ -65,18 +97,72 @@ mkForeignPtr (Ptr obj) = IO ( \ s# ->
(# s1#, fo# #) -> (# s1#, ForeignPtr fo# #) )
touchForeignPtr :: ForeignPtr a -> IO ()
-- ^This function ensures that the foreign object in
-- question is alive at the given place in the sequence of IO
-- actions. In particular 'withForeignPtr'
-- does a 'touchForeignPtr' after it
-- executes the user action.
--
-- This function can be used to express liveness
-- dependencies between 'ForeignPtr's: for
-- example, if the finalizer for one
-- 'ForeignPtr' touches a second
-- 'ForeignPtr', then it is ensured that the
-- second 'ForeignPtr' will stay alive at
-- least as long as the first. This can be useful when you
-- want to manipulate /interior pointers/ to
-- a foreign structure: you can use
-- 'touchForeignObj' to express the
-- requirement that the exterior pointer must not be finalized
-- until the interior pointer is no longer referenced.
touchForeignPtr (ForeignPtr fo)
= IO $ \s -> case touch# fo s of s -> (# s, () #)
withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b
-- ^This is a way to look at the pointer living inside a
-- foreign object. This function takes a function which is
-- applied to that pointer. The resulting 'IO' action is then
-- executed. The foreign object is kept alive at least during
-- the whole action, even if it is not used directly
-- inside. Note that it is not safe to return the pointer from
-- the action and use it after the action completes. All uses
-- of the pointer should be inside the
-- 'withForeignPtr' bracket. The reason for
-- this unsafety is the same as for
-- 'foreignPtrToPtr' below: the finalizer
-- may run earlier than expected, because the compiler can only
-- track usage of the 'ForeignPtr' object, not
-- a 'Ptr' object made from it.
--
-- This function is normally used for marshalling data to
-- or from the object pointed to by the
-- 'ForeignPtr', using the operations from the
-- 'Storable' class.
withForeignPtr fo io
= do r <- io (foreignPtrToPtr fo)
touchForeignPtr fo
return r
foreignPtrToPtr :: ForeignPtr a -> Ptr a
-- ^This function extracts the pointer component of a foreign
-- pointer. This is a potentially dangerous operations, as if the
-- argument to 'foreignPtrToPtr' is the last usage
-- occurence of the given foreign pointer, then its finaliser(s) will
-- be run, which potentially invalidates the plain pointer just
-- obtained. Hence, 'touchForeignPtr' must be used
-- wherever it has to be guaranteed that the pointer lives on - i.e.,
-- has another usage occurrence.
--
-- To avoid subtle coding errors, hand written marshalling code
-- should preferably use 'withForeignPtr' rather
-- than combinations of 'foreignPtrToPtr' and
-- 'touchForeignPtr'. However, the later routines
-- are occasionally preferred in tool generated marshalling code.
foreignPtrToPtr (ForeignPtr fo) = Ptr (foreignObjToAddr# fo)
castForeignPtr :: ForeignPtr a -> ForeignPtr b
-- ^This function casts a 'ForeignPtr'
-- parameterised by one type into another type.
castForeignPtr (ForeignPtr a) = ForeignPtr a
#endif
......@@ -14,6 +14,7 @@
-----------------------------------------------------------------------------
module Foreign.Marshal.Alloc (
-- * Allocation
malloc, -- :: Storable a => IO (Ptr a)
mallocBytes, -- :: Int -> IO (Ptr a)
......@@ -43,7 +44,9 @@ import GHC.Base
-- exported functions
-- ------------------
-- |Allocate space for storable type. The size of the area allocated
-- is determined by the 'sizeOf' method from the instance of
-- 'Storable' for the appropriate type.
--
malloc :: Storable a => IO (Ptr a)
malloc = doMalloc undefined
......@@ -51,16 +54,16 @@ malloc = doMalloc undefined
doMalloc :: Storable a => a -> IO (Ptr a)
doMalloc dummy = mallocBytes (sizeOf dummy)
-- |Allocate given number of bytes of storage, equivalent to C\'s @malloc()@.
--
mallocBytes :: Int -> IO (Ptr a)
mallocBytes size = failWhenNULL "malloc" (_malloc (fromIntegral size))
 
-- |Temporarily allocate space for a storable type.
--
 
-- * the pointer passed as an argument to the function must *not* escape from
-- this function; in other words, in `alloca f' the allocated storage must
-- * the pointer passed as an argument to the function must /not/ escape from
-- this function; in other words, in @alloca f@ the allocated storage must
-- not be used after @f@ returns
--
alloca :: Storable a => (Ptr a -> IO b) -> IO b
alloca = doAlloca undefined
......@@ -68,11 +71,11 @@ alloca = doAlloca undefined
doAlloca :: Storable a => a -> (Ptr a -> IO b) -> IO b
doAlloca dummy = allocaBytes (sizeOf dummy)
-- temporarily allocate the given number of bytes of storage
-- |Temporarily allocate the given number of bytes of storage.
--
-- * the pointer passed as an argument to the function must *not* escape from
-- this function; in other words, in `allocaBytes n f' the allocated storage
-- must not be used after `f' returns
-- * the pointer passed as an argument to the function must /not/ escape from
-- this function; in other words, in @allocaBytes n f@ the allocated storage
-- must not be used after @f@ returns
--
#ifdef __GLASGOW_HASKELL__
allocaBytes :: Int -> (Ptr a -> IO b) -> IO b
......@@ -90,13 +93,15 @@ allocaBytes :: Int -> (Ptr a -> IO b) -> IO b
allocaBytes size = bracket (mallocBytes size) free
#endif
-- |Adjust a malloc\'ed storage area to the given size (equivalent to
-- C\'s @realloc()@).
--
reallocBytes :: Ptr a -> Int -> IO (Ptr a)
reallocBytes ptr size =
failWhenNULL "realloc" (_realloc ptr (fromIntegral size))
-- |Free malloc\'ed storage (equivalent to
-- C\'s @free()@)
--
free :: Ptr a -> IO ()
free = _free
......
......@@ -15,8 +15,9 @@
-----------------------------------------------------------------------------
module Foreign.Marshal.Array (
-- * Marshalling arrays
-- allocation
-- ** Allocation
--
mallocArray, -- :: Storable a => Int -> IO (Ptr a)
mallocArray0, -- :: Storable a => Int -> IO (Ptr a)
......@@ -27,7 +28,7 @@ module Foreign.Marshal.Array (
reallocArray, -- :: Storable a => Ptr a -> Int -> IO (Ptr a)
reallocArray0, -- :: Storable a => Ptr a -> Int -> IO (Ptr a)
-- marshalling
-- ** Marshalling
--
peekArray, -- :: Storable a => Int -> Ptr a -> IO [a]
peekArray0, -- :: (Storable a, Eq a) => a -> Ptr a -> IO [a]
......@@ -35,7 +36,7 @@ module Foreign.Marshal.Array (
pokeArray, -- :: Storable a => Ptr a -> [a] -> IO ()
pokeArray0, -- :: Storable a => a -> Ptr a -> [a] -> IO ()
-- combined allocation and marshalling
-- ** Combined allocation and marshalling
--
newArray, -- :: Storable a => [a] -> IO (Ptr a)
newArray0, -- :: Storable a => a -> [a] -> IO (Ptr a)
......@@ -43,16 +44,17 @@ module Foreign.Marshal.Array (
withArray, -- :: Storable a => [a] -> (Ptr a -> IO b) -> IO b
withArray0, -- :: Storable a => a -> [a] -> (Ptr a -> IO b) -> IO b
-- copying (argument order: destination, source)
--
-- ** Copying
-- | (argument order: destination, source)
copyArray, -- :: Storable a => Ptr a -> Ptr a -> Int -> IO ()
moveArray, -- :: Storable a => Ptr a -> Ptr a -> Int -> IO ()
-- finding the length
-- ** Finding the length
--
lengthArray0, -- :: (Storable a, Eq a) => a -> Ptr a -> IO Int
-- indexing
-- ** Indexing
--
advancePtr, -- :: Storable a => Ptr a -> Int -> Ptr a
) where
......@@ -62,7 +64,7 @@ import Control.Monad
#ifdef __GLASGOW_HASKELL__
import Foreign.Ptr (Ptr, plusPtr)
import GHC.Storable (Storable(sizeOf,peekElemOff,pokeElemOff))
import Foreign.Marshal.Alloc (mallocBytes, allocaBytes, reallocBytes)
import Foreign.Marshal.Alloc (alloca, mallocBytes, allocaBytes, reallocBytes)
import Foreign.Marshal.Utils (copyBytes, moveBytes)
import GHC.IOBase
import GHC.Num
......@@ -74,7 +76,7 @@ import GHC.Base
-- allocation
-- ----------
-- |Allocate storage for the given number of elements of a storable type.
--
mallocArray :: Storable a => Int -> IO (Ptr a)
mallocArray = doMalloc undefined
......@@ -82,14 +84,14 @@ mallocArray = doMalloc undefined
doMalloc :: Storable a => a -> Int -> IO (Ptr a)
doMalloc dummy size = mallocBytes (size * sizeOf dummy)
-- like `mallocArray', but add an extra element to signal the end of the array
-- |Like 'mallocArray', but add an extra element to signal the end of the array
--
mallocArray0 :: Storable a => Int -> IO (Ptr a)
mallocArray0 size = mallocArray (size + 1)
-- temporarily allocate space for the given number of elements
-- |Temporarily allocate space for the given number of elements.
--
-- * see `MarshalAlloc.alloca' for the storage lifetime constraints
-- * see 'Foreign.Marshal.Alloc.alloca' for the storage lifetime constraints
--
allocaArray :: Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray = doAlloca undefined
......@@ -97,12 +99,12 @@ allocaArray = doAlloca undefined
doAlloca :: Storable a => a -> Int -> (Ptr a -> IO b) -> IO b
doAlloca dummy size = allocaBytes (size * sizeOf dummy)
-- like `allocaArray', but add an extra element to signal the end of the array
-- |Like 'allocaArray', but add an extra element to signal the end of the array
--
allocaArray0 :: Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray0 size = allocaArray (size + 1)
-- |Adjust the size of an array
--
reallocArray :: Storable a => Ptr a -> Int -> IO (Ptr a)
reallocArray = doRealloc undefined
......@@ -110,7 +112,7 @@ reallocArray = doRealloc undefined
doRealloc :: Storable a => a -> Ptr a -> Int -> IO (Ptr a)
doRealloc dummy ptr size = reallocBytes ptr (size * sizeOf dummy)
-- |Adjust the size of an array while adding an element for the end marker
--
reallocArray0 :: Storable a => Ptr a -> Int -> IO (Ptr a)
reallocArray0 ptr size = reallocArray ptr (size + 1)
......@@ -119,7 +121,7 @@ reallocArray0 ptr size = reallocArray ptr (size + 1)
-- marshalling
-- -----------
-- convert an array of given length into a Haskell list. This version
-- |Convert an array of given length into a Haskell list. This version
-- traverses the array backwards using an accumulating parameter,
-- which uses constant stack space. The previous version using mapM
-- needed linear stack space.
......@@ -131,7 +133,7 @@ peekArray size ptr | size <= 0 = return []
f 0 acc = do e <- peekElemOff ptr 0; return (e:acc)
f n acc = do e <- peekElemOff ptr n; f (n-1) (e:acc)
-- convert an array terminated by the given end marker into a Haskell list
-- |Convert an array terminated by the given end marker into a Haskell list
--
peekArray0 :: (Storable a, Eq a) => a -> Ptr a -> IO [a]
peekArray0 marker ptr = loop 0
......@@ -142,12 +144,12 @@ peekArray0 marker ptr = loop 0
rest <- loop (i+1)
return (val:rest)
-- write the list elements consecutive into memory
-- |Write the list elements consecutive into memory
--
pokeArray :: Storable a => Ptr a -> [a] -> IO ()
pokeArray ptr vals = zipWithM_ (pokeElemOff ptr) [0..] vals
-- write the list elements consecutive into memory and terminate them with the
-- |Write the list elements consecutive into memory and terminate them with the
-- given marker element
--
pokeArray0 :: Storable a => a -> Ptr a -> [a] -> IO ()
......@@ -159,7 +161,7 @@ pokeArray0 marker ptr vals = do
-- combined allocation and marshalling
-- -----------------------------------
-- write a list of storable elements into a newly allocated, consecutive
-- |Write a list of storable elements into a newly allocated, consecutive
-- sequence of storable values
--
newArray :: Storable a => [a] -> IO (Ptr a)
......@@ -168,7 +170,7 @@ newArray vals = do
pokeArray ptr vals
return ptr
-- write a list of storable elements into a newly allocated, consecutive
-- |Write a list of storable elements into a newly allocated, consecutive
-- sequence of storable values, where the end is fixed by the given end marker
--
newArray0 :: Storable a => a -> [a] -> IO (Ptr a)
......@@ -177,7 +179,7 @@ newArray0 marker vals = do
pokeArray0 marker ptr vals
return ptr
-- temporarily store a list of storable values in memory
-- |Temporarily store a list of storable values in memory
--
withArray :: Storable a => [a] -> (Ptr a -> IO b) -> IO b
withArray vals f =
......@@ -188,7 +190,7 @@ withArray vals f =
where
len = length vals
-- like `withArray', but a terminator indicates where the array ends
-- |Like 'withArray', but a terminator indicates where the array ends
--
withArray0 :: Storable a => a -> [a] -> (Ptr a -> IO b) -> IO b
withArray0 marker vals f =
......@@ -203,8 +205,8 @@ withArray0 marker vals f =
-- copying (argument order: destination, source)
-- -------
-- copy the given number of elements from the second array (source) into the
-- first array (destination); the copied areas may *not* overlap
-- |Copy the given number of elements from the second array (source) into the
-- first array (destination); the copied areas may /not/ overlap
--
copyArray :: Storable a => Ptr a -> Ptr a -> Int -> IO ()
copyArray = doCopy undefined
......@@ -212,8 +214,8 @@ copyArray = doCopy undefined
doCopy :: Storable a => a -> Ptr a -> Ptr a -> Int -> IO ()
doCopy dummy dest src size = copyBytes dest src (size * sizeOf dummy)
-- copy the given number of elements from the second array (source) into the
-- first array (destination); the copied areas *may* overlap
-- |Copy the given number of elements from the second array (source) into the
-- first array (destination); the copied areas /may/ overlap
--
moveArray :: Storable a => Ptr a -> Ptr a -> Int -> IO ()
moveArray = doMove undefined
......@@ -225,7 +227,7 @@ moveArray = doMove undefined
-- finding the length
-- ------------------
-- return the number of elements in an array, excluding the terminator
-- |Return the number of elements in an array, excluding the terminator
--
lengthArray0 :: (Storable a, Eq a) => a -> Ptr a -> IO Int
lengthArray0 marker ptr = loop 0
......@@ -238,7 +240,7 @@ lengthArray0 marker ptr = loop 0
-- indexing
-- --------
-- |Advance a pointer into an array by the given number of elements
--
advancePtr :: Storable a => Ptr a -> Int -> Ptr a
advancePtr = doAdvance undefined
......
......@@ -14,8 +14,9 @@
-----------------------------------------------------------------------------
module Foreign.Marshal.Error (
-- * Error utilities
-- throw an exception on specific return values
-- |Throw an exception on specific return values
--
throwIf, -- :: (a -> Bool) -> (a -> String) -> IO a -> IO a
throwIf_, -- :: (a -> Bool) -> (a -> String) -> IO a -> IO ()
......@@ -25,7 +26,7 @@ module Foreign.Marshal.Error (
-- => (a -> String) -> IO a -> IO ()
throwIfNull, -- :: String -> IO (Ptr a) -> IO (Ptr a)
-- discard return value
-- Discard return value
--
void -- IO a -> IO ()
) where
......@@ -41,10 +42,10 @@ import GHC.IOBase
-- exported functions
-- ------------------
-- guard an IO operation and throw an exception if the result meets the given
-- |Guard an 'IO' operation and throw an exception if the result meets the given
-- predicate
--
-- * the second argument computes an error message from the result of the IO
-- * the second argument computes an error message from the result of the 'IO'
-- operation
--
throwIf :: (a -> Bool) -> (a -> String) -> IO a -> IO a
......@@ -53,27 +54,27 @@ throwIf pred msgfct act =
res <- act
(if pred res then ioError . userError . msgfct else return) res
-- like `throwIf', but discarding the result
-- |Like 'throwIf', but discarding the result
--
throwIf_ :: (a -> Bool) -> (a -> String) -> IO a -> IO ()
throwIf_ pred msgfct act = void $ throwIf pred msgfct act
-- guards against negative result values
-- |Guards against negative result values
--
throwIfNeg :: (Ord a, Num a) => (a -> String) -> IO a -> IO a
throwIfNeg = throwIf (< 0)
-- like `throwIfNeg', but discarding the result
-- |Like 'throwIfNeg', but discarding the result
--
throwIfNeg_ :: (Ord a, Num a) => (a -> String) -> IO a -> IO ()
throwIfNeg_ = throwIf_ (< 0)
-- guards against null pointers
-- |Guards against null pointers
--
throwIfNull :: String -> IO (Ptr a) -> IO (Ptr a)
throwIfNull = throwIf (== nullPtr) . const
-- discard the return value of an IO action
-- |Discard the return value of an 'IO' action
--
void :: IO a -> IO ()
void act = act >> return ()
......@@ -14,19 +14,20 @@
-----------------------------------------------------------------------------
module Foreign.Marshal.Utils (
-- * General marshalling utilities
-- combined allocation and marshalling
-- ** Combined allocation and marshalling
--
withObject, -- :: Storable a => a -> (Ptr a -> IO b) -> IO b
{- FIXME: should be `with' -}
new, -- :: Storable a => a -> IO (Ptr a)
-- marshalling of Boolean values (non-zero corresponds to `True')
-- ** Marshalling of Boolean values (non-zero corresponds to 'True')
--
fromBool, -- :: Num a => Bool -> a
toBool, -- :: Num a => a -> Bool
-- marshalling of Maybe values
-- ** Marshalling of Maybe values
--
maybeNew, -- :: ( a -> IO (Ptr a))
-- -> (Maybe a -> IO (Ptr a))
......@@ -35,13 +36,13 @@ module Foreign.Marshal.Utils (
maybePeek, -- :: (Ptr a -> IO b )
-- -> (Ptr a -> IO (Maybe b))
-- marshalling lists of storable objects
-- ** Marshalling lists of storable objects
--
withMany, -- :: (a -> (b -> res) -> res) -> [a] -> ([b] -> res) -> res
-- Haskellish interface to memcpy and memmove
-- (argument order: destination, source)
--
-- ** 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
......@@ -62,7 +63,7 @@ import GHC.Base
-- combined allocation and marshalling
-- -----------------------------------
-- |Allocate storage for a value and marshal it into this storage
--
new :: Storable a => a -> IO (Ptr a)
new val =
......@@ -71,9 +72,9 @@ new val =
poke ptr val
return ptr
-- |Allocate temporary storage for a value and marshal it into this storage
--
 
-- * see the life time constraints imposed by 'alloca'
--
{- FIXME: should be called `with' -}
withObject :: Storable a => a -> (Ptr a -> IO b) -> IO b
......@@ -84,16 +85,16 @@ withObject val f =
return res
-- marshalling of Boolean values (non-zero corresponds to `True')
-- marshalling of Boolean values (non-zero corresponds to 'True')
-- -----------------------------
-- convert a Haskell Boolean to its numeric representation
-- |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
-- |Convert a Boolean in numeric representation to a Haskell value
--
toBool :: Num a => a -> Bool
toBool = (/= 0)
......@@ -102,23 +103,23 @@ 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
-- |Converts a @withXXX@ combinator into one marshalling a value wrapped into a
-- 'Maybe'
--
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
-- |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
......@@ -128,7 +129,7 @@ maybePeek peek ptr | ptr == nullPtr = return Nothing
-- marshalling lists of storable objects
-- -------------------------------------
-- replicates a withXXX combinator over a list of objects, yielding a list of
-- |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
......@@ -143,14 +144,14 @@ withMany withFoo (x:xs) f = withFoo x $ \x' ->
-- 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
-- |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 = memcpy dest src (fromIntegral size)
-- copies the given number of elements from the second area (source) into the
-- first (destination); the copied areas *may* overlap
-- |Copies the given number of elements 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 = memmove dest src (fromIntegral size)
......@@ -159,7 +160,7 @@ moveBytes dest src size = memmove dest src (fromIntegral size)
-- auxilliary routines
-- -------------------
-- basic C routines needed for memory copying
-- |Basic C routines needed for memory copying