[gjs] Support for writing structures



commit 75e12e5908b9192abeaa19837dcd3ddcbc2156b5
Author: Colin Walters <walters verbum org>
Date:   Fri Jun 12 17:01:57 2009 -0400

    Support for writing structures
    
    Allow sending DBUS_TYPE_STRUCT using arrays.

 modules/dbus-values.c |   95 +++++++++++++++++++++++++++++++++++-------------
 test/js/testDbus.js   |   35 ++++++++++++++++--
 2 files changed, 101 insertions(+), 29 deletions(-)
---
diff --git a/modules/dbus-values.c b/modules/dbus-values.c
index f8e9faa..1a6561a 100644
--- a/modules/dbus-values.c
+++ b/modules/dbus-values.c
@@ -531,14 +531,13 @@ append_array(JSContext         *context,
     DBusSignatureIter element_sig_iter;
     int forced_type;
     jsval 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) {
+        DBusMessageIter variant_iter;
         DBusSignatureIter variant_sig_iter;
 
         dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
@@ -552,39 +551,83 @@ append_array(JSContext         *context,
         dbus_message_iter_close_container(iter, &variant_iter);
 
         return JS_TRUE;
-    } else if (forced_type != DBUS_TYPE_ARRAY) {
-        gjs_throw(context,
-                  "JavaScript Array can't be converted to dbus type %c",
-                  forced_type);
-        return JS_FALSE;
-    }
-
-    g_assert(dbus_signature_iter_get_current_type(sig_iter) == DBUS_TYPE_ARRAY);
-    dbus_signature_iter_recurse(sig_iter, &element_sig_iter);
+    } else if (forced_type == DBUS_TYPE_STRUCT) {
+        DBusMessageIter struct_iter;
+        dbus_bool_t have_next;
+
+        g_assert(dbus_signature_iter_get_current_type(sig_iter) == DBUS_TYPE_STRUCT);
+        dbus_signature_iter_recurse(sig_iter, &element_sig_iter);
+
+        dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, NULL, &struct_iter);
+        
+        have_next = dbus_signature_iter_get_current_type(&element_sig_iter) != DBUS_TYPE_INVALID;
+
+        for (i = 0; i < length; i++) {
+            element = JSVAL_VOID;
+            
+            if (!have_next) {
+                gjs_throw(context, "Insufficient elements for structure in JS Array");
+                return JS_FALSE;
+            }
 
-    sig = dbus_signature_iter_get_signature(&element_sig_iter);
-    dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, sig, &array_iter);
-    dbus_free(sig);
+            if (!JS_GetElement(context, array, i, &element)) {
+                gjs_throw(context, "Failed to get element in JS Array");
+                return JS_FALSE;
+            }
 
-    for (i = 0; i < length; i++) {
-        element = JSVAL_VOID;
+            gjs_debug(GJS_DEBUG_DBUS_MARSHAL,
+                      " Adding struct element %u", i);
 
-        if (!JS_GetElement(context, array, i, &element)) {
-            gjs_throw(context, "Failed to get element in JS Array");
+            if (!gjs_js_one_value_to_dbus(context, element, &struct_iter,
+                                          &element_sig_iter))
+                return JS_FALSE;
+            
+            have_next = dbus_signature_iter_next (&element_sig_iter);
+        }
+        
+        if (have_next) {
+            gjs_throw(context, "Too many elements for structure in JS Array");
             return JS_FALSE;
         }
 
-        gjs_debug(GJS_DEBUG_DBUS_MARSHAL,
-                  " Adding array element %u", i);
+        dbus_message_iter_close_container(iter, &struct_iter);
 
-        if (!gjs_js_one_value_to_dbus(context, element, &array_iter,
-                                      &element_sig_iter))
-            return JS_FALSE;
-    }
+        return JS_TRUE;
+    } else if (forced_type == DBUS_TYPE_ARRAY) {
+        DBusMessageIter array_iter;
 
-    dbus_message_iter_close_container(iter, &array_iter);
+        g_assert(dbus_signature_iter_get_current_type(sig_iter) == DBUS_TYPE_ARRAY);
+        dbus_signature_iter_recurse(sig_iter, &element_sig_iter);
 
-    return JS_TRUE;
+        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 = JSVAL_VOID;
+
+            if (!JS_GetElement(context, array, i, &element)) {
+                gjs_throw(context, "Failed to get element in JS Array");
+                return JS_FALSE;
+            }
+
+            gjs_debug(GJS_DEBUG_DBUS_MARSHAL,
+                      " Adding array element %u", i);
+
+            if (!gjs_js_one_value_to_dbus(context, element, &array_iter,
+                                          &element_sig_iter))
+                return JS_FALSE;
+        }
+
+        dbus_message_iter_close_container(iter, &array_iter);
+        
+        return JS_TRUE;
+    } else {
+      gjs_throw(context,
+                "JavaScript Array can't be converted to dbus type %c",
+                forced_type);
+      return JS_FALSE;
+    }
 }
 
 static JSBool
