@@ -625,7 +625,6 @@ MaybeLocal<Value> StringBytes::Encode(Isolate* isolate,
625
625
size_t buflen,
626
626
enum encoding encoding,
627
627
Local<Value>* error) {
628
- CHECK_NE (encoding, UCS2);
629
628
CHECK_BUFLEN_IN_RANGE (buflen);
630
629
631
630
if (!buflen && encoding != BUFFER) {
@@ -703,6 +702,37 @@ MaybeLocal<Value> StringBytes::Encode(Isolate* isolate,
703
702
return ExternOneByteString::New (isolate, dst, dlen, error);
704
703
}
705
704
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
+
706
736
default :
707
737
CHECK (0 && " unknown encoding" );
708
738
break ;
@@ -742,30 +772,7 @@ MaybeLocal<Value> StringBytes::Encode(Isolate* isolate,
742
772
enum encoding encoding,
743
773
Local<Value>* error) {
744
774
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);
769
776
}
770
777
771
778
} // namespace node
0 commit comments