diff options
author | Chad Austin <chad@imvu.com> | 2013-04-10 23:59:51 -0700 |
---|---|---|
committer | Jukka Jylänki <jujjyl@gmail.com> | 2013-04-18 20:08:09 +0300 |
commit | 6a4574cfe44b75f8cfaa916a08b402f99baf6cc7 (patch) | |
tree | b9bb8c88e5ce73bddcd96da4897eab07d91ed59c | |
parent | bcf017994524b515274344dcf667dc03b8153448 (diff) |
Add support for returning std::wstring
-rwxr-xr-x | src/embind/embind.js | 31 | ||||
-rwxr-xr-x | system/include/emscripten/bind.h | 7 | ||||
-rwxr-xr-x | system/include/emscripten/wire.h | 20 | ||||
-rwxr-xr-x | system/lib/embind/bind.cpp | 21 | ||||
-rwxr-xr-x | tests/embind/embind.test.js | 20 | ||||
-rw-r--r-- | tests/embind/embind_test.cpp | 10 |
6 files changed, 99 insertions, 10 deletions
diff --git a/src/embind/embind.js b/src/embind/embind.js index 42250601..576a519e 100755 --- a/src/embind/embind.js +++ b/src/embind/embind.js @@ -317,12 +317,12 @@ function __embind_register_float(rawType, name) { }); } -function __embind_register_cstring(rawType, name) { +function __embind_register_std_string(rawType, name) { name = Pointer_stringify(name); registerType(rawType, { name: name, fromWireType: function(value) { - var length = HEAP32[value >> 2]; + var length = HEAPU32[value >> 2]; var a = new Array(length); for (var i = 0; i < length; ++i) { a[i] = String.fromCharCode(HEAPU8[value + 4 + i]); @@ -334,7 +334,7 @@ function __embind_register_cstring(rawType, name) { // assumes 4-byte alignment var length = value.length; var ptr = _malloc(4 + length); - HEAP32[ptr >> 2] = length; + HEAPU32[ptr >> 2] = length; for (var i = 0; i < length; ++i) { HEAPU8[ptr + 4 + i] = value.charCodeAt(i); } @@ -344,6 +344,31 @@ function __embind_register_cstring(rawType, name) { }); } +function __embind_register_std_wstring(rawType, charSize, name) { + name = Pointer_stringify(name); + var HEAP, shift; + if (charSize == 2) { + HEAP = HEAPU16; + shift = 1; + } else if (charSize == 4) { + HEAP = HEAPU32; + shift = 2; + } + registerType(rawType, { + name: name, + fromWireType: function(value) { + var length = HEAPU32[value >> 2]; + var a = new Array(length); + var start = (value + 4) >> shift; + for (var i = 0; i < length; ++i) { + a[i] = String.fromCharCode(HEAP[start + i]); + } + _free(value); + return a.join(''); + }, + }); +} + function __embind_register_emval(rawType, name) { name = Pointer_stringify(name); registerType(rawType, { diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h index 73a8d4da..9b6e69c9 100755 --- a/system/include/emscripten/bind.h +++ b/system/include/emscripten/bind.h @@ -47,10 +47,15 @@ namespace emscripten { TYPEID floatType, const char* name); - void _embind_register_cstring( + void _embind_register_std_string( TYPEID stringType, const char* name); + void _embind_register_std_wstring( + TYPEID stringType, + size_t charSize, + const char* name); + void _embind_register_emval( TYPEID emvalType, const char* name); diff --git a/system/include/emscripten/wire.h b/system/include/emscripten/wire.h index 64114491..0e8334e8 100755 --- a/system/include/emscripten/wire.h +++ b/system/include/emscripten/wire.h @@ -181,6 +181,26 @@ namespace emscripten { } }; + template<> + struct BindingType<std::wstring> { + typedef struct { + size_t length; + wchar_t data[1]; // trailing data + }* WireType; + static WireType toWireType(const std::wstring& v) { + WireType wt = (WireType)malloc(sizeof(size_t) + v.length() * sizeof(wchar_t)); + wt->length = v.length(); + wmemcpy(wt->data, v.data(), v.length()); + return wt; + } + static std::wstring fromWireType(WireType v) { + return std::wstring(v->data, v->length); + } + static void destroy(WireType v) { + free(v); + } + }; + template<typename T> struct BindingType<const T> : public BindingType<T> { }; diff --git a/system/lib/embind/bind.cpp b/system/lib/embind/bind.cpp index deb55138..6cacf1e2 100755 --- a/system/lib/embind/bind.cpp +++ b/system/lib/embind/bind.cpp @@ -44,6 +44,24 @@ namespace emscripten { }
}
+// TODO: fix in library.js or a proper emscripten libc
+extern "C" wchar_t *wmemset(wchar_t *dest, wchar_t c, size_t count) {
+ wchar_t *o = dest;
+ while (count--) {
+ *o++ = c;
+ }
+ return dest;
+}
+
+// TODO: fix in library.js or a proper emscripten libc
+extern "C" wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, size_t count) {
+ wchar_t *o = dest;
+ while (count--) {
+ *dest++ = *src++;
+ }
+ return dest;
+}
+
EMSCRIPTEN_BINDINGS(native_and_builtin_types) {
using namespace emscripten::internal;
@@ -64,6 +82,7 @@ EMSCRIPTEN_BINDINGS(native_and_builtin_types) { _embind_register_float(TypeID<float>::get(), "float");
_embind_register_float(TypeID<double>::get(), "double");
- _embind_register_cstring(TypeID<std::string>::get(), "std::string");
+ _embind_register_std_string(TypeID<std::string>::get(), "std::string");
+ _embind_register_std_wstring(TypeID<std::wstring>::get(), sizeof(wchar_t), "std::wstring");
_embind_register_emval(TypeID<val>::get(), "emscripten::val");
}
diff --git a/tests/embind/embind.test.js b/tests/embind/embind.test.js index 07f093ea..872ee398 100755 --- a/tests/embind/embind.test.js +++ b/tests/embind/embind.test.js @@ -389,11 +389,21 @@ module({ }); BaseFixture.extend("string", function() { - var expected = ''; - for (var i = 0; i < 128; ++i) { - expected += String.fromCharCode(128 + i); - } - assert.equal(expected, cm.get_non_ascii_string()); + test("non-ascii strings", function() { + var expected = ''; + for (var i = 0; i < 128; ++i) { + expected += String.fromCharCode(128 + i); + } + assert.equal(expected, cm.get_non_ascii_string()); + }); + + test("non-ascii wstrings", function() { + var expected = String.fromCharCode(10) + + String.fromCharCode(1234) + + String.fromCharCode(2345) + + String.fromCharCode(65535); + assert.equal(expected, cm.get_non_ascii_wstring()); + }); }); BaseFixture.extend("embind", function() { diff --git a/tests/embind/embind_test.cpp b/tests/embind/embind_test.cpp index 6a3d5dba..f274fbf5 100644 --- a/tests/embind/embind_test.cpp +++ b/tests/embind/embind_test.cpp @@ -88,6 +88,15 @@ std::string get_non_ascii_string() { return c;
}
+std::wstring get_non_ascii_wstring() {
+ std::wstring ws(4, 0);
+ ws[0] = 10;
+ ws[1] = 1234;
+ ws[2] = 2345;
+ ws[3] = 65535;
+ return ws;
+}
+
std::string emval_test_take_and_return_const_char_star(const char* str) {
return str;
}
@@ -1503,6 +1512,7 @@ EMSCRIPTEN_BINDINGS(tests) { function("emval_test_sum", &emval_test_sum);
function("get_non_ascii_string", &get_non_ascii_string);
+ function("get_non_ascii_wstring", &get_non_ascii_wstring);
//function("emval_test_take_and_return_const_char_star", &emval_test_take_and_return_const_char_star);
function("emval_test_take_and_return_std_string", &emval_test_take_and_return_std_string);
function("emval_test_take_and_return_std_string_const_ref", &emval_test_take_and_return_std_string_const_ref);
|