@@ -625,7 +625,6 @@ MaybeLocal<Value> StringBytes::Encode(Isolate* isolate,
625625 size_t buflen,
626626 enum encoding encoding,
627627 Local<Value>* error) {
628- CHECK_NE (encoding, UCS2);
629628 CHECK_BUFLEN_IN_RANGE (buflen);
630629
631630 if (!buflen && encoding != BUFFER) {
@@ -703,6 +702,37 @@ MaybeLocal<Value> StringBytes::Encode(Isolate* isolate,
703702 return ExternOneByteString::New (isolate, dst, dlen, error);
704703 }
705704
705+ case UCS2: {
706+ if (IsBigEndian ()) {
707+ uint16_t * dst = node::UncheckedMalloc<uint16_t >(buflen / 2 );
708+ if (dst == nullptr ) {
709+ *error = node::ERR_MEMORY_ALLOCATION_FAILED (isolate);
710+ return MaybeLocal<Value>();
711+ }
712+ for (size_t i = 0 , k = 0 ; k < buflen / 2 ; i += 2 , k += 1 ) {
713+ // The input is in *little endian*, because that's what Node.js
714+ // expects, so the high byte comes after the low byte.
715+ const uint8_t hi = static_cast <uint8_t >(buf[i + 1 ]);
716+ const uint8_t lo = static_cast <uint8_t >(buf[i + 0 ]);
717+ dst[k] = static_cast <uint16_t >(hi) << 8 | lo;
718+ }
719+ return ExternTwoByteString::New (isolate, dst, buflen / 2 , error);
720+ }
721+ if (reinterpret_cast <uintptr_t >(buf) % 2 != 0 ) {
722+ // Unaligned data still means we can't directly pass it to V8.
723+ char * dst = node::UncheckedMalloc (buflen);
724+ if (dst == nullptr ) {
725+ *error = node::ERR_MEMORY_ALLOCATION_FAILED (isolate);
726+ return MaybeLocal<Value>();
727+ }
728+ memcpy (dst, buf, buflen);
729+ return ExternTwoByteString::New (
730+ isolate, reinterpret_cast <uint16_t *>(dst), buflen / 2 , error);
731+ }
732+ return ExternTwoByteString::NewFromCopy (
733+ isolate, reinterpret_cast <const uint16_t *>(buf), buflen / 2 , error);
734+ }
735+
706736 default :
707737 CHECK (0 && " unknown encoding" );
708738 break ;
@@ -742,30 +772,7 @@ MaybeLocal<Value> StringBytes::Encode(Isolate* isolate,
742772 enum encoding encoding,
743773 Local<Value>* error) {
744774 const size_t len = strlen (buf);
745- MaybeLocal<Value> ret;
746- if (encoding == UCS2) {
747- // In Node, UCS2 means utf16le. The data must be in little-endian
748- // order and must be aligned on 2-bytes. This returns an empty
749- // value if it's not aligned and ensures the appropriate byte order
750- // on big endian architectures.
751- const bool be = IsBigEndian ();
752- if (len % 2 != 0 )
753- return ret;
754- std::vector<uint16_t > vec (len / 2 );
755- for (size_t i = 0 , k = 0 ; i < len; i += 2 , k += 1 ) {
756- const uint8_t hi = static_cast <uint8_t >(buf[i + 0 ]);
757- const uint8_t lo = static_cast <uint8_t >(buf[i + 1 ]);
758- vec[k] = be ?
759- static_cast <uint16_t >(hi) << 8 | lo
760- : static_cast <uint16_t >(lo) << 8 | hi;
761- }
762- ret = vec.empty () ?
763- static_cast < Local<Value> >(String::Empty (isolate))
764- : StringBytes::Encode (isolate, &vec[0 ], vec.size (), error);
765- } else {
766- ret = StringBytes::Encode (isolate, buf, len, encoding, error);
767- }
768- return ret;
775+ return Encode (isolate, buf, len, encoding, error);
769776}
770777
771778} // namespace node
0 commit comments