Index: src/JsValue.cpp |
=================================================================== |
new file mode 100644 |
--- /dev/null |
+++ b/src/JsValue.cpp |
@@ -0,0 +1,185 @@ |
+#include <AdblockPlus.h> |
+ |
+namespace |
+{ |
+ std::string fromV8String(v8::Handle<v8::Value> value) |
+ { |
+ v8::String::Utf8Value stringValue(value); |
+ if (stringValue.length()) |
+ return std::string(*stringValue, stringValue.length()); |
+ else |
+ return std::string(); |
+ } |
+ |
+ v8::Local<v8::String> toV8String(const std::string& str) |
+ { |
+ return v8::String::New(str.c_str(), str.length()); |
+ } |
+} |
+ |
+AdblockPlus::JsValue::JsValue(AdblockPlus::JsEngine& jsEngine, |
+ v8::Handle<v8::Value> value) |
+ : jsEngine(jsEngine), |
+ value(v8::Persistent<v8::Value>::New(jsEngine.isolate, value)) |
+{ |
+} |
+ |
+AdblockPlus::JsValue::~JsValue() |
+{ |
+ value.Dispose(jsEngine.isolate); |
+} |
+ |
+bool AdblockPlus::JsValue::IsUndefined() const |
+{ |
+ return value->IsUndefined(); |
+} |
+ |
+bool AdblockPlus::JsValue::IsNull() const |
+{ |
+ return value->IsNull(); |
+} |
+ |
+bool AdblockPlus::JsValue::IsString() const |
+{ |
+ return value->IsString() || value->IsStringObject(); |
+} |
+ |
+bool AdblockPlus::JsValue::IsNumber() const |
+{ |
+ return value->IsNumber() || value->IsNumberObject(); |
+} |
+ |
+bool AdblockPlus::JsValue::IsBool() const |
+{ |
+ return value->IsBoolean() || value->IsBooleanObject(); |
+} |
+ |
+bool AdblockPlus::JsValue::IsObject() const |
+{ |
+ return value->IsObject(); |
+} |
+ |
+bool AdblockPlus::JsValue::IsArray() const |
+{ |
+ return value->IsArray(); |
+} |
+ |
+bool AdblockPlus::JsValue::IsFunction() const |
+{ |
+ return value->IsFunction(); |
+} |
+ |
+std::string AdblockPlus::JsValue::AsString() const |
+{ |
+ const JsEngine::Context context(jsEngine); |
+ return fromV8String(value); |
+} |
+ |
+int64_t AdblockPlus::JsValue::AsInt() const |
+{ |
+ const JsEngine::Context context(jsEngine); |
+ return value->IntegerValue(); |
+} |
+ |
+bool AdblockPlus::JsValue::AsBool() const |
+{ |
+ const JsEngine::Context context(jsEngine); |
+ return value->BooleanValue(); |
+} |
+ |
+AdblockPlus::JsValueList AdblockPlus::JsValue::AsList() const |
+{ |
+ if (!IsArray()) |
+ throw std::runtime_error("Cannot convert a non-array to list"); |
+ |
+ const JsEngine::Context context(jsEngine); |
+ JsValueList result; |
+ v8::Persistent<v8::Array> array = v8::Persistent<v8::Array>::Cast(value); |
+ uint32_t length = array->Length(); |
+ for (uint32_t i = 0; i < length; i++) |
+ { |
+ v8::Local<v8::Value> item = array->Get(i); |
+ result.push_back(JsValuePtr(new JsValue(jsEngine, item))); |
+ } |
+ return result; |
+} |
+ |
+AdblockPlus::JsValuePtr AdblockPlus::JsValue::GetProperty(const std::string& name) const |
+{ |
+ if (!IsObject()) |
+ throw new std::runtime_error("Attempting to get property of a non-object"); |
+ |
+ const JsEngine::Context context(jsEngine); |
+ v8::Local<v8::String> property = toV8String(name); |
+ v8::Persistent<v8::Object> obj = v8::Persistent<v8::Object>::Cast(value); |
+ return JsValuePtr(new JsValue(jsEngine, obj->Get(property))); |
+} |
+ |
+void AdblockPlus::JsValue::SetProperty(const std::string& name, v8::Handle<v8::Value> val) |
+{ |
+ if (!IsObject()) |
+ throw new std::runtime_error("Attempting to set property on a non-object"); |
+ |
+ v8::Local<v8::String> property = toV8String(name); |
+ v8::Persistent<v8::Object> obj = v8::Persistent<v8::Object>::Cast(value); |
+ obj->Set(property, val); |
+} |
+ |
+void AdblockPlus::JsValue::SetProperty(const std::string& name, const std::string& val) |
+{ |
+ const JsEngine::Context context(jsEngine); |
+ SetProperty(name, toV8String(val)); |
+} |
+ |
+void AdblockPlus::JsValue::SetProperty(const std::string& name, int64_t val) |
+{ |
+ const JsEngine::Context context(jsEngine); |
+ SetProperty(name, v8::Integer::New(val)); |
+} |
+ |
+void AdblockPlus::JsValue::SetProperty(const std::string& name, bool val) |
+{ |
+ const JsEngine::Context context(jsEngine); |
+ SetProperty(name, v8::Boolean::New(val)); |
+} |
+ |
+std::string AdblockPlus::JsValue::GetClassName() const |
+{ |
+ if (!IsObject()) |
+ throw new std::runtime_error("Cannot get constructor of a non-object"); |
+ |
+ const JsEngine::Context context(jsEngine); |
+ v8::Persistent<v8::Object> obj = v8::Persistent<v8::Object>::Cast(value); |
+ return fromV8String(obj->GetConstructorName()); |
+} |
+ |
+AdblockPlus::JsValuePtr AdblockPlus::JsValue::Call( |
+ const JsValueList& params, |
+ AdblockPlus::JsValuePtr thisPtr) const |
+{ |
+ if (!IsFunction()) |
+ throw new std::runtime_error("Attempting to call a non-function"); |
+ |
+ const JsEngine::Context context(jsEngine); |
+ |
+ if (!thisPtr) |
+ thisPtr = JsValuePtr(new JsValue(jsEngine, jsEngine.context->Global())); |
+ if (!thisPtr->IsObject()) |
+ throw new std::runtime_error("`this` pointer has to be an object"); |
+ v8::Persistent<v8::Object> thisObj = v8::Persistent<v8::Object>::Cast(thisPtr->value); |
+ |
+ size_t argc = params.size(); |
+ v8::Handle<v8::Value>* argv = new v8::Handle<v8::Value>[argc]; |
+ for (size_t i = 0; i < argc; ++i) |
+ argv[i] = params[i]->value; |
+ |
+ const v8::TryCatch tryCatch; |
+ v8::Persistent<v8::Function> func = v8::Persistent<v8::Function>::Cast(value); |
+ v8::Local<v8::Value> result = func->Call(thisObj, argc, argv); |
+ delete argv; |
+ |
+ if (tryCatch.HasCaught()) |
+ throw AdblockPlus::JsError(tryCatch.Exception(), tryCatch.Message()); |
+ |
+ return JsValuePtr(new JsValue(jsEngine, result)); |
+} |