From 622cc8af6181d7e3d839ec0bdfad376648863844 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 11 Jul 2005 16:12:50 +0000 Subject: 2005-07-11 Colin Walters * glib/dbus-gvalue.c (struct _DBusGValue): Delete. (dbus_g_value_types_init): Remove assertion. (dbus_g_value_get_g_type, dbus_g_value_open) (dbus_g_value_iterator_get_values, dbus_g_value_get_signature) (dbus_g_value_copy, dbus_g_value_free): Delete unimplemented functions related to DBusGValue. Now we marshal/demarshal structures as GValueArray. (dbus_gtype_from_signature_iter): Return G_TYPE_VALUE_ARRAY for structures. (signature_iter_to_g_type_array): Don't call signature_iter_to_g_type_struct. (signature_iter_to_g_type_struct): Delete. (dbus_gvalue_to_signature): Delete. (dbus_gvalue_to_signature): New function with same name as other one; we can convert structures to signatures. (demarshal_valuearray): New function. (get_type_demarshaller): Use it. (demarshal_recurse): Delete. (marshal_proxy): New function. (marshal_map): Warn if we can't determine signature from type. (marshal_collection_ptrarray): Ditto. (marshal_collection_array): Ditto. (get_type_marshaller): Use marshal_valuearray. (marshal_recurse): Delete. (_dbus_gvalue_test): Add some tests. * dbus/dbus-glib.h (struct _DBusGValueIterator): (dbus_g_value_get_g_type, DBUS_TYPE_G_VALUE) (dbus_g_value_open, dbus_g_value_iterator_get_value) (dbus_g_value_iterator_get_values, dbus_g_value_iterator_recurse) (dbus_g_value_free): Remove prototypes. * glib/dbus-binding-tool-glib.c (dbus_g_type_get_lookup_function): Handle G_TYPE_VALUE_ARRAY. * glib/examples/example-service.c: * glib/examples/example-client.c: Implement GetTuple. * test/glib/test-dbus-glib.c: * test/glib/test-service-glib.c: * test/glib/test-service-glib.xml: Add structure tests. --- ChangeLog | 44 +++++ dbus/dbus-glib.h | 49 ------ glib/dbus-binding-tool-glib.c | 1 + glib/dbus-gvalue.c | 358 +++++++++++++++++++--------------------- glib/examples/example-client.c | 32 +++- glib/examples/example-service.c | 21 ++- test/glib/test-dbus-glib.c | 45 +++++ test/glib/test-service-glib.c | 28 ++++ test/glib/test-service-glib.xml | 5 + 9 files changed, 331 insertions(+), 252 deletions(-) diff --git a/ChangeLog b/ChangeLog index 53023ddd..965c4623 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,47 @@ +2005-07-11 Colin Walters + + * glib/dbus-gvalue.c (struct _DBusGValue): Delete. + (dbus_g_value_types_init): Remove assertion. + (dbus_g_value_get_g_type, dbus_g_value_open) + (dbus_g_value_iterator_get_values, dbus_g_value_get_signature) + (dbus_g_value_copy, dbus_g_value_free): Delete unimplemented + functions related to DBusGValue. Now we marshal/demarshal + structures as GValueArray. + (dbus_gtype_from_signature_iter): Return G_TYPE_VALUE_ARRAY for + structures. + (signature_iter_to_g_type_array): Don't call + signature_iter_to_g_type_struct. + (signature_iter_to_g_type_struct): Delete. + (dbus_gvalue_to_signature): Delete. + (dbus_gvalue_to_signature): New function with same name as other + one; we can convert structures to signatures. + (demarshal_valuearray): New function. + (get_type_demarshaller): Use it. + (demarshal_recurse): Delete. + (marshal_proxy): New function. + (marshal_map): Warn if we can't determine signature from type. + (marshal_collection_ptrarray): Ditto. + (marshal_collection_array): Ditto. + (get_type_marshaller): Use marshal_valuearray. + (marshal_recurse): Delete. + (_dbus_gvalue_test): Add some tests. + + * dbus/dbus-glib.h (struct _DBusGValueIterator): + (dbus_g_value_get_g_type, DBUS_TYPE_G_VALUE) + (dbus_g_value_open, dbus_g_value_iterator_get_value) + (dbus_g_value_iterator_get_values, dbus_g_value_iterator_recurse) + (dbus_g_value_free): Remove prototypes. + + * glib/dbus-binding-tool-glib.c (dbus_g_type_get_lookup_function): Handle + G_TYPE_VALUE_ARRAY. + + * glib/examples/example-service.c: + * glib/examples/example-client.c: Implement GetTuple. + + * test/glib/test-dbus-glib.c: + * test/glib/test-service-glib.c: + * test/glib/test-service-glib.xml: Add structure tests. + 2005-07-10 Colin Walters * doc/TODO: Knock off some GLib items with this patch. diff --git a/dbus/dbus-glib.h b/dbus/dbus-glib.h index ad156b83..5b5095d7 100644 --- a/dbus/dbus-glib.h +++ b/dbus/dbus-glib.h @@ -115,34 +115,6 @@ void dbus_g_connection_register_g_object (DBusGConnection *connectio GObject * dbus_g_connection_lookup_g_object (DBusGConnection *connection, const char *at_path); - -/** - * Generic recursive value - */ - -typedef struct _DBusGValueIterator DBusGValueIterator; -struct _DBusGValueIterator -{ - void *dummy1; /**< Don't use this */ - void *dummy2; /**< Don't use this */ - guint32 dummy3; /**< Don't use this */ - int dummy4; /**< Don't use this */ - int dummy5; /**< Don't use this */ - int dummy6; /**< Don't use this */ - int dummy7; /**< Don't use this */ - int dummy8; /**< Don't use this */ - int dummy9; /**< Don't use this */ - int dummy10; /**< Don't use this */ - int dummy11; /**< Don't use this */ - int pad1; /**< Don't use this */ - int pad2; /**< Don't use this */ - void *pad3; /**< Don't use this */ - void *pad4; /**< Don't use this */ - void *pad5; /**< Don't use this */ -}; - -typedef struct _DBusGValue DBusGValue; - #ifdef DBUS_COMPILATION #include "glib/dbus-gtype-specialized.h" #else @@ -160,30 +132,9 @@ typedef struct _DBusGValue DBusGValue; #define DBUS_TYPE_G_STRING_STRING_HASHTABLE (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING)) -/* Generic recursive value */ -GType dbus_g_value_get_g_type (void) G_GNUC_CONST; -#define DBUS_TYPE_G_VALUE (dbus_g_value_get_g_type ()) - GType dbus_g_object_path_get_g_type (void) G_GNUC_CONST; #define DBUS_TYPE_G_OBJECT_PATH (dbus_g_object_path_get_g_type ()) -void dbus_g_value_open (DBusGValue *value, - DBusGValueIterator *iter); - -GType dbus_g_value_iterator_get_value (DBusGValueIterator *iter, - GValue *value); - -gboolean dbus_g_value_iterator_get_values (DBusGValueIterator *iter, - GError **error, - GValue *first_val, - ...); - -void dbus_g_value_iterator_recurse (DBusGValueIterator *iter, - DBusGValueIterator *sub); - -void dbus_g_value_free (DBusGValue *value); - - void dbus_g_object_register_marshaller (GClosureMarshal marshaller, GType rettype, ...); diff --git a/glib/dbus-binding-tool-glib.c b/glib/dbus-binding-tool-glib.c index 43b23c6d..39c180fd 100644 --- a/glib/dbus-binding-tool-glib.c +++ b/glib/dbus-binding-tool-glib.c @@ -1032,6 +1032,7 @@ dbus_g_type_get_lookup_function (GType gtype) } MAP_KNOWN(G_TYPE_VALUE); MAP_KNOWN(G_TYPE_STRV); + MAP_KNOWN(G_TYPE_VALUE_ARRAY); MAP_KNOWN(DBUS_TYPE_G_PROXY); MAP_KNOWN(DBUS_TYPE_G_OBJECT_PATH); return NULL; diff --git a/glib/dbus-gvalue.c b/glib/dbus-gvalue.c index 88397731..e5f019fa 100644 --- a/glib/dbus-gvalue.c +++ b/glib/dbus-gvalue.c @@ -37,29 +37,8 @@ static gboolean demarshal_static_variant (DBusGValueMarshalCtx *context, DBusMessageIter *iter, GValue *value, GError **error); -static gpointer dbus_g_value_copy (gpointer value); -struct _DBusGValue -{ - enum { - DBUS_G_VALUE_TYPE_TOPLEVEL, - DBUS_G_VALUE_TYPE_ITERATOR - } type; - union { - struct { - DBusGConnection *connection; - DBusGProxy *proxy; - DBusMessage *message; - char *signature; - } toplevel; - struct { - DBusGValue *toplevel; - DBusMessageIter iterator; - } recurse; - } value; -}; - static gboolean marshal_basic (DBusMessageIter *iter, const GValue *value); static gboolean demarshal_basic (DBusGValueMarshalCtx *context, @@ -72,6 +51,12 @@ static gboolean demarshal_strv (DBusGValueMarshalCtx *cont DBusMessageIter *iter, GValue *value, GError **error); +static gboolean marshal_valuearray (DBusMessageIter *iter, + const GValue *value); +static gboolean demarshal_valuearray (DBusGValueMarshalCtx *context, + DBusMessageIter *iter, + GValue *value, + GError **error); static gboolean marshal_variant (DBusMessageIter *iter, const GValue *value); static gboolean demarshal_variant (DBusGValueMarshalCtx *context, @@ -122,13 +107,6 @@ static gboolean demarshal_collection_array (DBusGValueMarshalCtx *cont GValue *value, GError **error); -static gboolean marshal_recurse (DBusMessageIter *iter, - const GValue *value); -static gboolean demarshal_recurse (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error); - typedef gboolean (*DBusGValueMarshalFunc) (DBusMessageIter *iter, const GValue *value); typedef gboolean (*DBusGValueDemarshalFunc) (DBusGValueMarshalCtx *context, @@ -215,8 +193,6 @@ dbus_g_value_types_init (void) if (types_initialized) return; - g_assert (sizeof (DBusGValueIterator) >= sizeof (DBusMessageIter)); - dbus_g_type_specialized_init (); dbus_g_type_specialized_builtins_init (); @@ -408,95 +384,6 @@ dbus_g_object_path_get_g_type (void) return type_id; } -/** - * Get the GLib type ID for a DBusGValue boxed type. - * - * @returns GLib type - */ -GType -dbus_g_value_get_g_type (void) -{ - static GType type_id = 0; - - if (!type_id) - type_id = g_boxed_type_register_static ("DBusGValue", - dbus_g_value_copy, - (GBoxedFreeFunc) dbus_g_value_free); - return type_id; -} - -void -dbus_g_value_open (DBusGValue *value, - DBusGValueIterator *iter) -{ - DBusGValue *real; - - g_return_if_fail (value->type == DBUS_G_VALUE_TYPE_TOPLEVEL); - - real = (DBusGValue*) iter; - real->type = DBUS_G_VALUE_TYPE_ITERATOR; - real->value.recurse.toplevel = value; - - dbus_message_iter_init (value->value.toplevel.message, - &(real->value.recurse.iterator)); - value->value.recurse.toplevel = value; -} - -gboolean -dbus_g_value_iterator_get_values (DBusGValueIterator *iter, - GError **error, - GValue *first_val, - ...) -{ - GValue *value; - va_list args; - DBusGValue *iterval; - - va_start (args, first_val); - - iterval = (DBusGValue *) iter; - - value = first_val; - do - { - DBusGValueMarshalCtx context; - - 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, - error)) - return FALSE; - } while ((value = va_arg (args, GValue *)) != NULL); - - return TRUE; -} - -static char * -dbus_g_value_get_signature (DBusGValue *value) -{ - return value->value.toplevel.signature; -} - -static gpointer -dbus_g_value_copy (gpointer value) -{ - /* FIXME */ - return NULL; -} - -void -dbus_g_value_free (DBusGValue *value) -{ - if (value->type == DBUS_G_VALUE_TYPE_TOPLEVEL) - { - dbus_message_unref (value->value.toplevel.message); - g_free (value->value.toplevel.signature); - } -} - static GType signature_iter_to_g_type_dict (const DBusSignatureIter *subiter, gboolean is_client) { @@ -553,27 +440,6 @@ signature_iter_to_g_type_array (DBusSignatureIter *iter, gboolean is_client) return G_TYPE_INVALID; } -static gboolean -signature_iter_to_g_type_struct (DBusSignatureIter *origiter, gboolean is_client) -{ - /* FIXME allow structures */ - return G_TYPE_INVALID; -#if 0 - DBusSignatureIter iter; - int current_type; - - iter = *origiter; - - while ((current_type = dbus_signature_iter_get_current_type (&iter)) != DBUS_TYPE_INVALID) - { - subtype = dbus_gtype_from_signature_iter (&iter, is_client); - if (subtype == G_TYPE_INVALID) - return G_TYPE_INVALID; - } - return DBUS_TYPE_G_VALUE (); -#endif -} - GType dbus_gtype_from_signature_iter (DBusSignatureIter *iter, gboolean is_client) { @@ -592,7 +458,9 @@ dbus_gtype_from_signature_iter (DBusSignatureIter *iter, gboolean is_client) g_assert (dbus_type_is_container (current_type)); if (current_type == DBUS_TYPE_VARIANT) - return g_value_get_type (); + return G_TYPE_VALUE; + if (current_type == DBUS_TYPE_STRUCT) + return G_TYPE_VALUE_ARRAY; dbus_signature_iter_recurse (iter, &subiter); @@ -604,10 +472,6 @@ dbus_gtype_from_signature_iter (DBusSignatureIter *iter, gboolean is_client) 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 if (current_type == DBUS_TYPE_DICT_ENTRY) - return G_TYPE_INVALID; else { g_assert_not_reached (); @@ -626,26 +490,6 @@ dbus_gtype_from_signature (const char *signature, gboolean is_client) return dbus_gtype_from_signature_iter (&iter, is_client); } -static char * -dbus_gvalue_to_signature (GValue *value) -{ - char *ret; - - ret = dbus_gtype_to_signature (G_VALUE_TYPE (value)); - if (ret) - return ret; - else - { - DBusGValue *val; - - g_assert (G_VALUE_TYPE (value) == DBUS_TYPE_G_VALUE); - - val = g_value_get_boxed (value); - - return dbus_g_value_get_signature (val); - } -} - char * dbus_gtype_to_signature (GType gtype) { @@ -688,6 +532,34 @@ dbus_gtype_to_signature (GType gtype) return ret; } +static char * +dbus_gvalue_to_signature (const GValue *val) +{ + GType gtype; + + gtype = G_VALUE_TYPE (val); + if (g_type_is_a (gtype, G_TYPE_VALUE_ARRAY)) + { + GString *str; + guint i; + GValueArray *array; + + array = g_value_get_boxed (val); + + str = g_string_new (""); + for (i = 0; i < array->n_values; i++) + { + char *sig; + sig = dbus_gvalue_to_signature (g_value_array_get_nth (array, i)); + g_string_append (str, sig); + g_free (sig); + } + return g_string_free (str, FALSE); + } + else + return dbus_gtype_to_signature (gtype); +} + GArray * dbus_gtypes_from_arg_signature (const char *argsig, gboolean is_client) { @@ -997,6 +869,69 @@ demarshal_strv (DBusGValueMarshalCtx *context, return TRUE; } +static gboolean +demarshal_valuearray (DBusGValueMarshalCtx *context, + DBusMessageIter *iter, + GValue *value, + GError **error) +{ + int current_type; + GValueArray *ret; + DBusMessageIter subiter; + + 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); + + ret = g_value_array_new (12); + + while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID) + { + GValue *val; + GType elt_type; + char *current_sig; + + g_value_array_append (ret, NULL); + val = g_value_array_get_nth (ret, ret->n_values - 1); + + current_sig = dbus_message_iter_get_signature (&subiter); + elt_type = dbus_gtype_from_signature (current_sig, TRUE); + + g_free (current_sig); + if (elt_type == G_TYPE_INVALID) + { + g_value_array_free (ret); + g_set_error (error, + DBUS_GERROR, + DBUS_GERROR_INVALID_ARGS, + _("Couldn't demarshal argument with signature \"%s\""), current_sig); + return FALSE; + } + + g_value_init (val, elt_type); + + if (!dbus_gvalue_demarshal (context, &subiter, val, error)) + { + g_value_array_free (ret); + return FALSE; + } + + dbus_message_iter_next (&subiter); + } + + g_value_set_boxed_take_ownership (value, ret); + + return TRUE; +} + static gboolean demarshal_map (DBusGValueMarshalCtx *context, DBusMessageIter *iter, @@ -1088,8 +1023,8 @@ get_type_demarshaller (GType type) typedata = g_type_get_qdata (type, dbus_g_type_metadata_data_quark ()); if (typedata == NULL) { - if (g_type_is_a (type, DBUS_TYPE_G_VALUE)) - return demarshal_recurse; + if (g_type_is_a (type, G_TYPE_VALUE_ARRAY)) + return demarshal_valuearray; if (dbus_g_type_is_collection (type)) return demarshal_collection; if (dbus_g_type_is_map (type)) @@ -1225,15 +1160,6 @@ demarshal_collection_array (DBusGValueMarshalCtx *context, return TRUE; } -static gboolean -demarshal_recurse (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error) -{ - return FALSE; -} - gboolean dbus_gvalue_demarshal (DBusGValueMarshalCtx *context, DBusMessageIter *iter, @@ -1492,6 +1418,39 @@ marshal_strv (DBusMessageIter *iter, return ret; } +static gboolean +marshal_valuearray (DBusMessageIter *iter, + const GValue *value) +{ + GValueArray *array; + guint i; + DBusMessageIter subiter; + + g_assert (G_VALUE_TYPE (value) == G_TYPE_VALUE_ARRAY); + + array = g_value_get_boxed (value); + + if (!dbus_message_iter_open_container (iter, + DBUS_TYPE_STRUCT, + NULL, + &subiter)) + goto oom; + + for (i = 0; i < array->n_values; i++) + { + if (!dbus_gvalue_marshal (&subiter, g_value_array_get_nth (array, i))) + return FALSE; + } + + if (!dbus_message_iter_close_container (iter, &subiter)) + goto oom; + + return TRUE; + oom: + g_error ("out of memory"); + return FALSE; +} + static gboolean marshal_proxy (DBusMessageIter *iter, const GValue *value) @@ -1595,10 +1554,10 @@ marshal_map (DBusMessageIter *iter, DBusMessageIter arr_iter; gboolean ret; struct DBusGLibHashMarshalData hashdata; + char *key_sig; + char *value_sig; GType key_type; GType value_type; - const char *key_sig; - const char *value_sig; char *entry_sig; char *array_sig; @@ -1612,8 +1571,21 @@ marshal_map (DBusMessageIter *iter, g_assert (dbus_gtype_is_valid_hash_value (value_type)); key_sig = dbus_gtype_to_signature (key_type); + if (!key_sig) + { + g_warning ("Cannot marshal type \"%s\" in map\n", g_type_name (key_type)); + return FALSE; + } value_sig = dbus_gtype_to_signature (value_type); + if (!value_sig) + { + g_free (key_sig); + g_warning ("Cannot marshal type \"%s\" in map\n", g_type_name (value_type)); + return FALSE; + } entry_sig = g_strdup_printf ("%s%s", key_sig, value_sig); + g_free (key_sig); + g_free (value_sig); array_sig = g_strdup_printf ("%c%s%c", DBUS_DICT_ENTRY_BEGIN_CHAR, entry_sig, @@ -1660,8 +1632,7 @@ marshal_variant (DBusMessageIter *iter, variant_sig = dbus_gvalue_to_signature (real_value); if (variant_sig == NULL) { - g_warning ("Unsupported value type \"%s\"", - g_type_name (value_gtype)); + g_warning ("Cannot marshal type \"%s\" in variant", g_type_name (value_gtype)); return FALSE; } @@ -1691,8 +1662,8 @@ get_type_marshaller (GType type) typedata = g_type_get_qdata (type, dbus_g_type_metadata_data_quark ()); if (typedata == NULL) { - if (g_type_is_a (type, DBUS_TYPE_G_VALUE)) - return marshal_recurse; + if (g_type_is_a (type, G_TYPE_VALUE_ARRAY)) + return marshal_valuearray; if (dbus_g_type_is_collection (type)) return marshal_collection; if (dbus_g_type_is_map (type)) @@ -1757,8 +1728,12 @@ marshal_collection_ptrarray (DBusMessageIter *iter, if (!data.marshaller) return FALSE; - /* FIXME - this means we can't send an array of DBusGValue right now... */ elt_sig = dbus_gtype_to_signature (elt_gtype); + if (!elt_sig) + { + g_warning ("Cannot marshal type \"%s\" in collection\n", g_type_name (elt_gtype)); + return FALSE; + } if (!dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, @@ -1797,7 +1772,11 @@ marshal_collection_array (DBusMessageIter *iter, 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); + if (!subsignature_str) + { + g_warning ("Cannot marshal type \"%s\" in collection\n", g_type_name (elt_gtype)); + return FALSE; + } elt_size = dbus_g_type_fixed_get_size (elt_gtype); @@ -1828,13 +1807,6 @@ marshal_collection_array (DBusMessageIter *iter, return FALSE; } -static gboolean -marshal_recurse (DBusMessageIter *iter, - const GValue *value) -{ - return FALSE; -} - gboolean dbus_gvalue_marshal (DBusMessageIter *iter, const GValue *value) @@ -1889,6 +1861,10 @@ _dbus_gvalue_test (const char *test_data_dir) 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); assert_bidirectional_mapping (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), diff --git a/glib/examples/example-client.c b/glib/examples/example-client.c index fb157a75..dac1f825 100644 --- a/glib/examples/example-client.c +++ b/glib/examples/example-client.c @@ -41,12 +41,21 @@ main (int argc, char **argv) GError *error = NULL; char **reply_list; char **reply_ptr; - DBusGValue *hello_reply_struct; + GValueArray *hello_reply_struct; GHashTable *hello_reply_dict; char *introspect_data; + guint i; g_type_init (); + { + GLogLevelFlags fatal_mask; + + fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); + fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL; + g_log_set_always_fatal (fatal_mask); + } + bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); if (!bus) lose_gerror ("Couldn't connect to session bus", error); @@ -62,12 +71,10 @@ main (int argc, char **argv) lose_gerror ("Failed to complete HelloWorld", error); - /* FIXME - we don't support recursive values yet */ -#if 0 if (!dbus_g_proxy_call (remote_object, "GetTuple", &error, - DBUS_TYPE_G_VALUE, &hello_reply_struct, G_TYPE_INVALID)) + G_TYPE_INVALID, + G_TYPE_VALUE_ARRAY, &hello_reply_struct, G_TYPE_INVALID)) lose_gerror ("Failed to complete GetTuple", error); -#endif if (!dbus_g_proxy_call (remote_object, "GetDict", &error, G_TYPE_INVALID, @@ -80,11 +87,18 @@ main (int argc, char **argv) printf ("\n"); g_strfreev (reply_list); - /* FIXME; do something with hello_reply_struct */ -#if 0 - dbus_g_value_free (hello_reply_struct); + for (i = 0; i < hello_reply_struct->n_values; i++) + { + GValue strval = { 0, }; + + g_value_init (&strval, G_TYPE_STRING); + if (!g_value_transform (g_value_array_get_nth (hello_reply_struct, i), &strval)) + g_value_set_static_string (&strval, "(couldn't transform to string)"); + g_print ("%s: %s\n", g_type_name (G_VALUE_TYPE (g_value_array_get_nth (hello_reply_struct, i))), + g_value_get_string (&strval)); + } + g_value_array_free (hello_reply_struct); printf ("\n"); -#endif g_hash_table_foreach (hello_reply_dict, print_hash_value, NULL); g_hash_table_destroy (hello_reply_dict); diff --git a/glib/examples/example-service.c b/glib/examples/example-service.c index d1f8c62e..5e58175f 100644 --- a/glib/examples/example-service.c +++ b/glib/examples/example-service.c @@ -51,7 +51,7 @@ struct SomeObjectClass G_DEFINE_TYPE(SomeObject, some_object, G_TYPE_OBJECT) gboolean some_object_hello_world (SomeObject *obj, const char *hello_message, char ***ret, GError **error); -gboolean some_object_get_tuple (SomeObject *obj, DBusGValue **ret, GError **error); +gboolean some_object_get_tuple (SomeObject *obj, GValueArray **ret, GError **error); gboolean some_object_get_dict (SomeObject *obj, GHashTable **ret, GError **error); #include "example-service-glue.h" @@ -79,9 +79,16 @@ some_object_hello_world (SomeObject *obj, const char *hello_message, char ***ret } gboolean -some_object_get_tuple (SomeObject *obj, DBusGValue **ret, GError **error) +some_object_get_tuple (SomeObject *obj, GValueArray **ret, GError **error) { - /* FIXME */ + *ret = g_value_array_new (6); + g_value_array_prepend (*ret, NULL); + g_value_init (g_value_array_get_nth (*ret, 0), G_TYPE_STRING); + g_value_set_string (g_value_array_get_nth (*ret, 0), "hello"); + g_value_array_prepend (*ret, NULL); + g_value_init (g_value_array_get_nth (*ret, 0), G_TYPE_UINT); + g_value_set_uint (g_value_array_get_nth (*ret, 0), 42); + return TRUE; } @@ -105,6 +112,14 @@ main (int argc, char **argv) guint request_name_result; g_type_init (); + + { + GLogLevelFlags fatal_mask; + + fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); + fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL; + g_log_set_always_fatal (fatal_mask); + } dbus_g_object_type_install_info (SOME_TYPE_OBJECT, &dbus_glib_some_object_object_info); diff --git a/test/glib/test-dbus-glib.c b/test/glib/test-dbus-glib.c index 786235de..962db15e 100644 --- a/test/glib/test-dbus-glib.c +++ b/test/glib/test-dbus-glib.c @@ -884,6 +884,51 @@ main (int argc, char **argv) run_mainloop (); + { + GValueArray *vals; + GValueArray *vals_ret; + GValue *val; + + vals = g_value_array_new (3); + + g_value_array_append (vals, NULL); + g_value_init (g_value_array_get_nth (vals, vals->n_values - 1), G_TYPE_STRING); + g_value_set_string (g_value_array_get_nth (vals, 0), "foo"); + + g_value_array_append (vals, NULL); + g_value_init (g_value_array_get_nth (vals, vals->n_values - 1), G_TYPE_UINT); + g_value_set_uint (g_value_array_get_nth (vals, vals->n_values - 1), 42); + + g_value_array_append (vals, NULL); + g_value_init (g_value_array_get_nth (vals, vals->n_values - 1), G_TYPE_VALUE); + val = g_new0 (GValue, 1); + g_value_init (val, G_TYPE_UCHAR); + g_value_set_uchar (val, '!'); + g_value_set_boxed (g_value_array_get_nth (vals, vals->n_values - 1), val); + + vals_ret = NULL; + g_print ("Calling SendCar\n"); + if (!dbus_g_proxy_call (proxy, "SendCar", &error, + G_TYPE_VALUE_ARRAY, vals, + G_TYPE_INVALID, + G_TYPE_VALUE_ARRAY, &vals_ret, + G_TYPE_INVALID)) + lose_gerror ("Failed to complete SendCar call", error); + + g_assert (vals_ret != NULL); + g_assert (vals_ret->n_values == 2); + + g_assert (G_VALUE_HOLDS_UINT (g_value_array_get_nth (vals_ret, 0))); + g_assert (g_value_get_uint (g_value_array_get_nth (vals_ret, 0)) == 43); + + g_assert (G_VALUE_TYPE (g_value_array_get_nth (vals_ret, 1)) == DBUS_TYPE_G_OBJECT_PATH); + g_assert (!strcmp ("/org/freedesktop/DBus/Tests/MyTestObject2", + g_value_get_boxed (g_value_array_get_nth (vals_ret, 1)))); + + g_value_array_free (vals); + g_value_array_free (vals_ret); + } + { GValue *val; GHashTable *table; diff --git a/test/glib/test-service-glib.c b/test/glib/test-service-glib.c index e44310f3..b0043e80 100644 --- a/test/glib/test-service-glib.c +++ b/test/glib/test-service-glib.c @@ -80,6 +80,8 @@ gboolean my_object_many_uppercase (MyObject *obj, const char * const *in, char * gboolean my_object_str_hash_len (MyObject *obj, GHashTable *table, guint *len, GError **error); +gboolean my_object_send_car (MyObject *obj, GValueArray *invals, GValueArray **outvals, GError **error); + gboolean my_object_get_hash (MyObject *obj, GHashTable **table, GError **error); gboolean my_object_increment_val (MyObject *obj, GError **error); @@ -501,6 +503,32 @@ my_object_str_hash_len (MyObject *obj, GHashTable *table, guint *len, GError **e return TRUE; } +gboolean +my_object_send_car (MyObject *obj, GValueArray *invals, GValueArray **outvals, GError **error) +{ + if (invals->n_values != 3 + || G_VALUE_TYPE (g_value_array_get_nth (invals, 0)) != G_TYPE_STRING + || G_VALUE_TYPE (g_value_array_get_nth (invals, 1)) != G_TYPE_UINT + || G_VALUE_TYPE (g_value_array_get_nth (invals, 2)) != G_TYPE_VALUE) + { + g_set_error (error, + MY_OBJECT_ERROR, + MY_OBJECT_ERROR_FOO, + "invalid incoming values"); + return FALSE; + } + *outvals = g_value_array_new (2); + g_value_array_append (*outvals, NULL); + g_value_init (g_value_array_get_nth (*outvals, (*outvals)->n_values - 1), G_TYPE_UINT); + g_value_set_uint (g_value_array_get_nth (*outvals, (*outvals)->n_values - 1), + g_value_get_uint (g_value_array_get_nth (invals, 1)) + 1); + g_value_array_append (*outvals, NULL); + g_value_init (g_value_array_get_nth (*outvals, (*outvals)->n_values - 1), DBUS_TYPE_G_OBJECT_PATH); + g_value_set_boxed (g_value_array_get_nth (*outvals, (*outvals)->n_values - 1), + g_strdup ("/org/freedesktop/DBus/Tests/MyTestObject2")); + return TRUE; +} + gboolean my_object_get_hash (MyObject *obj, GHashTable **ret, GError **error) { diff --git a/test/glib/test-service-glib.xml b/test/glib/test-service-glib.xml index 4ea2b2bb..f63beada 100644 --- a/test/glib/test-service-glib.xml +++ b/test/glib/test-service-glib.xml @@ -81,6 +81,11 @@ + + + + + -- cgit