aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Austin <chad@imvu.com>2013-04-10 23:59:51 -0700
committerJukka Jylänki <jujjyl@gmail.com>2013-04-18 20:08:09 +0300
commit6a4574cfe44b75f8cfaa916a08b402f99baf6cc7 (patch)
treeb9bb8c88e5ce73bddcd96da4897eab07d91ed59c
parentbcf017994524b515274344dcf667dc03b8153448 (diff)
Add support for returning std::wstring
-rwxr-xr-xsrc/embind/embind.js31
-rwxr-xr-xsystem/include/emscripten/bind.h7
-rwxr-xr-xsystem/include/emscripten/wire.h20
-rwxr-xr-xsystem/lib/embind/bind.cpp21
-rwxr-xr-xtests/embind/embind.test.js20
-rw-r--r--tests/embind/embind_test.cpp10
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);