From 929e2ed5ba29693892ab134a86b218ea72a33e44 Mon Sep 17 00:00:00 2001 From: Andrew Low Date: Tue, 8 Apr 2014 10:39:33 -0400 Subject: [PATCH] string_bytes: ucs2 support big endian 64bit constants are keyed for x64 platforms only, add PowerPC based platform constants. Node's "ucs2" encoding wants LE character data stored in the Buffer, so we need to reorder on BE platforms. See http://nodejs.org/api/buffer.html regarding Node's "ucs2" encoding specification Signed-off-by: Timothy J Fontaine --- src/string_bytes.cc | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/string_bytes.cc b/src/string_bytes.cc index de41ec1d4ace6c..1a7b4e1ebea71a 100644 --- a/src/string_bytes.cc +++ b/src/string_bytes.cc @@ -336,6 +336,16 @@ size_t StringBytes::Write(Isolate* isolate, memcpy(buf, data, len * 2); else len = str->Write(reinterpret_cast(buf), 0, buflen, flags); + if (IsBigEndian()) { + // Node's "ucs2" encoding wants LE character data stored in + // the Buffer, so we need to reorder on BE platforms. See + // http://nodejs.org/api/buffer.html regarding Node's "ucs2" + // encoding specification + uint16_t* buf16 = reinterpret_cast(buf); + for (size_t i = 0; i < len; i++) { + buf16[i] = (buf16[i] << 8) | (buf16[i] >> 8); + } + } if (chars_written != NULL) *chars_written = len; len = len * sizeof(uint16_t); @@ -515,7 +525,8 @@ static bool contains_non_ascii(const char* src, size_t len) { } -#if defined(__x86_64__) || defined(_WIN64) +#if defined(__x86_64__) || defined(_WIN64) || defined(__PPC64__) || \ + defined(_ARCH_PPC64) const uintptr_t mask = 0x8080808080808080ll; #else const uintptr_t mask = 0x80808080l; @@ -570,7 +581,8 @@ static void force_ascii(const char* src, char* dst, size_t len) { } } -#if defined(__x86_64__) || defined(_WIN64) +#if defined(__x86_64__) || defined(_WIN64) || defined(__PPC64__) || \ + defined(_ARCH_PPC64) const uintptr_t mask = ~0x8080808080808080ll; #else const uintptr_t mask = ~0x80808080l; @@ -738,6 +750,18 @@ Local StringBytes::Encode(Isolate* isolate, case UCS2: { const uint16_t* out = reinterpret_cast(buf); + uint16_t* dst = NULL; + if (IsBigEndian()) { + // Node's "ucs2" encoding expects LE character data inside a + // Buffer, so we need to reorder on BE platforms. See + // http://nodejs.org/api/buffer.html regarding Node's "ucs2" + // encoding specification + dst = new uint16_t[buflen / 2]; + for (size_t i = 0; i < buflen / 2; i++) { + dst[i] = (out[i] << 8) | (out[i] >> 8); + } + out = dst; + } if (buflen < EXTERN_APEX) val = String::NewFromTwoByte(isolate, out, @@ -745,6 +769,8 @@ Local StringBytes::Encode(Isolate* isolate, buflen / 2); else val = ExternTwoByteString::NewFromCopy(isolate, out, buflen / 2); + if (dst) + delete[] dst; break; }