[gjs] Support gunichar



commit 34fdc293117109f003967aec397b0e87a33c9f53
Author: Colin Walters <walters verbum org>
Date:   Tue Oct 26 11:16:08 2010 -0400

    Support gunichar
    
    This is a new fundamental type tag.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=633199

 gi/arg.c                       |   29 +++++++++++++++++++++++++++++
 gi/boxed.c                     |    1 +
 gjs/jsapi-util-string.c        |   25 +++++++++++++++++++++++++
 gjs/jsapi-util.h               |    6 ++++++
 test/js/testEverythingBasic.js |    4 ++++
 5 files changed, 65 insertions(+), 0 deletions(-)
---
diff --git a/gi/arg.c b/gi/arg.c
index 0663a12..121d82a 100644
--- a/gi/arg.c
+++ b/gi/arg.c
@@ -790,6 +790,16 @@ gjs_value_to_g_argument(JSContext      *context,
             wrong = TRUE;
         break;
 
+    case GI_TYPE_TAG_UNICHAR:
+        if (JSVAL_IS_STRING(value)) {
+            if (!gjs_unichar_from_string(context, value, &arg->v_uint32))
+                wrong = TRUE;
+        } else {
+            wrong = TRUE;
+            report_type_mismatch = TRUE;
+        }
+        break;
+
     case GI_TYPE_TAG_FILENAME:
         nullable_type = TRUE;
         if (JSVAL_IS_NULL(value)) {
@@ -1262,6 +1272,7 @@ gjs_g_argument_init_default(JSContext      *context,
         break;
 
     case GI_TYPE_TAG_UINT32:
+    case GI_TYPE_TAG_UNICHAR:
         arg->v_uint32 = 0;
         break;
 
@@ -1648,6 +1659,24 @@ gjs_value_from_g_argument (JSContext  *context,
     case GI_TYPE_TAG_DOUBLE:
         return JS_NewNumberValue(context, arg->v_double, value_p);
 
+    case GI_TYPE_TAG_UNICHAR:
+        {
+            char utf8[7];
+            gint bytes;
+
+            /* Preserve the bidirectional mapping between 0 and "" */
+            if (arg->v_uint32 == 0) {
+                return gjs_string_from_utf8 (context, "", 0, value_p);
+            } else if (!g_unichar_validate (arg->v_uint32)) {
+                gjs_throw("Invalid unicode codepoint %" G_GUINT32_FORMAT,
+                          arg->v_uint32);
+                return JS_FALSE;
+            } else {
+                bytes = g_unichar_to_utf8 (arg->v_uint32, &utf8);
+                return gjs_string_from_utf8 (context, (char*)utf8, bytes, value_p);
+            }
+        }
+
     case GI_TYPE_TAG_FILENAME:
         if (arg->v_pointer)
             return gjs_string_from_filename(context, arg->v_pointer, -1, value_p);
diff --git a/gi/boxed.c b/gi/boxed.c
index f27a899..6559ad0 100644
--- a/gi/boxed.c
+++ b/gi/boxed.c
@@ -1045,6 +1045,7 @@ struct_is_simple(GIStructInfo *info)
             case GI_TYPE_TAG_UINT64:
             case GI_TYPE_TAG_FLOAT:
             case GI_TYPE_TAG_DOUBLE:
+            case GI_TYPE_TAG_UNICHAR:
                 break;
             case GI_TYPE_TAG_VOID:
             case GI_TYPE_TAG_GTYPE:
diff --git a/gjs/jsapi-util-string.c b/gjs/jsapi-util-string.c
index e4a8948..1934097 100644
--- a/gjs/jsapi-util-string.c
+++ b/gjs/jsapi-util-string.c
@@ -449,6 +449,31 @@ gjs_get_string_id (JSContext       *context,
     }
 }
 
+/**
+ * gjs_unichar_from_string:
+ * @string: A string
+ * @result: (out): A unicode character
+ *
+ * If successful, @result is assigned the Unicode codepoint
+ * corresponding to the first full character in @string.  This
+ * function handles characters outside the BMP.
+ *
+ * If @string is empty, @result will be 0.  An exception will
+ * be thrown if @string can not be represented as UTF-8.
+ */
+gboolean
+gjs_unichar_from_string (JSContext *context,
+                         JSString  *string,
+                         gunichar  *result)
+{
+    char *utf8_str;
+    if (gjs_string_to_utf8(context, STRING_TO_JSVAL(string), &utf8_str)) {
+        *result = g_utf8_get_char(utf8_str);
+        g_free(utf8_str);
+        return TRUE;
+    }
+    return FALSE;
+}
 
 #if GJS_BUILD_TESTS
 #include "unit-test-utils.h"
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index cdaa6d5..b4a07ef 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -329,6 +329,12 @@ JSBool      gjs_string_get_uint16_data       (JSContext       *context,
 JSBool      gjs_get_string_id                (JSContext       *context,
                                               jsid             id,
                                               const char     **name_p);
+
+
+gboolean    gjs_unichar_from_string          (JSContext       *context,
+                                              JSString        *string,
+                                              gunichar        *result);
+
 const char* gjs_get_type_name                (jsval            value);
 
 jsval       gjs_date_from_time_t             (JSContext *context, time_t time);
diff --git a/test/js/testEverythingBasic.js b/test/js/testEverythingBasic.js
index 2a9982b..0730eba 100644
--- a/test/js/testEverythingBasic.js
+++ b/test/js/testEverythingBasic.js
@@ -74,6 +74,10 @@ function testLifeUniverseAndEverything() {
     assertEquals(42, Everything.test_double(42));
     assertEquals(-42, Everything.test_double(-42));
 
+    assertEquals("c", Everything.test_unichar("c"));
+    assertEquals("", Everything.test_unichar(""));
+    assertEquals("\u2665", Everything.test_unichar("\u2665"));
+
     let now = Math.floor(new Date().getTime() / 1000);
     let bounced = Math.floor(Everything.test_timet(now));
     assertEquals(bounced, now);



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