Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(135)

Side by Side Diff: webkit/glue/plugins/pepper_var.cc

Issue 5828003: Move the Pepper implementation from webkit/glue/plugins/pepper_* to... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/glue/plugins/pepper_var.h ('k') | webkit/glue/plugins/pepper_video_decoder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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/glue/plugins/pepper_var.h"
6
7 #include <limits>
8
9 #include "base/logging.h"
10 #include "base/scoped_ptr.h"
11 #include "base/string_util.h"
12 #include "ppapi/c/dev/ppb_var_deprecated.h"
13 #include "ppapi/c/ppb_var.h"
14 #include "ppapi/c/pp_var.h"
15 #include "third_party/WebKit/WebKit/chromium/public/WebBindings.h"
16 #include "webkit/glue/plugins/pepper_common.h"
17 #include "webkit/glue/plugins/pepper_plugin_instance.h"
18 #include "webkit/glue/plugins/pepper_plugin_module.h"
19 #include "webkit/glue/plugins/pepper_plugin_object.h"
20 #include "v8/include/v8.h"
21
22 using WebKit::WebBindings;
23
24 namespace pepper {
25
26 namespace {
27
28 const char kInvalidObjectException[] = "Error: Invalid object";
29 const char kInvalidPropertyException[] = "Error: Invalid property";
30 const char kInvalidValueException[] = "Error: Invalid value";
31 const char kUnableToGetPropertyException[] = "Error: Unable to get property";
32 const char kUnableToSetPropertyException[] = "Error: Unable to set property";
33 const char kUnableToRemovePropertyException[] =
34 "Error: Unable to remove property";
35 const char kUnableToGetAllPropertiesException[] =
36 "Error: Unable to get all properties";
37 const char kUnableToCallMethodException[] = "Error: Unable to call method";
38 const char kUnableToConstructException[] = "Error: Unable to construct";
39
40 // ---------------------------------------------------------------------------
41 // Utilities
42
43 // Converts the given PP_Var to an NPVariant, returning true on success.
44 // False means that the given variant is invalid. In this case, the result
45 // NPVariant will be set to a void one.
46 //
47 // The contents of the PP_Var will NOT be copied, so you need to ensure that
48 // the PP_Var remains valid while the resultant NPVariant is in use.
49 bool PPVarToNPVariantNoCopy(PP_Var var, NPVariant* result) {
50 switch (var.type) {
51 case PP_VARTYPE_UNDEFINED:
52 VOID_TO_NPVARIANT(*result);
53 break;
54 case PP_VARTYPE_NULL:
55 NULL_TO_NPVARIANT(*result);
56 break;
57 case PP_VARTYPE_BOOL:
58 BOOLEAN_TO_NPVARIANT(var.value.as_bool, *result);
59 break;
60 case PP_VARTYPE_INT32:
61 INT32_TO_NPVARIANT(var.value.as_int, *result);
62 break;
63 case PP_VARTYPE_DOUBLE:
64 DOUBLE_TO_NPVARIANT(var.value.as_double, *result);
65 break;
66 case PP_VARTYPE_STRING: {
67 scoped_refptr<StringVar> string(StringVar::FromPPVar(var));
68 if (!string) {
69 VOID_TO_NPVARIANT(*result);
70 return false;
71 }
72 const std::string& value = string->value();
73 STRINGN_TO_NPVARIANT(value.c_str(), value.size(), *result);
74 break;
75 }
76 case PP_VARTYPE_OBJECT: {
77 scoped_refptr<ObjectVar> object(ObjectVar::FromPPVar(var));
78 if (!object) {
79 VOID_TO_NPVARIANT(*result);
80 return false;
81 }
82 OBJECT_TO_NPVARIANT(object->np_object(), *result);
83 break;
84 }
85 default:
86 VOID_TO_NPVARIANT(*result);
87 return false;
88 }
89 return true;
90 }
91
92 // ObjectAccessorTryCatch ------------------------------------------------------
93
94 // Automatically sets up a TryCatch for accessing the object identified by the
95 // given PP_Var. The module from the object will be used for the exception
96 // strings generated by the TryCatch.
97 //
98 // This will automatically retrieve the ObjectVar from the object and throw
99 // an exception if it's invalid. At the end of construction, if there is no
100 // exception, you know that there is no previously set exception, that the
101 // object passed in is valid and ready to use (via the object() getter), and
102 // that the TryCatch's module() getter is also set up properly and ready to
103 // use.
104 class ObjectAccessorTryCatch : public TryCatch {
105 public:
106 ObjectAccessorTryCatch(PP_Var object, PP_Var* exception)
107 : TryCatch(NULL, exception),
108 object_(ObjectVar::FromPPVar(object)) {
109 if (!object_) {
110 // No object or an invalid object was given. This means we have no module
111 // to associated with the exception text, so use the magic invalid object
112 // exception.
113 SetInvalidObjectException();
114 } else {
115 // When the object is valid, we have a valid module to associate
116 set_module(object_->module());
117 }
118 }
119
120 ObjectVar* object() { return object_.get(); }
121
122 protected:
123 scoped_refptr<ObjectVar> object_;
124
125 DISALLOW_COPY_AND_ASSIGN(ObjectAccessorTryCatch);
126 };
127
128 // ObjectAccessiorWithIdentifierTryCatch ---------------------------------------
129
130 // Automatically sets up a TryCatch for accessing the identifier on the given
131 // object. This just extends ObjectAccessorTryCatch to additionally convert
132 // the given identifier to an NPIdentifier and validate it, throwing an
133 // exception if it's invalid.
134 //
135 // At the end of construction, if there is no exception, you know that there is
136 // no previously set exception, that the object passed in is valid and ready to
137 // use (via the object() getter), that the identifier is valid and ready to
138 // use (via the identifier() getter), and that the TryCatch's module() getter
139 // is also set up properly and ready to use.
140 class ObjectAccessorWithIdentifierTryCatch : public ObjectAccessorTryCatch {
141 public:
142 ObjectAccessorWithIdentifierTryCatch(PP_Var object,
143 PP_Var identifier,
144 PP_Var* exception)
145 : ObjectAccessorTryCatch(object, exception),
146 identifier_(0) {
147 if (!has_exception()) {
148 identifier_ = Var::PPVarToNPIdentifier(identifier);
149 if (!identifier_)
150 SetException(kInvalidPropertyException);
151 }
152 }
153
154 NPIdentifier identifier() const { return identifier_; }
155
156 private:
157 NPIdentifier identifier_;
158
159 DISALLOW_COPY_AND_ASSIGN(ObjectAccessorWithIdentifierTryCatch);
160 };
161
162 PP_Var RunJSFunction(PP_Var scope_var,
163 const char* function_script,
164 PP_Var* argv,
165 unsigned argc,
166 PP_Var* exception) {
167 TryCatch try_catch(NULL, exception);
168 if (try_catch.has_exception())
169 return PP_MakeUndefined();
170
171 scoped_refptr<ObjectVar> obj = ObjectVar::FromPPVar(scope_var);
172 if (!obj) {
173 try_catch.SetInvalidObjectException();
174 return PP_MakeUndefined();
175 }
176
177 try_catch.set_module(obj->module());
178
179 scoped_array<NPVariant> args;
180 if (argc) {
181 args.reset(new NPVariant[argc]);
182 for (uint32_t i = 0; i < argc; ++i) {
183 if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) {
184 // This argument was invalid, throw an exception & give up.
185 try_catch.SetException(kInvalidValueException);
186 return PP_MakeUndefined();
187 }
188 }
189 }
190
191 NPVariant function_var;
192 VOID_TO_NPVARIANT(function_var);
193 NPString function_string = { function_script, strlen(function_script) };
194 if (!WebBindings::evaluate(NULL, obj->np_object(), &function_string,
195 &function_var)) {
196 try_catch.SetException(kInvalidValueException);
197 return PP_MakeUndefined();
198 }
199 DCHECK(NPVARIANT_IS_OBJECT(function_var));
200 DCHECK(!try_catch.has_exception());
201
202 NPVariant result_var;
203 VOID_TO_NPVARIANT(result_var);
204 PP_Var result;
205
206 if (WebBindings::invokeDefault(NULL, NPVARIANT_TO_OBJECT(function_var),
207 args.get(), argc, &result_var)) {
208 result = Var::NPVariantToPPVar(obj->module(), &result_var);
209 } else {
210 DCHECK(try_catch.has_exception());
211 result = PP_MakeUndefined();
212 }
213
214 WebBindings::releaseVariantValue(&function_var);
215 WebBindings::releaseVariantValue(&result_var);
216 return result;
217 }
218
219 // PPB_Var methods -------------------------------------------------------------
220
221 PP_Var VarFromUtf8(PP_Module module_id, const char* data, uint32_t len) {
222 PluginModule* module = ResourceTracker::Get()->GetModule(module_id);
223 if (!module)
224 return PP_MakeNull();
225 return StringVar::StringToPPVar(module, data, len);
226 }
227
228 const char* VarToUtf8(PP_Var var, uint32_t* len) {
229 scoped_refptr<StringVar> str(StringVar::FromPPVar(var));
230 if (!str) {
231 *len = 0;
232 return NULL;
233 }
234 *len = static_cast<uint32_t>(str->value().size());
235 if (str->value().empty())
236 return ""; // Don't return NULL on success.
237 return str->value().data();
238 }
239
240 PP_Var ConvertType(PP_Instance instance,
241 struct PP_Var var,
242 PP_VarType new_type,
243 PP_Var* exception) {
244 TryCatch try_catch(NULL, exception);
245 if (try_catch.has_exception())
246 return PP_MakeUndefined();
247
248 if (var.type == new_type)
249 return var;
250
251 PluginInstance* plugin_instance =
252 ResourceTracker::Get()->GetInstance(instance);
253 if (!plugin_instance) {
254 try_catch.SetInvalidObjectException();
255 return PP_MakeUndefined();
256 }
257
258 try_catch.set_module(plugin_instance->module());
259 PP_Var object = plugin_instance->GetWindowObject();
260
261 PP_Var params[] = {
262 var,
263 PP_MakeInt32(new_type),
264 PP_MakeInt32(PP_VARTYPE_NULL),
265 PP_MakeInt32(PP_VARTYPE_BOOL),
266 PP_MakeInt32(PP_VARTYPE_INT32),
267 PP_MakeInt32(PP_VARTYPE_DOUBLE),
268 PP_MakeInt32(PP_VARTYPE_STRING),
269 PP_MakeInt32(PP_VARTYPE_OBJECT)
270 };
271 PP_Var result = RunJSFunction(object,
272 "(function(v, new_type, type_null, type_bool, type_int32, type_double,"
273 " type_string, type_object) {"
274 " switch(new_type) {"
275 " case type_null: return null;"
276 " case type_bool: return Boolean(v);"
277 " case type_int32: case type_double: return Number(v);"
278 " case type_string: return String(v);"
279 " case type_object: return Object(v);"
280 " default: return undefined;"
281 " }})",
282 params, sizeof(params) / sizeof(PP_Var), exception);
283
284 // Massage Number into the correct type.
285 if (new_type == PP_VARTYPE_INT32 && result.type == PP_VARTYPE_DOUBLE) {
286 double value = result.value.as_double;
287 // Exclusive test wouldn't deal with NaNs correctly.
288 if (value >= std::numeric_limits<int32_t>::max()
289 && value <= std::numeric_limits<int32_t>::min())
290 result = PP_MakeInt32(static_cast<int32_t>(value));
291 else
292 result = PP_MakeInt32(0);
293 } else if (new_type == PP_VARTYPE_DOUBLE && result.type == PP_VARTYPE_INT32) {
294 result = PP_MakeDouble(result.value.as_int);
295 }
296
297 Var::PluginReleasePPVar(object);
298 return result;
299 }
300
301 PP_Var BoolToPPVar(bool value) {
302 return PP_MakeBool(BoolToPPBool(value));
303 }
304
305 void DefineProperty(struct PP_Var object,
306 struct PP_ObjectProperty property,
307 PP_Var* exception) {
308 PP_Var params[] = {
309 object, property.name,
310 BoolToPPVar(!!(property.modifiers & PP_OBJECTPROPERTY_MODIFIER_HASVALUE)),
311 property.value,
312 BoolToPPVar(property.getter.type == PP_VARTYPE_OBJECT),
313 property.getter,
314 BoolToPPVar(property.setter.type == PP_VARTYPE_OBJECT),
315 property.setter,
316 BoolToPPVar(!!(property.modifiers & PP_OBJECTPROPERTY_MODIFIER_READONLY)),
317 BoolToPPVar(!!(property.modifiers & PP_OBJECTPROPERTY_MODIFIER_DONTDELETE)),
318 BoolToPPVar(!!(property.modifiers & PP_OBJECTPROPERTY_MODIFIER_DONTENUM))
319 };
320
321 RunJSFunction(object,
322 "(function(o, name,"
323 " has_value, value,"
324 " has_getter, getter,"
325 " has_setter, setter,"
326 " modifier_readonly, modifier_dontdelete, modifier_dontenum) {"
327 " prop = { 'enumerable': !modifier_dontenum,"
328 " 'configurable': !modifier_dontdelete };"
329 " if (has_value && !modifier_readonly) prop.writable = true;"
330 " if (has_value) prop.value = value;"
331 " if (has_getter) prop.get = getter;"
332 " if (has_setter) prop.set = setter;"
333 " return Object.defineProperty(o, name, prop); })",
334 params, sizeof(params) / sizeof(PP_Var), exception);
335 }
336
337 PP_Bool HasProperty(PP_Var var,
338 PP_Var name,
339 PP_Var* exception) {
340 ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
341 if (accessor.has_exception())
342 return PP_FALSE;
343 return BoolToPPBool(WebBindings::hasProperty(NULL,
344 accessor.object()->np_object(),
345 accessor.identifier()));
346 }
347
348 bool HasPropertyDeprecated(PP_Var var,
349 PP_Var name,
350 PP_Var* exception) {
351 return PPBoolToBool(HasProperty(var, name, exception));
352 }
353
354 bool HasMethodDeprecated(PP_Var var,
355 PP_Var name,
356 PP_Var* exception) {
357 ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
358 if (accessor.has_exception())
359 return false;
360 return WebBindings::hasMethod(NULL, accessor.object()->np_object(),
361 accessor.identifier());
362 }
363
364 PP_Var GetProperty(PP_Var var,
365 PP_Var name,
366 PP_Var* exception) {
367 ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
368 if (accessor.has_exception())
369 return PP_MakeUndefined();
370
371 NPVariant result;
372 if (!WebBindings::getProperty(NULL, accessor.object()->np_object(),
373 accessor.identifier(), &result)) {
374 // An exception may have been raised.
375 accessor.SetException(kUnableToGetPropertyException);
376 return PP_MakeUndefined();
377 }
378
379 PP_Var ret = Var::NPVariantToPPVar(accessor.object()->module(), &result);
380 WebBindings::releaseVariantValue(&result);
381 return ret;
382 }
383
384 void EnumerateProperties(PP_Var var,
385 uint32_t* property_count,
386 PP_Var** properties,
387 PP_Var* exception) {
388 *properties = NULL;
389 *property_count = 0;
390
391 ObjectAccessorTryCatch accessor(var, exception);
392 if (accessor.has_exception())
393 return;
394
395 NPIdentifier* identifiers = NULL;
396 uint32_t count = 0;
397 if (!WebBindings::enumerate(NULL, accessor.object()->np_object(),
398 &identifiers, &count)) {
399 accessor.SetException(kUnableToGetAllPropertiesException);
400 return;
401 }
402
403 if (count == 0)
404 return;
405
406 *property_count = count;
407 *properties = static_cast<PP_Var*>(malloc(sizeof(PP_Var) * count));
408 for (uint32_t i = 0; i < count; ++i) {
409 (*properties)[i] = Var::NPIdentifierToPPVar(accessor.object()->module(),
410 identifiers[i]);
411 }
412 free(identifiers);
413 }
414
415 void SetPropertyDeprecated(PP_Var var,
416 PP_Var name,
417 PP_Var value,
418 PP_Var* exception) {
419 ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
420 if (accessor.has_exception())
421 return;
422
423 NPVariant variant;
424 if (!PPVarToNPVariantNoCopy(value, &variant)) {
425 accessor.SetException(kInvalidValueException);
426 return;
427 }
428 if (!WebBindings::setProperty(NULL, accessor.object()->np_object(),
429 accessor.identifier(), &variant))
430 accessor.SetException(kUnableToSetPropertyException);
431 }
432
433 PP_Bool DeleteProperty(PP_Var var,
434 PP_Var name,
435 PP_Var* exception) {
436 ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
437 if (accessor.has_exception())
438 return PP_FALSE;
439
440 return BoolToPPBool(
441 WebBindings::removeProperty(NULL,
442 accessor.object()->np_object(),
443 accessor.identifier()));
444 }
445
446 void DeletePropertyDeprecated(PP_Var var,
447 PP_Var name,
448 PP_Var* exception) {
449 ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
450 if (accessor.has_exception())
451 return;
452
453 if (!WebBindings::removeProperty(NULL, accessor.object()->np_object(),
454 accessor.identifier()))
455 accessor.SetException(kUnableToRemovePropertyException);
456 }
457
458 PP_Bool IsCallable(struct PP_Var object) {
459 PP_Var result = RunJSFunction(object,
460 "(function() { return typeof(this) == 'function' })", NULL, 0, NULL);
461 if (result.type == PP_VARTYPE_BOOL)
462 return result.value.as_bool;
463 return PP_FALSE;
464 }
465
466 struct PP_Var Call(struct PP_Var object,
467 struct PP_Var this_object,
468 uint32_t argc,
469 struct PP_Var* argv,
470 struct PP_Var* exception) {
471 ObjectAccessorTryCatch accessor(object, exception);
472 if (accessor.has_exception())
473 return PP_MakeUndefined();
474
475 scoped_array<NPVariant> args;
476 if (argc) {
477 args.reset(new NPVariant[argc]);
478 for (uint32_t i = 0; i < argc; ++i) {
479 if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) {
480 // This argument was invalid, throw an exception & give up.
481 accessor.SetException(kInvalidValueException);
482 return PP_MakeUndefined();
483 }
484 }
485 }
486
487 NPVariant result;
488 if (!WebBindings::invokeDefault(NULL, accessor.object()->np_object(),
489 args.get(), argc, &result)) {
490 // An exception may have been raised.
491 accessor.SetException(kUnableToCallMethodException);
492 return PP_MakeUndefined();
493 }
494
495 PP_Var ret = Var::NPVariantToPPVar(accessor.module(), &result);
496 WebBindings::releaseVariantValue(&result);
497 return ret;
498 }
499
500 PP_Var CallDeprecated(PP_Var var,
501 PP_Var method_name,
502 uint32_t argc,
503 PP_Var* argv,
504 PP_Var* exception) {
505 ObjectAccessorTryCatch accessor(var, exception);
506 if (accessor.has_exception())
507 return PP_MakeUndefined();
508
509 NPIdentifier identifier;
510 if (method_name.type == PP_VARTYPE_UNDEFINED) {
511 identifier = NULL;
512 } else if (method_name.type == PP_VARTYPE_STRING) {
513 // Specifically allow only string functions to be called.
514 identifier = Var::PPVarToNPIdentifier(method_name);
515 if (!identifier) {
516 accessor.SetException(kInvalidPropertyException);
517 return PP_MakeUndefined();
518 }
519 } else {
520 accessor.SetException(kInvalidPropertyException);
521 return PP_MakeUndefined();
522 }
523
524 scoped_array<NPVariant> args;
525 if (argc) {
526 args.reset(new NPVariant[argc]);
527 for (uint32_t i = 0; i < argc; ++i) {
528 if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) {
529 // This argument was invalid, throw an exception & give up.
530 accessor.SetException(kInvalidValueException);
531 return PP_MakeUndefined();
532 }
533 }
534 }
535
536 bool ok;
537
538 NPVariant result;
539 if (identifier) {
540 ok = WebBindings::invoke(NULL, accessor.object()->np_object(),
541 identifier, args.get(), argc, &result);
542 } else {
543 ok = WebBindings::invokeDefault(NULL, accessor.object()->np_object(),
544 args.get(), argc, &result);
545 }
546
547 if (!ok) {
548 // An exception may have been raised.
549 accessor.SetException(kUnableToCallMethodException);
550 return PP_MakeUndefined();
551 }
552
553 PP_Var ret = Var::NPVariantToPPVar(accessor.module(), &result);
554 WebBindings::releaseVariantValue(&result);
555 return ret;
556 }
557
558 PP_Var Construct(PP_Var var,
559 uint32_t argc,
560 PP_Var* argv,
561 PP_Var* exception) {
562 ObjectAccessorTryCatch accessor(var, exception);
563 if (accessor.has_exception())
564 return PP_MakeUndefined();
565
566 scoped_array<NPVariant> args;
567 if (argc) {
568 args.reset(new NPVariant[argc]);
569 for (uint32_t i = 0; i < argc; ++i) {
570 if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) {
571 // This argument was invalid, throw an exception & give up.
572 accessor.SetException(kInvalidValueException);
573 return PP_MakeUndefined();
574 }
575 }
576 }
577
578 NPVariant result;
579 if (!WebBindings::construct(NULL, accessor.object()->np_object(),
580 args.get(), argc, &result)) {
581 // An exception may have been raised.
582 accessor.SetException(kUnableToConstructException);
583 return PP_MakeUndefined();
584 }
585
586 PP_Var ret = Var::NPVariantToPPVar(accessor.module(), &result);
587 WebBindings::releaseVariantValue(&result);
588 return ret;
589 }
590
591 bool IsInstanceOfDeprecated(PP_Var var,
592 const PPP_Class_Deprecated* ppp_class,
593 void** ppp_class_data) {
594 scoped_refptr<ObjectVar> object(ObjectVar::FromPPVar(var));
595 if (!object)
596 return false; // Not an object at all.
597
598 return PluginObject::IsInstanceOf(object->np_object(),
599 ppp_class, ppp_class_data);
600 }
601
602 PP_Var CreateObjectDeprecated(PP_Module module_id,
603 const PPP_Class_Deprecated* ppp_class,
604 void* ppp_class_data) {
605 PluginModule* module = ResourceTracker::Get()->GetModule(module_id);
606 if (!module)
607 return PP_MakeNull();
608 return PluginObject::Create(module, ppp_class, ppp_class_data);
609 }
610
611 const PPB_Var_Deprecated var_deprecated_interface = {
612 &Var::PluginAddRefPPVar,
613 &Var::PluginReleasePPVar,
614 &VarFromUtf8,
615 &VarToUtf8,
616 &HasPropertyDeprecated,
617 &HasMethodDeprecated,
618 &GetProperty,
619 &EnumerateProperties,
620 &SetPropertyDeprecated,
621 &DeletePropertyDeprecated,
622 &CallDeprecated,
623 &Construct,
624 &IsInstanceOfDeprecated,
625 &CreateObjectDeprecated
626 };
627
628 const PPB_Var var_interface = {
629 &Var::PluginAddRefPPVar,
630 &Var::PluginReleasePPVar,
631 &VarFromUtf8,
632 &VarToUtf8,
633 &ConvertType,
634 &DefineProperty,
635 &HasProperty,
636 &GetProperty,
637 &DeleteProperty,
638 &EnumerateProperties,
639 &IsCallable,
640 &Call,
641 &Construct,
642 };
643
644
645 } // namespace
646
647 // Var -------------------------------------------------------------------------
648
649 Var::Var(PluginModule* module) : Resource(module) {
650 }
651
652 Var::~Var() {
653 }
654
655 Var* Var::AsVar() {
656 return this;
657 }
658
659 // static
660 PP_Var Var::NPVariantToPPVar(PluginModule* module, const NPVariant* variant) {
661 switch (variant->type) {
662 case NPVariantType_Void:
663 return PP_MakeUndefined();
664 case NPVariantType_Null:
665 return PP_MakeNull();
666 case NPVariantType_Bool:
667 return BoolToPPVar(NPVARIANT_TO_BOOLEAN(*variant));
668 case NPVariantType_Int32:
669 return PP_MakeInt32(NPVARIANT_TO_INT32(*variant));
670 case NPVariantType_Double:
671 return PP_MakeDouble(NPVARIANT_TO_DOUBLE(*variant));
672 case NPVariantType_String:
673 return StringVar::StringToPPVar(
674 module,
675 NPVARIANT_TO_STRING(*variant).UTF8Characters,
676 NPVARIANT_TO_STRING(*variant).UTF8Length);
677 case NPVariantType_Object:
678 return ObjectVar::NPObjectToPPVar(module, NPVARIANT_TO_OBJECT(*variant));
679 }
680 NOTREACHED();
681 return PP_MakeUndefined();
682 }
683
684 // static
685 NPIdentifier Var::PPVarToNPIdentifier(PP_Var var) {
686 switch (var.type) {
687 case PP_VARTYPE_STRING: {
688 scoped_refptr<StringVar> string(StringVar::FromPPVar(var));
689 if (!string)
690 return NULL;
691 return WebBindings::getStringIdentifier(string->value().c_str());
692 }
693 case PP_VARTYPE_INT32:
694 return WebBindings::getIntIdentifier(var.value.as_int);
695 default:
696 return NULL;
697 }
698 }
699
700 // static
701 PP_Var Var::NPIdentifierToPPVar(PluginModule* module, NPIdentifier id) {
702 const NPUTF8* string_value = NULL;
703 int32_t int_value = 0;
704 bool is_string = false;
705 WebBindings::extractIdentifierData(id, string_value, int_value, is_string);
706 if (is_string)
707 return StringVar::StringToPPVar(module, string_value);
708
709 return PP_MakeInt32(int_value);
710 }
711
712 // static
713 void Var::PluginAddRefPPVar(PP_Var var) {
714 if (var.type == PP_VARTYPE_STRING || var.type == PP_VARTYPE_OBJECT) {
715 // TODO(brettw) consider checking that the ID is actually a var ID rather
716 // than some random other resource ID.
717 PP_Resource resource = static_cast<PP_Resource>(var.value.as_id);
718 if (!ResourceTracker::Get()->AddRefResource(resource))
719 DLOG(WARNING) << "AddRefVar()ing a nonexistant string/object var.";
720 }
721 }
722
723 // static
724 void Var::PluginReleasePPVar(PP_Var var) {
725 if (var.type == PP_VARTYPE_STRING || var.type == PP_VARTYPE_OBJECT) {
726 // TODO(brettw) consider checking that the ID is actually a var ID rather
727 // than some random other resource ID.
728 PP_Resource resource = static_cast<PP_Resource>(var.value.as_id);
729 if (!ResourceTracker::Get()->UnrefResource(resource))
730 DLOG(WARNING) << "ReleaseVar()ing a nonexistant string/object var.";
731 }
732 }
733
734 // static
735 const PPB_Var_Deprecated* Var::GetDeprecatedInterface() {
736 return &var_deprecated_interface;
737 }
738
739 const PPB_Var* Var::GetInterface() {
740 return &var_interface;
741 }
742
743 // StringVar -------------------------------------------------------------------
744
745 StringVar::StringVar(PluginModule* module, const char* str, uint32 len)
746 : Var(module),
747 value_(str, len) {
748 }
749
750 StringVar::~StringVar() {
751 }
752
753 StringVar* StringVar::AsStringVar() {
754 return this;
755 }
756
757 // static
758 PP_Var StringVar::StringToPPVar(PluginModule* module, const std::string& var) {
759 return StringToPPVar(module, var.c_str(), var.size());
760 }
761
762 // static
763 PP_Var StringVar::StringToPPVar(PluginModule* module,
764 const char* data, uint32 len) {
765 scoped_refptr<StringVar> str(new StringVar(module, data, len));
766 if (!str || !IsStringUTF8(str->value()))
767 return PP_MakeNull();
768
769 PP_Var ret;
770 ret.type = PP_VARTYPE_STRING;
771
772 // The caller takes ownership now.
773 ret.value.as_id = str->GetReference();
774 return ret;
775 }
776
777 // static
778 scoped_refptr<StringVar> StringVar::FromPPVar(PP_Var var) {
779 if (var.type != PP_VARTYPE_STRING)
780 return scoped_refptr<StringVar>(NULL);
781 PP_Resource resource = static_cast<PP_Resource>(var.value.as_id);
782 return Resource::GetAs<StringVar>(resource);
783 }
784
785 // ObjectVar -------------------------------------------------------------
786
787 ObjectVar::ObjectVar(PluginModule* module, NPObject* np_object)
788 : Var(module),
789 np_object_(np_object) {
790 WebBindings::retainObject(np_object_);
791 module->AddNPObjectVar(this);
792 }
793
794 ObjectVar::~ObjectVar() {
795 module()->RemoveNPObjectVar(this);
796 WebBindings::releaseObject(np_object_);
797 }
798
799 ObjectVar* ObjectVar::AsObjectVar() {
800 return this;
801 }
802
803 // static
804 PP_Var ObjectVar::NPObjectToPPVar(PluginModule* module, NPObject* object) {
805 scoped_refptr<ObjectVar> object_var(module->ObjectVarForNPObject(object));
806 if (!object_var) // No object for this module yet, make a new one.
807 object_var = new ObjectVar(module, object);
808
809 if (!object_var)
810 return PP_MakeUndefined();
811
812 // Convert to a PP_Var, GetReference will AddRef for us.
813 PP_Var result;
814 result.type = PP_VARTYPE_OBJECT;
815 result.value.as_id = object_var->GetReference();
816 return result;
817 }
818
819 // static
820 scoped_refptr<ObjectVar> ObjectVar::FromPPVar(PP_Var var) {
821 if (var.type != PP_VARTYPE_OBJECT)
822 return scoped_refptr<ObjectVar>(NULL);
823 PP_Resource resource = static_cast<PP_Resource>(var.value.as_id);
824 return Resource::GetAs<ObjectVar>(resource);
825 }
826
827 // TryCatch --------------------------------------------------------------------
828
829 TryCatch::TryCatch(PluginModule* module, PP_Var* exception)
830 : module_(module),
831 has_exception_(exception && exception->type != PP_VARTYPE_UNDEFINED),
832 exception_(exception) {
833 WebBindings::pushExceptionHandler(&TryCatch::Catch, this);
834 }
835
836 TryCatch::~TryCatch() {
837 WebBindings::popExceptionHandler();
838 }
839
840 void TryCatch::SetException(const char* message) {
841 if (!module_) {
842 // Don't have a module to make the string.
843 SetInvalidObjectException();
844 return;
845 }
846
847 if (!has_exception()) {
848 has_exception_ = true;
849 if (exception_)
850 *exception_ = StringVar::StringToPPVar(module_, message, strlen(message));
851 }
852 }
853
854 void TryCatch::SetInvalidObjectException() {
855 if (!has_exception()) {
856 has_exception_ = true;
857 // TODO(brettw) bug 54504: Have a global singleton string that can hold
858 // a generic error message.
859 if (exception_)
860 *exception_ = PP_MakeInt32(1);
861 }
862 }
863
864 // static
865 void TryCatch::Catch(void* self, const char* message) {
866 static_cast<TryCatch*>(self)->SetException(message);
867 }
868
869 } // namespace pepper
OLDNEW
« no previous file with comments | « webkit/glue/plugins/pepper_var.h ('k') | webkit/glue/plugins/pepper_video_decoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698