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 {
|
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>
|
template<typename T, typename Enable = void>
|
||||||
struct Converter {};
|
struct Converter {};
|
||||||
|
|
||||||
|
@ -241,18 +255,59 @@ struct Converter<std::set<T> > {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct ToV8ReturnsMaybe<std::vector<T>> {
|
||||||
|
static const bool value = true;
|
||||||
|
};
|
||||||
|
|
||||||
// Convenience functions that deduce T.
|
// Convenience functions that deduce T.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
v8::Local<v8::Value> ConvertToV8(v8::Isolate* isolate,
|
v8::Local<v8::Value> ConvertToV8(v8::Isolate* isolate, const T& input) {
|
||||||
const T& input) {
|
|
||||||
return Converter<T>::ToV8(isolate, input);
|
return Converter<T>::ToV8(isolate, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline v8::Local<v8::Value> ConvertToV8(v8::Isolate* isolate,
|
inline v8::Local<v8::Value> ConvertToV8(v8::Isolate* isolate,
|
||||||
const char* input) {
|
const char* input) {
|
||||||
return Converter<const char*>::ToV8(isolate, input);
|
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(
|
inline v8::Local<v8::String> StringToV8(
|
||||||
v8::Isolate* isolate,
|
v8::Isolate* isolate,
|
||||||
const base::StringPiece& input) {
|
const base::StringPiece& input) {
|
||||||
|
|
|
@ -10,6 +10,15 @@
|
||||||
|
|
||||||
namespace mate {
|
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
|
// Dictionary is useful when writing bindings for a function that either
|
||||||
// receives an arbitrary JavaScript object as an argument or returns an
|
// receives an arbitrary JavaScript object as an argument or returns an
|
||||||
// arbitrary JavaScript object as a result. For example, Dictionary is useful
|
// arbitrary JavaScript object as a result. For example, Dictionary is useful
|
||||||
|
@ -32,27 +41,44 @@ class Dictionary {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool Get(const base::StringPiece& key, T* out) const {
|
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);
|
return ConvertFromV8(isolate_, val, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool GetHidden(const base::StringPiece& key, T* out) const {
|
bool GetHidden(const base::StringPiece& key, T* out) const {
|
||||||
v8::Local<v8::Value> val = GetHandle()->GetHiddenValue(
|
v8::Local<v8::Value> val =
|
||||||
StringToV8(isolate_, key));
|
GetHandle()->GetHiddenValue(StringToV8(isolate_, key));
|
||||||
return ConvertFromV8(isolate_, val, out);
|
return ConvertFromV8(isolate_, val, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool Set(const base::StringPiece& key, T val) {
|
bool Set(const base::StringPiece& key, T val) {
|
||||||
return GetHandle()->Set(StringToV8(isolate_, key),
|
v8::Local<v8::Value> v8_value;
|
||||||
ConvertToV8(isolate_, val));
|
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>
|
template<typename T>
|
||||||
bool SetHidden(const base::StringPiece& key, T val) {
|
bool SetHidden(const base::StringPiece& key, T val) {
|
||||||
return GetHandle()->SetHiddenValue(StringToV8(isolate_, key),
|
v8::Local<v8::Value> v8_value;
|
||||||
ConvertToV8(isolate_, val));
|
if (!TryConvertToV8(isolate_, val, &v8_value))
|
||||||
|
return false;
|
||||||
|
return GetHandle()->SetHiddenValue(StringToV8(isolate_, key), v8_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
Loading…
Reference in a new issue