xfconf-4.8.0.0: System/XFCE/Xfconf/GHashTable.chs
{-# LANGUAGE CPP, ForeignFunctionInterface #-}
-- vim:filetype=haskell:
{- | A limited binding to glib GHashTable structures. We only handle
hash tables as returned by @xfconf_channel_get_properties@. They have
@gchar *@ keys and @GValue *@ values.
Objectives:
* get back the list of keys when keys are strings
* extract values
-}
#include <glib.h>
{# context lib="glib" prefix="g_hash_table" #}
module System.XFCE.Xfconf.GHashTable (
-- * Private data type
GHashTable,
-- * Marshalling functions
withGHashTable,
mkGHashTable,
-- * Query functions
gHashTableKeys,
gHashTableLookup
) where
import Control.Monad ((>=>))
import System.Glib.GList
import System.Glib.GValue
import System.Glib.UTFString
import System.XFCE.Xfconf.FFI
-- | Haskell representation of a C @GHashTable*@ with @gchar *@ keys and
-- @GValue*@ values. Memory management is automatically managed by a
-- special Haskell finalizer calling @g_hash_table_destroy@.
{#pointer *GHashTable as GHashTable foreign newtype #}
-- withGHashTable is auto-generated by C2HS, but not by gtk2hsC2hs
withGHashTable :: GHashTable -> (Ptr GHashTable -> IO b) -> IO b
withGHashTable (GHashTable ptr) = withForeignPtr ptr
-- | The glib finalizer for hash tables.
foreign import ccall unsafe "glib.h &g_hash_table_destroy"
c_destroy :: FinalizerPtr GHashTable
{- | Marshal out a raw C @GHashTable*@ by wrapping it in the Haskell
type 'GHashTable' and adding it a finalizer (which calls
@g_hash_table_destroy@).
Should be called for every function returning a @GHashTable*@, see
for example in /System.XFCE.Xfconf.Channel.chs/:
@
{#fun unsafe get_properties as ^
{ channelPtr \`Channel\' -- ^ channel pointer
, withUTFString* \`String\' -- ^ property base
} -> \`GHashTable\' mkGHashTable* #}
@
-}
mkGHashTable :: Ptr GHashTable -> IO (GHashTable)
mkGHashTable ptr = GHashTable `fmap` newForeignPtr c_destroy ptr
-- XXX: fromGList calls g_list_delete_link which I suppose is the same
-- as calling g_list_free
-- XXX: readGList read whereas fromGList read *and* free the list
-- peekUTFString read whereas readUTFString read *and* free the str
-- somewhat, I feel completely lost (^^)
-- XXX: we do NOT readUTFString, we just peek them !
-- the GHashTablePtr finalizer should take care itself of freeing
-- them
-- | Retrieves every key inside a 'GHashTable'. The returned data is
-- valid until the table is modified.
{#fun unsafe get_keys as gHashTableKeys
{ withGHashTable* `GHashTable'
} -> `[String]' marshallOut* #}
where marshallOut = fromGList >=> mapM peekUTFString
-- | Looks up a key in a GHashTable. Note that this function cannot
-- distinguish between a key that is not present and one which is
-- present and has the value 'Nothing'.
{#fun unsafe lookup as gHashTableLookup
{ withGHashTable* `GHashTable'
, withUTFString'* `String'
} -> `Maybe GValue' marshallGValue #}
where withUTFString' :: String -> (Ptr () -> IO b) -> IO b
withUTFString' s io = withUTFString s (io . castPtr)
marshallGValue :: Ptr a -> Maybe GValue
marshallGValue ptr = if ptr == nullPtr
then Nothing
else Just . GValue . castPtr $ ptr