summaryrefslogtreecommitdiffstats
path: root/glib/dbus-gvalue.c
diff options
context:
space:
mode:
Diffstat (limited to 'glib/dbus-gvalue.c')
-rw-r--r--glib/dbus-gvalue.c402
1 files changed, 210 insertions, 192 deletions
diff --git a/glib/dbus-gvalue.c b/glib/dbus-gvalue.c
index 4e7495c7..88397731 100644
--- a/glib/dbus-gvalue.c
+++ b/glib/dbus-gvalue.c
@@ -22,6 +22,8 @@
*
*/
+#include "config.h"
+#include "dbus-gtest.h"
#include "dbus-gvalue.h"
#include "dbus-gobject.h"
#include "dbus-gvalue-utils.h"
@@ -76,12 +78,6 @@ static gboolean demarshal_variant (DBusGValueMarshalCtx *cont
DBusMessageIter *iter,
GValue *value,
GError **error);
-static gboolean marshal_garray_basic (DBusMessageIter *iter,
- const GValue *value);
-static gboolean demarshal_garray_basic (DBusGValueMarshalCtx *context,
- DBusMessageIter *iter,
- GValue *value,
- GError **error);
static gboolean marshal_proxy (DBusMessageIter *iter,
const GValue *value);
static gboolean demarshal_proxy (DBusGValueMarshalCtx *context,
@@ -102,17 +98,29 @@ static gboolean demarshal_object (DBusGValueMarshalCtx *cont
GError **error);
static gboolean marshal_map (DBusMessageIter *iter,
const GValue *value);
-static gboolean demarshal_ghashtable (DBusGValueMarshalCtx *context,
+static gboolean demarshal_map (DBusGValueMarshalCtx *context,
DBusMessageIter *iter,
GValue *value,
GError **error);
static gboolean marshal_collection (DBusMessageIter *iter,
const GValue *value);
+static gboolean marshal_collection_ptrarray (DBusMessageIter *iter,
+ const GValue *value);
+static gboolean marshal_collection_array (DBusMessageIter *iter,
+ const GValue *value);
static gboolean demarshal_collection (DBusGValueMarshalCtx *context,
DBusMessageIter *iter,
GValue *value,
GError **error);
+static gboolean demarshal_collection_ptrarray (DBusGValueMarshalCtx *context,
+ DBusMessageIter *iter,
+ GValue *value,
+ GError **error);
+static gboolean demarshal_collection_array (DBusGValueMarshalCtx *context,
+ DBusMessageIter *iter,
+ GValue *value,
+ GError **error);
static gboolean marshal_recurse (DBusMessageIter *iter,
const GValue *value);
@@ -198,30 +206,6 @@ register_basic (int typecode, const DBusGTypeMarshalData *typedata)
set_type_metadata (basic_typecode_to_gtype (typecode), typedata);
}
-static void
-register_array (int typecode, const DBusGTypeMarshalData *typedata)
-{
- GType elt_gtype;
- GType gtype;
-
- elt_gtype = basic_typecode_to_gtype (typecode);
- gtype = dbus_g_type_get_collection ("GArray", elt_gtype);
- set_type_metadata (gtype, typedata);
-}
-
-static void
-register_dict (int key_type, int value_type, const DBusGTypeMarshalData *typedata)
-{
- GType key_gtype;
- GType value_gtype;
- GType gtype;
-
- key_gtype = basic_typecode_to_gtype (key_type);
- value_gtype = basic_typecode_to_gtype (value_type);
- gtype = dbus_g_type_get_map ("GHashTable", key_gtype, value_gtype);
- set_type_metadata (gtype, typedata);
-}
-
void
dbus_g_value_types_init (void)
{
@@ -240,14 +224,6 @@ dbus_g_value_types_init (void)
marshal_basic,
demarshal_basic
};
- static const DBusGTypeMarshalVtable garray_basic_vtable = {
- marshal_garray_basic,
- demarshal_garray_basic
- };
- static const DBusGTypeMarshalVtable ghashtable_vtable = {
- marshal_map,
- demarshal_ghashtable
- };
/* Register basic types */
{
@@ -374,56 +350,8 @@ dbus_g_value_types_init (void)
set_type_metadata (G_TYPE_STRV, &typedata);
};
- {
- static const DBusGTypeMarshalData typedata = {
- DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BOOLEAN_AS_STRING,
- &garray_basic_vtable
- };
- register_array (DBUS_TYPE_BOOLEAN, &typedata);
- }
- {
- static const DBusGTypeMarshalData typedata = {
- DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
- &garray_basic_vtable
- };
- register_array (DBUS_TYPE_BYTE, &typedata);
- }
- {
- static const DBusGTypeMarshalData typedata = {
- DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
- &garray_basic_vtable
- };
- register_array (DBUS_TYPE_UINT32, &typedata);
- }
- {
- static const DBusGTypeMarshalData typedata = {
- DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING,
- &garray_basic_vtable
- };
- register_array (DBUS_TYPE_INT32, &typedata);
- }
- {
- static const DBusGTypeMarshalData typedata = {
- DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_UINT64_AS_STRING,
- &garray_basic_vtable
- };
- register_array (DBUS_TYPE_UINT64, &typedata);
- }
- {
- static const DBusGTypeMarshalData typedata = {
- DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT64_AS_STRING,
- &garray_basic_vtable
- };
- register_array (DBUS_TYPE_INT64, &typedata);
- }
- {
- static const DBusGTypeMarshalData typedata = {
- DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
- &ghashtable_vtable,
- };
- register_dict (DBUS_TYPE_STRING, DBUS_TYPE_STRING, &typedata);
- }
+ /* Register some types specific to the D-BUS GLib bindings */
{
static const DBusGTypeMarshalVtable vtable = {
marshal_proxy,
@@ -535,6 +463,7 @@ dbus_g_value_iterator_get_values (DBusGValueIterator *iter,
context.gconnection = (iterval->value.recurse.toplevel)->value.toplevel.connection;
context.proxy = (iterval->value.recurse.toplevel)->value.toplevel.proxy;
+
if (!dbus_gvalue_demarshal (&context,
&(iterval->value.recurse.iterator),
value,
@@ -661,6 +590,10 @@ dbus_gtype_from_signature_iter (DBusSignatureIter *iter, gboolean is_client)
DBusSignatureIter subiter;
g_assert (dbus_type_is_container (current_type));
+
+ if (current_type == DBUS_TYPE_VARIANT)
+ return g_value_get_type ();
+
dbus_signature_iter_recurse (iter, &subiter);
if (current_type == DBUS_TYPE_ARRAY)
@@ -673,8 +606,6 @@ dbus_gtype_from_signature_iter (DBusSignatureIter *iter, gboolean is_client)
}
else if (current_type == DBUS_TYPE_STRUCT)
return signature_iter_to_g_type_struct (&subiter, is_client);
- else if (current_type == DBUS_TYPE_VARIANT)
- return g_value_get_type ();
else if (current_type == DBUS_TYPE_DICT_ENTRY)
return G_TYPE_INVALID;
else
@@ -721,10 +652,6 @@ dbus_gtype_to_signature (GType gtype)
char *ret;
DBusGTypeMarshalData *typedata;
- typedata = g_type_get_qdata (gtype, dbus_g_type_metadata_data_quark ());
- if (typedata == NULL)
- return NULL;
-
if (dbus_g_type_is_collection (gtype))
{
GType elt_gtype;
@@ -751,7 +678,12 @@ dbus_gtype_to_signature (GType gtype)
g_free (val_subsig);
}
else
- ret = g_strdup (typedata->sig);
+ {
+ typedata = g_type_get_qdata (gtype, dbus_g_type_metadata_data_quark ());
+ if (typedata == NULL)
+ return NULL;
+ ret = g_strdup (typedata->sig);
+ }
return ret;
}
@@ -1066,53 +998,18 @@ demarshal_strv (DBusGValueMarshalCtx *context,
}
static gboolean
-demarshal_garray_basic (DBusGValueMarshalCtx *context,
- DBusMessageIter *iter,
- GValue *value,
- GError **error)
-{
- DBusMessageIter subiter;
- GArray *ret;
- GType elt_gtype;
- int elt_size;
- void *msgarray;
- int msgarray_len;
-
- dbus_message_iter_recurse (iter, &subiter);
-
- elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value));
- g_assert (elt_gtype != G_TYPE_INVALID);
- g_assert (dbus_g_type_is_fixed (elt_gtype));
-
- elt_size = dbus_g_type_fixed_get_size (elt_gtype);
-
- ret = g_array_new (FALSE, TRUE, elt_size);
-
- msgarray = NULL;
- dbus_message_iter_get_fixed_array (&subiter,
- &msgarray,
- &msgarray_len);
- g_assert (msgarray != NULL);
- g_assert (msgarray_len >= 0);
- g_array_append_vals (ret, msgarray, (guint) msgarray_len);
-
- g_value_set_boxed_take_ownership (value, ret);
-
- return TRUE;
-}
-
-static gboolean
-demarshal_ghashtable (DBusGValueMarshalCtx *context,
- DBusMessageIter *iter,
- GValue *value,
- GError **error)
+demarshal_map (DBusGValueMarshalCtx *context,
+ DBusMessageIter *iter,
+ GValue *value,
+ GError **error)
{
GType gtype;
DBusMessageIter subiter;
int current_type;
- GHashTable *ret;
+ gpointer ret;
GType key_gtype;
GType value_gtype;
+ DBusGTypeSpecializedAppendContext appendctx;
current_type = dbus_message_iter_get_arg_type (iter);
if (current_type != DBUS_TYPE_ARRAY)
@@ -1140,14 +1037,12 @@ demarshal_ghashtable (DBusGValueMarshalCtx *context,
}
key_gtype = dbus_g_type_get_map_key_specialization (gtype);
- g_assert (dbus_gtype_is_valid_hash_key (key_gtype));
value_gtype = dbus_g_type_get_map_value_specialization (gtype);
- g_assert (dbus_gtype_is_valid_hash_value (value_gtype));
- ret = g_hash_table_new_full (dbus_g_hash_func_from_gtype (key_gtype),
- dbus_g_hash_equal_from_gtype (key_gtype),
- dbus_g_hash_free_from_gtype (key_gtype),
- dbus_g_hash_free_from_gtype (value_gtype));
+ ret = dbus_g_type_specialized_construct (gtype);
+ g_value_set_boxed_take_ownership (value, ret);
+
+ dbus_g_type_specialized_init_append (value, &appendctx);
while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
{
@@ -1176,14 +1071,11 @@ demarshal_ghashtable (DBusGValueMarshalCtx *context,
error))
return FALSE;
- dbus_g_hash_table_insert_steal_values (ret,
- &key_value,
- &value_value);
- /* Ownership of values passes to hash table, don't unset */
+ dbus_g_type_specialized_map_append (&appendctx, &key_value, &value_value);
+ /* Ownership of values passes to map, don't unset */
dbus_message_iter_next (&subiter);
}
- g_value_set_boxed_take_ownership (value, ret);
return TRUE;
}
@@ -1200,6 +1092,8 @@ get_type_demarshaller (GType type)
return demarshal_recurse;
if (dbus_g_type_is_collection (type))
return demarshal_collection;
+ if (dbus_g_type_is_map (type))
+ return demarshal_map;
g_warning ("No demarshaller registered for type \"%s\"", g_type_name (type));
return NULL;
@@ -1216,6 +1110,24 @@ demarshal_collection (DBusGValueMarshalCtx *context,
{
GType coltype;
GType subtype;
+
+ coltype = G_VALUE_TYPE (value);
+ subtype = dbus_g_type_get_collection_specialization (coltype);
+
+ if (dbus_g_type_is_fixed (subtype))
+ return demarshal_collection_array (context, iter, value, error);
+ else
+ return demarshal_collection_ptrarray (context, iter, value, error);
+}
+
+static gboolean
+demarshal_collection_ptrarray (DBusGValueMarshalCtx *context,
+ DBusMessageIter *iter,
+ GValue *value,
+ GError **error)
+{
+ GType coltype;
+ GType subtype;
gpointer instance;
DBusGTypeSpecializedAppendContext ctx;
DBusGValueDemarshalFunc demarshaller;
@@ -1254,7 +1166,7 @@ demarshal_collection (DBusGValueMarshalCtx *context,
instance = dbus_g_type_specialized_construct (coltype);
g_value_set_boxed_take_ownership (value, instance);
- dbus_g_type_specialized_collection_init_append (value, &ctx);
+ dbus_g_type_specialized_init_append (value, &ctx);
while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
{
@@ -1278,6 +1190,42 @@ demarshal_collection (DBusGValueMarshalCtx *context,
}
static gboolean
+demarshal_collection_array (DBusGValueMarshalCtx *context,
+ DBusMessageIter *iter,
+ GValue *value,
+ GError **error)
+{
+ DBusMessageIter subiter;
+ GArray *ret;
+ GType elt_gtype;
+ int elt_size;
+ void *msgarray;
+ int msgarray_len;
+
+ dbus_message_iter_recurse (iter, &subiter);
+
+ elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value));
+ g_assert (elt_gtype != G_TYPE_INVALID);
+ g_assert (dbus_g_type_is_fixed (elt_gtype));
+
+ elt_size = dbus_g_type_fixed_get_size (elt_gtype);
+
+ ret = g_array_new (FALSE, TRUE, elt_size);
+
+ msgarray = NULL;
+ dbus_message_iter_get_fixed_array (&subiter,
+ &msgarray,
+ &msgarray_len);
+ g_assert (msgarray != NULL);
+ g_assert (msgarray_len >= 0);
+ g_array_append_vals (ret, msgarray, (guint) msgarray_len);
+
+ g_value_set_boxed_take_ownership (value, ret);
+
+ return TRUE;
+}
+
+static gboolean
demarshal_recurse (DBusGValueMarshalCtx *context,
DBusMessageIter *iter,
GValue *value,
@@ -1545,50 +1493,6 @@ marshal_strv (DBusMessageIter *iter,
}
static gboolean
-marshal_garray_basic (DBusMessageIter *iter,
- const GValue *value)
-{
- GType elt_gtype;
- DBusMessageIter subiter;
- GArray *array;
- guint elt_size;
- char *subsignature_str;
-
- elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value));
- /* FIXME - this means we can't send an array of DBusGValue right now... */
- subsignature_str = dbus_gtype_to_signature (elt_gtype);
- g_assert (subsignature_str != NULL);
-
- elt_size = dbus_g_type_fixed_get_size (elt_gtype);
-
- array = g_value_get_boxed (value);
-
- if (!dbus_message_iter_open_container (iter,
- DBUS_TYPE_ARRAY,
- subsignature_str,
- &subiter))
- goto oom;
-
- /* TODO - This assumes that basic values are the same size
- * is this always true? If it is we can probably avoid
- * a lot of the overhead in _marshal_basic_instance...
- */
- if (!dbus_message_iter_append_fixed_array (&subiter,
- subsignature_str[0],
- &(array->data),
- array->len))
- goto oom;
-
- if (!dbus_message_iter_close_container (iter, &subiter))
- goto oom;
- g_free (subsignature_str);
- return TRUE;
- oom:
- g_error ("out of memory");
- return FALSE;
-}
-
-static gboolean
marshal_proxy (DBusMessageIter *iter,
const GValue *value)
{
@@ -1791,6 +1695,8 @@ get_type_marshaller (GType type)
return marshal_recurse;
if (dbus_g_type_is_collection (type))
return marshal_collection;
+ if (dbus_g_type_is_map (type))
+ return marshal_map;
g_warning ("No marshaller registered for type \"%s\"", g_type_name (type));
return NULL;
@@ -1824,6 +1730,22 @@ marshal_collection (DBusMessageIter *iter,
const GValue *value)
{
GType coltype;
+ GType subtype;
+
+ coltype = G_VALUE_TYPE (value);
+ subtype = dbus_g_type_get_collection_specialization (coltype);
+
+ if (dbus_g_type_is_fixed (subtype))
+ return marshal_collection_array (iter, value);
+ else
+ return marshal_collection_ptrarray (iter, value);
+}
+
+static gboolean
+marshal_collection_ptrarray (DBusMessageIter *iter,
+ const GValue *value)
+{
+ GType coltype;
GType elt_gtype;
DBusGValueCollectionMarshalData data;
DBusMessageIter subiter;
@@ -1861,6 +1783,51 @@ marshal_collection (DBusMessageIter *iter,
return FALSE;
}
+
+static gboolean
+marshal_collection_array (DBusMessageIter *iter,
+ const GValue *value)
+{
+ GType elt_gtype;
+ DBusMessageIter subiter;
+ GArray *array;
+ guint elt_size;
+ char *subsignature_str;
+
+ elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value));
+ g_assert (dbus_g_type_is_fixed (elt_gtype));
+ subsignature_str = dbus_gtype_to_signature (elt_gtype);
+ g_assert (subsignature_str != NULL);
+
+ elt_size = dbus_g_type_fixed_get_size (elt_gtype);
+
+ array = g_value_get_boxed (value);
+
+ if (!dbus_message_iter_open_container (iter,
+ DBUS_TYPE_ARRAY,
+ subsignature_str,
+ &subiter))
+ goto oom;
+
+ /* TODO - This assumes that basic values are the same size
+ * is this always true? If it is we can probably avoid
+ * a lot of the overhead in _marshal_basic_instance...
+ */
+ if (!dbus_message_iter_append_fixed_array (&subiter,
+ subsignature_str[0],
+ &(array->data),
+ array->len))
+ goto oom;
+
+ if (!dbus_message_iter_close_container (iter, &subiter))
+ goto oom;
+ g_free (subsignature_str);
+ return TRUE;
+ oom:
+ g_error ("out of memory");
+ return FALSE;
+}
+
static gboolean
marshal_recurse (DBusMessageIter *iter,
const GValue *value)
@@ -1882,3 +1849,54 @@ dbus_gvalue_marshal (DBusMessageIter *iter,
return FALSE;
return marshaller (iter, value);
}
+
+#ifdef DBUS_BUILD_TESTS
+
+static void
+assert_type_maps_to (GType gtype, const char *expected_sig)
+{
+ char *sig;
+ sig = dbus_gtype_to_signature (gtype);
+ g_assert (sig != NULL);
+ g_assert (!strcmp (expected_sig, sig));
+ g_free (sig);
+}
+
+static void
+assert_signature_maps_to (const char *sig, GType expected_gtype)
+{
+ g_assert (dbus_gtype_from_signature (sig, TRUE) == expected_gtype);
+}
+
+static void
+assert_bidirectional_mapping (GType gtype, const char *expected_sig)
+{
+ assert_type_maps_to (gtype, expected_sig);
+ assert_signature_maps_to (expected_sig, gtype);
+}
+
+/**
+ * @ingroup DBusGLibInternals
+ * Unit test for general glib stuff
+ * @returns #TRUE on success.
+ */
+gboolean
+_dbus_gvalue_test (const char *test_data_dir)
+{
+ dbus_g_value_types_init ();
+
+ assert_bidirectional_mapping (G_TYPE_STRING, DBUS_TYPE_STRING_AS_STRING);
+ assert_bidirectional_mapping (G_TYPE_UCHAR, DBUS_TYPE_BYTE_AS_STRING);
+ assert_bidirectional_mapping (G_TYPE_UINT, DBUS_TYPE_UINT32_AS_STRING);
+
+ 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);
+ 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);
+
+ return TRUE;
+}
+
+#endif /* DBUS_BUILD_TESTS */