Skip to content

Commit 929e2ed

Browse files
andrewlowtjfontaine
authored andcommitted
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 <tjfontaine@gmail.com>
1 parent 765b032 commit 929e2ed

1 file changed

Lines changed: 28 additions & 2 deletions

File tree

src/string_bytes.cc

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,16 @@ size_t StringBytes::Write(Isolate* isolate,
336336
memcpy(buf, data, len * 2);
337337
else
338338
len = str->Write(reinterpret_cast<uint16_t*>(buf), 0, buflen, flags);
339+
if (IsBigEndian()) {
340+
// Node's "ucs2" encoding wants LE character data stored in
341+
// the Buffer, so we need to reorder on BE platforms. See
342+
// http://nodejs.org/api/buffer.html regarding Node's "ucs2"
343+
// encoding specification
344+
uint16_t* buf16 = reinterpret_cast<uint16_t*>(buf);
345+
for (size_t i = 0; i < len; i++) {
346+
buf16[i] = (buf16[i] << 8) | (buf16[i] >> 8);
347+
}
348+
}
339349
if (chars_written != NULL)
340350
*chars_written = len;
341351
len = len * sizeof(uint16_t);
@@ -515,7 +525,8 @@ static bool contains_non_ascii(const char* src, size_t len) {
515525
}
516526

517527

518-
#if defined(__x86_64__) || defined(_WIN64)
528+
#if defined(__x86_64__) || defined(_WIN64) || defined(__PPC64__) || \
529+
defined(_ARCH_PPC64)
519530
const uintptr_t mask = 0x8080808080808080ll;
520531
#else
521532
const uintptr_t mask = 0x80808080l;
@@ -570,7 +581,8 @@ static void force_ascii(const char* src, char* dst, size_t len) {
570581
}
571582
}
572583

573-
#if defined(__x86_64__) || defined(_WIN64)
584+
#if defined(__x86_64__) || defined(_WIN64) || defined(__PPC64__) || \
585+
defined(_ARCH_PPC64)
574586
const uintptr_t mask = ~0x8080808080808080ll;
575587
#else
576588
const uintptr_t mask = ~0x80808080l;
@@ -738,13 +750,27 @@ Local<Value> StringBytes::Encode(Isolate* isolate,
738750

739751
case UCS2: {
740752
const uint16_t* out = reinterpret_cast<const uint16_t*>(buf);
753+
uint16_t* dst = NULL;
754+
if (IsBigEndian()) {
755+
// Node's "ucs2" encoding expects LE character data inside a
756+
// Buffer, so we need to reorder on BE platforms. See
757+
// http://nodejs.org/api/buffer.html regarding Node's "ucs2"
758+
// encoding specification
759+
dst = new uint16_t[buflen / 2];
760+
for (size_t i = 0; i < buflen / 2; i++) {
761+
dst[i] = (out[i] << 8) | (out[i] >> 8);
762+
}
763+
out = dst;
764+
}
741765
if (buflen < EXTERN_APEX)
742766
val = String::NewFromTwoByte(isolate,
743767
out,
744768
String::kNormalString,
745769
buflen / 2);
746770
else
747771
val = ExternTwoByteString::NewFromCopy(isolate, out, buflen / 2);
772+
if (dst)
773+
delete[] dst;
748774
break;
749775
}
750776

0 commit comments

Comments
 (0)