-
Notifications
You must be signed in to change notification settings - Fork 15k
/
dictionary.h
161 lines (135 loc) · 5.55 KB
/
dictionary.h
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE.chromium file.
#ifndef NATIVE_MATE_NATIVE_MATE_DICTIONARY_H_
#define NATIVE_MATE_NATIVE_MATE_DICTIONARY_H_
#include "native_mate/converter.h"
#include "native_mate/object_template_builder.h"
namespace mate {
namespace internal {
// Returns true if |maybe| is both a value, and that value is true.
inline bool IsTrue(v8::Maybe<bool> maybe) {
return maybe.IsJust() && maybe.FromJust();
}
} // namespace internal
// Dictionary is useful when writing bindings for a function that either
// receives an arbitrary JavaScript object as an argument or returns an
// arbitrary JavaScript object as a result. For example, Dictionary is useful
// when you might use the |dictionary| type in WebIDL:
//
// http://heycam.github.io/webidl/#idl-dictionaries
//
// WARNING: You cannot retain a Dictionary object in the heap. The underlying
// storage for Dictionary is tied to the closest enclosing
// v8::HandleScope. Generally speaking, you should store a Dictionary
// on the stack.
//
class Dictionary {
public:
Dictionary();
Dictionary(v8::Isolate* isolate, v8::Local<v8::Object> object);
Dictionary(const Dictionary& other);
virtual ~Dictionary();
static Dictionary CreateEmpty(v8::Isolate* isolate);
bool Has(base::StringPiece key) const {
v8::Local<v8::Context> context = isolate_->GetCurrentContext();
v8::Local<v8::String> v8_key = StringToV8(isolate_, key);
return internal::IsTrue(GetHandle()->Has(context, v8_key));
}
template <typename T>
bool Get(base::StringPiece key, T* out) const {
// Check for existence before getting, otherwise this method will always
// returns true when T == v8::Local<v8::Value>.
v8::Local<v8::Context> context = isolate_->GetCurrentContext();
v8::Local<v8::String> v8_key = StringToV8(isolate_, key);
if (!internal::IsTrue(GetHandle()->Has(context, v8_key)))
return false;
v8::Local<v8::Value> val;
if (!GetHandle()->Get(context, v8_key).ToLocal(&val))
return false;
return ConvertFromV8(isolate_, val, out);
}
template <typename T>
bool GetHidden(base::StringPiece key, T* out) const {
v8::Local<v8::Context> context = isolate_->GetCurrentContext();
v8::Local<v8::Private> privateKey =
v8::Private::ForApi(isolate_, StringToV8(isolate_, key));
v8::Local<v8::Value> value;
v8::Maybe<bool> result = GetHandle()->HasPrivate(context, privateKey);
if (internal::IsTrue(result) &&
GetHandle()->GetPrivate(context, privateKey).ToLocal(&value))
return ConvertFromV8(isolate_, value, out);
return false;
}
template <typename T>
bool Set(base::StringPiece key, const T& val) {
v8::Local<v8::Value> v8_value;
if (!TryConvertToV8(isolate_, val, &v8_value))
return false;
v8::Maybe<bool> result = GetHandle()->Set(
isolate_->GetCurrentContext(), StringToV8(isolate_, key), v8_value);
return !result.IsNothing() && result.FromJust();
}
template <typename T>
bool SetHidden(base::StringPiece key, T val) {
v8::Local<v8::Value> v8_value;
if (!TryConvertToV8(isolate_, val, &v8_value))
return false;
v8::Local<v8::Context> context = isolate_->GetCurrentContext();
v8::Local<v8::Private> privateKey =
v8::Private::ForApi(isolate_, StringToV8(isolate_, key));
v8::Maybe<bool> result =
GetHandle()->SetPrivate(context, privateKey, v8_value);
return !result.IsNothing() && result.FromJust();
}
template <typename T>
bool SetReadOnly(base::StringPiece key, T val) {
v8::Local<v8::Value> v8_value;
if (!TryConvertToV8(isolate_, val, &v8_value))
return false;
v8::Maybe<bool> result = GetHandle()->DefineOwnProperty(
isolate_->GetCurrentContext(), StringToV8(isolate_, key), v8_value,
v8::ReadOnly);
return !result.IsNothing() && result.FromJust();
}
template <typename T>
bool SetReadOnlyNonConfigurable(base::StringPiece key, T val) {
v8::Local<v8::Value> v8_value;
if (!TryConvertToV8(isolate_, val, &v8_value))
return false;
v8::Maybe<bool> result = GetHandle()->DefineOwnProperty(
isolate_->GetCurrentContext(), StringToV8(isolate_, key), v8_value,
static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
return !result.IsNothing() && result.FromJust();
}
template <typename T>
bool SetMethod(base::StringPiece key, const T& callback) {
return GetHandle()
->Set(isolate_->GetCurrentContext(), StringToV8(isolate_, key),
CallbackTraits<T>::CreateTemplate(isolate_, callback)
->GetFunction(isolate_->GetCurrentContext())
.ToLocalChecked())
.ToChecked();
}
bool Delete(base::StringPiece key) {
v8::Maybe<bool> result = GetHandle()->Delete(isolate_->GetCurrentContext(),
StringToV8(isolate_, key));
return !result.IsNothing() && result.FromJust();
}
bool IsEmpty() const { return isolate() == NULL; }
virtual v8::Local<v8::Object> GetHandle() const;
v8::Isolate* isolate() const { return isolate_; }
protected:
v8::Isolate* isolate_;
private:
v8::Local<v8::Object> object_;
};
template <>
struct Converter<Dictionary> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, Dictionary val);
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
Dictionary* out);
};
} // namespace mate
#endif // NATIVE_MATE_NATIVE_MATE_DICTIONARY_H_