summaryrefslogtreecommitdiffstats
path: root/glib/dbus-gvalue-utils.c
diff options
context:
space:
mode:
authorRobert McQueen <robot101@debian.org>2006-02-13 22:30:11 +0000
committerRobert McQueen <robot101@debian.org>2006-02-13 22:30:11 +0000
commit4a48fff0c7c0377d68d1e24cc113e275057b4800 (patch)
tree729444babf3951c53d44b9be4f0569cc173f81a8 /glib/dbus-gvalue-utils.c
parent385c443cc7aacaadbdef391d3951699a7511fbb2 (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.c184
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;
}