1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
// Copyright 2020 The Emscripten Authors. All rights reserved.
// Emscripten is available under two separate licenses, the MIT license and the
// University of Illinois/NCSA Open Source License. Both these licenses can be
// found in the LICENSE file.
#include <cassert>
#include <emscripten.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <wchar.h>
// Roundtrip a (non-)null-terminated string between C++ and JS.
EM_JS(void, roundtripString, (const char16_t* str, int strBytes, char16_t* result, int resultBytes), {
var jsStr = UTF16ToString(str, strBytes >= 0 ? strBytes : undefined);
out(jsStr);
var bytesWritten = stringToUTF16(jsStr, result, resultBytes);
if (bytesWritten != resultBytes - 2) throw 'stringToUTF16 wrote an invalid length: ' + numBytesWritten;
});
static void testString(const char16_t* arg) {
// Test with null-terminated string.
std::u16string strz(arg);
char16_t* result = new char16_t[strz.size() + 1]();
int resultBytes = (strz.size() + 1) * sizeof(char16_t);
roundtripString(strz.data(), -1, result, resultBytes);
// Compare strings after taking a route through JS side.
assert(std::equal(result, result + strz.size() + 1, strz.data()));
// Same test with non-null-terminated string and explicit length.
std::vector<char16_t> str(strz.begin(), strz.end());
std::fill_n(result, str.size() + 1, 0);
roundtripString(str.data(), str.size() * sizeof(char16_t), result, resultBytes);
assert(std::equal(result, result + str.size(), str.data()));
// Test again with some garbage at the end of the string.
std::vector<char16_t> strx(str);
strx.insert(strx.end(), 10, 'x');
std::fill_n(result, str.size() + 1, 0);
roundtripString(strx.data(), str.size() * sizeof(char16_t), result, resultBytes);
assert(std::equal(result, result + str.size(), str.data()));
delete[] result;
}
// This code tests that UTF16 strings can be marshalled between C++ and JS.
int main() {
// For the conversion of long strings (more than 32 bytes), TextDecoder can be used.
testString(u"abc\u2603\u20AC\U0002007C123 --- abc\u2603\u20AC\U0002007C123");
// But for shorter strings it's never used.
testString(u"short\u2603\u20AC\U0002007C123");
testString(u"a");
testString(u"");
printf("OK.\n");
}
|