[gjs] Add support for GArray to gjs_value_to_g_argument



commit 7dada73f134407b6e08fd4cea3fe8a30cf396636
Author: Danielle Madeley <danielle madeley collabora co uk>
Date:   Thu Apr 29 20:02:52 2010 +1000

    Add support for GArray to gjs_value_to_g_argument
    
    Needs to be extended to support GByteArray and GPtrArray.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=581696

 Makefile-test.am             |    1 +
 gi/arg.c                     |   78 ++++++++++++++++++++++++++++++++++++++++-
 test/js/testGIMarshalling.js |   43 +++++++++++++++++++++++
 3 files changed, 120 insertions(+), 2 deletions(-)
---
diff --git a/Makefile-test.am b/Makefile-test.am
index 60299d5..b804e98 100644
--- a/Makefile-test.am
+++ b/Makefile-test.am
@@ -127,6 +127,7 @@ EXTRA_DIST +=					\
 	test/js/testEverythingBasic.js		\
 	test/js/testEverythingEncapsulated.js	\
 	test/js/testGI.js			\
+	test/js/testGIMarshalling.js		\
 	test/js/testImporter.js			\
 	test/js/testLang.js			\
 	test/js/testLocale.js			\
diff --git a/gi/arg.c b/gi/arg.c
index 16b1358..beaa3e3 100644
--- a/gi/arg.c
+++ b/gi/arg.c
@@ -551,6 +551,63 @@ gjs_array_to_array(JSContext   *context,
     }
 }
 
+static JSBool
+gjs_array_to_g_array(JSContext   *context,
+                     jsval        array_value,
+                     unsigned int length,
+                     GITypeInfo  *param_info,
+                     void       **arr_p)
+{
+    GArray *array;
+    GITypeTag element_type;
+    gpointer contents;
+    guint element_size;
+
+    element_type = g_type_info_get_tag(param_info);
+    element_type = normalize_int_types(element_type);
+
+    switch (element_type) {
+    case GI_TYPE_TAG_UINT8:
+    case GI_TYPE_TAG_INT8:
+      element_size = sizeof(guint8);
+      break;
+    case GI_TYPE_TAG_UINT16:
+    case GI_TYPE_TAG_INT16:
+      element_size = sizeof(guint16);
+      break;
+    case GI_TYPE_TAG_UINT32:
+    case GI_TYPE_TAG_INT32:
+      element_size = sizeof(guint32);
+      break;
+    case GI_TYPE_TAG_UINT64:
+    case GI_TYPE_TAG_INT64:
+      element_size = sizeof(guint64);
+      break;
+    default:
+        gjs_throw(context,
+                  "Unhandled GArray element-type %d", element_type);
+        return JS_FALSE;
+    }
+
+    /* create a C array */
+    if (!gjs_array_to_array (context,
+                             array_value,
+                             length,
+                             param_info,
+                             &contents))
+      return JS_FALSE;
+
+    /* append that array to the GArray */
+    array = g_array_sized_new(TRUE, TRUE, element_size, length);
+    g_array_append_vals(array, contents, length);
+
+    g_free(contents);
+
+    *arr_p = array;
+
+    return JS_TRUE;
+}
+
 static gchar *
 get_argument_display_name(const char     *arg_name,
                           GjsArgumentType arg_type)
@@ -1047,13 +1104,30 @@ gjs_value_to_g_argument(JSContext      *context,
                 !JS_ValueToECMAUint32(context, length_value, &length)) {
                 wrong = TRUE;
             } else {
+                GIArrayType array_type = g_type_info_get_array_type(type_info);
                 GITypeInfo *param_info;
 
                 param_info = g_type_info_get_param_type(type_info, 0);
                 g_assert(param_info != NULL);
 
-                if (!gjs_array_to_array (context, value, length, param_info, &arg->v_pointer))
-                    wrong = TRUE;
+                if (array_type == GI_ARRAY_TYPE_C) {
+                    if (!gjs_array_to_array (context,
+                                             value,
+                                             length,
+                                             param_info,
+                                             &arg->v_pointer))
+                      wrong = TRUE;
+                } else if (array_type == GI_ARRAY_TYPE_ARRAY) {
+                    if (!gjs_array_to_g_array (context,
+                                               value,
+                                               length,
+                                               param_info,
+                                               &arg->v_pointer))
+                      wrong = TRUE;
+                /* FIXME: support ByteArray and PtrArray */
+                } else {
+                    g_assert_not_reached();
+                }
 
                 g_base_info_unref((GIBaseInfo*) param_info);
             }
diff --git a/test/js/testGIMarshalling.js b/test/js/testGIMarshalling.js
new file mode 100644
index 0000000..62c05b2
--- /dev/null
+++ b/test/js/testGIMarshalling.js
@@ -0,0 +1,43 @@
+const GIMarshallingTests = imports.gi.GIMarshallingTests;
+
+// We use Gio to have some objects that we know exist
+const Gio = imports.gi.Gio;
+const Lang = imports.lang;
+
+function testGArray() {
+    var array = GIMarshallingTests.garray_int_none_return();
+    assertEquals(-1, array[0]);
+    assertEquals(0, array[1]);
+    assertEquals(1, array[2]);
+    assertEquals(2, array[3]);
+    array = GIMarshallingTests.garray_utf8_none_return()
+    assertEquals("0", array[0]);
+    assertEquals("1", array[1]);
+    assertEquals("2", array[2]);
+    array = GIMarshallingTests.garray_utf8_container_return()
+    assertEquals("0", array[0]);
+    assertEquals("1", array[1]);
+    assertEquals("2", array[2]);
+    array = GIMarshallingTests.garray_utf8_full_return()
+    assertEquals("0", array[0]);
+    assertEquals("1", array[1]);
+    assertEquals("2", array[2]);
+
+    GIMarshallingTests.garray_int_none_in([-1, 0, 1, 2])
+    // GIMarshallingTests.garray_utf8_none_in(["0", "1", "2"])
+
+    array = GIMarshallingTests.garray_utf8_none_out()
+    assertEquals("0", array[0]);
+    assertEquals("1", array[1]);
+    assertEquals("2", array[2]);
+    array = GIMarshallingTests.garray_utf8_container_out()
+    assertEquals("0", array[0]);
+    assertEquals("1", array[1]);
+    assertEquals("2", array[2]);
+    array = GIMarshallingTests.garray_utf8_full_out()
+    assertEquals("0", array[0]);
+    assertEquals("1", array[1]);
+    assertEquals("2", array[2]);
+}
+
+gjstestRun();



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