Check whether key exists in Dictionary::Get
This commit is contained in:
parent
8ca005eb41
commit
b7387da085
2 changed files with 91 additions and 10 deletions
|
@ -15,6 +15,20 @@
|
|||
|
||||
namespace mate {
|
||||
|
||||
template<typename KeyType>
|
||||
bool SetProperty(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> object,
|
||||
KeyType key,
|
||||
v8::Local<v8::Value> value) {
|
||||
auto maybe = object->Set(isolate->GetCurrentContext(), key, value);
|
||||
return !maybe.IsNothing() && maybe.FromJust();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct ToV8ReturnsMaybe {
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<typename T, typename Enable = void>
|
||||
struct Converter {};
|
||||
|
||||
|
@ -241,10 +255,14 @@ struct Converter<std::set<T> > {
|
|||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ToV8ReturnsMaybe<std::vector<T>> {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
// Convenience functions that deduce T.
|
||||
template<typename T>
|
||||
v8::Local<v8::Value> ConvertToV8(v8::Isolate* isolate,
|
||||
const T& input) {
|
||||
v8::Local<v8::Value> ConvertToV8(v8::Isolate* isolate, const T& input) {
|
||||
return Converter<T>::ToV8(isolate, input);
|
||||
}
|
||||
|
||||
|
@ -253,6 +271,43 @@ inline v8::Local<v8::Value> ConvertToV8(v8::Isolate* isolate,
|
|||
return Converter<const char*>::ToV8(isolate, input);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
v8::MaybeLocal<v8::Value> ConvertToV8(v8::Local<v8::Context> context,
|
||||
const T& input) {
|
||||
return Converter<T>::ToV8(context, input);
|
||||
}
|
||||
|
||||
template<typename T, bool = ToV8ReturnsMaybe<T>::value> struct ToV8Traits;
|
||||
|
||||
template <typename T>
|
||||
struct ToV8Traits<T, true> {
|
||||
static bool TryConvertToV8(v8::Isolate* isolate,
|
||||
const T& input,
|
||||
v8::Local<v8::Value>* output) {
|
||||
auto maybe = ConvertToV8(isolate->GetCurrentContext(), input);
|
||||
if (maybe.IsEmpty())
|
||||
return false;
|
||||
*output = maybe.ToLocalChecked();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct ToV8Traits<T, false> {
|
||||
static bool TryConvertToV8(v8::Isolate* isolate,
|
||||
const T& input,
|
||||
v8::Local<v8::Value>* output) {
|
||||
*output = ConvertToV8(isolate, input);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
bool TryConvertToV8(v8::Isolate* isolate,
|
||||
T input,
|
||||
v8::Local<v8::Value>* output) {
|
||||
return ToV8Traits<T>::TryConvertToV8(isolate, input, output);
|
||||
}
|
||||
inline v8::Local<v8::String> StringToV8(
|
||||
v8::Isolate* isolate,
|
||||
const base::StringPiece& input) {
|
||||
|
|
|
@ -10,6 +10,15 @@
|
|||
|
||||
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
|
||||
|
@ -32,27 +41,44 @@ class Dictionary {
|
|||
|
||||
template<typename T>
|
||||
bool Get(const base::StringPiece& key, T* out) const {
|
||||
v8::Local<v8::Value> val = GetHandle()->Get(StringToV8(isolate_, key));
|
||||
// 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(const base::StringPiece& key, T* out) const {
|
||||
v8::Local<v8::Value> val = GetHandle()->GetHiddenValue(
|
||||
StringToV8(isolate_, key));
|
||||
v8::Local<v8::Value> val =
|
||||
GetHandle()->GetHiddenValue(StringToV8(isolate_, key));
|
||||
return ConvertFromV8(isolate_, val, out);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool Set(const base::StringPiece& key, T val) {
|
||||
return GetHandle()->Set(StringToV8(isolate_, key),
|
||||
ConvertToV8(isolate_, 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(const base::StringPiece& key, T val) {
|
||||
return GetHandle()->SetHiddenValue(StringToV8(isolate_, key),
|
||||
ConvertToV8(isolate_, val));
|
||||
v8::Local<v8::Value> v8_value;
|
||||
if (!TryConvertToV8(isolate_, val, &v8_value))
|
||||
return false;
|
||||
return GetHandle()->SetHiddenValue(StringToV8(isolate_, key), v8_value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
|
Loading…
Reference in a new issue