@@ -690,6 +690,7 @@ Local<Value> StringBytes::Encode(Isolate* isolate,
690690 enum encoding encoding) {
691691 EscapableHandleScope scope (isolate);
692692
693+ CHECK_NE (encoding, UCS2);
693694 CHECK_LE (buflen, Buffer::kMaxLength );
694695 if (!buflen && encoding != BUFFER)
695696 return scope.Escape (String::Empty (isolate));
@@ -747,32 +748,6 @@ Local<Value> StringBytes::Encode(Isolate* isolate,
747748 break ;
748749 }
749750
750- case UCS2: {
751- // Node's "ucs2" encoding expects LE character data inside a
752- // Buffer, so we need to reorder on BE platforms. See
753- // http://nodejs.org/api/buffer.html regarding Node's "ucs2"
754- // encoding specification. Note that we have to make a copy
755- // to avoid pointer aliasing and unaligned access, something
756- // that we can't guarantee by just reinterpret_casting |buf|.
757- size_t srclen = buflen / 2 ;
758- uint16_t * src = new uint16_t [srclen];
759- for (size_t i = 0 , k = 0 ; i < srclen; i += 1 , k += 2 ) {
760- const uint8_t lo = static_cast <uint8_t >(buf[k + 0 ]);
761- const uint8_t hi = static_cast <uint8_t >(buf[k + 1 ]);
762- src[i] = lo | hi << 8 ;
763- }
764- if (buflen < EXTERN_APEX) {
765- val = String::NewFromTwoByte (isolate,
766- src,
767- String::kNormalString ,
768- srclen);
769- } else {
770- val = ExternTwoByteString::NewFromCopy (isolate, src, srclen);
771- }
772- delete[] src;
773- break ;
774- }
775-
776751 case HEX: {
777752 size_t dlen = buflen * 2 ;
778753 char * dst = new char [dlen];
@@ -796,4 +771,39 @@ Local<Value> StringBytes::Encode(Isolate* isolate,
796771 return scope.Escape (val);
797772}
798773
774+
775+ Local<Value> StringBytes::Encode (Isolate* isolate,
776+ const uint16_t * buf,
777+ size_t buflen) {
778+ const uint16_t * src = buf;
779+
780+ // Node's "ucs2" encoding expects LE character data inside a
781+ // Buffer, so we need to reorder on BE platforms. See
782+ // http://nodejs.org/api/buffer.html regarding Node's "ucs2"
783+ // encoding specification.
784+ if (IsBigEndian ()) {
785+ // Inefficient, see StringSlice<UCS2>() in src/node_buffer.cc;
786+ // this is potentially the second copy of the actual input.
787+ uint16_t * copy = new uint16_t [buflen];
788+ for (size_t i = 0 ; i < buflen; i += 1 )
789+ copy[i] = buf[i] << 8 | buf[i] >> 8 ;
790+ src = copy;
791+ }
792+
793+ Local<String> val;
794+ if (buflen < EXTERN_APEX) {
795+ val = String::NewFromTwoByte (isolate,
796+ src,
797+ String::kNormalString ,
798+ buflen);
799+ } else {
800+ val = ExternTwoByteString::NewFromCopy (isolate, src, buflen);
801+ }
802+
803+ if (src != buf)
804+ delete[] src;
805+
806+ return val;
807+ }
808+
799809} // namespace node
0 commit comments