diff options
author | Robert McQueen <robot101@debian.org> | 2006-02-13 22:30:11 +0000 |
---|---|---|
committer | Robert McQueen <robot101@debian.org> | 2006-02-13 22:30:11 +0000 |
commit | 4a48fff0c7c0377d68d1e24cc113e275057b4800 (patch) | |
tree | 729444babf3951c53d44b9be4f0569cc173f81a8 /glib/dbus-gvalue-utils.c | |
parent | 385c443cc7aacaadbdef391d3951699a7511fbb2 (diff) |
2006-02-13 Robert McQueen <robot101@debian.org>
* glib/dbus-binding-tool-glib.c, glib/dbus-gmain.c,
glib/dbus-gsignature.c, glib/dbus-gtype-specialized.c,
glib/dbus-gtype-specialized.h, glib/dbus-gvalue-utils.c,
glib/dbus-gvalue-utils.h, glib/dbus-gvalue.c:
Patch from Rob Taylor <rob.taylor@collabora.co.uk> to add a big
missing piece of the glib bindings jigsaw puzzle. This modifies
the existing specialised types to have N type parameters (rather
than the current 1 or 2 for arrays and dictionaries respectively).
You can then use this to get a glib type to represent any arbitrary
D-Bus struct type using dbus_g_type_get_struct. The only
implementation of these types is with GValueArrays as before,
but it's now possible to store these in arrays, emit them in
signals, etc.
Diffstat (limited to 'glib/dbus-gvalue-utils.c')
-rw-r--r-- | glib/dbus-gvalue-utils.c | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/glib/dbus-gvalue-utils.c b/glib/dbus-gvalue-utils.c index 04c0c3e8..f64a921f 100644 --- a/glib/dbus-gvalue-utils.c +++ b/glib/dbus-gvalue-utils.c @@ -334,6 +334,16 @@ hash_free_from_gtype (GType gtype, GDestroyNotify *func) return TRUE; } } + else if (dbus_g_type_is_struct (gtype)) + { + const DBusGTypeSpecializedStructVtable *vtable; + vtable = dbus_g_type_struct_peek_vtable (gtype); + if (vtable->base_vtable.simple_free_func) + { + *func = vtable->base_vtable.simple_free_func; + return TRUE; + } + } return FALSE; } } @@ -612,6 +622,67 @@ hashtable_simple_free (gpointer val) } static gpointer +valuearray_constructor (GType type) +{ + GValueArray *ret; + guint size = dbus_g_type_get_struct_size (type); + guint i; + ret = g_value_array_new (size); + for (i=0; i < size; i++) + { + GValue val = {0,}; + g_value_init (&val, dbus_g_type_get_struct_member_type (type, i)); + g_value_array_append(ret, &val); + } + return (gpointer)ret; +} + +static gpointer +valuearray_copy (GType type, gpointer src) +{ + return g_value_array_copy ((GValueArray*) src); +} + +static void +valuearray_simple_free (gpointer val) +{ + g_value_array_free (val); +} + +static gboolean +valuearray_get_member (GType type, gpointer instance, + guint member, GValue *ret) +{ + GValueArray *va = (GValueArray*) instance; + const GValue *val; + if (member < dbus_g_type_get_struct_size (type)) + { + val = g_value_array_get_nth (va, member); + g_value_copy (val, ret); + return TRUE; + } + else + return FALSE; +} + +static gboolean +valuearray_set_member (GType type, gpointer instance, + guint member, const GValue *member_type) +{ + GValueArray *va = (GValueArray*) instance; + GValue *vp; + if (member < dbus_g_type_get_struct_size (type)) + { + vp = g_value_array_get_nth (va, member); + g_value_copy (member_type, vp); + return TRUE; + } + else + return FALSE; +} + + +static gpointer array_constructor (GType type) { GArray *array; @@ -945,10 +1016,24 @@ _dbus_g_type_specialized_builtins_init (void) hashtable_append }; + static const DBusGTypeSpecializedStructVtable valuearray_vtable = { + { + valuearray_constructor, + NULL, + valuearray_copy, + valuearray_simple_free, + NULL, + NULL + }, + valuearray_get_member, + valuearray_set_member + }; + dbus_g_type_register_collection ("GSList", &slist_vtable, 0); dbus_g_type_register_collection ("GArray", &array_vtable, 0); dbus_g_type_register_collection ("GPtrArray", &ptrarray_vtable, 0); dbus_g_type_register_map ("GHashTable", &hashtable_vtable, 0); + dbus_g_type_register_struct ("GValueArray", &valuearray_vtable, 0); } #ifdef DBUS_BUILD_TESTS @@ -1160,6 +1245,105 @@ _dbus_gvalue_utils_test (const char *datadir) g_value_unset (&val); } + type = dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_UINT, DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); + g_assert (dbus_g_type_is_struct (type)); + g_assert (dbus_g_type_get_struct_size (type) == 3); + g_assert (dbus_g_type_get_struct_member_type (type, 0) == G_TYPE_STRING); + g_assert (dbus_g_type_get_struct_member_type (type, 1) == G_TYPE_UINT); + g_assert (dbus_g_type_get_struct_member_type (type, 2) == DBUS_TYPE_G_OBJECT_PATH); + { + GValueArray *instance; + GValue val = {0, }; + GValue memval = {0, }; + + instance = dbus_g_type_specialized_construct (type); + + g_assert (instance->n_values == 3); + + g_value_init (&val, type); + g_value_set_boxed_take_ownership (&val, instance); + + g_value_init (&memval, G_TYPE_STRING); + g_value_set_static_string (&memval, "foo"); + dbus_g_type_struct_set_member (&val, 0, &memval); + g_value_unset (&memval); + + g_value_init (&memval, G_TYPE_UINT); + g_value_set_uint (&memval, 42); + dbus_g_type_struct_set_member (&val, 1, &memval); + g_value_unset (&memval); + + g_value_init (&memval, DBUS_TYPE_G_OBJECT_PATH); + g_value_set_static_boxed (&memval, "/bar/moo/foo/baz"); + dbus_g_type_struct_set_member (&val, 2, &memval); + g_value_unset (&memval); + + g_assert (instance->n_values == 3); + + g_value_init (&memval, G_TYPE_STRING); + dbus_g_type_struct_get_member (&val, 0, &memval); + g_assert (0 == strcmp (g_value_get_string (&memval), "foo")); + g_value_unset (&memval); + + g_value_init (&memval, G_TYPE_UINT); + dbus_g_type_struct_get_member (&val, 1, &memval); + g_assert (g_value_get_uint (&memval) == 42); + g_value_unset (&memval); + + g_value_init (&memval, DBUS_TYPE_G_OBJECT_PATH); + dbus_g_type_struct_get_member (&val, 2, &memval); + g_assert (0 == strcmp ((gchar*) g_value_get_boxed (&memval), + "/bar/moo/foo/baz")); + g_value_unset (&memval); + + g_value_unset (&val); + } + + type = dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_UINT, DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); + g_assert (dbus_g_type_is_struct (type)); + g_assert (dbus_g_type_get_struct_size (type) == 3); + g_assert (dbus_g_type_get_struct_member_type (type, 0) == G_TYPE_STRING); + g_assert (dbus_g_type_get_struct_member_type (type, 1) == G_TYPE_UINT); + g_assert (dbus_g_type_get_struct_member_type (type, 2) == DBUS_TYPE_G_OBJECT_PATH); + { + GValueArray *instance; + GValue val = {0, }; + + instance = dbus_g_type_specialized_construct (type); + + g_assert (instance->n_values == 3); + + g_value_init (&val, type); + g_value_set_boxed_take_ownership (&val, instance); + + dbus_g_type_struct_set (&val, + 0,"foo", + 1, 42, + 2, "/bar/moo/foo/baz", + G_MAXUINT); + + g_assert (instance->n_values == 3); + + { + gchar *string; + guint intval; + gchar *path; + + dbus_g_type_struct_get (&val, + 0, &string, + 1, &intval, + 2, &path, + G_MAXUINT); + + g_assert (0 == strcmp (string, "foo")); + g_assert (intval == 42); + g_assert (0 == strcmp (path, "/bar/moo/foo/baz")); + } + + g_value_unset (&val); + } + + return TRUE; } |