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