| Index: webkit/glue/plugins/pepper_var.cc
|
| ===================================================================
|
| --- webkit/glue/plugins/pepper_var.cc (revision 47777)
|
| +++ webkit/glue/plugins/pepper_var.cc (working copy)
|
| @@ -9,6 +9,7 @@
|
| #include "base/string_util.h"
|
| #include "third_party/ppapi/c/pp_var.h"
|
| #include "third_party/ppapi/c/ppb_var.h"
|
| +#include "third_party/ppapi/c/ppp_class.h"
|
| #include "third_party/WebKit/WebKit/chromium/public/WebBindings.h"
|
| #include "webkit/glue/plugins/pepper_string.h"
|
| #include "v8/include/v8.h"
|
| @@ -22,6 +23,7 @@
|
|
|
| namespace {
|
|
|
| +void Release(PP_Var var);
|
| PP_Var VarFromUtf8(const char* data, uint32_t len);
|
|
|
| // ---------------------------------------------------------------------------
|
| @@ -78,6 +80,12 @@
|
| return reinterpret_cast<String*>(var.value.as_id);
|
| }
|
|
|
| +String* GetString(PP_Var var) {
|
| + if (var.type != PP_VarType_String)
|
| + return NULL;
|
| + return GetStringUnchecked(var);
|
| +}
|
| +
|
| NPObject* GetNPObjectUnchecked(PP_Var var) {
|
| return reinterpret_cast<NPObject*>(var.value.as_id);
|
| }
|
| @@ -90,7 +98,7 @@
|
|
|
| // Returns a PP_Var that corresponds to the given NPVariant. The contents of
|
| // the NPVariant will be copied unless the NPVariant corresponds to an object.
|
| -PP_Var NPVariantToPPVar(NPVariant* variant) {
|
| +PP_Var NPVariantToPPVar(const NPVariant* variant) {
|
| switch (variant->type) {
|
| case NPVariantType_Void:
|
| return PP_MakeVoid();
|
| @@ -195,7 +203,273 @@
|
| }
|
| }
|
|
|
| +PP_Var NPIdentifierToPPVar(NPIdentifier id) {
|
| + const NPUTF8* string_value = NULL;
|
| + int32_t int_value = 0;
|
| + bool is_string = false;
|
| + WebBindings::extractIdentifierData(id, string_value, int_value, is_string);
|
| + if (is_string)
|
| + return VarFromUtf8(string_value, strlen(string_value));
|
| +
|
| + return PP_MakeInt32(int_value);
|
| +}
|
| +
|
| +PP_Var NPIdentifierToPPVarString(NPIdentifier id) {
|
| + PP_Var var = NPIdentifierToPPVar(id);
|
| + if (var.type == PP_VarType_String)
|
| + return var;
|
| + DCHECK(var.type == PP_VarType_Int32);
|
| + const std::string& str = IntToString(var.value.as_int);
|
| + return VarFromUtf8(str.data(), str.size());
|
| +}
|
| +
|
| +void ThrowException(NPObject* object, PP_Var exception) {
|
| + String* str = GetString(exception);
|
| + if (str)
|
| + WebBindings::setException(object, str->value().c_str());
|
| +}
|
| +
|
| // ---------------------------------------------------------------------------
|
| +// NPObject implementation in terms of PPP_Class
|
| +
|
| +struct WrapperObject : NPObject {
|
| + const PPP_Class* ppp_class;
|
| + void* ppp_class_data;
|
| +};
|
| +
|
| +static WrapperObject* ToWrapper(NPObject* object) {
|
| + return static_cast<WrapperObject*>(object);
|
| +}
|
| +
|
| +NPObject* WrapperClass_Allocate(NPP npp, NPClass* unused) {
|
| + return new WrapperObject;
|
| +}
|
| +
|
| +void WrapperClass_Deallocate(NPObject* object) {
|
| + WrapperObject* wrapper = ToWrapper(object);
|
| + wrapper->ppp_class->Deallocate(wrapper->ppp_class_data);
|
| + delete object;
|
| +}
|
| +
|
| +void WrapperClass_Invalidate(NPObject* object) {
|
| + // TODO(darin): Do I need to do something here?
|
| +}
|
| +
|
| +bool WrapperClass_HasMethod(NPObject* object, NPIdentifier method_name) {
|
| + WrapperObject* wrapper = ToWrapper(object);
|
| +
|
| + PP_Var method_name_var = NPIdentifierToPPVarString(method_name);
|
| + PP_Var exception = PP_MakeVoid();
|
| + bool rv = wrapper->ppp_class->HasMethod(wrapper->ppp_class_data,
|
| + method_name_var,
|
| + &exception);
|
| + Release(method_name_var);
|
| +
|
| + if (exception.type != PP_VarType_Void) {
|
| + ThrowException(object, exception);
|
| + Release(exception);
|
| + return false;
|
| + }
|
| + return rv;
|
| +}
|
| +
|
| +bool WrapperClass_Invoke(NPObject* object, NPIdentifier method_name,
|
| + const NPVariant* argv, uint32_t argc,
|
| + NPVariant* result) {
|
| + WrapperObject* wrapper = ToWrapper(object);
|
| +
|
| + scoped_array<PP_Var> args;
|
| + if (argc) {
|
| + args.reset(new PP_Var[argc]);
|
| + for (uint32_t i = 0; i < argc; ++i)
|
| + args[i] = NPVariantToPPVar(&argv[i]);
|
| + }
|
| + PP_Var method_name_var = NPIdentifierToPPVarString(method_name);
|
| + PP_Var exception = PP_MakeVoid();
|
| + PP_Var result_var = wrapper->ppp_class->Call(wrapper->ppp_class_data,
|
| + method_name_var, argc,
|
| + args.get(), &exception);
|
| + Release(method_name_var);
|
| + for (uint32_t i = 0; i < argc; ++i)
|
| + Release(args[i]);
|
| +
|
| + bool rv;
|
| + if (exception.type == PP_VarType_Void) {
|
| + rv = true;
|
| + *result = PPVarToNPVariant(result_var);
|
| + } else {
|
| + rv = false;
|
| + ThrowException(object, exception);
|
| + Release(exception);
|
| + }
|
| + Release(result_var);
|
| + return rv;
|
| +}
|
| +
|
| +bool WrapperClass_InvokeDefault(NPObject* object, const NPVariant* argv,
|
| + uint32_t argc, NPVariant* result) {
|
| + WrapperObject* wrapper = ToWrapper(object);
|
| +
|
| + scoped_array<PP_Var> args;
|
| + if (argc) {
|
| + args.reset(new PP_Var[argc]);
|
| + for (uint32_t i = 0; i < argc; ++i)
|
| + args[i] = NPVariantToPPVar(&argv[i]);
|
| + }
|
| + PP_Var exception = PP_MakeVoid();
|
| + PP_Var result_var = wrapper->ppp_class->Call(wrapper->ppp_class_data,
|
| + PP_MakeVoid(), argc, args.get(),
|
| + &exception);
|
| + for (uint32_t i = 0; i < argc; ++i)
|
| + Release(args[i]);
|
| +
|
| + bool rv;
|
| + if (exception.type == PP_VarType_Void) {
|
| + rv = true;
|
| + *result = PPVarToNPVariant(result_var);
|
| + } else {
|
| + rv = false;
|
| + ThrowException(object, exception);
|
| + Release(exception);
|
| + }
|
| + Release(result_var);
|
| + return rv;
|
| +}
|
| +
|
| +bool WrapperClass_HasProperty(NPObject* object, NPIdentifier property_name) {
|
| + WrapperObject* wrapper = ToWrapper(object);
|
| +
|
| + PP_Var property_name_var = NPIdentifierToPPVar(property_name);
|
| + PP_Var exception = PP_MakeVoid();
|
| + bool rv = wrapper->ppp_class->HasProperty(wrapper->ppp_class_data,
|
| + property_name_var,
|
| + &exception);
|
| + Release(property_name_var);
|
| +
|
| + if (exception.type != PP_VarType_Void) {
|
| + ThrowException(object, exception);
|
| + Release(exception);
|
| + return false;
|
| + }
|
| + return rv;
|
| +}
|
| +
|
| +bool WrapperClass_GetProperty(NPObject* object, NPIdentifier property_name,
|
| + NPVariant* result) {
|
| + WrapperObject* wrapper = ToWrapper(object);
|
| +
|
| + PP_Var property_name_var = NPIdentifierToPPVar(property_name);
|
| + PP_Var exception = PP_MakeVoid();
|
| + PP_Var result_var = wrapper->ppp_class->GetProperty(wrapper->ppp_class_data,
|
| + property_name_var,
|
| + &exception);
|
| + Release(property_name_var);
|
| +
|
| + bool rv;
|
| + if (exception.type == PP_VarType_Void) {
|
| + rv = true;
|
| + *result = PPVarToNPVariant(result_var);
|
| + } else {
|
| + rv = false;
|
| + ThrowException(object, exception);
|
| + Release(exception);
|
| + }
|
| + Release(result_var);
|
| + return rv;
|
| +}
|
| +
|
| +bool WrapperClass_SetProperty(NPObject* object, NPIdentifier property_name,
|
| + const NPVariant* value) {
|
| + WrapperObject* wrapper = ToWrapper(object);
|
| +
|
| + PP_Var property_name_var = NPIdentifierToPPVar(property_name);
|
| + PP_Var value_var = NPVariantToPPVar(value);
|
| + PP_Var exception = PP_MakeVoid();
|
| + wrapper->ppp_class->SetProperty(wrapper->ppp_class_data, property_name_var,
|
| + value_var, &exception);
|
| + Release(value_var);
|
| + Release(property_name_var);
|
| +
|
| + if (exception.type != PP_VarType_Void) {
|
| + ThrowException(object, exception);
|
| + Release(exception);
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +bool WrapperClass_RemoveProperty(NPObject* object, NPIdentifier property_name) {
|
| + WrapperObject* wrapper = ToWrapper(object);
|
| +
|
| + PP_Var property_name_var = NPIdentifierToPPVar(property_name);
|
| + PP_Var exception = PP_MakeVoid();
|
| + wrapper->ppp_class->RemoveProperty(wrapper->ppp_class_data, property_name_var,
|
| + &exception);
|
| + Release(property_name_var);
|
| +
|
| + if (exception.type != PP_VarType_Void) {
|
| + ThrowException(object, exception);
|
| + Release(exception);
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +bool WrapperClass_Enumerate(NPObject* object, NPIdentifier** values,
|
| + uint32_t* count) {
|
| + // TODO(darin): Implement this method!
|
| + WebBindings::setException(object, kUnableToGetAllPropertiesException);
|
| + return false;
|
| +}
|
| +
|
| +bool WrapperClass_Construct(NPObject* object, const NPVariant* argv,
|
| + uint32_t argc, NPVariant* result) {
|
| + WrapperObject* wrapper = ToWrapper(object);
|
| +
|
| + scoped_array<PP_Var> args;
|
| + if (argc) {
|
| + args.reset(new PP_Var[argc]);
|
| + for (uint32_t i = 0; i < argc; ++i)
|
| + args[i] = NPVariantToPPVar(&argv[i]);
|
| + }
|
| +
|
| + PP_Var exception = PP_MakeVoid();
|
| + PP_Var result_var = wrapper->ppp_class->Construct(wrapper->ppp_class_data,
|
| + argc, args.get(),
|
| + &exception);
|
| + for (uint32_t i = 0; i < argc; ++i)
|
| + Release(args[i]);
|
| +
|
| + bool rv;
|
| + if (exception.type == PP_VarType_Void) {
|
| + rv = true;
|
| + *result = PPVarToNPVariant(result_var);
|
| + } else {
|
| + rv = false;
|
| + ThrowException(object, exception);
|
| + Release(exception);
|
| + }
|
| + Release(result_var);
|
| + return rv;
|
| +}
|
| +
|
| +const NPClass wrapper_class = {
|
| + NP_CLASS_STRUCT_VERSION,
|
| + WrapperClass_Allocate,
|
| + WrapperClass_Deallocate,
|
| + WrapperClass_Invalidate,
|
| + WrapperClass_HasMethod,
|
| + WrapperClass_Invoke,
|
| + WrapperClass_InvokeDefault,
|
| + WrapperClass_HasProperty,
|
| + WrapperClass_GetProperty,
|
| + WrapperClass_SetProperty,
|
| + WrapperClass_RemoveProperty,
|
| + WrapperClass_Enumerate,
|
| + WrapperClass_Construct
|
| +};
|
| +
|
| +// ---------------------------------------------------------------------------
|
| // PPB_Var methods
|
|
|
| void AddRef(PP_Var var) {
|
| @@ -259,6 +533,28 @@
|
| return WebBindings::hasProperty(NULL, object, identifier);
|
| }
|
|
|
| +bool HasMethod(PP_Var var,
|
| + PP_Var name,
|
| + PP_Var* exception) {
|
| + TryCatch try_catch(exception);
|
| + if (try_catch.HasException())
|
| + return false;
|
| +
|
| + NPObject* object = GetNPObject(var);
|
| + if (!object) {
|
| + try_catch.SetException(kInvalidObjectException);
|
| + return false;
|
| + }
|
| +
|
| + NPIdentifier identifier = PPVarToNPIdentifier(name);
|
| + if (!identifier) {
|
| + try_catch.SetException(kInvalidPropertyException);
|
| + return false;
|
| + }
|
| +
|
| + return WebBindings::hasMethod(NULL, object, identifier);
|
| +}
|
| +
|
| PP_Var GetProperty(PP_Var var,
|
| PP_Var name,
|
| PP_Var* exception) {
|
| @@ -444,23 +740,48 @@
|
| return ret;
|
| }
|
|
|
| -PP_Var CreateObject(const PPP_Class* object_class,
|
| - void* object_data) {
|
| - return PP_MakeVoid(); // TODO(darin): Implement this method!
|
| +bool IsInstanceOf(PP_Var var, const PPP_Class* ppp_class,
|
| + void** ppp_class_data) {
|
| + NPObject* object = GetNPObject(var);
|
| + if (!object)
|
| + return false;
|
| +
|
| + if (object->_class != &wrapper_class)
|
| + return false;
|
| +
|
| + WrapperObject* wrapper = ToWrapper(object);
|
| + if (wrapper->ppp_class != ppp_class)
|
| + return false;
|
| +
|
| + if (ppp_class_data)
|
| + *ppp_class_data = wrapper->ppp_class_data;
|
| + return true;
|
| }
|
|
|
| +PP_Var CreateObject(const PPP_Class* ppp_class, void* ppp_class_data) {
|
| + NPObject* object =
|
| + WebBindings::createObject(NULL, const_cast<NPClass*>(&wrapper_class));
|
| + static_cast<WrapperObject*>(object)->ppp_class = ppp_class;
|
| + static_cast<WrapperObject*>(object)->ppp_class_data = ppp_class_data;
|
| + PP_Var ret = NPObjectToPPVar(object);
|
| + WebBindings::releaseObject(object); // Release reference from createObject
|
| + return ret;
|
| +}
|
| +
|
| const PPB_Var var_interface = {
|
| &AddRef,
|
| &Release,
|
| &VarFromUtf8,
|
| &VarToUtf8,
|
| &HasProperty,
|
| + &HasMethod,
|
| &GetProperty,
|
| &GetAllPropertyNames,
|
| &SetProperty,
|
| &RemoveProperty,
|
| &Call,
|
| &Construct,
|
| + &IsInstanceOf,
|
| &CreateObject
|
| };
|
|
|
|
|