36 #define EXTERN_APEX 0xFBEE9    40 #define SB_MALLOC_FAILED_ERROR \    41   v8::Exception::Error(OneByteString(isolate, "\"toString()\" failed"))    43 #define SB_STRING_TOO_LONG_ERROR \    44   v8::Exception::Error(OneByteString(isolate, "\"toString()\" failed"))    46 #define SB_BUFFER_CREATION_ERROR \    47   v8::Exception::Error(OneByteString(isolate, "\"toString()\" failed"))    49 #define SB_BUFFER_SIZE_EXCEEDED_ERROR \    50   v8::Exception::Error(OneByteString(isolate, "\"toString()\" failed"))    54 using v8::HandleScope;
    63 template <
typename ResourceType, 
typename TypeName>
    64 class ExternString: 
public ResourceType {
    66   ~ExternString()
 override {
    67     free(const_cast<TypeName*>(data_));
    68     isolate()->AdjustAmountOfExternalAllocatedMemory(-byte_length());
    71   const TypeName* 
data()
 const override {
    75   size_t length()
 const override {
    79   int64_t byte_length()
 const {
    80     return length() * 
sizeof(*
data());
    83   static MaybeLocal<Value> NewFromCopy(Isolate* isolate,
    86                                        Local<Value>* error) {
    88       return String::Empty(isolate);
    91       return NewSimpleFromCopy(isolate, data, length, error);
    93     TypeName* new_data = node::UncheckedMalloc<TypeName>(length);
    94     if (new_data == 
nullptr) {
    96       return MaybeLocal<Value>();
    98     memcpy(new_data, data, length * 
sizeof(*new_data));
   107   static MaybeLocal<Value> 
New(Isolate* isolate,
   110                                Local<Value>* error) {
   112       return String::Empty(isolate);
   115       MaybeLocal<Value> str = NewSimpleFromCopy(isolate, data, length, error);
   120     ExternString* h_str = 
new ExternString<ResourceType, TypeName>(isolate,
   123     MaybeLocal<Value> str = NewExternal(isolate, h_str);
   124     isolate->AdjustAmountOfExternalAllocatedMemory(h_str->byte_length());
   129       return MaybeLocal<Value>();
   132     return str.ToLocalChecked();
   135   inline Isolate* isolate()
 const { 
return isolate_; }
   138   ExternString(Isolate* isolate, 
const TypeName* data, 
size_t length)
   139     : isolate_(isolate), data_(data), length_(length) { }
   140   static MaybeLocal<Value> NewExternal(Isolate* isolate,
   141                                        ExternString* h_str);
   144   static MaybeLocal<Value> NewSimpleFromCopy(Isolate* isolate,
   145                                              const TypeName* data,
   147                                              Local<Value>* error);
   150   const TypeName* data_;
   155 typedef ExternString<String::ExternalOneByteStringResource,
   156                      char> ExternOneByteString;
   157 typedef ExternString<String::ExternalStringResource,
   158                      uint16_t> ExternTwoByteString;
   162 MaybeLocal<Value> ExternOneByteString::NewExternal(
   163     Isolate* isolate, ExternOneByteString* h_str) {
   164   return String::NewExternalOneByte(isolate, h_str).FromMaybe(Local<Value>());
   169 MaybeLocal<Value> ExternTwoByteString::NewExternal(
   170     Isolate* isolate, ExternTwoByteString* h_str) {
   171   return String::NewExternalTwoByte(isolate, h_str).FromMaybe(Local<Value>());
   175 MaybeLocal<Value> ExternOneByteString::NewSimpleFromCopy(Isolate* isolate,
   178                                                          Local<Value>* error) {
   179   MaybeLocal<String> str =
   180       String::NewFromOneByte(isolate,
   181                              reinterpret_cast<const uint8_t*>(data),
   182                              v8::NewStringType::kNormal,
   186     return MaybeLocal<Value>();
   188   return str.ToLocalChecked();
   193 MaybeLocal<Value> ExternTwoByteString::NewSimpleFromCopy(Isolate* isolate,
   194                                                          const uint16_t* data,
   196                                                          Local<Value>* error) {
   197   MaybeLocal<String> str =
   198       String::NewFromTwoByte(isolate,
   200                              v8::NewStringType::kNormal,
   204     return MaybeLocal<Value>();
   206   return str.ToLocalChecked();
   213   { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -2, -1, -1,
   214     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   215     -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63,
   216     52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
   217     -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
   218     15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63,
   219     -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
   220     41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
   221     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   222     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   223     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   224     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   225     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   226     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   227     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   228     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
   232 static const int8_t unhex_table[256] =
   233   { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   234     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   235     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   236      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,
   237     -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   238     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   239     -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   240     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   241     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   242     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   243     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   244     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   245     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   246     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   247     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   248     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
   251 static inline unsigned unhex(uint8_t x) {
   252   return unhex_table[x];
   255 template <
typename TypeName>
   256 static size_t hex_decode(
char* 
buf,
   259                          const size_t srcLen) {
   261   for (i = 0; i < len && i * 2 + 1 < srcLen; ++i) {
   262     unsigned a = unhex(src[i * 2 + 0]);
   263     unsigned b = unhex(src[i * 2 + 1]);
   266     buf[i] = (a << 4) | b;
   273 bool StringBytes::GetExternalParts(Local<Value> val,
   282   if (!val->IsString())
   285   Local<String> str = val.As<String>();
   287   if (str->IsExternalOneByte()) {
   288     const String::ExternalOneByteStringResource* ext;
   289     ext = str->GetExternalOneByteStringResource();
   291     *len = ext->length();
   294   } 
else if (str->IsExternal()) {
   295     const String::ExternalStringResource* ext;
   296     ext = str->GetExternalStringResource();
   297     *data = 
reinterpret_cast<const char*
>(ext->data());
   298     *len = ext->length() * 
sizeof(*ext->data());
   306 size_t StringBytes::WriteUCS2(
char* buf,
   310                               size_t* chars_written) {
   311   uint16_t* 
const dst = 
reinterpret_cast<uint16_t*
>(
buf);
   313   size_t max_chars = (buflen / 
sizeof(*dst));
   315   size_t alignment = 
reinterpret_cast<uintptr_t
>(dst) % 
sizeof(*dst);
   316   if (alignment == 0) {
   317     nchars = str->Write(dst, 0, max_chars, flags);
   318     *chars_written = nchars;
   319     return nchars * 
sizeof(*dst);
   322   uint16_t* aligned_dst =
   323       reinterpret_cast<uint16_t*
>(buf + 
sizeof(*dst) - alignment);
   324   CHECK_EQ(reinterpret_cast<uintptr_t>(aligned_dst) % 
sizeof(*dst), 0);
   327   nchars = str->Write(aligned_dst, 0, max_chars - 1, flags);
   330   memmove(dst, aligned_dst, nchars * 
sizeof(*dst));
   334   if (nchars == max_chars - 1 && str->Write(&last, nchars, 1, flags) != 0) {
   335     memcpy(buf + nchars * 
sizeof(*dst), &last, 
sizeof(last));
   339   *chars_written = nchars;
   340   return nchars * 
sizeof(*dst);
   344 size_t StringBytes::Write(Isolate* isolate,
   349                           int* chars_written) {
   350   HandleScope scope(isolate);
   351   const char* data = 
nullptr;
   353   const bool is_extern = GetExternalParts(val, &data, &nbytes);
   354   const size_t external_nbytes = nbytes;
   356   CHECK(val->IsString() == 
true);
   357   Local<String> str = val.As<String>();
   362   int flags = String::HINT_MANY_WRITES_EXPECTED |
   363               String::NO_NULL_TERMINATION |
   364               String::REPLACE_INVALID_UTF8;
   369       if (is_extern && str->IsOneByte()) {
   370         memcpy(buf, data, nbytes);
   372         uint8_t* 
const dst = 
reinterpret_cast<uint8_t*
>(
buf);
   373         nbytes = str->WriteOneByte(dst, 0, buflen, flags);
   375       if (chars_written != 
nullptr)
   376         *chars_written = nbytes;
   381       nbytes = str->WriteUtf8(buf, buflen, chars_written, flags);
   387       if (is_extern && !str->IsOneByte()) {
   388         memcpy(buf, data, nbytes);
   389         nchars = nbytes / 
sizeof(uint16_t);
   391         nbytes = WriteUCS2(buf, buflen, str, flags, &nchars);
   393       if (chars_written != 
nullptr)
   394         *chars_written = nchars;
   401         SwapBytes16(buf, nbytes);
   408         nbytes = base64_decode(buf, buflen, data, external_nbytes);
   410         String::Value value(str);
   411         nbytes = base64_decode(buf, buflen, *value, value.length());
   413       if (chars_written != 
nullptr) {
   414         *chars_written = nbytes;
   420         nbytes = hex_decode(buf, buflen, data, external_nbytes);
   422         String::Value value(str);
   423         nbytes = hex_decode(buf, buflen, *value, value.length());
   425       if (chars_written != 
nullptr) {
   426         *chars_written = nbytes;
   431       CHECK(0 && 
"unknown encoding");
   439 bool StringBytes::IsValidString(Local<String> 
string,
   441   if (enc == 
HEX && string->Length() % 2 != 0)
   451 size_t StringBytes::StorageSize(Isolate* isolate,
   453                                 enum encoding encoding) {
   454   HandleScope scope(isolate);
   455   size_t data_size = 0;
   458   if (is_buffer && (encoding == 
BUFFER || encoding == 
LATIN1)) {
   462   Local<String> str = val->ToString(isolate);
   467       data_size = str->Length();
   475       data_size = 3 * str->Length();
   479       data_size = str->Length() * 
sizeof(uint16_t);
   483       data_size = base64_decoded_size_fast(str->Length());
   487       CHECK(str->Length() % 2 == 0 && 
"invalid hex string length");
   488       data_size = str->Length() / 2;
   492       CHECK(0 && 
"unknown encoding");
   500 size_t StringBytes::Size(Isolate* isolate,
   502                          enum encoding encoding) {
   503   HandleScope scope(isolate);
   504   size_t data_size = 0;
   507   if (is_buffer && (encoding == 
BUFFER || encoding == 
LATIN1))
   511   if (GetExternalParts(val, &data, &data_size))
   514   Local<String> str = val->ToString(isolate);
   519       data_size = str->Length();
   524       data_size = str->Utf8Length();
   528       data_size = str->Length() * 
sizeof(uint16_t);
   532       String::Value value(str);
   533       data_size = base64_decoded_size(*value, value.length());
   538       data_size = str->Length() / 2;
   542       CHECK(0 && 
"unknown encoding");
   552 static bool contains_non_ascii_slow(
const char* buf, 
size_t len) {
   553   for (
size_t i = 0; i < 
len; ++i) {
   561 static bool contains_non_ascii(
const char* src, 
size_t len) {
   563     return contains_non_ascii_slow(src, len);
   566   const unsigned bytes_per_word = 
sizeof(uintptr_t);
   567   const unsigned align_mask = bytes_per_word - 1;
   568   const unsigned unaligned = 
reinterpret_cast<uintptr_t
>(src) & align_mask;
   571     const unsigned n = bytes_per_word - unaligned;
   572     if (contains_non_ascii_slow(src, n))
   579 #if defined(_WIN64) || defined(_LP64)   580   const uintptr_t mask = 0x8080808080808080ll;
   582   const uintptr_t mask = 0x80808080l;
   585   const uintptr_t* srcw = 
reinterpret_cast<const uintptr_t*
>(src);
   587   for (
size_t i = 0, 
n = len / bytes_per_word; i < 
n; ++i) {
   592   const unsigned remainder = len & align_mask;
   594     const size_t offset = len - remainder;
   595     if (contains_non_ascii_slow(src + offset, remainder))
   603 static void force_ascii_slow(
const char* src, 
char* dst, 
size_t len) {
   604   for (
size_t i = 0; i < 
len; ++i) {
   605     dst[i] = src[i] & 0x7f;
   610 static void force_ascii(
const char* src, 
char* dst, 
size_t len) {
   612     force_ascii_slow(src, dst, len);
   616   const unsigned bytes_per_word = 
sizeof(uintptr_t);
   617   const unsigned align_mask = bytes_per_word - 1;
   618   const unsigned src_unalign = 
reinterpret_cast<uintptr_t
>(src) & align_mask;
   619   const unsigned dst_unalign = 
reinterpret_cast<uintptr_t
>(dst) & align_mask;
   621   if (src_unalign > 0) {
   622     if (src_unalign == dst_unalign) {
   623       const unsigned unalign = bytes_per_word - src_unalign;
   624       force_ascii_slow(src, dst, unalign);
   629       force_ascii_slow(src, dst, len);
   634 #if defined(_WIN64) || defined(_LP64)   635   const uintptr_t mask = ~0x8080808080808080ll;
   637   const uintptr_t mask = ~0x80808080l;
   640   const uintptr_t* srcw = 
reinterpret_cast<const uintptr_t*
>(src);
   641   uintptr_t* dstw = 
reinterpret_cast<uintptr_t*
>(dst);
   643   for (
size_t i = 0, 
n = len / bytes_per_word; i < 
n; ++i) {
   644     dstw[i] = srcw[i] & mask;
   647   const unsigned remainder = len & align_mask;
   649     const size_t offset = len - remainder;
   650     force_ascii_slow(src + offset, dst + offset, remainder);
   655 static size_t hex_encode(
const char* src, 
size_t slen, 
char* dst, 
size_t dlen) {
   657   CHECK(dlen >= slen * 2 &&
   658       "not enough space provided for hex encode");
   661   for (uint32_t i = 0, k = 0; k < dlen; i += 1, k += 2) {
   662     static const char hex[] = 
"0123456789abcdef";
   663     uint8_t val = 
static_cast<uint8_t
>(src[i]);
   664     dst[k + 0] = hex[val >> 4];
   665     dst[k + 1] = hex[val & 15];
   672 #define CHECK_BUFLEN_IN_RANGE(len)                                    \   674     if ((len) > Buffer::kMaxLength) {                                 \   675       *error = SB_BUFFER_SIZE_EXCEEDED_ERROR;                         \   676       return MaybeLocal<Value>();                                     \   684                                       enum encoding encoding,
   685                                       Local<Value>* error) {
   686   CHECK_NE(encoding, 
UCS2);
   689   *error = Local<Value>();
   690   if (!buflen && encoding != 
BUFFER) {
   691     return String::Empty(isolate);
   694   MaybeLocal<String> val;
   700         if (maybe_buf.IsEmpty()) {
   702           return MaybeLocal<Value>();
   704         return maybe_buf.ToLocalChecked();
   708       if (contains_non_ascii(buf, buflen)) {
   709         char* out = node::UncheckedMalloc(buflen);
   710         if (out == 
nullptr) {
   712           return MaybeLocal<Value>();
   714         force_ascii(buf, out, buflen);
   717         return ExternOneByteString::NewFromCopy(isolate, buf, buflen, error);
   721       val = String::NewFromUtf8(isolate,
   723                                 v8::NewStringType::kNormal,
   727         return MaybeLocal<Value>();
   729       return val.ToLocalChecked();
   732       return ExternOneByteString::NewFromCopy(isolate, buf, buflen, error);
   735       size_t dlen = base64_encoded_size(buflen);
   736       char* dst = node::UncheckedMalloc(dlen);
   737       if (dst == 
nullptr) {
   739         return MaybeLocal<Value>();
   742       size_t written = base64_encode(buf, buflen, dst, dlen);
   743       CHECK_EQ(written, dlen);
   749       size_t dlen = buflen * 2;
   750       char* dst = node::UncheckedMalloc(dlen);
   751       if (dst == 
nullptr) {
   753         return MaybeLocal<Value>();
   755       size_t written = hex_encode(buf, buflen, dst, dlen);
   756       CHECK_EQ(written, dlen);
   762       CHECK(0 && 
"unknown encoding");
   773                                       Local<Value>* error) {
   775   *error = Local<Value>();
   781   std::vector<uint16_t> dst;
   783     dst.assign(buf, buf + buflen);
   784     size_t nbytes = buflen * 
sizeof(dst[0]);
   785     SwapBytes16(reinterpret_cast<char*>(&dst[0]), nbytes);
   789   return ExternTwoByteString::NewFromCopy(isolate, buf, buflen, error);
   794                                       enum encoding encoding,
   795                                       Local<Value>* error) {
   796   const size_t len = strlen(buf);
   797   MaybeLocal<Value> ret;
   798   if (encoding == 
UCS2) {
   803     const bool be = IsBigEndian();
   806     std::vector<uint16_t> vec(len / 2);
   807     for (
size_t i = 0, k = 0; i < 
len; i += 2, k += 1) {
   808       const uint8_t hi = 
static_cast<uint8_t
>(buf[i + 0]);
   809       const uint8_t lo = 
static_cast<uint8_t
>(buf[i + 1]);
   811           static_cast<uint16_t
>(hi) << 8 | lo
   812           : static_cast<uint16_t>(lo) << 8 | hi;
   815         static_cast< Local<Value> 
>(String::Empty(isolate))
 
bool HasInstance(Local< Value > val)
 
#define SB_STRING_TOO_LONG_ERROR
 
union node::cares_wrap::@8::CaresAsyncData::@0 data
 
const int8_t unbase64_table[256]
 
size_t Length(Local< Value > val)
 
char * Data(Local< Value > val)
 
#define SB_BUFFER_CREATION_ERROR
 
MaybeLocal< Object > New(Isolate *isolate, Local< String > string, enum encoding enc)
 
#define SB_MALLOC_FAILED_ERROR
 
#define CHECK_BUFLEN_IN_RANGE(len)
 
NODE_DEPRECATED("Use ParseEncoding(isolate, ...)", inline enum encoding ParseEncoding(v8::Local< v8::Value > encoding_v, enum encoding default_encoding=LATIN1) { return ParseEncoding(v8::Isolate::GetCurrent(), encoding_v, default_encoding);}) NODE_EXTERN void FatalException(v8 NODE_DEPRECATED("Use FatalException(isolate, ...)", inline void FatalException(const v8::TryCatch &try_catch) { return FatalException(v8::Isolate::GetCurrent(), try_catch);}) NODE_EXTERN v8 NODE_EXTERN v8::Local< v8::Value > Encode(v8::Isolate *isolate, const uint16_t *buf, size_t len)
 
MaybeLocal< Object > Copy(Isolate *isolate, const char *data, size_t length)