[gjs] arg: Use a template function to fill gjs array from zero-terminated C vector



commit ca6a92dbcb97ed0fc99db028e5c90f955d9a7111
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Fri May 8 17:53:07 2020 +0200

    arg: Use a template function to fill gjs array from zero-terminated C vector
    
    This allows to generate code statically checked by gcc with proper type
    checks

 gi/arg.cpp | 41 ++++++++++++++++++++++++++---------------
 1 file changed, 26 insertions(+), 15 deletions(-)
---
diff --git a/gi/arg.cpp b/gi/arg.cpp
index 056b50da..da36f09e 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -2686,6 +2686,27 @@ gjs_array_from_boxed_array (JSContext             *context,
                                           param_info, length, data);
 }
 
+template <typename T, T GIArgument::*member>
+GJS_JSAPI_RETURN_CONVENTION static bool fill_vector_from_zero_terminated_carray(
+    JSContext* cx, JS::RootedValueVector& elems,  // NOLINT(runtime/references)
+    GITypeInfo* param_info, GIArgument* arg, void* c_array) {
+    T* array = static_cast<T*>(c_array);
+
+    for (size_t i = 0; array[i]; i++) {
+        arg->*member = array[i];
+
+        if (!elems.growBy(1)) {
+            JS_ReportOutOfMemory(cx);
+            return false;
+        }
+
+        if (!gjs_value_from_g_argument(cx, elems[i], param_info, arg, true))
+            return false;
+    }
+
+    return true;
+}
+
 GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_array_from_zero_terminated_c_array (JSContext             *context,
@@ -2695,7 +2716,6 @@ gjs_array_from_zero_terminated_c_array (JSContext             *context,
 {
     GArgument arg;
     GITypeTag element_type;
-    guint i;
 
     element_type = g_type_info_get_tag(param_info);
 
@@ -2715,20 +2735,11 @@ gjs_array_from_zero_terminated_c_array (JSContext             *context,
 
     JS::RootedValueVector elems(context);
 
-#define ITERATE(type) \
-    do { \
-        g##type *array = (g##type *) c_array; \
-        for (i = 0; array[i]; i++) { \
-            arg.v_##type = array[i]; \
-            if (!elems.growBy(1)) {                                     \
-                JS_ReportOutOfMemory(context);                          \
-                return false;                                           \
-            }                                                           \
-            if (!gjs_value_from_g_argument(context, elems[i],           \
-                                           param_info, &arg, true))     \
-                return false; \
-        } \
-    } while(0);
+#define ITERATE(type)                                                    \
+    if (!fill_vector_from_zero_terminated_carray<g##type,                \
+                                                 &GIArgument::v_##type>( \
+            context, elems, param_info, &arg, c_array))                  \
+        return false;
 
     switch (element_type) {
         /* Special cases handled above. */


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