[seed] Work on porting dbus-values.c from GJS dbus bindings
- From: Robert Carr <racarr src gnome org>
- To: svn-commits-list gnome org
- Subject: [seed] Work on porting dbus-values.c from GJS dbus bindings
- Date: Sat, 9 May 2009 01:19:17 -0400 (EDT)
commit 2a99e51d6f69e5e302fb346eb3a81cb06aa50134
Author: Robert Carr <racarr svn gnome org>
Date: Sat May 9 00:31:55 2009 -0400
Work on porting dbus-values.c from GJS dbus bindings
---
modules/dbus/dbus-values.c | 977 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 977 insertions(+), 0 deletions(-)
diff --git a/modules/dbus/dbus-values.c b/modules/dbus/dbus-values.c
new file mode 100644
index 0000000..6d14513
--- /dev/null
+++ b/modules/dbus/dbus-values.c
@@ -0,0 +1,977 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/* Copyright 2008 litl, LLC. All Rights Reserved. */
+
+#include "dbus-values.h"
+
+#include <seed.h>
+
+//#include <util/dbus.h>
+//#include <util/log.h>
+
+#include <string.h>
+
+gboolean
+seed_js_one_value_from_dbus (SeedContext ctx,
+ DBusMessageIter * iter,
+ SeedValue *value_p,
+ SeedException *exception)
+{
+ int arg_type;
+
+ *value_p = seed_make_unefined (ctx);
+
+ arg_type = dbus_message_iter_get_arg_type (iter);
+
+ // big_debug_marshal(BIG_DEBUG_JS_DBUS,
+ // "Converting dbus type '%c' to SeedValue",
+ // arg_type != DBUS_TYPE_INVALID ? arg_type : '0');
+
+ switch (arg_type)
+ {
+ case DBUS_TYPE_STRUCT:
+ {
+ SeedObject obj;
+ DBusMessageIter struct_iter;
+ int index;
+
+ obj = seed_make_object (ctx, NULL, NULL);
+
+ dbus_message_iter_recurse (iter, &struct_iter);
+ index = 0;
+ while (dbus_message_iter_get_arg_type (&struct_iter) !=
+ DBUS_TYPE_INVALID)
+ {
+ SeedValue prop_value;
+
+ prop_value = seed_make_undefined (ctx);
+
+ if (!seed_js_one_value_from_dbus
+ (context, &struct_iter, &prop_value, exception))
+ {
+ return FALSE;
+ }
+
+ seed_object_set_property_at_index (ctx, obj, index,
+ prop_value, exception);
+ dbus_message_iter_next (&struct_iter);
+ index++;
+ }
+ *value_p = (SeedValue) obj;
+ }
+ break;
+ case DBUS_TYPE_ARRAY:
+ {
+ int elem_type = dbus_message_iter_get_element_type (iter);
+
+ if (elem_type == DBUS_TYPE_DICT_ENTRY)
+ {
+ /* Create a dictionary object */
+ SeedObject obj;
+ DBusMessageIter array_iter;
+
+ obj = seed_make_object (ctx, NULL, NULL);
+
+ dbus_message_iter_recurse (iter, &array_iter);
+ while (dbus_message_iter_get_arg_type (&array_iter) !=
+ DBUS_TYPE_INVALID)
+ {
+ DBusMessageIter entry_iter;
+ const char *key;
+ SeedValue entry_value;
+
+ dbus_message_iter_recurse (&array_iter, &entry_iter);
+
+ if (dbus_message_iter_get_arg_type (&entry_iter) !=
+ DBUS_TYPE_STRING)
+ {
+ seed_make_exception (ctx,
+ "Dictionary keys are not strings,"
+ "can't convert to JavaScript",
+ exception);
+ return FALSE;
+ }
+
+ dbus_message_iter_get_basic (&entry_iter, &key);
+
+ dbus_message_iter_next (&entry_iter);
+
+ // big_debug_marshal (BIG_DEBUG_JS_DBUS,
+ // "Defining dict entry %s in jsval dict",
+ // key);
+
+ entry_value = seed_make_undefined (ctx);
+
+ if (!seed_js_one_value_from_dbus
+ (ctx, &entry_iter, &entry_value, exception))
+ {
+ return FALSE;
+ }
+
+ seed_object_set_property (ctx, obj,
+ key, entry_value);
+
+ dbus_message_iter_next (&array_iter);
+ }
+
+ *value_p = (SeedValue) obj;
+ }
+ else if (elem_type == DBUS_TYPE_BYTE)
+ {
+ /* byte arrays go to a string */
+ const char *v_BYTES;
+ int n_bytes;
+ DBusMessageIter array_iter;
+
+ dbus_message_iter_recurse (iter, &array_iter);
+ dbus_message_iter_get_fixed_array (&array_iter,
+ &v_BYTES, &n_bytes);
+ // This is where I am.
+ *value_p = seed_value_from_binary_string (ctx, v_BYTES, n_bytes, exception);
+ }
+ else
+ {
+ SeedObject obj;
+ DBusMessageIter array_iter;
+ int index;
+
+ obj = seed_make_object (ctx, NULL, NULL);
+
+ dbus_message_iter_recurse (iter, &array_iter);
+ index = 0;
+ while (dbus_message_iter_get_arg_type (&array_iter) !=
+ DBUS_TYPE_INVALID)
+ {
+ SeedValue prop_value;
+
+ prop_value = seed_make_undefined (ctx);
+
+ if (!seed_js_one_value_from_dbus
+ (context, &array_iter, &prop_value, exception))
+ {
+ return FALSE;
+ }
+
+ seed_object_set_property_at_index (ctx, obj, index, prop_value, exception);
+
+ JS_RemoveRoot (context, &prop_value);
+ dbus_message_iter_next (&array_iter);
+ index++;
+ }
+ *value_p = (SeedValue) obj;
+ }
+ }
+ break;
+ case DBUS_TYPE_BOOLEAN:
+ {
+ dbus_bool_t v_BOOLEAN;
+ dbus_message_iter_get_basic (iter, &v_BOOLEAN);
+ *value_p = seed_value_from_boolean (ctx, v_BOOLEAN, exception);
+ }
+ break;
+ case DBUS_TYPE_BYTE:
+ {
+ unsigned char v_BYTE;
+ dbus_message_iter_get_basic (iter, &v_BYTE);
+ *value_p = seed_value_from_int (ctx, v_BYTE, exception);
+ }
+ break;
+ case DBUS_TYPE_INT32:
+ {
+ dbus_int32_t v_INT32;
+ dbus_message_iter_get_basic (iter, &v_INT32);
+ *value_p = seed_value_from_int (ctx, v_INT32, exception);
+ }
+ break;
+ case DBUS_TYPE_UINT32:
+ {
+ dbus_uint32_t v_UINT32;
+ dbus_message_iter_get_basic (iter, &v_UINT32);
+ *value_p = seed_value_from_uint (ctx, v_UINT32, exception);
+ }
+ break;
+ case DBUS_TYPE_INT64:
+ {
+ dbus_int64_t v_INT64;
+ dbus_message_iter_get_basic (iter, &v_INT64);
+ *value_p = seed_value_from_int64 (ctx, v_INT64, exception);
+ }
+ break;
+ case DBUS_TYPE_UINT64:
+ {
+ dbus_uint64_t v_UINT64;
+ dbus_message_iter_get_basic (iter, &v_UINT64);
+ *value_p = seed_value_from_uint64 (ctx, v_UINT64, exception);
+ }
+ break;
+ case DBUS_TYPE_DOUBLE:
+ {
+ double v_DOUBLE;
+ dbus_message_iter_get_basic (iter, &v_DOUBLE);
+ *value_p = seed_value_from_double (ctx, v_DOUBLE, exception);
+ }
+ break;
+ case DBUS_TYPE_OBJECT_PATH:
+ case DBUS_TYPE_STRING:
+ {
+ const char *v_STRING;
+
+ dbus_message_iter_get_basic (iter, &v_STRING);
+
+ *value_p = seed_value_from_string (ctx, v_STRING, exception);
+ }
+ break;
+
+ case DBUS_TYPE_VARIANT:
+ {
+ DBusMessageIter variant_iter;
+
+ dbus_message_iter_recurse (iter, &variant_iter);
+
+ return seed_js_one_value_from_dbus (context, &variant_iter, value_p, exception);
+ }
+ break;
+
+ case DBUS_TYPE_INVALID:
+ *value_p = seed_make_undefined (ctx);
+ break;
+
+ default:/*
+ big_debug (BIG_DEBUG_JS_DBUS,
+ "Don't know how to convert dbus type %c to JavaScript",
+ arg_type);
+ gjs_throw (context,
+ "Don't know how to convert dbus type %c to JavaScript",
+ arg_type);*/
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+seed_js_values_from_dbus (SeedContext ctx,
+ DBusMessageIter * iter,
+ GArray **array_p,
+ SeedException *exception)
+{
+ GArray *array;
+ SeedValue value;
+
+ value = seed_make_undefined (ctx);
+
+ array = g_array_new (FALSE, FALSE, sizeof(SeedValue));
+
+ /* TODO */
+ // THIS IS WHERE IA M
+ // Wheee.
+ do
+ {
+ if (!seed_js_one_value_from_dbus (context, iter, &value))
+ {
+ g_array_free (array, TRUE);
+ return FALSE;
+ }
+
+ g_array_append_val (array, value);
+ }
+ while (dbus_message_iter_next (iter));
+
+ *array_p = array;
+ return TRUE;
+}
+
+static void
+append_basic_maybe_in_variant (DBusMessageIter * iter,
+ int dbus_type,
+ void *value, gboolean wrap_in_variant)
+{
+ if (wrap_in_variant)
+ {
+ char buf[2];
+ DBusMessageIter variant_iter;
+
+ buf[0] = dbus_type;
+ buf[1] = '\0';
+
+ dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, buf,
+ &variant_iter);
+ dbus_message_iter_append_basic (&variant_iter, dbus_type, value);
+ dbus_message_iter_close_container (iter, &variant_iter);
+ }
+ else
+ {
+ dbus_message_iter_append_basic (iter, dbus_type, value);
+ }
+}
+
+static void
+append_byte_array_maybe_in_variant (DBusMessageIter * iter,
+ const char *data,
+ gsize len,
+ gboolean wrap_in_variant)
+{
+ DBusMessageIter array_iter;
+ DBusMessageIter variant_iter;
+
+ if (wrap_in_variant)
+ {
+ dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "ay",
+ &variant_iter);
+ }
+
+ dbus_message_iter_open_container (wrap_in_variant ? &variant_iter : iter,
+ DBUS_TYPE_ARRAY, "y", &array_iter);
+
+ dbus_message_iter_append_fixed_array (&array_iter, DBUS_TYPE_BYTE,
+ &data, len);
+
+ dbus_message_iter_close_container (wrap_in_variant ? &variant_iter : iter,
+ &array_iter);
+
+ if (wrap_in_variant)
+ {
+ dbus_message_iter_close_container (iter, &variant_iter);
+ }
+}
+
+static gboolean
+append_string (SeedContext ctx,
+ DBusMessageIter * iter,
+ const char *forced_signature,
+ const char *s,
+ gsize len,
+ SeedException *exception)
+{
+ int forced_type;
+
+ if (forced_signature == NULL || *forced_signature == DBUS_TYPE_INVALID)
+ forced_type = DBUS_TYPE_STRING;
+ else
+ forced_type = *forced_signature;
+
+ switch (forced_type)
+ {
+ case DBUS_TYPE_STRING:
+ case DBUS_TYPE_OBJECT_PATH:
+ case DBUS_TYPE_SIGNATURE:
+ append_basic_maybe_in_variant (iter, forced_type, &s, FALSE);
+ break;
+ case DBUS_TYPE_VARIANT:
+ append_basic_maybe_in_variant (iter, DBUS_TYPE_STRING, &s, TRUE);
+ break;
+ case DBUS_TYPE_ARRAY:
+ g_assert (forced_signature != NULL);
+ g_assert (forced_signature[0] == DBUS_TYPE_ARRAY);
+ if (forced_signature[1] == DBUS_TYPE_BYTE)
+ {
+ append_byte_array_maybe_in_variant (iter, s, len, FALSE);
+ }
+ else
+ {
+ seed_make_exception (ctx, exception,
+ "JavaScript string can't be converted to dbus array with elements of type '%c'",
+ forced_signature[1]);
+ return FALSE;
+ }
+ break;
+ default:
+ seed_make_exception (ctx, exception,
+ "JavaScript string can't be converted to dbus type '%c'",
+ forced_type);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+append_int32 (SeedContext ctx,
+ DBusMessageIter * iter,
+ int forced_type,
+ dbus_int32_t v_INT32,
+ SeedException *exception)
+{
+ if (forced_type == DBUS_TYPE_INVALID)
+ forced_type = DBUS_TYPE_INT32;
+
+ switch (forced_type)
+ {
+ case DBUS_TYPE_INT32:
+ append_basic_maybe_in_variant (iter, forced_type, &v_INT32, FALSE);
+ break;
+ case DBUS_TYPE_VARIANT:
+ append_basic_maybe_in_variant (iter, DBUS_TYPE_INT32, &v_INT32, TRUE);
+ break;
+ case DBUS_TYPE_UINT32:
+ {
+ dbus_uint32_t v_UINT32 = v_INT32;
+ append_basic_maybe_in_variant (iter, forced_type, &v_UINT32, FALSE);
+ }
+ break;
+ case DBUS_TYPE_DOUBLE:
+ {
+ double v_DOUBLE = v_INT32;
+ append_basic_maybe_in_variant (iter, forced_type, &v_DOUBLE, FALSE);
+ }
+ break;
+ case DBUS_TYPE_BYTE:
+ {
+ unsigned char v_BYTE = v_INT32;
+ append_basic_maybe_in_variant (iter, forced_type, &v_BYTE, FALSE);
+ }
+ break;
+ default:
+ seed_make_exception_exception (ctx, exception,
+ "JavaScript Integer can't be converted to dbus type '%c'",
+ forced_type);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+append_double (SeedContext ctx,
+ DBusMessageIter * iter, int forced_type, double v_DOUBLE,
+ SeedException *exception)
+{
+ if (forced_type == DBUS_TYPE_INVALID)
+ forced_type = DBUS_TYPE_DOUBLE;
+
+ switch (forced_type)
+ {
+ case DBUS_TYPE_DOUBLE:
+ append_basic_maybe_in_variant (iter, forced_type, &v_DOUBLE, FALSE);
+ break;
+ case DBUS_TYPE_VARIANT:
+ append_basic_maybe_in_variant (iter, DBUS_TYPE_DOUBLE, &v_DOUBLE, TRUE);
+ break;
+ case DBUS_TYPE_INT32:
+ {
+ dbus_int32_t v_INT32 = v_DOUBLE;
+ append_basic_maybe_in_variant (iter, forced_type, &v_INT32, FALSE);
+ }
+ break;
+ case DBUS_TYPE_UINT32:
+ {
+ dbus_uint32_t v_UINT32 = v_DOUBLE;
+ append_basic_maybe_in_variant (iter, forced_type, &v_UINT32, FALSE);
+ }
+ break;
+ default:
+ seed_make_exception (ctx, exception,
+ "JavaScript Number can't be converted to dbus type '%c'",
+ forced_type);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+append_boolean (SeedContext ctx,
+ DBusMessageIter * iter,
+ int forced_type, dbus_bool_t v_BOOLEAN,
+ SeedException *exception)
+{
+ if (forced_type == DBUS_TYPE_INVALID)
+ forced_type = DBUS_TYPE_BOOLEAN;
+
+ switch (forced_type)
+ {
+ case DBUS_TYPE_BOOLEAN:
+ append_basic_maybe_in_variant (iter, forced_type, &v_BOOLEAN, FALSE);
+ break;
+ case DBUS_TYPE_VARIANT:
+ append_basic_maybe_in_variant (iter, DBUS_TYPE_BOOLEAN, &v_BOOLEAN,
+ TRUE);
+ break;
+ default:
+ seed_make_exception (ctx, exception,
+ "JavaScript Boolean can't be converted to dbus type '%c'",
+ forced_type);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+append_array (SeedContext ctx,
+ DBusMessageIter * iter,
+ DBusSignatureIter * sig_iter, SeedObject array,
+ int length,
+ SeedException *exception)
+{
+ DBusSignatureIter element_sig_iter;
+ int forced_type;
+ SeedValue element;
+ DBusMessageIter array_iter;
+ DBusMessageIter variant_iter;
+ int i;
+ char *sig;
+
+ forced_type = dbus_signature_iter_get_current_type (sig_iter);
+
+ if (forced_type == DBUS_TYPE_VARIANT)
+ {
+ DBusSignatureIter variant_sig_iter;
+
+ dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT,
+ "av", &variant_iter);
+ dbus_signature_iter_init (&variant_sig_iter, "av");
+ if (!append_array (context, &variant_iter,
+ &variant_sig_iter, array, length))
+ return FALSE;
+ dbus_message_iter_close_container (iter, &variant_iter);
+
+ return TRUE;
+ }
+ else if (forced_type != DBUS_TYPE_ARRAY)
+ {
+ seed_make_exception (ctx, exception,
+ "JavaScript Array can't be converted to dbus type %c",
+ forced_type);
+ return FALSE;
+ }
+
+ g_assert (dbus_signature_iter_get_current_type (sig_iter) ==
+ DBUS_TYPE_ARRAY);
+ dbus_signature_iter_recurse (sig_iter, &element_sig_iter);
+
+ sig = dbus_signature_iter_get_signature (&element_sig_iter);
+ dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, sig, &array_iter);
+ dbus_free (sig);
+
+ for (i = 0; i < length; i++)
+ {
+ element = seed_object_get_property_at_index (ctx, array, i, exception);
+
+ // big_debug_marshal (BIG_DEBUG_JS_DBUS, " Adding array element %u", i);
+
+ if (!seed_js_one_value_to_dbus (context, element, &array_iter,
+ &element_sig_iter))
+ return FALSE;
+ }
+
+ dbus_message_iter_close_container (iter, &array_iter);
+
+ return TRUE;
+}
+// TODO: THIS IS WHERE I AM
+static gboolean
+append_dict (SeedContext ctx,
+ DBusMessageIter * iter,
+ DBusSignatureIter * sig_iter,
+ SeedObject props,
+ SeedException *exception)
+{
+ DBusSignatureIter element_sig_iter;
+ int forced_type;
+ DBusMessageIter variant_iter;
+ SeedObject props_iter;
+ DBusMessageIter dict_iter;
+ DBusSignatureIter dict_value_sig_iter;
+ char *sig;
+ SeedValue prop_signatures;
+
+ forced_type = dbus_signature_iter_get_current_type (sig_iter);
+
+ if (forced_type == DBUS_TYPE_VARIANT)
+ {
+ DBusSignatureIter variant_sig_iter;
+
+ dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT,
+ "a{sv}", &variant_iter);
+ dbus_signature_iter_init (&variant_sig_iter, "a{sv}");
+ if (!append_dict (context, &variant_iter, &variant_sig_iter, props))
+ return FALSE;
+ dbus_message_iter_close_container (iter, &variant_iter);
+
+ return TRUE;
+ }
+ else if (forced_type != DBUS_TYPE_ARRAY)
+ {
+ seed_make_exception (ctx, exception,
+ "JavaScript Object can't be converted to dbus type %c",
+ forced_type);
+ return FALSE;
+ }
+
+ g_assert (dbus_signature_iter_get_current_type (sig_iter) ==
+ DBUS_TYPE_ARRAY);
+ dbus_signature_iter_recurse (sig_iter, &element_sig_iter);
+
+ if (dbus_signature_iter_get_current_type (&element_sig_iter) !=
+ DBUS_TYPE_DICT_ENTRY)
+ {
+ seed_make_exception (ctx, exception,
+ "Objects must be marshaled as array of dict entry not of %c",
+ dbus_signature_iter_get_current_type (&element_sig_iter));
+ return FALSE;
+ }
+
+ /* dbus itself enforces that dict keys are strings */
+
+ g_assert (dbus_signature_iter_get_current_type (&element_sig_iter) ==
+ DBUS_TYPE_DICT_ENTRY);
+ dbus_signature_iter_recurse (&element_sig_iter, &dict_value_sig_iter);
+ /* check it points to key type first */
+ g_assert (dbus_signature_iter_get_current_type (&dict_value_sig_iter) ==
+ DBUS_TYPE_STRING);
+ /* move to value type */
+ dbus_signature_iter_next (&dict_value_sig_iter);
+
+ sig = dbus_signature_iter_get_signature (&element_sig_iter);
+ dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, sig, &dict_iter);
+ dbus_free (sig);
+
+ /* If a dictionary contains another dictionary at key
+ * _dbus_signatures, the sub-dictionary can provide the signature
+ * of each value in the outer dictionary. This allows forcing
+ * integers to unsigned or whatever.
+ *
+ * _dbus_signatures has a weird name to avoid conflicting with
+ * real properties. Matches _dbus_sender which is used elsewhere.
+ *
+ * We don't bother rooting the signature object or the stuff in it
+ * because we assume the outer dictionary is rooted so the stuff
+ * in it is also.
+ */
+ prop_signatures = seed_object_get_property (ctx, props, "_dbus_signatures");
+
+ if (!seed_value_is_undefined (ctx, prop_signatures) && !seed_value_is_object (ctx, prop_signatures))
+ {
+ seed_make_exception (ctx, exception, "_dbus_signatures prop must be an object");
+ return FALSE;
+ }
+
+ if (!seed_value_is_undefined (ctx, prop_signatures) &&
+ dbus_signature_iter_get_current_type (&dict_value_sig_iter) !=
+ DBUS_TYPE_VARIANT)
+ {
+ seed_make_exception (ctx, exception,
+ "Specifying _dbus_signatures for a dictionary with non-variant values is useless");
+ return FALSE;
+ }
+
+ props_iter = JS_NewPropertyIterator (context, props);
+ if (props_iter == NULL)
+ {
+ gjs_throw (context,
+ "Failed to create property iterator for object props");
+ return FALSE;
+ }
+
+ prop_id = JSVAL_VOID;
+ if (!JS_NextProperty (context, props_iter, &prop_id))
+ return FALSE;
+
+ while (prop_id != JSVAL_VOID)
+ {
+ SeedValue nameval;
+ char *name;
+ SeedValue propval;
+ DBusMessageIter entry_iter;
+ const char *value_signature;
+
+ if (!JS_IdToValue (context, prop_id, &nameval))
+ return FALSE;
+
+ if (!gjs_string_to_utf8 (context, nameval, &name))
+ return FALSE;
+
+ if (strcmp (name, "_dbus_signatures") == 0)
+ {
+ /* skip the magic "_dbus_signatures" field */
+ goto next;
+ }
+
+ /* see if this prop has a forced signature */
+ value_signature = NULL;
+ if (prop_signatures != JSVAL_VOID)
+ {
+ SeedValue signature_value;
+ signature_value = JSVAL_VOID;
+ gjs_object_get_property (context,
+ JSVAL_TO_OBJECT (prop_signatures),
+ name, &signature_value);
+ if (signature_value != JSVAL_VOID)
+ {
+ value_signature = gjs_string_get_ascii_checked (context,
+ signature_value);
+ if (value_signature == NULL)
+ {
+ return FALSE;
+ }
+ }
+ }
+
+ if (!gjs_object_require_property
+ (context, props, "DBus append_dict", name, &propval))
+ return FALSE;
+
+ big_debug_marshal (BIG_DEBUG_JS_DBUS, " Adding property %s", name);
+
+ /* seed_js_one_value_to_dbus() would check this also, but would not
+ * print the property name, which is often useful
+ */
+ if (JSVAL_IS_NULL (propval))
+ {
+ gjs_throw (context,
+ "Property '%s' has a null value, can't send over dbus",
+ name);
+ return FALSE;
+ }
+
+ dbus_message_iter_open_container (&dict_iter, DBUS_TYPE_DICT_ENTRY,
+ NULL, &entry_iter);
+
+ dbus_message_iter_append_basic (&entry_iter, DBUS_TYPE_STRING, &name);
+ g_free (name);
+
+ if (value_signature != NULL)
+ {
+ DBusSignatureIter forced_signature_iter;
+ DBusMessageIter variant_iter;
+
+ g_assert (dbus_signature_iter_get_current_type
+ (&dict_value_sig_iter) == DBUS_TYPE_VARIANT);
+
+ dbus_message_iter_open_container (&entry_iter,
+ DBUS_TYPE_VARIANT,
+ value_signature, &variant_iter);
+
+ dbus_signature_iter_init (&forced_signature_iter, value_signature);
+
+ if (!seed_js_one_value_to_dbus (context, propval, &variant_iter,
+ &forced_signature_iter))
+ return FALSE;
+
+ dbus_message_iter_close_container (&entry_iter, &variant_iter);
+ }
+ else
+ {
+ if (!seed_js_one_value_to_dbus (context, propval, &entry_iter,
+ &dict_value_sig_iter))
+ return FALSE;
+ }
+
+ dbus_message_iter_close_container (&dict_iter, &entry_iter);
+
+ next:
+ prop_id = JSVAL_VOID;
+ if (!JS_NextProperty (context, props_iter, &prop_id))
+ return FALSE;
+ }
+
+ dbus_message_iter_close_container (iter, &dict_iter);
+
+ return TRUE;
+}
+
+gboolean
+seed_js_one_value_to_dbus (SeedContext ctx,
+ SeedValue value,
+ DBusMessageIter * iter,
+ DBusSignatureIter * sig_iter)
+{
+ int forced_type;
+
+ forced_type = dbus_signature_iter_get_current_type (sig_iter);
+
+ big_debug_marshal (BIG_DEBUG_JS_DBUS,
+ "Converting dbus type '%c' from SeedValue",
+ forced_type != DBUS_TYPE_INVALID ? forced_type : '0');
+
+ /* Don't write anything on the bus if the signature is empty */
+ if (forced_type == DBUS_TYPE_INVALID)
+ return TRUE;
+
+ if (SEEDVALUE_IS_NULL (value))
+ {
+ big_debug (BIG_DEBUG_JS_DBUS, "Can't send null values over dbus");
+ gjs_throw (context, "Can't send null values over dbus");
+ return FALSE;
+ }
+ else if (SEEDVALUE_IS_STRING (value))
+ {
+ char *data;
+ gsize len;
+ char buf[3] = { '\0', '\0', '\0' };
+ if (forced_type == DBUS_TYPE_ARRAY)
+ {
+ buf[0] = DBUS_TYPE_ARRAY;
+ buf[1] = dbus_signature_iter_get_element_type (sig_iter);
+ }
+ else
+ {
+ buf[0] = forced_type;
+ }
+
+ data = NULL;
+ len = 0;
+ if (buf[1] == DBUS_TYPE_BYTE)
+ {
+ if (!gjs_string_get_binary_data (context, value, &data, &len))
+ return FALSE;
+ }
+ else
+ {
+ if (!gjs_string_to_utf8 (context, value, &data))
+ return FALSE;
+ len = strlen (data);
+ }
+
+ if (!append_string (context, iter, buf, data, len))
+ {
+ g_free (data);
+ return FALSE;
+ }
+
+ g_free (data);
+ }
+ else if (SEEDVALUE_IS_INT (value))
+ {
+ dbus_int32_t v_INT32;
+ if (!JS_ValueToInt32 (context, value, &v_INT32))
+ return FALSE;
+
+ if (!append_int32 (context, iter, forced_type, v_INT32))
+ return FALSE;
+ }
+ else if (SEEDVALUE_IS_DOUBLE (value))
+ {
+ double v_DOUBLE;
+ if (!JS_ValueToNumber (context, value, &v_DOUBLE))
+ return FALSE;
+
+ if (!append_double (context, iter, forced_type, v_DOUBLE))
+ return FALSE;
+ }
+ else if (SEEDVALUE_IS_BOOLEAN (value))
+ {
+ gboolean v_JS_BOOLEAN;
+ dbus_bool_t v_BOOLEAN;
+ if (!JS_ValueToBoolean (context, value, &v_JS_BOOLEAN))
+ return FALSE;
+ v_BOOLEAN = v_JS_BOOLEAN != FALSE;
+
+ if (!append_boolean (context, iter, forced_type, v_BOOLEAN))
+ return FALSE;
+ }
+ else if (SEEDVALUE_IS_OBJECT (value))
+ {
+ JSObject *obj;
+ SeedValue lengthval;
+
+ obj = SEEDVALUE_TO_OBJECT (value);
+
+ /* see if there's a length property */
+ gjs_object_get_property (context, obj, "length", &lengthval);
+
+ if (SEEDVALUE_IS_INT (lengthval))
+ {
+ guint length;
+
+ length = SEEDVALUE_TO_INT (lengthval);
+
+ big_debug_marshal (BIG_DEBUG_JS_DBUS,
+ "Looks like an array length %u", length);
+ if (!append_array (context, iter, sig_iter, obj, length))
+ return FALSE;
+ }
+ else
+ {
+ big_debug_marshal (BIG_DEBUG_JS_DBUS, "Looks like a dictionary");
+ if (!append_dict (context, iter, sig_iter, obj))
+ return FALSE;
+ }
+ }
+ else if (value == SEEDVALUE_VOID)
+ {
+ big_debug (BIG_DEBUG_JS_DBUS,
+ "Can't send void (undefined) values over dbus");
+ gjs_throw (context, "Can't send void (undefined) values over dbus");
+ return FALSE;
+ }
+ else
+ {
+ big_debug (BIG_DEBUG_JS_DBUS,
+ "Don't know how to convert this jsval to dbus type");
+ gjs_throw (context,
+ "Don't know how to convert this jsval to dbus type");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+seed_js_values_to_dbus (SeedContext ctx,
+ int index,
+ jsval values,
+ DBusMessageIter * iter, DBusSignatureIter * sig_iter)
+{
+ jsval value;
+ jsuint length;
+
+ if (!JS_GetArrayLength (context, JSVAL_TO_OBJECT (values), &length))
+ {
+ gjs_throw (context, "Error retrieving length property of args array");
+ return FALSE;
+ }
+
+ if (index > (int) length)
+ {
+ gjs_throw (context, "Index %d is bigger than array length %d", index,
+ length);
+ return FALSE;
+ }
+
+ if (index == (int) length)
+ return TRUE;
+
+ if (!JS_GetElement (context, JSVAL_TO_OBJECT (values), index, &value))
+ {
+ gjs_throw (context, "Error accessing element %d of args array", index);
+ return FALSE;
+ }
+
+ if (!seed_js_one_value_to_dbus (context, value, iter, sig_iter))
+ {
+ gjs_throw (context, "Error marshalling js value to dbus");
+ return FALSE;
+ }
+
+ if (dbus_signature_iter_next (sig_iter))
+ {
+ return seed_js_values_to_dbus (context, index + 1, values, iter,
+ sig_iter);
+ }
+
+ return TRUE;
+}
+
+/* If jsval is an object, add properties from the DBusMessage such as the
+ * sender. If jsval is not an object, do nothing.
+ */
+gboolean
+seed_js_add_dbus_props (SeedContext ctx, DBusMessage * message, jsval value)
+{
+ const char *sender;
+
+ if (!JSVAL_IS_OBJECT (value))
+ return TRUE;
+
+ sender = dbus_message_get_sender (message);
+
+ if (!JS_DefineProperty (context, JSVAL_TO_OBJECT (value),
+ "_dbus_sender",
+ STRING_TO_JSVAL (JS_NewStringCopyZ
+ (context, sender)), NULL, NULL,
+ JSPROP_ENUMERATE))
+ return FALSE;
+
+ return TRUE;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]