OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "webkit/plugins/ppapi/var_object_class.h" |
| 6 |
| 7 #include "third_party/WebKit/WebKit/chromium/public/WebBindings.h" |
| 8 #include "webkit/plugins/ppapi/npapi_glue.h" |
| 9 #include "webkit/plugins/ppapi/resource_tracker.h" |
| 10 #include "webkit/plugins/ppapi/var.h" |
| 11 |
| 12 using WebKit::WebBindings; |
| 13 |
| 14 namespace webkit { |
| 15 namespace plugins { |
| 16 namespace ppapi { |
| 17 |
| 18 namespace { |
| 19 |
| 20 // VarObjectAccessorWithIdentifier --------------------------------------------- |
| 21 |
| 22 // Helper class for the new (PPB_Class) NPObject wrapper. This converts a call |
| 23 // from WebKit where it gives us an NPObject and an NPIdentifier to an |
| 24 // easily-accessible InstanceData (corresponding to the NPObject) and |
| 25 // std::string and Property (corresponding to the NPIdentifier). |
| 26 class VarObjectAccessorWithIdentifier { |
| 27 public: |
| 28 VarObjectAccessorWithIdentifier(NPObject* object, NPIdentifier identifier) |
| 29 : exists_(false), |
| 30 instance_(static_cast<VarObjectClass::InstanceData*>(object)), |
| 31 property_(NULL) { |
| 32 if (instance_) { |
| 33 const NPUTF8* string_value = NULL; |
| 34 int32_t int_value = 0; |
| 35 bool is_string = false; |
| 36 WebBindings::extractIdentifierData(identifier, string_value, int_value, |
| 37 is_string); |
| 38 if (is_string) { |
| 39 property_name_ = string_value; |
| 40 |
| 41 const VarObjectClass::PropertyMap& properties = |
| 42 instance_->object_class->properties(); |
| 43 VarObjectClass::PropertyMap::const_iterator it = |
| 44 properties.find(property_name_); |
| 45 if (it != properties.end()) { |
| 46 property_ = &it->second; |
| 47 exists_ = true; |
| 48 } |
| 49 } |
| 50 } |
| 51 } |
| 52 |
| 53 // Return true if the object is valid, the identifier is valid, and the |
| 54 // property with said name exists. |
| 55 bool exists() const { return exists_; } |
| 56 bool is_method() const { return exists() && property_->method; } |
| 57 bool is_readable() const { return exists() && property_->getter; } |
| 58 bool is_writable() const { |
| 59 return exists() && property_->setter && property_->writable; |
| 60 } |
| 61 const VarObjectClass::InstanceData* instance() const { return instance_; } |
| 62 const VarObjectClass::Property* property() const { return property_; } |
| 63 PluginModule* module() const { |
| 64 return instance_ ? instance_->object_class->module() : NULL; |
| 65 } |
| 66 |
| 67 private: |
| 68 bool exists_; |
| 69 const VarObjectClass::InstanceData* instance_; |
| 70 std::string property_name_; |
| 71 const VarObjectClass::Property* property_; |
| 72 |
| 73 DISALLOW_COPY_AND_ASSIGN(VarObjectAccessorWithIdentifier); |
| 74 }; |
| 75 |
| 76 NPObject* VarObjectClassAllocate(NPP npp, NPClass* the_class) { |
| 77 return new VarObjectClass::InstanceData; |
| 78 } |
| 79 |
| 80 void VarObjectClassDeallocate(NPObject* object) { |
| 81 VarObjectClass::InstanceData* instance = |
| 82 static_cast<VarObjectClass::InstanceData*>(object); |
| 83 if (instance->object_class->instance_native_destructor()) |
| 84 instance->object_class->instance_native_destructor()(instance->native_data); |
| 85 delete instance; |
| 86 } |
| 87 |
| 88 bool VarObjectClassHasMethod(NPObject* np_obj, NPIdentifier name) { |
| 89 VarObjectAccessorWithIdentifier accessor(np_obj, name); |
| 90 return accessor.is_method(); |
| 91 } |
| 92 |
| 93 bool VarObjectClassInvoke(NPObject* np_obj, NPIdentifier name, |
| 94 const NPVariant* args, uint32 arg_count, |
| 95 NPVariant* result) { |
| 96 VarObjectAccessorWithIdentifier accessor(np_obj, name); |
| 97 if (!accessor.is_method()) |
| 98 return false; |
| 99 |
| 100 PPResultAndExceptionToNPResult result_converter(np_obj, result); |
| 101 PPVarArrayFromNPVariantArray arguments(accessor.module(), arg_count, args); |
| 102 PPVarFromNPObject self(accessor.module(), np_obj); |
| 103 |
| 104 return result_converter.SetResult(accessor.property()->method( |
| 105 accessor.instance()->native_data, self.var(), arguments.array(), arg_count, |
| 106 result_converter.exception())); |
| 107 } |
| 108 |
| 109 bool VarObjectClassInvokeDefault(NPObject* np_obj, |
| 110 const NPVariant* args, |
| 111 uint32 arg_count, |
| 112 NPVariant* result) { |
| 113 VarObjectClass::InstanceData* instance = |
| 114 static_cast<VarObjectClass::InstanceData*>(np_obj); |
| 115 if (!instance || !instance->object_class->instance_invoke()) |
| 116 return false; |
| 117 |
| 118 PPResultAndExceptionToNPResult result_converter(np_obj, result); |
| 119 PPVarArrayFromNPVariantArray arguments(instance->object_class->module(), |
| 120 arg_count, args); |
| 121 PPVarFromNPObject self(instance->object_class->module(), np_obj); |
| 122 |
| 123 return result_converter.SetResult(instance->object_class->instance_invoke()( |
| 124 instance->native_data, self.var(), arguments.array(), arg_count, |
| 125 result_converter.exception())); |
| 126 } |
| 127 |
| 128 bool VarObjectClassHasProperty(NPObject* np_obj, NPIdentifier name) { |
| 129 VarObjectAccessorWithIdentifier accessor(np_obj, name); |
| 130 return accessor.is_readable(); |
| 131 } |
| 132 |
| 133 bool VarObjectClassGetProperty(NPObject* np_obj, NPIdentifier name, |
| 134 NPVariant* result) { |
| 135 VarObjectAccessorWithIdentifier accessor(np_obj, name); |
| 136 if (!accessor.is_readable()) { |
| 137 return false; |
| 138 } |
| 139 |
| 140 PPResultAndExceptionToNPResult result_converter(np_obj, result); |
| 141 PPVarFromNPObject self(accessor.module(), np_obj); |
| 142 |
| 143 return result_converter.SetResult(accessor.property()->getter( |
| 144 accessor.instance()->native_data, self.var(), 0, 0, |
| 145 result_converter.exception())); |
| 146 } |
| 147 |
| 148 bool VarObjectClassSetProperty(NPObject* np_obj, NPIdentifier name, |
| 149 const NPVariant* variant) { |
| 150 VarObjectAccessorWithIdentifier accessor(np_obj, name); |
| 151 if (!accessor.is_writable()) { |
| 152 return false; |
| 153 } |
| 154 |
| 155 PPResultAndExceptionToNPResult result_converter(np_obj, NULL); |
| 156 PPVarArrayFromNPVariantArray arguments(accessor.module(), 1, variant); |
| 157 PPVarFromNPObject self(accessor.module(), np_obj); |
| 158 |
| 159 // Ignore return value. |
| 160 Var::PluginReleasePPVar(accessor.property()->setter( |
| 161 accessor.instance()->native_data, self.var(), arguments.array(), 1, |
| 162 result_converter.exception())); |
| 163 |
| 164 return result_converter.CheckExceptionForNoResult(); |
| 165 } |
| 166 |
| 167 bool VarObjectClassEnumerate(NPObject *np_obj, NPIdentifier **value, |
| 168 uint32_t *count) { |
| 169 VarObjectClass::InstanceData* instance = |
| 170 static_cast<VarObjectClass::InstanceData*>(np_obj); |
| 171 *count = 0; |
| 172 *value = NULL; |
| 173 if (!instance) |
| 174 return false; |
| 175 |
| 176 const VarObjectClass::PropertyMap& properties = |
| 177 instance->object_class->properties(); |
| 178 |
| 179 // Don't bother calculating the size of enumerable properties, just allocate |
| 180 // enough for all and then fill it partially. |
| 181 *value = static_cast<NPIdentifier*>( |
| 182 malloc(sizeof(NPIdentifier) * properties.size())); |
| 183 |
| 184 NPIdentifier* inserter = *value; |
| 185 for (VarObjectClass::PropertyMap::const_iterator i = properties.begin(); |
| 186 i != properties.end(); ++i) |
| 187 if (i->second.enumerable) |
| 188 *inserter++ = WebBindings::getStringIdentifier(i->first.c_str()); |
| 189 |
| 190 *count = inserter - *value; |
| 191 return true; |
| 192 } |
| 193 |
| 194 NPClass objectclassvar_class = { |
| 195 NP_CLASS_STRUCT_VERSION, |
| 196 &VarObjectClassAllocate, |
| 197 &VarObjectClassDeallocate, |
| 198 NULL, |
| 199 &VarObjectClassHasMethod, |
| 200 &VarObjectClassInvoke, |
| 201 &VarObjectClassInvokeDefault, |
| 202 &VarObjectClassHasProperty, |
| 203 &VarObjectClassGetProperty, |
| 204 &VarObjectClassSetProperty, |
| 205 NULL, |
| 206 &VarObjectClassEnumerate, |
| 207 }; |
| 208 |
| 209 // PPB_Class ------------------------------------------------------------------- |
| 210 |
| 211 PP_Resource Create(PP_Module module, PP_ClassDestructor destruct, |
| 212 PP_ClassFunction invoke, PP_ClassProperty* properties) { |
| 213 PluginModule* plugin_module = ResourceTracker::Get()->GetModule(module); |
| 214 if (!properties || !plugin_module) |
| 215 return 0; |
| 216 scoped_refptr<VarObjectClass> cls = new VarObjectClass(plugin_module, |
| 217 destruct, |
| 218 invoke, |
| 219 properties); |
| 220 if (!cls) |
| 221 return 0; |
| 222 return cls->GetReference(); |
| 223 } |
| 224 |
| 225 PP_Var Instantiate(PP_Resource class_object, void* native_data, |
| 226 PP_Var* exception) { |
| 227 scoped_refptr<VarObjectClass> object_class = |
| 228 Resource::GetAs<VarObjectClass>(class_object); |
| 229 if (!object_class) |
| 230 return PP_MakeUndefined(); |
| 231 NPObject* obj = WebBindings::createObject(NULL, &objectclassvar_class); |
| 232 VarObjectClass::InstanceData* instance_data = |
| 233 static_cast<VarObjectClass::InstanceData*>(obj); |
| 234 instance_data->object_class = object_class; |
| 235 instance_data->native_data = native_data; |
| 236 return ObjectVar::NPObjectToPPVar(object_class->module(), obj); |
| 237 } |
| 238 |
| 239 } // namespace |
| 240 |
| 241 // VarObjectClass -------------------------------------------------------------- |
| 242 |
| 243 VarObjectClass::Property::Property(const PP_ClassProperty& prop) |
| 244 : method(prop.method), |
| 245 getter(prop.getter), |
| 246 setter(prop.setter), |
| 247 writable(!(prop.modifiers & PP_OBJECTPROPERTY_MODIFIER_READONLY)), |
| 248 enumerable(!(prop.modifiers & PP_OBJECTPROPERTY_MODIFIER_DONTENUM)) { |
| 249 } |
| 250 |
| 251 VarObjectClass::InstanceData::InstanceData() : native_data(NULL) { |
| 252 } |
| 253 |
| 254 VarObjectClass::VarObjectClass(PluginModule* module, |
| 255 PP_ClassDestructor destruct, |
| 256 PP_ClassFunction invoke, |
| 257 PP_ClassProperty* properties) |
| 258 : Resource(module), |
| 259 instance_native_destructor_(destruct), |
| 260 instance_invoke_(invoke) { |
| 261 PP_ClassProperty* prop = properties; |
| 262 while (prop->name) { |
| 263 properties_.insert(std::make_pair(std::string(prop->name), |
| 264 Property(*prop))); |
| 265 ++prop; |
| 266 } |
| 267 } |
| 268 |
| 269 // virtual |
| 270 VarObjectClass::~VarObjectClass() { |
| 271 } |
| 272 |
| 273 VarObjectClass* VarObjectClass::AsVarObjectClass() { |
| 274 return this; |
| 275 } |
| 276 |
| 277 // static |
| 278 const PPB_Class* VarObjectClass::GetInterface() { |
| 279 static PPB_Class interface = { |
| 280 &Create, |
| 281 &Instantiate |
| 282 }; |
| 283 return &interface; |
| 284 } |
| 285 |
| 286 } // namespace ppapi |
| 287 } // namespace plugins |
| 288 } // namespace webkit |
OLD | NEW |