summaryrefslogtreecommitdiffstats
path: root/glib
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2005-03-09 17:09:11 +0000
committerColin Walters <walters@verbum.org>2005-03-09 17:09:11 +0000
commit74b1b35402f6b9bbc09999a6224dfc04bc48b2a9 (patch)
treec9cae2dde5d4b11d4cf7e17e5c3009280e1f8ee5 /glib
parent2958e723fc996e2dd7edfdc6ac53dcdf48323549 (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.c73
-rw-r--r--glib/dbus-gproxy.c205
-rw-r--r--glib/dbus-gvalue.c254
-rw-r--r--glib/dbus-gvalue.h4
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