1 2 #ifndef SRC_NODE_UNION_BYTES_H_ 3 #define SRC_NODE_UNION_BYTES_H_ 4 5 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 6 7 // A union of const uint8_t* or const uint16_t* data that can be 8 // turned into external v8::String when given an isolate. 9 10 #include "v8.h" 11 12 namespace node { 13 14 class NonOwningExternalOneByteResource 15 : public v8::String::ExternalOneByteStringResource { 16 public: NonOwningExternalOneByteResource(const uint8_t * data,size_t length)17 explicit NonOwningExternalOneByteResource(const uint8_t* data, size_t length) 18 : data_(data), length_(length) {} 19 ~NonOwningExternalOneByteResource() override = default; 20 data()21 const char* data() const override { 22 return reinterpret_cast<const char*>(data_); 23 } length()24 size_t length() const override { return length_; } 25 26 NonOwningExternalOneByteResource(const NonOwningExternalOneByteResource&) = 27 delete; 28 NonOwningExternalOneByteResource& operator=( 29 const NonOwningExternalOneByteResource&) = delete; 30 31 private: 32 const uint8_t* data_; 33 size_t length_; 34 }; 35 36 class NonOwningExternalTwoByteResource 37 : public v8::String::ExternalStringResource { 38 public: NonOwningExternalTwoByteResource(const uint16_t * data,size_t length)39 explicit NonOwningExternalTwoByteResource(const uint16_t* data, size_t length) 40 : data_(data), length_(length) {} 41 ~NonOwningExternalTwoByteResource() override = default; 42 data()43 const uint16_t* data() const override { return data_; } length()44 size_t length() const override { return length_; } 45 46 NonOwningExternalTwoByteResource(const NonOwningExternalTwoByteResource&) = 47 delete; 48 NonOwningExternalTwoByteResource& operator=( 49 const NonOwningExternalTwoByteResource&) = delete; 50 51 private: 52 const uint16_t* data_; 53 size_t length_; 54 }; 55 56 // Similar to a v8::String, but it's independent from Isolates 57 // and can be materialized in Isolates as external Strings 58 // via ToStringChecked. The data pointers are owned by the caller. 59 class UnionBytes { 60 public: UnionBytes(const uint16_t * data,size_t length)61 UnionBytes(const uint16_t* data, size_t length) 62 : one_bytes_(nullptr), two_bytes_(data), length_(length) {} UnionBytes(const uint8_t * data,size_t length)63 UnionBytes(const uint8_t* data, size_t length) 64 : one_bytes_(data), two_bytes_(nullptr), length_(length) {} 65 66 UnionBytes(const UnionBytes&) = default; 67 UnionBytes& operator=(const UnionBytes&) = default; 68 UnionBytes(UnionBytes&&) = default; 69 UnionBytes& operator=(UnionBytes&&) = default; 70 is_one_byte()71 bool is_one_byte() const { return one_bytes_ != nullptr; } two_bytes_data()72 const uint16_t* two_bytes_data() const { 73 CHECK_NOT_NULL(two_bytes_); 74 return two_bytes_; 75 } one_bytes_data()76 const uint8_t* one_bytes_data() const { 77 CHECK_NOT_NULL(one_bytes_); 78 return one_bytes_; 79 } ToStringChecked(v8::Isolate * isolate)80 v8::Local<v8::String> ToStringChecked(v8::Isolate* isolate) const { 81 if (is_one_byte()) { 82 NonOwningExternalOneByteResource* source = 83 new NonOwningExternalOneByteResource(one_bytes_data(), length_); 84 return v8::String::NewExternalOneByte(isolate, source).ToLocalChecked(); 85 } else { 86 NonOwningExternalTwoByteResource* source = 87 new NonOwningExternalTwoByteResource(two_bytes_data(), length_); 88 return v8::String::NewExternalTwoByte(isolate, source).ToLocalChecked(); 89 } 90 } length()91 size_t length() { return length_; } 92 93 private: 94 const uint8_t* one_bytes_; 95 const uint16_t* two_bytes_; 96 size_t length_; 97 }; 98 99 } // namespace node 100 101 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 102 103 #endif // SRC_NODE_UNION_BYTES_H_ 104