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: |
17 |
|
448255 |
explicit NonOwningExternalOneByteResource(const uint8_t* data, size_t length) |
18 |
|
448255 |
: data_(data), length_(length) {} |
19 |
|
1613596 |
~NonOwningExternalOneByteResource() override = default; |
20 |
|
|
|
21 |
|
5042850 |
const char* data() const override { |
22 |
|
5042850 |
return reinterpret_cast<const char*>(data_); |
23 |
|
|
} |
24 |
|
1793020 |
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: |
39 |
|
1162 |
explicit NonOwningExternalTwoByteResource(const uint16_t* data, size_t length) |
40 |
|
1162 |
: data_(data), length_(length) {} |
41 |
|
3668 |
~NonOwningExternalTwoByteResource() override = default; |
42 |
|
|
|
43 |
|
30064 |
const uint16_t* data() const override { return data_; } |
44 |
|
4644 |
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: |
61 |
|
22411 |
UnionBytes(const uint16_t* data, size_t length) |
62 |
|
22411 |
: one_bytes_(nullptr), two_bytes_(data), length_(length) {} |
63 |
|
1696194 |
UnionBytes(const uint8_t* data, size_t length) |
64 |
|
1696194 |
: 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 |
|
|
|
71 |
|
449447 |
bool is_one_byte() const { return one_bytes_ != nullptr; } |
72 |
|
1162 |
const uint16_t* two_bytes_data() const { |
73 |
✗✓ |
1162 |
CHECK_NOT_NULL(two_bytes_); |
74 |
|
1162 |
return two_bytes_; |
75 |
|
|
} |
76 |
|
448255 |
const uint8_t* one_bytes_data() const { |
77 |
✗✓ |
448255 |
CHECK_NOT_NULL(one_bytes_); |
78 |
|
448255 |
return one_bytes_; |
79 |
|
|
} |
80 |
|
449417 |
v8::Local<v8::String> ToStringChecked(v8::Isolate* isolate) const { |
81 |
✓✓ |
449417 |
if (is_one_byte()) { |
82 |
|
|
NonOwningExternalOneByteResource* source = |
83 |
|
448255 |
new NonOwningExternalOneByteResource(one_bytes_data(), length_); |
84 |
|
896510 |
return v8::String::NewExternalOneByte(isolate, source).ToLocalChecked(); |
85 |
|
|
} else { |
86 |
|
|
NonOwningExternalTwoByteResource* source = |
87 |
|
1162 |
new NonOwningExternalTwoByteResource(two_bytes_data(), length_); |
88 |
|
2324 |
return v8::String::NewExternalTwoByte(isolate, source).ToLocalChecked(); |
89 |
|
|
} |
90 |
|
|
} |
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_ |