dbus/glib dbus-binding-tool-glib.c, 1.26, 1.27 dbus-gmain.c, 1.48,
1.49 dbus-gsignature.c, 1.1, 1.2 dbus-gtype-specialized.c, 1.4,
1.5 dbus-gtype-specialized.h, 1.4, 1.5 dbus-gvalue-utils.c,
1.8, 1.9 dbus-gvalue-utils.h, 1.4, 1.5 dbus-gvalue.c, 1.25, 1.26
Robert McQueen
robot101 at freedesktop.org
Mon Feb 13 14:30:13 PST 2006
Update of /cvs/dbus/dbus/glib
In directory gabe:/tmp/cvs-serv8556/glib
Modified Files:
dbus-binding-tool-glib.c dbus-gmain.c dbus-gsignature.c
dbus-gtype-specialized.c dbus-gtype-specialized.h
dbus-gvalue-utils.c dbus-gvalue-utils.h dbus-gvalue.c
Log Message:
2006-02-13 Robert McQueen <robot101 at 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 at 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.
Index: dbus-binding-tool-glib.c
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-binding-tool-glib.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- dbus-binding-tool-glib.c 27 Jan 2006 16:40:53 -0000 1.26
+++ dbus-binding-tool-glib.c 13 Feb 2006 22:30:11 -0000 1.27
@@ -98,6 +98,10 @@
dbus_g_type_get_c_name (GType gtype)
{
GType subtype;
+ if (dbus_g_type_is_struct (gtype))
+ {
+ return "GValueArray";
+ }
if (dbus_g_type_is_collection (gtype))
{
subtype = dbus_g_type_get_collection_specialization(gtype);
@@ -1050,6 +1054,28 @@
g_free (value_lookup);
return type_lookup;
}
+ else if (dbus_g_type_is_struct (gtype))
+ {
+ GType value_gtype;
+ GString *string;
+ char *value_lookup = NULL;
+ guint size, i;
+
+ string = g_string_new ("dbus_g_type_get_struct (\"GValueArray\"");
+
+ size = dbus_g_type_get_struct_size (gtype);
+ for (i=0; i < size; i++)
+ {
+ value_gtype = dbus_g_type_get_struct_member_type(gtype, i);
+ value_lookup = dbus_g_type_get_lookup_function (value_gtype);
+ g_assert (value_lookup);
+ g_string_append_printf (string, ", %s", value_lookup);
+ g_free (value_lookup);
+ }
+ g_string_append (string, ", G_TYPE_INVALID)");
+ return g_string_free (string, FALSE);
+ }
+
MAP_KNOWN(G_TYPE_VALUE);
MAP_KNOWN(G_TYPE_STRV);
MAP_KNOWN(G_TYPE_VALUE_ARRAY);
Index: dbus-gmain.c
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gmain.c,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -d -r1.48 -r1.49
--- dbus-gmain.c 30 Nov 2005 18:48:11 -0000 1.48
+++ dbus-gmain.c 13 Feb 2006 22:30:11 -0000 1.49
@@ -754,14 +754,14 @@
rectype = dbus_g_type_get_collection ("GArray", G_TYPE_UINT);
g_assert (rectype != G_TYPE_INVALID);
- g_assert (!strcmp (g_type_name (rectype), "GArray+guint"));
+ g_assert (!strcmp (g_type_name (rectype), "GArray_guint_"));
type = _dbus_gtype_from_signature ("au", TRUE);
g_assert (type == rectype);
rectype = dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING);
g_assert (rectype != G_TYPE_INVALID);
- g_assert (!strcmp (g_type_name (rectype), "GHashTable+gchararray+gchararray"));
+ g_assert (!strcmp (g_type_name (rectype), "GHashTable_gchararray+gchararray_"));
type = _dbus_gtype_from_signature ("a{ss}", TRUE);
g_assert (type == rectype);
Index: dbus-gsignature.c
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gsignature.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- dbus-gsignature.c 4 Aug 2005 15:49:30 -0000 1.1
+++ dbus-gsignature.c 13 Feb 2006 22:30:11 -0000 1.2
@@ -117,6 +117,25 @@
return G_TYPE_INVALID;
}
+static GType
+signature_iter_to_g_type_struct (DBusSignatureIter *iter, gboolean is_client)
+{
+ GArray *types;
+ GType ret;
+ types = g_array_new (FALSE, FALSE, sizeof (GType));
+ do
+ {
+ GType curtype;
+ curtype = _dbus_gtype_from_signature_iter (iter, is_client);
+ g_array_append_val (types, curtype);
+ }
+ while (dbus_signature_iter_next (iter));
+
+ ret = dbus_g_type_get_structv ("GValueArray", types->len, (GType*) types->data);
+ g_array_free (types, TRUE);
+ return ret;
+}
+
GType
_dbus_gtype_from_signature_iter (DBusSignatureIter *iter, gboolean is_client)
{
@@ -136,8 +155,6 @@
if (current_type == DBUS_TYPE_VARIANT)
return G_TYPE_VALUE;
- if (current_type == DBUS_TYPE_STRUCT)
- return G_TYPE_VALUE_ARRAY;
dbus_signature_iter_recurse (iter, &subiter);
@@ -149,6 +166,10 @@
else
return signature_iter_to_g_type_array (&subiter, is_client);
}
+ else if (current_type == DBUS_TYPE_STRUCT)
+ {
+ return signature_iter_to_g_type_struct (&subiter, is_client);
+ }
else
{
g_assert_not_reached ();
Index: dbus-gtype-specialized.c
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gtype-specialized.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- dbus-gtype-specialized.c 27 Jan 2006 15:40:36 -0000 1.4
+++ dbus-gtype-specialized.c 13 Feb 2006 22:30:11 -0000 1.5
@@ -28,7 +28,8 @@
typedef enum {
DBUS_G_SPECTYPE_COLLECTION,
- DBUS_G_SPECTYPE_MAP
+ DBUS_G_SPECTYPE_MAP,
+ DBUS_G_SPECTYPE_STRUCT
} DBusGTypeSpecializedType;
typedef struct {
@@ -37,7 +38,8 @@
} DBusGTypeSpecializedContainer;
typedef struct {
- GType types[6];
+ guint num_types;
+ GType *types;
const DBusGTypeSpecializedContainer *klass;
} DBusGTypeSpecializedData;
@@ -71,6 +73,7 @@
return g_type_get_qdata (type, specialized_type_data_quark ());
}
+
/* Copied from gboxed.c */
static void
proxy_value_init (GValue *value)
@@ -151,7 +154,9 @@
value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;
}
else
- value->data[0].v_pointer = data->klass->vtable->copy_func (type, collect_values[0].v_pointer);
+ {
+ value->data[0].v_pointer = data->klass->vtable->copy_func (type, collect_values[0].v_pointer);
+ }
}
return NULL;
@@ -188,18 +193,21 @@
}
static char *
-build_specialization_name (const char *prefix, GType first_type, GType second_type)
+build_specialization_name (const char *prefix, guint num_types, GType *types)
{
GString *fullname;
+ guint i;
fullname = g_string_new (prefix);
- g_string_append_c (fullname, '+');
- g_string_append (fullname, g_type_name (first_type));
- if (second_type != G_TYPE_INVALID)
+
+ g_string_append_c (fullname, '_');
+ for (i=0; i < num_types; i++)
{
- g_string_append_c (fullname, '+');
- g_string_append (fullname, g_type_name (second_type));
+ if (i!=0)
+ g_string_append_c (fullname, '+');
+ g_string_append (fullname, g_type_name (types[i]));
}
+ g_string_append_c (fullname, '_');
return g_string_free (fullname, FALSE);
}
@@ -235,6 +243,16 @@
register_container (name, DBUS_G_SPECTYPE_MAP, (const DBusGTypeSpecializedVtable*) vtable);
}
+void
+dbus_g_type_register_struct (const char *name,
+ const DBusGTypeSpecializedStructVtable *vtable,
+ guint flags)
+{
+ g_return_if_fail (specialized_types_is_initialized ());
+ register_container (name, DBUS_G_SPECTYPE_STRUCT, (const DBusGTypeSpecializedVtable*) vtable);
+}
+
+
const DBusGTypeSpecializedMapVtable* dbus_g_type_map_peek_vtable (GType map_type)
{
DBusGTypeSpecializedData *data;
@@ -257,12 +275,22 @@
return (DBusGTypeSpecializedCollectionVtable *)(data->klass->vtable);
}
+const DBusGTypeSpecializedStructVtable* dbus_g_type_struct_peek_vtable (GType struct_type)
+{
+ DBusGTypeSpecializedData *data;
+ g_return_val_if_fail (dbus_g_type_is_struct (struct_type), NULL);
+
+ data = lookup_specialization_data (struct_type);
+ g_assert (data != NULL);
+
+ return (DBusGTypeSpecializedStructVtable *)(data->klass->vtable);
+}
static GType
register_specialized_instance (const DBusGTypeSpecializedContainer *klass,
char *name,
- GType first_type,
- GType second_type)
+ guint num_types,
+ GType *types)
{
GType ret;
@@ -297,8 +325,8 @@
{
DBusGTypeSpecializedData *data;
data = g_new0 (DBusGTypeSpecializedData, 1);
- data->types[0] = first_type;
- data->types[1] = second_type;
+ data->num_types = num_types;
+ data->types = g_memdup (types, sizeof (GType) * num_types);
data->klass = klass;
g_type_set_qdata (ret, specialized_type_data_quark (), data);
}
@@ -308,8 +336,8 @@
static GType
lookup_or_register_specialized (const char *container,
- GType first_type,
- GType second_type)
+ guint num_types,
+ GType *types)
{
GType ret;
char *name;
@@ -320,14 +348,14 @@
klass = g_hash_table_lookup (specialized_containers, container);
g_return_val_if_fail (klass != NULL, G_TYPE_INVALID);
- name = build_specialization_name (container, first_type, second_type);
+ name = build_specialization_name (container, num_types, types);
ret = g_type_from_name (name);
if (ret == G_TYPE_INVALID)
{
/* Take ownership of name */
ret = register_specialized_instance (klass, name,
- first_type,
- second_type);
+ num_types,
+ types);
}
else
g_free (name);
@@ -338,7 +366,7 @@
dbus_g_type_get_collection (const char *container,
GType specialization)
{
- return lookup_or_register_specialized (container, specialization, G_TYPE_INVALID);
+ return lookup_or_register_specialized (container, 1, &specialization);
}
GType
@@ -346,9 +374,42 @@
GType key_specialization,
GType value_specialization)
{
- return lookup_or_register_specialized (container, key_specialization, value_specialization);
+ GType types[2] = {key_specialization, value_specialization};
+ return lookup_or_register_specialized (container, 2, types);
+}
+
+GType
+dbus_g_type_get_structv (const char *container,
+ guint num_items,
+ GType *types)
+{
+ return lookup_or_register_specialized (container, num_items, types);
}
+GType
+dbus_g_type_get_struct (const char *container,
+ GType first_type,
+ ...)
+{
+ GArray *types;
+ GType curtype;
+ va_list args;
+ va_start (args, first_type);
+
+ types = g_array_new (FALSE, FALSE, sizeof (GType));
+ curtype = first_type;
+ while (curtype != G_TYPE_INVALID)
+ {
+ g_array_append_val (types, curtype);
+ curtype = va_arg (args, GType);
+ }
+ va_end (args);
+ return lookup_or_register_specialized (container, types->len, (GType*)types->data);
+
+}
+
+
+
gboolean
dbus_g_type_is_collection (GType gtype)
{
@@ -369,13 +430,27 @@
return data->klass->type == DBUS_G_SPECTYPE_MAP;
}
+gboolean
+dbus_g_type_is_struct (GType gtype)
+{
+ DBusGTypeSpecializedData *data;
+ data = lookup_specialization_data (gtype);
+ if (data == NULL)
+ return FALSE;
+ return data->klass->type == DBUS_G_SPECTYPE_STRUCT;
+}
+
+
static GType
get_specialization_index (GType gtype, guint i)
{
DBusGTypeSpecializedData *data;
data = lookup_specialization_data (gtype);
- return data->types[i];
+ if (i < data->num_types)
+ return data->types[i];
+ else
+ return G_TYPE_INVALID;
}
GType
@@ -399,6 +474,25 @@
return get_specialization_index (gtype, 1);
}
+GType
+dbus_g_type_get_struct_member_type (GType gtype, guint index)
+{
+ g_return_val_if_fail (dbus_g_type_is_struct (gtype), G_TYPE_INVALID);
+ return get_specialization_index (gtype, index);
+}
+
+guint
+dbus_g_type_get_struct_size (GType gtype)
+{
+ DBusGTypeSpecializedData *data;
+ g_return_val_if_fail (dbus_g_type_is_struct (gtype), G_TYPE_INVALID);
+
+ data = lookup_specialization_data (gtype);
+ return data->num_types;
+}
+
+
+
gpointer
dbus_g_type_specialized_construct (GType type)
{
@@ -469,7 +563,8 @@
gtype = G_VALUE_TYPE (value);
specdata = lookup_specialization_data (gtype);
g_return_if_fail (specdata != NULL);
-
+ g_return_if_fail (specdata->num_types != 0);
+
realctx->val = value;
realctx->specialization_type = specdata->types[0];
realctx->specdata = specdata;
@@ -519,3 +614,160 @@
g_value_get_boxed (value),
iterator, user_data);
}
+
+gboolean
+dbus_g_type_struct_get_member (const GValue *value,
+ guint index,
+ GValue *dest)
+{
+ DBusGTypeSpecializedData *data;
+ GType gtype;
+
+ g_return_val_if_fail (specialized_types_is_initialized (), FALSE);
+ g_return_val_if_fail (G_VALUE_HOLDS_BOXED (value), FALSE);
+
+ gtype = G_VALUE_TYPE (value);
+ data = lookup_specialization_data (gtype);
+ g_return_val_if_fail (data != NULL, FALSE);
+
+ return ((DBusGTypeSpecializedStructVtable *) (data->klass->vtable))->get_member(gtype,
+ g_value_get_boxed (value),
+ index, dest);
+}
+
+gboolean
+dbus_g_type_struct_set_member (GValue *value,
+ guint index,
+ const GValue *src)
+{
+ DBusGTypeSpecializedData *data;
+ GType gtype;
+
+ g_return_val_if_fail (specialized_types_is_initialized (), FALSE);
+ g_return_val_if_fail (G_VALUE_HOLDS_BOXED (value), FALSE);
+
+ gtype = G_VALUE_TYPE (value);
+ data = lookup_specialization_data (gtype);
+ g_return_val_if_fail (data != NULL, FALSE);
+
+ return ((DBusGTypeSpecializedStructVtable *) (data->klass->vtable))->set_member(gtype,
+ g_value_get_boxed (value),
+ index, src);
+}
+
+/**
+ * dbus_g_type_struct_get:
+ * @value: a GValue containing a DBusGTypeStruct type
+ * @member: struct member to get
+ * @...: location in which to return the value of this member,
+ * followed optionally by more member/return locations pairs, followed by
+ * by G_MAXUINT
+ *
+ * Collects the selected values of this struct into the return locations
+ * provided.
+ *
+ * Returns: FALSE on failure
+ */
+
+gboolean
+dbus_g_type_struct_get (const GValue *value,
+ guint first_member,
+ ...)
+{
+ va_list var_args;
+ GType type;
+ guint size,i;
+ gchar *error;
+ GValue val = {0,};
+
+ g_return_val_if_fail (dbus_g_type_is_struct (G_VALUE_TYPE (value)), FALSE);
+
+ va_start (var_args, first_member);
+ size = dbus_g_type_get_struct_size (G_VALUE_TYPE (value));
+ i = first_member;
+ while (i != G_MAXUINT)
+ {
+ if (i >= size)
+ goto error;
+
+ type = dbus_g_type_get_struct_member_type (G_VALUE_TYPE (value),i);
+
+ g_value_init (&val, type);
+ dbus_g_type_struct_get_member (value, i, &val);
+
+ G_VALUE_LCOPY (&val, var_args, 0, &error);
+ if (error)
+ {
+ g_warning ("%s, %s", G_STRFUNC, error);
+ g_free (error);
+ g_value_unset (&val);
+ goto error;
+ }
+ g_value_unset (&val);
+ i = va_arg (var_args, guint);
+ }
+ va_end (var_args);
+ return TRUE;
+error:
+ va_end (var_args);
+ return FALSE;
+}
+
+/**
+ * dbus_g_type_struct_set:
+ * @value: a GValue containing a DBusGTypeStruct type
+ * @member: struct member to set
+ * @...: value for the first member, followed optionally by
+ * more member/value pairs, followed by G_MAXUINT
+ *
+ * Sets the selected members of the struct in @value.
+ *
+ * Returns: FALSE on failure
+ */
+
+gboolean
+dbus_g_type_struct_set (GValue *value,
+ guint first_member,
+ ...)
+{
+ va_list var_args;
+ GType type;
+ guint size,i;
+ gchar *error;
+ GValue val = {0,};
+
+ g_return_val_if_fail (dbus_g_type_is_struct (G_VALUE_TYPE (value)), FALSE);
+
+ va_start (var_args, first_member);
+ size = dbus_g_type_get_struct_size (G_VALUE_TYPE (value));
+ i = first_member;
+ while (i != G_MAXUINT)
+ {
+ if (i >= size)
+ goto error;
+
+ type = dbus_g_type_get_struct_member_type (G_VALUE_TYPE (value),i);
+
+ g_value_init (&val, type);
+
+ G_VALUE_COLLECT (&val, var_args, 0, &error);
+ if (error)
+ {
+ g_warning ("%s, %s", G_STRFUNC, error);
+ g_free (error);
+ g_value_unset (&val);
+ goto error;
+ }
+
+ dbus_g_type_struct_set_member (value, i, &val);
+
+ g_value_unset (&val);
+ i = va_arg (var_args, guint);
+ }
+ va_end (var_args);
+ return TRUE;
+error:
+ va_end (var_args);
+ return FALSE;
+}
+
Index: dbus-gtype-specialized.h
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gtype-specialized.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- dbus-gtype-specialized.h 27 Jan 2006 15:40:36 -0000 1.4
+++ dbus-gtype-specialized.h 13 Feb 2006 22:30:11 -0000 1.5
@@ -34,11 +34,21 @@
GType dbus_g_type_get_map (const char *container,
GType key_specialization,
GType value_specialization);
+GType dbus_g_type_get_structv (const char *container,
+ guint num_items,
+ GType *types);
+GType dbus_g_type_get_struct (const char *container,
+ GType first_type,
+ ...);
gboolean dbus_g_type_is_collection (GType gtype);
gboolean dbus_g_type_is_map (GType gtype);
+gboolean dbus_g_type_is_struct (GType gtype);
GType dbus_g_type_get_collection_specialization (GType gtype);
GType dbus_g_type_get_map_key_specialization (GType gtype);
GType dbus_g_type_get_map_value_specialization (GType gtype);
+GType dbus_g_type_get_struct_member_type (GType gtype,
+ guint index);
+guint dbus_g_type_get_struct_size (GType gtype);
typedef void (*DBusGTypeSpecializedCollectionIterator) (const GValue *val,
gpointer user_data);
@@ -81,6 +91,21 @@
DBusGTypeSpecializedMapIterator iterator,
gpointer user_data);
+gboolean dbus_g_type_struct_get_member (const GValue *value,
+ guint index,
+ GValue *dest);
+gboolean dbus_g_type_struct_set_member (GValue *value,
+ guint index,
+ const GValue *src);
+
+gboolean dbus_g_type_struct_get (const GValue *value,
+ guint member,
+ ...);
+
+gboolean dbus_g_type_struct_set (GValue *value,
+ guint member,
+ ...);
+
typedef gpointer (*DBusGTypeSpecializedConstructor) (GType type);
typedef void (*DBusGTypeSpecializedFreeFunc) (GType type, gpointer val);
typedef gpointer (*DBusGTypeSpecializedCopyFunc) (GType type, gpointer src);
@@ -116,6 +141,15 @@
DBusGTypeSpecializedMapAppendFunc append_func;
} DBusGTypeSpecializedMapVtable;
+typedef gboolean (*DBusGTypeSpecializedStructGetMember) (GType type, gpointer instance, guint member, GValue *ret_value);
+typedef gboolean (*DBusGTypeSpecializedStructSetMember) (GType type, gpointer instance, guint member, const GValue *new_value);
+
+typedef struct {
+ DBusGTypeSpecializedVtable base_vtable;
+ DBusGTypeSpecializedStructGetMember get_member;
+ DBusGTypeSpecializedStructSetMember set_member;
+} DBusGTypeSpecializedStructVtable;
+
void dbus_g_type_specialized_init (void);
void dbus_g_type_register_collection (const char *name,
@@ -128,6 +162,15 @@
const DBusGTypeSpecializedMapVtable* dbus_g_type_map_peek_vtable (GType map_type);
const DBusGTypeSpecializedCollectionVtable* dbus_g_type_collection_peek_vtable (GType collection_type);
+void dbus_g_type_register_struct (const char *name,
+ const DBusGTypeSpecializedStructVtable *vtable,
+ guint flags);
+
+const DBusGTypeSpecializedMapVtable* dbus_g_type_map_peek_vtable (GType map_type);
+const DBusGTypeSpecializedCollectionVtable* dbus_g_type_collection_peek_vtable (GType collection_type);
+
+const DBusGTypeSpecializedStructVtable* dbus_g_type_struct_peek_vtable (GType struct_type);
+
G_END_DECLS
#endif
Index: dbus-gvalue-utils.c
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gvalue-utils.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- dbus-gvalue-utils.c 27 Jan 2006 15:40:36 -0000 1.8
+++ dbus-gvalue-utils.c 13 Feb 2006 22:30:11 -0000 1.9
@@ -334,6 +334,16 @@
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 @@
}
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 @@
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 @@
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;
}
Index: dbus-gvalue-utils.h
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gvalue-utils.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- dbus-gvalue-utils.h 4 Aug 2005 15:49:30 -0000 1.4
+++ dbus-gvalue-utils.h 13 Feb 2006 22:30:11 -0000 1.5
@@ -29,7 +29,7 @@
G_BEGIN_DECLS
-void _dbus_g_type_specialized_builtins_init (void);
+void _dbus_g_type_specialized_builtins_init (void);
gboolean _dbus_g_type_is_fixed (GType gtype);
guint _dbus_g_type_fixed_get_size (GType gtype);
Index: dbus-gvalue.c
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gvalue.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- dbus-gvalue.c 27 Jan 2006 15:15:16 -0000 1.25
+++ dbus-gvalue.c 13 Feb 2006 22:30:11 -0000 1.26
@@ -107,6 +107,13 @@
DBusMessageIter *iter,
GValue *value,
GError **error);
+static gboolean marshal_struct (DBusMessageIter *iter,
+ const GValue *value);
+static gboolean demarshal_struct (DBusGValueMarshalCtx *context,
+ DBusMessageIter *iter,
+ GValue *value,
+ GError **error);
+
typedef gboolean (*DBusGValueMarshalFunc) (DBusMessageIter *iter,
const GValue *value);
@@ -346,6 +353,7 @@
return type_id;
}
+
char *
_dbus_gtype_to_signature (GType gtype)
{
@@ -377,6 +385,21 @@
g_free (key_subsig);
g_free (val_subsig);
}
+ else if (dbus_g_type_is_struct (gtype))
+ {
+ guint i, size;
+ GString *sig;
+ size = dbus_g_type_get_struct_size (gtype);
+ sig = g_string_sized_new (size+2); /*some sensible starting size*/
+ g_string_assign (sig, DBUS_STRUCT_BEGIN_CHAR_AS_STRING);
+ for (i=0; i < size; i++)
+ {
+ g_string_append (sig, _dbus_gtype_to_signature (
+ dbus_g_type_get_struct_member_type (gtype, i)));
+ }
+ g_string_append (sig, DBUS_STRUCT_END_CHAR_AS_STRING);
+ ret = g_string_free (sig, FALSE);
+ }
else
{
typedata = g_type_get_qdata (gtype, dbus_g_type_metadata_data_quark ());
@@ -384,7 +407,6 @@
return NULL;
ret = g_strdup (typedata->sig);
}
-
return ret;
}
@@ -851,6 +873,76 @@
return TRUE;
}
+static gboolean
+demarshal_struct (DBusGValueMarshalCtx *context,
+ DBusMessageIter *iter,
+ GValue *value,
+ GError **error)
+{
+ int current_type;
+ DBusMessageIter subiter;
+ guint i, size;
+ GValue val = {0,};
+ GType elt_type;
+
+ current_type = dbus_message_iter_get_arg_type (iter);
+ if (current_type != DBUS_TYPE_STRUCT)
+ {
+ g_set_error (error,
+ DBUS_GERROR,
+ DBUS_GERROR_INVALID_ARGS,
+ _("Expected D-BUS struct, got type code \'%c\'"), (guchar) current_type);
+ return FALSE;
+ }
+
+ dbus_message_iter_recurse (iter, &subiter);
+
+ g_value_set_boxed_take_ownership (value,
+ dbus_g_type_specialized_construct (G_VALUE_TYPE (value)));
+
+ size = dbus_g_type_get_struct_size (G_VALUE_TYPE (value));
+
+ for (i=0; i < size; i++)
+ {
+
+ elt_type = dbus_g_type_get_struct_member_type (G_VALUE_TYPE(value), i);
+ if (elt_type == G_TYPE_INVALID)
+ {
+ g_value_unset (value);
+ g_set_error (error,
+ DBUS_GERROR,
+ DBUS_GERROR_INVALID_ARGS,
+ _("Couldn't demarshal argument, "
+ "struct type %s has no member %d"),
+ g_type_name (G_VALUE_TYPE(value)), i);
+ return FALSE;
+ }
+
+ g_value_init (&val, elt_type);
+
+ if (!_dbus_gvalue_demarshal (context, &subiter, &val, error))
+ {
+ g_value_unset (&val);
+ g_value_unset (value);
+ return FALSE;
+ }
+ if (!dbus_g_type_struct_set_member (value, i, &val))
+ {
+ g_value_unset (&val);
+ g_value_unset (value);
+ return FALSE;
+ }
+
+ dbus_message_iter_next (&subiter);
+ g_value_unset (&val);
+ }
+
+ g_assert (dbus_message_iter_get_arg_type (&subiter) == DBUS_TYPE_INVALID);
+
+ return TRUE;
+}
+
+
static DBusGValueDemarshalFunc
get_type_demarshaller (GType type)
{
@@ -865,6 +957,8 @@
return demarshal_collection;
if (dbus_g_type_is_map (type))
return demarshal_map;
+ if (dbus_g_type_is_struct (type))
+ return demarshal_struct;
g_warning ("No demarshaller registered for type \"%s\"", g_type_name (type));
return NULL;
@@ -1453,6 +1547,48 @@
}
static gboolean
+marshal_struct (DBusMessageIter *iter,
+ const GValue *value)
+{
+ GType gtype;
+ DBusMessageIter subiter;
+ gboolean ret;
+ guint size, i;
+ GValue val = {0,};
+
+ gtype = G_VALUE_TYPE (value);
+
+ ret = FALSE;
+
+ size = dbus_g_type_get_struct_size (gtype);
+
+ if (!dbus_message_iter_open_container (iter,
+ DBUS_TYPE_STRUCT,
+ NULL,
+ &subiter))
+ goto oom;
+
+ for (i = 0; i < size; i++)
+ {
+ g_value_init (&val, dbus_g_type_get_struct_member_type
+ (G_VALUE_TYPE(value), i));
+ if (!dbus_g_type_struct_get_member (value, i, &val))
+ return FALSE;
+ if (!_dbus_gvalue_marshal (&subiter, &val))
+ return FALSE;
+ g_value_unset(&val);
+ }
+
+ if (!dbus_message_iter_close_container (iter, &subiter))
+ goto oom;
+
+ return TRUE;
+ oom:
+ g_error ("out of memory");
+ return FALSE;
+}
+
+static gboolean
marshal_variant (DBusMessageIter *iter,
const GValue *value)
{
@@ -1504,6 +1640,8 @@
return marshal_collection;
if (dbus_g_type_is_map (type))
return marshal_map;
+ if (dbus_g_type_is_struct (type))
+ return marshal_struct;
g_warning ("No marshaller registered for type \"%s\"", g_type_name (type));
return NULL;
@@ -1697,17 +1835,15 @@
assert_bidirectional_mapping (G_TYPE_UCHAR, DBUS_TYPE_BYTE_AS_STRING);
assert_bidirectional_mapping (G_TYPE_UINT, DBUS_TYPE_UINT32_AS_STRING);
- assert_signature_maps_to (DBUS_STRUCT_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_STRUCT_END_CHAR_AS_STRING, G_TYPE_VALUE_ARRAY);
- assert_signature_maps_to (DBUS_STRUCT_BEGIN_CHAR_AS_STRING DBUS_STRUCT_END_CHAR_AS_STRING, G_TYPE_VALUE_ARRAY);
- assert_signature_maps_to (DBUS_STRUCT_BEGIN_CHAR_AS_STRING DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_STRUCT_END_CHAR_AS_STRING, G_TYPE_VALUE_ARRAY);
-
assert_bidirectional_mapping (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
- DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING);
+ DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING);
assert_bidirectional_mapping (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING);
assert_bidirectional_mapping (dbus_g_type_get_collection ("GArray", G_TYPE_INT),
DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING);
+ assert_bidirectional_mapping (dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_STRING, DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID),
+ DBUS_STRUCT_BEGIN_CHAR_AS_STRING DBUS_TYPE_INT32_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING DBUS_STRUCT_END_CHAR_AS_STRING );
return TRUE;
}
More information about the dbus-commit
mailing list