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