diff --git a/src/string_bytes.cc b/src/string_bytes.cc index de41ec1d4ac..1a7b4e1ebea 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; }