diff --git a/test/js/testDbus.js b/test/js/testDbus.js
index 2ea5cf8..a1ed63d 100644
--- a/test/js/testDbus.js
+++ b/test/js/testDbus.js
@@ -13,7 +13,10 @@ Malarky.prototype = {
 };
 
 /* The methods list with their signatures. We test both notations for json
- * methods (only name or explicit signatures) */
+ * methods (only name or explicit signatures)
+ *
+ * *** NOTE: If you add stuff here, you need to update testIntrospectReal
+ */
 var realIface = {
     name: 'com.litl.Real',
     methods: [{ name: 'nonJsonFrobateStuff',
@@ -49,7 +52,9 @@ var realIface = {
               { name: "dictEcho", outSignature: "a{sv}",
                 inSignature: "a{sv}" },
               { name: "echo", outSignature: "si",
-                inSignature: "si" }
+                inSignature: "si" },
+              { name: "structArray", outSignature: "a(ii)",
+                inSignature: '' }
              ],
     signals: [
         { name: 'signalFoo', inSignature: 's' }
@@ -193,6 +198,10 @@ Real.prototype = {
 
     set PropReadWrite(value) {
         this._propReadWrite = value;
+    },
+    
+    structArray: function () {
+        return [[128, 123456], [42, 654321]];
     }
 };
 
@@ -777,6 +786,26 @@ function testBytes() {
     }
 }
 
+function testStructArray() {
+    let theResult, theExcp;
+    Mainloop.idle_add(function() {
+                      let proxy = new Malarky();
+                      proxy.structArrayRemote(function(result, excp) {
+                                                  theResult = result;
+                                                  theExcp = excp;
+                                                  Mainloop.quit('testDbus');
+                                              });
+                      });
+    Mainloop.run('testDbus');
+    assertNull(theExcp);
+    assertNotNull(theResult);
+    log(theResult);
+    assertEquals(theResult[0][0], 128);
+    assertEquals(theResult[0][1], 123456);
+    assertEquals(theResult[1][0], 42);
+    assertEquals(theResult[1][1], 654321);
+}
+
 function testDictSignatures() {
     let someDict = {
         // should be a double after round trip except
@@ -941,7 +970,7 @@ function testIntrospectReal() {
     // we get the 'realIface', plus 'Introspectable' and 'Properties'
     assertEquals(3, xml.interface.length());
     assertEquals('com.litl.Real', xml interface[0]  name toString());
-    assertEquals(18, xml.interface[0].method.length());
+    assertEquals(19, xml.interface[0].method.length());
     assertEquals(3, xml.interface[0].property.length());
     assertEquals(1, xml.interface[0].signal.length());
     assertEquals('org.freedesktop.DBus.Introspectable', xml interface[1]  name toString());



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]