1 // Copyright (c) 2011 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 "ppapi/cpp/dev/scriptable_object_deprecated.h"
6 
7 #include <stddef.h>
8 #include <stdint.h>
9 
10 #include "ppapi/c/dev/ppb_memory_dev.h"
11 #include "ppapi/c/dev/ppp_class_deprecated.h"
12 #include "ppapi/cpp/module.h"
13 #include "ppapi/cpp/var.h"
14 
15 namespace pp {
16 
17 namespace deprecated {
18 
19 namespace {
20 
21 // Allows converting an output param of a Var to an output param of a PP_Var
22 // for exceptions. The object is only copied if it is not void, which we
23 // take to mean an exception occurred.
24 class ExceptionConverter {
25  public:
ExceptionConverter(PP_Var * out)26   ExceptionConverter(PP_Var* out) : out_(out) {
27   }
~ExceptionConverter()28   ~ExceptionConverter() {
29     if (!exception_.is_undefined())
30       *out_ = exception_.Detach();
31   }
32 
Get()33   Var* Get() { return &exception_; }
34 
35  private:
36   PP_Var* out_;
37   Var exception_;
38 };
39 
40 // Used internally to convert a C-style array of PP_Var to a vector of Var.
ArgListToVector(uint32_t argc,PP_Var * argv,std::vector<Var> * output)41 void ArgListToVector(uint32_t argc, PP_Var* argv, std::vector<Var>* output) {
42   output->reserve(argc);
43   for (size_t i = 0; i < argc; i++)
44     output->push_back(Var(Var::DontManage(), argv[i]));
45 }
46 
HasProperty(void * object,PP_Var name,PP_Var * exception)47 bool HasProperty(void* object, PP_Var name, PP_Var* exception) {
48   ExceptionConverter e(exception);
49   return static_cast<ScriptableObject*>(object)->HasProperty(
50       Var(Var::DontManage(), name), e.Get());
51 }
52 
HasMethod(void * object,PP_Var name,PP_Var * exception)53 bool HasMethod(void* object, PP_Var name, PP_Var* exception) {
54   ExceptionConverter e(exception);
55   return static_cast<ScriptableObject*>(object)->HasMethod(
56       Var(Var::DontManage(), name), e.Get());
57 }
58 
GetProperty(void * object,PP_Var name,PP_Var * exception)59 PP_Var GetProperty(void* object,
60                    PP_Var name,
61                    PP_Var* exception) {
62   ExceptionConverter e(exception);
63   return static_cast<ScriptableObject*>(object)->GetProperty(
64       Var(Var::DontManage(), name), e.Get()).Detach();
65 }
66 
GetAllPropertyNames(void * object,uint32_t * property_count,PP_Var ** properties,PP_Var * exception)67 void GetAllPropertyNames(void* object,
68                          uint32_t* property_count,
69                          PP_Var** properties,
70                          PP_Var* exception) {
71   ExceptionConverter e(exception);
72   std::vector<Var> props;
73   static_cast<ScriptableObject*>(object)->GetAllPropertyNames(&props, e.Get());
74   if (props.empty())
75     return;
76   *property_count = static_cast<uint32_t>(props.size());
77 
78   const PPB_Memory_Dev* memory_if = static_cast<const PPB_Memory_Dev*>(
79       pp::Module::Get()->GetBrowserInterface(PPB_MEMORY_DEV_INTERFACE));
80   *properties = static_cast<PP_Var*>(memory_if->MemAlloc(
81       static_cast<uint32_t>(sizeof(PP_Var) * props.size())));
82 
83   for (size_t i = 0; i < props.size(); ++i)
84     (*properties)[i] = props[i].Detach();
85 }
86 
SetProperty(void * object,PP_Var name,PP_Var value,PP_Var * exception)87 void SetProperty(void* object,
88                  PP_Var name,
89                  PP_Var value,
90                  PP_Var* exception) {
91   ExceptionConverter e(exception);
92   static_cast<ScriptableObject*>(object)->SetProperty(
93       Var(Var::DontManage(), name), Var(Var::DontManage(), value), e.Get());
94 }
95 
RemoveProperty(void * object,PP_Var name,PP_Var * exception)96 void RemoveProperty(void* object,
97                     PP_Var name,
98                     PP_Var* exception) {
99   ExceptionConverter e(exception);
100   static_cast<ScriptableObject*>(object)->RemoveProperty(
101       Var(Var::DontManage(), name), e.Get());
102 }
103 
Call(void * object,PP_Var method_name,uint32_t argc,PP_Var * argv,PP_Var * exception)104 PP_Var Call(void* object,
105             PP_Var method_name,
106             uint32_t argc,
107             PP_Var* argv,
108             PP_Var* exception) {
109   ExceptionConverter e(exception);
110 
111   std::vector<Var> args;
112   ArgListToVector(argc, argv, &args);
113   return static_cast<ScriptableObject*>(object)->Call(
114       Var(Var::DontManage(), method_name), args, e.Get()).Detach();
115 }
116 
Construct(void * object,uint32_t argc,PP_Var * argv,PP_Var * exception)117 PP_Var Construct(void* object,
118                  uint32_t argc,
119                  PP_Var* argv,
120                  PP_Var* exception) {
121   ExceptionConverter e(exception);
122 
123   std::vector<Var> args;
124   ArgListToVector(argc, argv, &args);
125   return static_cast<ScriptableObject*>(object)->Construct(
126       args, e.Get()).Detach();
127 }
128 
Deallocate(void * object)129 void Deallocate(void* object) {
130   delete static_cast<ScriptableObject*>(object);
131 }
132 
133 PPP_Class_Deprecated plugin_class = {
134   &HasProperty,
135   &HasMethod,
136   &GetProperty,
137   &GetAllPropertyNames,
138   &SetProperty,
139   &RemoveProperty,
140   &Call,
141   &Construct,
142   &Deallocate
143 };
144 
145 }  // namespace
146 
HasProperty(const Var &,Var *)147 bool ScriptableObject::HasProperty(const Var& /*name*/, Var* /*exception*/) {
148   return false;
149 }
150 
HasMethod(const Var &,Var *)151 bool ScriptableObject::HasMethod(const Var& /*name*/, Var* /*exception*/) {
152   return false;
153 }
154 
GetProperty(const Var &,Var * exception)155 Var ScriptableObject::GetProperty(const Var& /*name*/, Var* exception) {
156   *exception = Var("Property does not exist on ScriptableObject");
157   return Var();
158 }
159 
GetAllPropertyNames(std::vector<Var> *,Var *)160 void ScriptableObject::GetAllPropertyNames(std::vector<Var>* /*properties*/,
161                                            Var* /*exception*/) {
162 }
163 
SetProperty(const Var &,const Var &,Var * exception)164 void ScriptableObject::SetProperty(const Var& /*name*/,
165                                    const Var& /*value*/,
166                                    Var* exception) {
167   *exception = Var("Property can not be set on ScriptableObject");
168 }
169 
RemoveProperty(const Var &,Var * exception)170 void ScriptableObject::RemoveProperty(const Var& /*name*/,
171                                       Var* exception) {
172   *exception = Var(
173       "Property does does not exist to be removed in ScriptableObject");
174 }
175 
Call(const Var &,const std::vector<Var> &,Var * exception)176 Var ScriptableObject::Call(const Var& /*method_name*/,
177                            const std::vector<Var>& /*args*/,
178                            Var* exception) {
179   *exception = Var("Method does not exist to call in ScriptableObject");
180   return Var();
181 }
182 
Construct(const std::vector<Var> &,Var * exception)183 Var ScriptableObject::Construct(const std::vector<Var>& /*args*/,
184                                 Var* exception) {
185   *exception = Var("Construct method does not exist in ScriptableObject");
186   return Var();
187 }
188 
189 // static
GetClass()190 const PPP_Class_Deprecated* ScriptableObject::GetClass() {
191   return &plugin_class;
192 }
193 
194 }  // namespace deprecated
195 
196 }  // namespace pp
197