Skip to content

Commit

Permalink
src: move BE/LE buffer conversion to StringSlice()
Browse files Browse the repository at this point in the history
Move the big endian to little endian conversion logic for UCS2 input
from src/string_bytes.cc to src/node_buffer.cc; StringSlice() is the
only function that actually needs it and with this commit, a second
copy is avoided on big endian architectures.
  • Loading branch information
bnoordhuis committed Dec 14, 2014
1 parent 56fde66 commit 52fc406
Show file tree
Hide file tree
Showing 4 changed files with 7 additions and 14 deletions.
1 change: 1 addition & 0 deletions src/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ NODE_EXTERN v8::Local<v8::Value> Encode(v8::Isolate* isolate,
size_t len,
enum encoding encoding = BINARY);

// The input buffer should be in host endianness.
NODE_EXTERN v8::Local<v8::Value> Encode(v8::Isolate* isolate,
const uint16_t* buf,
size_t len);
Expand Down
6 changes: 5 additions & 1 deletion src/node_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,11 @@ void StringSlice<UCS2>(const FunctionCallbackInfo<Value>& args) {
const uint16_t* buf;
bool release = false;

if (reinterpret_cast<uintptr_t>(data) % sizeof(*buf) == 0) {
// 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.
const bool aligned = (reinterpret_cast<uintptr_t>(data) % sizeof(*buf) == 0);
if (IsLittleEndian() && aligned) {
buf = reinterpret_cast<const uint16_t*>(data);
} else {
// Make a copy to avoid unaligned accesses in v8::String::NewFromTwoByte().
Expand Down
13 changes: 0 additions & 13 deletions src/string_bytes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -777,19 +777,6 @@ Local<Value> StringBytes::Encode(Isolate* isolate,
size_t buflen) {
const uint16_t* src = buf;

// 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.
if (IsBigEndian()) {
// Inefficient, see StringSlice<UCS2>() in src/node_buffer.cc;
// this is potentially the second copy of the actual input.
uint16_t* copy = new uint16_t[buflen];
for (size_t i = 0; i < buflen; i += 1)
copy[i] = buf[i] << 8 | buf[i] >> 8;
src = copy;
}

Local<String> val;
if (buflen < EXTERN_APEX) {
val = String::NewFromTwoByte(isolate,
Expand Down
1 change: 1 addition & 0 deletions src/string_bytes.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ class StringBytes {
size_t buflen,
enum encoding encoding);

// The input buffer should be in host endianness.
static v8::Local<v8::Value> Encode(v8::Isolate* isolate,
const uint16_t* buf,
size_t buflen);
Expand Down

0 comments on commit 52fc406

Please sign in to comment.