packages feed

CoreFoundation-0.1: CoreFoundation/Marshal.hs

{- |
Marshalling assistance for foreign calls using CoreFoundation types.
-}
module CoreFoundation.Marshal(
  -- * Accessing the underlying pointers
  withObject,
  withMaybe,
  -- * Managing memory
  -- $memory
  Ref,
  -- ** Schemes
  -- $scheme
  Scheme,
  create,
  maybeCreate,
  get,
  constant,
  passThrough,
  checkError,
  -- ** Helper functions
  -- $helper
  call1,
  call2,
  call3,
  call4,
  call5,
  call6,
  ) where

import Foreign
import CoreFoundation.Types.Base

-- | Get the pointer for the object, or a null pointer otherwise
withMaybe :: CF a => Maybe a -> (Ptr (Repr a) -> IO b) -> IO b
withMaybe Nothing f = f nullPtr
withMaybe (Just o) f = withObject o f


{- $helper
These functions are all defined in roughly the same way. For example:

> call2 scheme f = \arg1 arg2 ->
>   withObject arg1 $ \parg1 ->
>   withObject arg2 $ \parg2 ->
>   scheme $
>   f parg1 parg2

That is, they all unpack their parameters into pointers, call the
given function, and then use the appropriate scheme to put the
resulting value under memory management. The Scheme section has some
common schemes to use. Also see the @createArray@ scheme in "CoreFoundation.Types.Array".

See "CoreFoundation.Preferences" for example uses of these helpers. For example:

> getValue :: Key -> AppID -> UserID -> HostID -> IO (Maybe Plist)
> getValue = call4 maybeCreate {#call unsafe CFPreferencesCopyValue as ^ #}

-}

call1 scheme f = \arg1 ->
  withObject arg1 $ \parg1 ->
  scheme $
  f parg1

call2 scheme f = \arg1 arg2 ->
  withObject arg1 $ \parg1 ->
  withObject arg2 $ \parg2 ->
  scheme $
  f parg1 parg2

call3 scheme f = \arg1 arg2 arg3 ->
  withObject arg1 $ \parg1 ->
  withObject arg2 $ \parg2 ->
  withObject arg3 $ \parg3 ->
  scheme $
  f parg1 parg2 parg3

call4 scheme f = \arg1 arg2 arg3 arg4 ->
  withObject arg1 $ \parg1 ->
  withObject arg2 $ \parg2 ->
  withObject arg3 $ \parg3 ->
  withObject arg4 $ \parg4 ->
  scheme $
  f parg1 parg2 parg3 parg4

call5 scheme f = \arg1 arg2 arg3 arg4 arg5 ->
  withObject arg1 $ \parg1 ->
  withObject arg2 $ \parg2 ->
  withObject arg3 $ \parg3 ->
  withObject arg4 $ \parg4 ->
  withObject arg5 $ \parg5 ->
  scheme $
  f parg1 parg2 parg3 parg4 parg5

call6 scheme f = \arg1 arg2 arg3 arg4 arg5 arg6 ->
  withObject arg1 $ \parg1 ->
  withObject arg2 $ \parg2 ->
  withObject arg3 $ \parg3 ->
  withObject arg4 $ \parg4 ->
  withObject arg5 $ \parg5 ->
  withObject arg6 $ \parg6 ->
  scheme $
  f parg1 parg2 parg3 parg4 parg5 parg6