diff options
author | Colin Walters <walters@verbum.org> | 2005-03-09 17:09:11 +0000 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2005-03-09 17:09:11 +0000 |
commit | 74b1b35402f6b9bbc09999a6224dfc04bc48b2a9 (patch) | |
tree | c9cae2dde5d4b11d4cf7e17e5c3009280e1f8ee5 /glib | |
parent | 2958e723fc996e2dd7edfdc6ac53dcdf48323549 (diff) |
2005-03-09 Colin Walters <walters@verbum.org>
* glib/dbus-gproxy.c (dbus_g_proxy_invoke): New method; calls
to this are generated for client-side wrappers. Invokes a
D-BUS method and returns reply values.
* glib/dbus-binding-tool-glib.c (write_args_sig_for_direction): New
function; writes signature string for argument direction.
(write_args_for_direction): Change to pass input values directly
instead of via address, and fix indentation.
(generate_client_glue): Change to invoke dbus_g_proxy_invoke. Also
make generated wrappers inlineable.
* dbus/dbus-message.c (dbus_message_iter_get_fixed_array): Add
note about using dbus_type_is_fixed.
* dbus/dbus-marshal-basic.c (_dbus_type_is_fixed): Moved to
dbus/dbus-signature.c as dbus_type_is_fixed.
All callers updated.
* dbus/dbus-signature.c (dbus_type_is_fixed): Moved here
from dbus/dbus-marshal-basic.c:_dbus_type_is_fixed.
* dbus/dbus-signature.h: Prototype.
* glib/dbus-binding-tool-glib.c (compute_marshaller_name): Fix
error printf code.
* test/glib/test-dbus-glib.c (main): Be sure to clear error as
appropriate instead of just freeing it.
(main): Free returned strings using g_free.
* test/glib/Makefile.am (test-service-glib-glue.h)
(test-service-glib-bindings.h): Add dependency on dbus-binding-tool.
* glib/dbus-gvalue.c (MAP_BASIC): Refactored from MAP_BASIC_INIT;
simply maps a simple D-BUS type to GType.
(dbus_dbus_type_to_gtype): Function which maps D-BUS type to
GType.
(dbus_gvalue_init): Just invoke dbus_dbus_type_to_gtype and
initialize the value with it.
(dbus_gvalue_binding_type_from_type): Unused, delete.
(dbus_gvalue_demarshal): Switch to hardcoding demarshalling for
various types instead of unmarshalling to value data directly.
Remove can_convert boolean.
(dbus_gvalue_marshal): Remove duplicate initialization; switch to
returning directly instead of using can_convert boolean.
(dbus_gvalue_store): New function; not related to D-BUS per-se.
Stores a GValue in a pointer to a value of its corresponding C
type.
* glib/dbus-gvalue.h: Remove dbus_gvalue_binding_type_from_type,
add dbus_gvalue_store.
Diffstat (limited to 'glib')
-rw-r--r-- | glib/dbus-binding-tool-glib.c | 73 | ||||
-rw-r--r-- | glib/dbus-gproxy.c | 205 | ||||
-rw-r--r-- | glib/dbus-gvalue.c | 254 | ||||
-rw-r--r-- | glib/dbus-gvalue.h | 4 |
4 files changed, 392 insertions, 144 deletions
diff --git a/glib/dbus-binding-tool-glib.c b/glib/dbus-binding-tool-glib.c index 641f07da..5bd413e1 100644 --- a/glib/dbus-binding-tool-glib.c +++ b/glib/dbus-binding-tool-glib.c @@ -140,7 +140,7 @@ compute_marshaller_name (MethodInfo *method, GError **error) g_set_error (error, DBUS_BINDING_TOOL_ERROR, DBUS_BINDING_TOOL_ERROR_UNSUPPORTED_CONVERSION, - _("Unsupported conversion from D-BUS type %d to glib-genmarshal type"), + _("Unsupported conversion from D-BUS type %s to glib-genmarshal type"), type); g_string_free (ret, TRUE); return NULL; @@ -647,42 +647,54 @@ write_formal_parameters (InterfaceInfo *iface, MethodInfo *method, GIOChannel *c } static gboolean -write_args_for_direction (InterfaceInfo *iface, MethodInfo *method, GIOChannel *channel, int direction, GError **error) +write_args_sig_for_direction (InterfaceInfo *iface, MethodInfo *method, GIOChannel *channel, int direction, GError **error) { GSList *args; + WRITE_OR_LOSE ("\""); + for (args = method_info_get_args (method); args; args = args->next) { ArgInfo *arg; - const char *type_str; arg = args->data; if (direction != arg_info_get_direction (arg)) continue; - type_str = dbus_gvalue_binding_type_from_type (arg_info_get_type (arg)); - if (!type_str) - { - g_set_error (error, - DBUS_BINDING_TOOL_ERROR, - DBUS_BINDING_TOOL_ERROR_UNSUPPORTED_CONVERSION, - _("Unsupported conversion from D-BUS type %s"), - arg_info_get_type (arg)); - return FALSE; - } + if (!write_printf_to_iochannel ("%s", channel, error, arg_info_get_type (arg))) + goto io_lose; + } + + WRITE_OR_LOSE ("\", "); + + return TRUE; + io_lose: + return FALSE; +} + +static gboolean +write_args_for_direction (InterfaceInfo *iface, MethodInfo *method, GIOChannel *channel, int direction, GError **error) +{ + GSList *args; + + for (args = method_info_get_args (method); args; args = args->next) + { + ArgInfo *arg; + + arg = args->data; + + if (direction != arg_info_get_direction (arg)) + continue; - switch (direction) { case ARG_IN: - if (!write_printf_to_iochannel (" %s, &IN_%s,\n", channel, error, - type_str, arg_info_get_name (arg))) + if (!write_printf_to_iochannel ("IN_%s, ", channel, error, arg_info_get_name (arg))) goto io_lose; break; case ARG_OUT: - if (!write_printf_to_iochannel (" %s, OUT_%s,\n", channel, error, - type_str, arg_info_get_name (arg))) + if (!write_printf_to_iochannel ("OUT_%s, ", channel, error, arg_info_get_name (arg))) goto io_lose; break; case ARG_INVALID: @@ -746,7 +758,7 @@ generate_client_glue (BaseInfo *base, DBusBindingToolCData *data, GError **error method_name = compute_client_method_name (interface, method); - WRITE_OR_LOSE ("static gboolean\n"); + WRITE_OR_LOSE ("static\n#ifdef G_HAVE_INLINE\ninline\n#endif\ngboolean\n"); if (!write_printf_to_iochannel ("%s (DBusGProxy *proxy", channel, error, method_name)) goto io_lose; @@ -758,29 +770,26 @@ generate_client_glue (BaseInfo *base, DBusBindingToolCData *data, GError **error WRITE_OR_LOSE (", GError **error)\n\n"); WRITE_OR_LOSE ("{\n"); - WRITE_OR_LOSE (" gboolean ret;\n\n"); - WRITE_OR_LOSE (" DBusGPendingCall *call;\n\n"); - if (!write_printf_to_iochannel (" call = dbus_g_proxy_begin_call (proxy, \"%s\",\n", - channel, error, + if (!write_printf_to_iochannel (" return dbus_g_proxy_invoke (proxy, \"%s\", ", channel, error, method_info_get_name (method))) goto io_lose; - if (!write_args_for_direction (interface, method, channel, ARG_IN, error)) + if (!write_args_sig_for_direction (interface, method, channel, ARG_IN, error)) goto io_lose; - WRITE_OR_LOSE (" DBUS_TYPE_INVALID);\n"); - WRITE_OR_LOSE (" ret = dbus_g_proxy_end_call (proxy, call, error,\n"); - - if (!write_args_for_direction (interface, method, channel, ARG_OUT, error)) + if (!write_args_sig_for_direction (interface, method, channel, ARG_OUT, error)) goto io_lose; - WRITE_OR_LOSE (" DBUS_TYPE_INVALID);\n"); + WRITE_OR_LOSE ("error, "); - WRITE_OR_LOSE (" dbus_g_pending_call_unref (call);\n"); - WRITE_OR_LOSE (" return ret;\n"); + if (!write_args_for_direction (interface, method, channel, ARG_IN, error)) + goto io_lose; + + if (!write_args_for_direction (interface, method, channel, ARG_OUT, error)) + goto io_lose; - WRITE_OR_LOSE ("}\n\n"); + WRITE_OR_LOSE ("NULL);\n}\n\n"); } } return TRUE; diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c index 65f14e12..b5e977a4 100644 --- a/glib/dbus-gproxy.c +++ b/glib/dbus-gproxy.c @@ -22,11 +22,14 @@ */ #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> +#include <dbus/dbus-signature.h> #include "dbus-gutils.h" #include "dbus-gmarshal.h" #include "dbus-gvalue.h" #include "dbus-gobject.h" #include <string.h> +#include <glib/gi18n.h> +#include <gobject/gvaluecollector.h> /** * @addtogroup DBusGLibInternals @@ -1397,6 +1400,208 @@ dbus_g_proxy_end_call (DBusGProxy *proxy, } /** + * Function for invoking a method and receiving reply values. + * Normally this is not used directly - calls to it are generated + * from client-side wrappers (see dbus-binding-tool). + * + * This function takes two type signatures, one for method arguments, + * and one for return values. The remaining arguments after the + * error parameter should be values of the input arguments, + * followed by pointer values to storage for return values. + * + * @param proxy a proxy for a remote interface + * @param method method to invoke + * @param insig signature of input values + * @param outsig signature of output values + * @param error return location for an error + * @returns #FALSE if an error is set, TRUE otherwise + */ +gboolean +dbus_g_proxy_invoke (DBusGProxy *proxy, + const char *method, + const char *insig, + const char *outsig, + GError **error, + ...) +{ + DBusPendingCall *pending; + DBusMessage *message; + DBusMessage *reply; + va_list args; + va_list args_unwind; + int n_retvals_processed; + DBusMessageIter msgiter; + DBusSignatureIter sigiter; + int expected_type; + gboolean ret; + DBusError derror; + + g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), FALSE); + g_return_val_if_fail (!DBUS_G_PROXY_DESTROYED (proxy), FALSE); + + va_start (args, error); + /* Keep around a copy of output arguments so we + * can free on error. */ + G_VA_COPY (args_unwind, args); + + ret = FALSE; + pending = NULL; + reply = NULL; + n_retvals_processed = 0; + message = dbus_message_new_method_call (proxy->name, + proxy->path, + proxy->interface, + method); + if (message == NULL) + goto oom; + + dbus_signature_iter_init (&sigiter, insig); + dbus_message_iter_init_append (message, &msgiter); + while ((expected_type = dbus_signature_iter_get_current_type (&sigiter)) != DBUS_TYPE_INVALID) + { + GValue gvalue = {0, }; + char *collect_err; + + if (!dbus_gvalue_init (expected_type, &gvalue)) + { + g_set_error (error, DBUS_GERROR, + DBUS_GERROR_INVALID_ARGS, + _("Unsupported type '%c'"), expected_type); + goto out; + } + + G_VALUE_COLLECT (&gvalue, args, G_VALUE_NOCOPY_CONTENTS, &collect_err); + + if (collect_err) + { + g_set_error (error, DBUS_GERROR, + DBUS_GERROR_INVALID_ARGS, + collect_err); + goto out; + } + + /* Anything we can init must be marshallable */ + if (!dbus_gvalue_marshal (&msgiter, &gvalue)) + g_assert_not_reached (); + g_value_unset (&gvalue); + + dbus_signature_iter_next (&sigiter); + } + + if (!dbus_connection_send_with_reply (proxy->manager->connection, + message, + &pending, + -1)) + goto oom; + + dbus_pending_call_block (pending); + reply = dbus_pending_call_steal_reply (pending); + + g_assert (reply != NULL); + + dbus_error_init (&derror); + + switch (dbus_message_get_type (reply)) + { + case DBUS_MESSAGE_TYPE_METHOD_RETURN: + + dbus_signature_iter_init (&sigiter, outsig); + dbus_message_iter_init (reply, &msgiter); + while ((expected_type = dbus_signature_iter_get_current_type (&sigiter)) != DBUS_TYPE_INVALID) + { + int arg_type; + gpointer *value_ret; + GValue gvalue = { 0, }; + + value_ret = va_arg (args, gpointer *); + + arg_type = dbus_message_iter_get_arg_type (&msgiter); + if (expected_type != arg_type) + { + if (arg_type == DBUS_TYPE_INVALID) + g_set_error (error, DBUS_GERROR, + DBUS_GERROR_INVALID_ARGS, + _("Too few arguments in reply")); + else + g_set_error (error, DBUS_GERROR, + DBUS_GERROR_INVALID_ARGS, + _("Reply argument was \"%c\", expected \"%c\""), + arg_type, expected_type); + goto out; + } + + if (!dbus_gvalue_demarshal (&msgiter, &gvalue)) + { + g_set_error (error, + DBUS_GERROR, + DBUS_GERROR_INVALID_ARGS, + _("Couldn't convert argument type \"%c\""), expected_type); + goto out; + } + /* Anything that can be demarshaled must be storable */ + if (!dbus_gvalue_store (&gvalue, value_ret)) + g_assert_not_reached (); + g_value_unset (&gvalue); + + n_retvals_processed++; + dbus_signature_iter_next (&sigiter); + dbus_message_iter_next (&msgiter); + } + if (dbus_message_iter_get_arg_type (&msgiter) != DBUS_TYPE_INVALID) + { + g_set_error (error, DBUS_GERROR, + DBUS_GERROR_INVALID_ARGS, + _("Too many arguments")); + goto out; + } + break; + case DBUS_MESSAGE_TYPE_ERROR: + dbus_set_error_from_message (&derror, reply); + dbus_set_g_error (error, &derror); + dbus_error_free (&derror); + goto out; + break; + default: + dbus_set_error (&derror, DBUS_ERROR_FAILED, + "Reply was neither a method return nor an exception"); + dbus_set_g_error (error, &derror); + dbus_error_free (&derror); + goto out; + break; + } + + ret = TRUE; + out: + va_end (args); + + if (ret == FALSE) + { + int i; + for (i = 0; i < n_retvals_processed; i++) + { + gpointer retval; + + retval = va_arg (args_unwind, gpointer); + + g_free (retval); + } + } + va_end (args_unwind); + + if (pending) + dbus_pending_call_unref (pending); + if (message) + dbus_message_unref (message); + if (reply) + dbus_message_unref (reply); + return ret; + oom: + g_error ("Out of memory"); + ret = FALSE; + goto out; +} + +/** * Sends a method call message as with dbus_g_proxy_begin_call(), but * does not ask for a reply or allow you to receive one. * diff --git a/glib/dbus-gvalue.c b/glib/dbus-gvalue.c index bcda9259..eae5a458 100644 --- a/glib/dbus-gvalue.c +++ b/glib/dbus-gvalue.c @@ -26,50 +26,51 @@ #include "dbus/dbus-signature.h" /* This is slightly evil, we don't use g_value_set_foo() functions */ -#define MAP_BASIC_INIT(d_t, g_t) \ - case DBUS_TYPE_##d_t: \ - g_value_init (value, G_TYPE_##g_t); \ - break +#define MAP_BASIC(d_t, g_t) \ + case DBUS_TYPE_##d_t: \ + return G_TYPE_##g_t; -gboolean -dbus_gvalue_init (int type, - GValue *value) +static GType +dbus_dbus_type_to_gtype (int type) { - gboolean can_convert; - - can_convert = TRUE; - switch (type) { - MAP_BASIC_INIT (BOOLEAN, BOOLEAN); - MAP_BASIC_INIT (BYTE, UCHAR); - MAP_BASIC_INIT (INT32, INT); - MAP_BASIC_INIT (UINT32, UINT); - MAP_BASIC_INIT (INT64, INT64); - MAP_BASIC_INIT (UINT64, UINT64); - MAP_BASIC_INIT (DOUBLE, DOUBLE); - + MAP_BASIC (BOOLEAN, BOOLEAN); + MAP_BASIC (BYTE, UCHAR); + MAP_BASIC (INT32, INT); + MAP_BASIC (UINT32, UINT); + MAP_BASIC (INT64, INT64); + MAP_BASIC (UINT64, UINT64); + MAP_BASIC (DOUBLE, DOUBLE); case DBUS_TYPE_INT16: - g_value_init (value, G_TYPE_INT); - break; + return G_TYPE_INT; case DBUS_TYPE_UINT16: - g_value_init (value, G_TYPE_UINT); - break; - + return G_TYPE_UINT; case DBUS_TYPE_STRING: case DBUS_TYPE_OBJECT_PATH: case DBUS_TYPE_SIGNATURE: - g_value_init (value, G_TYPE_STRING); - break; - + return G_TYPE_STRING; case DBUS_TYPE_STRUCT: case DBUS_TYPE_ARRAY: case DBUS_TYPE_VARIANT: default: - can_convert = FALSE; + return G_TYPE_INVALID; } -#undef MAP_BASIC_INIT - return can_convert; +} + +#undef MAP_BASIC + +gboolean +dbus_gvalue_init (int type, + GValue *value) +{ + GType gtype; + + gtype = dbus_dbus_type_to_gtype (type); + if (gtype == G_TYPE_INVALID) + return FALSE; + g_value_init (value, gtype); + return TRUE; } /* FIXME - broken for containers @@ -125,43 +126,6 @@ dbus_gvalue_genmarshal_name_from_type (const char *signature) } const char * -dbus_gvalue_binding_type_from_type (const char *signature) -{ - int type; - - type = base_type_from_signature (signature); - -#define STRINGIFY(x) \ - case x: \ - return (#x) - - switch (type) - { - STRINGIFY(DBUS_TYPE_BOOLEAN); - STRINGIFY(DBUS_TYPE_BYTE); - STRINGIFY(DBUS_TYPE_INT32); - STRINGIFY(DBUS_TYPE_UINT32); - STRINGIFY(DBUS_TYPE_INT64); - STRINGIFY(DBUS_TYPE_UINT64); - STRINGIFY(DBUS_TYPE_DOUBLE); - case DBUS_TYPE_INT16: - return "DBUS_TYPE_INT32"; - case DBUS_TYPE_UINT16: - return "DBUS_TYPE_UINT32"; - STRINGIFY(DBUS_TYPE_STRING); - STRINGIFY(DBUS_TYPE_OBJECT_PATH); - STRINGIFY(DBUS_TYPE_SIGNATURE); - - case DBUS_TYPE_STRUCT: - case DBUS_TYPE_ARRAY: - case DBUS_TYPE_VARIANT: - return NULL; - } -#undef STRINGIFY - return NULL; -} - -const char * dbus_gvalue_ctype_from_type (const char *signature, gboolean in) { int type; @@ -249,69 +213,96 @@ dbus_gtype_to_dbus_type (GType type) gboolean dbus_gvalue_demarshal (DBusMessageIter *iter, GValue *value) { - gboolean can_convert = TRUE; - g_assert (sizeof (dbus_bool_t) == sizeof (value->data[0].v_int)); dbus_gvalue_init (dbus_message_iter_get_arg_type (iter), value); -/* This is slightly evil, we don't use g_value_set_foo() functions */ -#define MAP_BASIC(d_t, g_t) \ - case DBUS_TYPE_##d_t: \ - dbus_message_iter_get_basic (iter, &value->data[0]); \ - break - switch (dbus_message_iter_get_arg_type (iter)) { - MAP_BASIC (BOOLEAN, BOOLEAN); - MAP_BASIC (BYTE, UCHAR); - MAP_BASIC (INT32, INT); - MAP_BASIC (UINT32, UINT); - MAP_BASIC (INT64, INT64); - MAP_BASIC (UINT64, UINT64); - MAP_BASIC (DOUBLE, DOUBLE); - + case DBUS_TYPE_BOOLEAN: + { + dbus_bool_t bool; + dbus_message_iter_get_basic (iter, &bool); + g_value_set_boolean (value, bool); + return TRUE; + } + case DBUS_TYPE_BYTE: + { + unsigned char byte; + dbus_message_iter_get_basic (iter, &byte); + g_value_set_uchar (value, byte); + return TRUE; + } + case DBUS_TYPE_INT32: + { + dbus_int32_t intval; + dbus_message_iter_get_basic (iter, &intval); + g_value_set_int (value, intval); + return TRUE; + } + case DBUS_TYPE_UINT32: + { + dbus_uint32_t intval; + dbus_message_iter_get_basic (iter, &intval); + g_value_set_uint (value, intval); + return TRUE; + } + case DBUS_TYPE_INT64: + { + dbus_int64_t intval; + dbus_message_iter_get_basic (iter, &intval); + g_value_set_int64 (value, intval); + return TRUE; + } + case DBUS_TYPE_UINT64: + { + dbus_uint64_t intval; + dbus_message_iter_get_basic (iter, &intval); + g_value_set_uint64 (value, intval); + return TRUE; + } + case DBUS_TYPE_DOUBLE: + { + double dval; + dbus_message_iter_get_basic (iter, &dval); + g_value_set_double (value, dval); + return TRUE; + } case DBUS_TYPE_INT16: { dbus_int16_t v; dbus_message_iter_get_basic (iter, &v); g_value_set_int (value, v); + return TRUE; } - break; case DBUS_TYPE_UINT16: { dbus_uint16_t v; dbus_message_iter_get_basic (iter, &v); g_value_set_uint (value, v); + return TRUE; } - break; - case DBUS_TYPE_STRING: case DBUS_TYPE_OBJECT_PATH: case DBUS_TYPE_SIGNATURE: { const char *s; - dbus_message_iter_get_basic (iter, &s); g_value_set_string (value, s); + return TRUE; } - break; - case DBUS_TYPE_STRUCT: case DBUS_TYPE_ARRAY: case DBUS_TYPE_VARIANT: default: - can_convert = FALSE; + return FALSE; } -#undef MAP_BASIC - return can_convert; } gboolean dbus_gvalue_marshal (DBusMessageIter *iter, GValue *value) { - gboolean can_convert = TRUE; - GType value_type = G_VALUE_TYPE (value); + GType value_type; value_type = G_VALUE_TYPE (value); @@ -325,7 +316,7 @@ dbus_gvalue_marshal (DBusMessageIter *iter, GValue *value) &b)) goto nomem; } - break; + return TRUE; case G_TYPE_UCHAR: { unsigned char b = g_value_get_uchar (value); @@ -334,7 +325,7 @@ dbus_gvalue_marshal (DBusMessageIter *iter, GValue *value) &b)) goto nomem; } - break; + return TRUE; case G_TYPE_BOOLEAN: { dbus_bool_t b = g_value_get_boolean (value); @@ -343,7 +334,7 @@ dbus_gvalue_marshal (DBusMessageIter *iter, GValue *value) &b)) goto nomem; } - break; + return TRUE; case G_TYPE_INT: { dbus_int32_t v = g_value_get_int (value); @@ -352,7 +343,7 @@ dbus_gvalue_marshal (DBusMessageIter *iter, GValue *value) &v)) goto nomem; } - break; + return TRUE; case G_TYPE_UINT: { dbus_uint32_t v = g_value_get_uint (value); @@ -361,7 +352,7 @@ dbus_gvalue_marshal (DBusMessageIter *iter, GValue *value) &v)) goto nomem; } - break; + return TRUE; /* long gets cut to 32 bits so the remote API is consistent * on all architectures */ @@ -373,7 +364,7 @@ dbus_gvalue_marshal (DBusMessageIter *iter, GValue *value) &v)) goto nomem; } - break; + return TRUE; case G_TYPE_ULONG: { dbus_uint32_t v = g_value_get_ulong (value); @@ -382,7 +373,7 @@ dbus_gvalue_marshal (DBusMessageIter *iter, GValue *value) &v)) goto nomem; } - break; + return TRUE; case G_TYPE_INT64: { gint64 v = g_value_get_int64 (value); @@ -391,7 +382,7 @@ dbus_gvalue_marshal (DBusMessageIter *iter, GValue *value) &v)) goto nomem; } - break; + return TRUE; case G_TYPE_UINT64: { guint64 v = g_value_get_uint64 (value); @@ -400,7 +391,7 @@ dbus_gvalue_marshal (DBusMessageIter *iter, GValue *value) &v)) goto nomem; } - break; + return TRUE; case G_TYPE_FLOAT: { double v = g_value_get_float (value); @@ -410,7 +401,7 @@ dbus_gvalue_marshal (DBusMessageIter *iter, GValue *value) &v)) goto nomem; } - break; + return TRUE; case G_TYPE_DOUBLE: { double v = g_value_get_double (value); @@ -420,7 +411,7 @@ dbus_gvalue_marshal (DBusMessageIter *iter, GValue *value) &v)) goto nomem; } - break; + return TRUE; case G_TYPE_STRING: /* FIXME, the GValue string may not be valid UTF-8 */ { @@ -430,19 +421,62 @@ dbus_gvalue_marshal (DBusMessageIter *iter, GValue *value) &v)) goto nomem; } - break; + return TRUE; default: /* FIXME: we need to define custom boxed types for arrays etc. so we can map them transparently / pleasantly */ - can_convert = FALSE; - break; + return FALSE; } - return can_convert; - nomem: g_error ("no memory"); return FALSE; } +/* FIXME is there a better way to do this? */ +gboolean +dbus_gvalue_store (GValue *value, + gpointer storage) +{ + switch (G_VALUE_TYPE (value)) + { + case G_TYPE_CHAR: + *((gchar *) storage) = g_value_get_char (value); + return TRUE; + case G_TYPE_UCHAR: + *((guchar *) storage) = g_value_get_uchar (value); + return TRUE; + case G_TYPE_BOOLEAN: + *((gboolean *) storage) = g_value_get_boolean (value); + return TRUE; + case G_TYPE_LONG: + *((glong *) storage) = g_value_get_long (value); + return TRUE; + case G_TYPE_ULONG: + *((gulong *) storage) = g_value_get_ulong (value); + return TRUE; + case G_TYPE_INT: + *((gint *) storage) = g_value_get_int (value); + return TRUE; + case G_TYPE_UINT: + *((guint *) storage) = g_value_get_uint (value); + return TRUE; + case G_TYPE_INT64: + *((gint64 *) storage) = g_value_get_int64 (value); + return TRUE; + case G_TYPE_UINT64: + *((guint64 *) storage) = g_value_get_uint64 (value); + return TRUE; + case G_TYPE_FLOAT: + case G_TYPE_DOUBLE: + *((gdouble *) storage) = g_value_get_double (value); + return TRUE; + case G_TYPE_STRING: + /* FIXME - should optimize by not duping string twice */ + *((gchar **) storage) = g_value_dup_string (value); + return TRUE; + default: + return FALSE; + } +} diff --git a/glib/dbus-gvalue.h b/glib/dbus-gvalue.h index dc1cf323..4caa6880 100644 --- a/glib/dbus-gvalue.h +++ b/glib/dbus-gvalue.h @@ -24,8 +24,6 @@ const char * dbus_gvalue_genmarshal_name_from_type (const char *type); const char * dbus_gvalue_ctype_from_type (const char *type, gboolean in); -const char * dbus_gvalue_binding_type_from_type (const char *type); - const char * dbus_gtype_to_dbus_type (GType type); gboolean dbus_gvalue_init (int type, @@ -36,6 +34,8 @@ gboolean dbus_gvalue_demarshal (DBusMessageIter *iter, gboolean dbus_gvalue_marshal (DBusMessageIter *iter, GValue *value); +gboolean dbus_gvalue_store (GValue *value, + gpointer storage); G_END_DECLS |