diff options
author | Colin Walters <walters@verbum.org> | 2010-10-26 11:16:08 -0400 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2010-11-17 20:09:14 -0500 |
commit | 34fdc293117109f003967aec397b0e87a33c9f53 (patch) | |
tree | 812bbebdb1252f22df5e21cb37c4adc88434a974 | |
parent | d605a3aa40f5394ee1cad5ad621ad655d4e9e7f9 (diff) | |
download | gjs-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.c | 29 | ||||
-rw-r--r-- | gi/boxed.c | 1 | ||||
-rw-r--r-- | gjs/jsapi-util-string.c | 25 | ||||
-rw-r--r-- | gjs/jsapi-util.h | 6 | ||||
-rw-r--r-- | test/js/testEverythingBasic.js | 4 |
5 files changed, 65 insertions, 0 deletions
@@ -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); @@ -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); |