summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2010-10-26 11:16:08 -0400
committerColin Walters <walters@verbum.org>2010-11-17 20:09:14 -0500
commit34fdc293117109f003967aec397b0e87a33c9f53 (patch)
tree812bbebdb1252f22df5e21cb37c4adc88434a974
parentd605a3aa40f5394ee1cad5ad621ad655d4e9e7f9 (diff)
downloadgjs-34fdc293117109f003967aec397b0e87a33c9f53.tar.gz
Support gunichar
This is a new fundamental type tag. https://bugzilla.gnome.org/show_bug.cgi?id=633199
-rw-r--r--gi/arg.c29
-rw-r--r--gi/boxed.c1
-rw-r--r--gjs/jsapi-util-string.c25
-rw-r--r--gjs/jsapi-util.h6
-rw-r--r--test/js/testEverythingBasic.js4
5 files changed, 65 insertions, 0 deletions
diff --git a/gi/arg.c b/gi/arg.c
index 0663a120..121d82aa 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 f27a8997..6559ad03 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 e4a89487..1934097a 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 cdaa6d56..b4a07efa 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 2a9982b2..0730eba5 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);