OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ppapi/cpp/var.h" | 5 #include "ppapi/cpp/var.h" |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 #include <string.h> | 8 #include <string.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
11 | 11 |
12 #include "ppapi/c/dev/ppb_memory_dev.h" | |
13 #ifndef PPAPI_VAR_REMOVE_SCRIPTING | |
14 # include "ppapi/c/dev/ppb_var_deprecated.h" | |
15 #endif | |
16 #include "ppapi/c/pp_var.h" | 12 #include "ppapi/c/pp_var.h" |
17 #include "ppapi/c/ppb_var.h" | 13 #include "ppapi/c/ppb_var.h" |
18 #include "ppapi/cpp/instance.h" | 14 #include "ppapi/cpp/instance.h" |
19 #include "ppapi/cpp/logging.h" | 15 #include "ppapi/cpp/logging.h" |
20 #include "ppapi/cpp/module.h" | 16 #include "ppapi/cpp/module.h" |
21 #include "ppapi/cpp/module_impl.h" | 17 #include "ppapi/cpp/module_impl.h" |
22 #include "ppapi/cpp/dev/scriptable_object_deprecated.h" | |
23 | 18 |
24 // Define equivalent to snprintf on Windows. | 19 // Define equivalent to snprintf on Windows. |
25 #if defined(_MSC_VER) | 20 #if defined(_MSC_VER) |
26 # define snprintf sprintf_s | 21 # define snprintf sprintf_s |
27 #endif | 22 #endif |
28 | 23 |
29 namespace pp { | 24 namespace pp { |
30 | 25 |
31 namespace { | 26 namespace { |
32 | 27 |
33 template <> const char* interface_name<PPB_Var>() { | 28 template <> const char* interface_name<PPB_Var>() { |
34 return PPB_VAR_INTERFACE; | 29 return PPB_VAR_INTERFACE; |
35 } | 30 } |
36 | 31 |
37 #ifdef PPAPI_VAR_REMOVE_SCRIPTING | |
38 typedef PPB_Var PPB_Var_Interface_Type; | |
39 #else | |
40 typedef PPB_Var_Deprecated PPB_Var_Interface_Type; | |
41 | |
42 template <> const char* interface_name<PPB_Var_Deprecated>() { | |
43 return PPB_VAR_DEPRECATED_INTERFACE; | |
44 } | |
45 #endif | |
46 | |
47 // Technically you can call AddRef and Release on any Var, but it may involve | 32 // Technically you can call AddRef and Release on any Var, but it may involve |
48 // cross-process calls depending on the plugin. This is an optimization so we | 33 // cross-process calls depending on the plugin. This is an optimization so we |
49 // only do refcounting on the necessary objects. | 34 // only do refcounting on the necessary objects. |
50 inline bool NeedsRefcounting(const PP_Var& var) { | 35 inline bool NeedsRefcounting(const PP_Var& var) { |
51 return var.type > PP_VARTYPE_DOUBLE; | 36 return var.type > PP_VARTYPE_DOUBLE; |
52 } | 37 } |
53 | 38 |
54 } // namespace | 39 } // namespace |
55 | 40 |
56 using namespace deprecated; | |
57 | |
58 Var::Var() { | 41 Var::Var() { |
59 memset(&var_, 0, sizeof(var_)); | 42 memset(&var_, 0, sizeof(var_)); |
60 var_.type = PP_VARTYPE_UNDEFINED; | 43 var_.type = PP_VARTYPE_UNDEFINED; |
61 needs_release_ = false; | 44 needs_release_ = false; |
62 } | 45 } |
63 | 46 |
64 Var::Var(Null) { | 47 Var::Var(Null) { |
65 memset(&var_, 0, sizeof(var_)); | 48 memset(&var_, 0, sizeof(var_)); |
66 var_.type = PP_VARTYPE_NULL; | 49 var_.type = PP_VARTYPE_NULL; |
67 needs_release_ = false; | 50 needs_release_ = false; |
(...skipping 14 matching lines...) Expand all Loading... |
82 } | 65 } |
83 | 66 |
84 Var::Var(double d) { | 67 Var::Var(double d) { |
85 var_.type = PP_VARTYPE_DOUBLE; | 68 var_.type = PP_VARTYPE_DOUBLE; |
86 var_.padding = 0; | 69 var_.padding = 0; |
87 var_.value.as_double = d; | 70 var_.value.as_double = d; |
88 needs_release_ = false; | 71 needs_release_ = false; |
89 } | 72 } |
90 | 73 |
91 Var::Var(const char* utf8_str) { | 74 Var::Var(const char* utf8_str) { |
92 if (has_interface<PPB_Var_Interface_Type>()) { | 75 if (has_interface<PPB_Var>()) { |
93 uint32_t len = utf8_str ? static_cast<uint32_t>(strlen(utf8_str)) : 0; | 76 uint32_t len = utf8_str ? static_cast<uint32_t>(strlen(utf8_str)) : 0; |
94 var_ = get_interface<PPB_Var_Interface_Type>()->VarFromUtf8( | 77 var_ = get_interface<PPB_Var>()->VarFromUtf8(Module::Get()->pp_module(), |
95 Module::Get()->pp_module(), utf8_str, len); | 78 utf8_str, len); |
96 } else { | 79 } else { |
97 var_.type = PP_VARTYPE_NULL; | 80 var_.type = PP_VARTYPE_NULL; |
98 var_.padding = 0; | 81 var_.padding = 0; |
99 } | 82 } |
100 needs_release_ = (var_.type == PP_VARTYPE_STRING); | 83 needs_release_ = (var_.type == PP_VARTYPE_STRING); |
101 } | 84 } |
102 | 85 |
103 Var::Var(const std::string& utf8_str) { | 86 Var::Var(const std::string& utf8_str) { |
104 if (has_interface<PPB_Var_Interface_Type>()) { | 87 if (has_interface<PPB_Var>()) { |
105 var_ = get_interface<PPB_Var_Interface_Type>()->VarFromUtf8( | 88 var_ = get_interface<PPB_Var>()->VarFromUtf8( |
106 Module::Get()->pp_module(), | 89 Module::Get()->pp_module(), |
107 utf8_str.c_str(), | 90 utf8_str.c_str(), |
108 static_cast<uint32_t>(utf8_str.size())); | 91 static_cast<uint32_t>(utf8_str.size())); |
109 } else { | 92 } else { |
110 var_.type = PP_VARTYPE_NULL; | 93 var_.type = PP_VARTYPE_NULL; |
111 var_.padding = 0; | 94 var_.padding = 0; |
112 } | 95 } |
113 needs_release_ = (var_.type == PP_VARTYPE_STRING); | 96 needs_release_ = (var_.type == PP_VARTYPE_STRING); |
114 } | 97 } |
115 | 98 |
116 Var::Var(const Var& other) { | 99 Var::Var(const Var& other) { |
117 var_ = other.var_; | 100 var_ = other.var_; |
118 if (NeedsRefcounting(var_)) { | 101 if (NeedsRefcounting(var_)) { |
119 if (has_interface<PPB_Var_Interface_Type>()) { | 102 if (has_interface<PPB_Var>()) { |
120 needs_release_ = true; | 103 needs_release_ = true; |
121 get_interface<PPB_Var_Interface_Type>()->AddRef(var_); | 104 get_interface<PPB_Var>()->AddRef(var_); |
122 } else { | 105 } else { |
123 var_.type = PP_VARTYPE_NULL; | 106 var_.type = PP_VARTYPE_NULL; |
124 needs_release_ = false; | 107 needs_release_ = false; |
125 } | 108 } |
126 } else { | 109 } else { |
127 needs_release_ = false; | 110 needs_release_ = false; |
128 } | 111 } |
129 } | 112 } |
130 | 113 |
131 Var::~Var() { | 114 Var::~Var() { |
132 if (needs_release_ && has_interface<PPB_Var_Interface_Type>()) | 115 if (needs_release_ && has_interface<PPB_Var>()) |
133 get_interface<PPB_Var_Interface_Type>()->Release(var_); | 116 get_interface<PPB_Var>()->Release(var_); |
134 } | 117 } |
135 | 118 |
136 Var& Var::operator=(const Var& other) { | 119 Var& Var::operator=(const Var& other) { |
137 if (needs_release_ && has_interface<PPB_Var_Interface_Type>()) | 120 if (needs_release_ && has_interface<PPB_Var>()) |
138 get_interface<PPB_Var_Interface_Type>()->Release(var_); | 121 get_interface<PPB_Var>()->Release(var_); |
139 var_ = other.var_; | 122 var_ = other.var_; |
140 if (NeedsRefcounting(var_)) { | 123 if (NeedsRefcounting(var_)) { |
141 if (has_interface<PPB_Var_Interface_Type>()) { | 124 if (has_interface<PPB_Var>()) { |
142 needs_release_ = true; | 125 needs_release_ = true; |
143 get_interface<PPB_Var_Interface_Type>()->AddRef(var_); | 126 get_interface<PPB_Var>()->AddRef(var_); |
144 } else { | 127 } else { |
145 var_.type = PP_VARTYPE_NULL; | 128 var_.type = PP_VARTYPE_NULL; |
146 needs_release_ = false; | 129 needs_release_ = false; |
147 } | 130 } |
148 } else { | 131 } else { |
149 needs_release_ = false; | 132 needs_release_ = false; |
150 } | 133 } |
151 return *this; | 134 return *this; |
152 } | 135 } |
153 | 136 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 PP_NOTREACHED(); | 181 PP_NOTREACHED(); |
199 return 0.0; | 182 return 0.0; |
200 } | 183 } |
201 | 184 |
202 std::string Var::AsString() const { | 185 std::string Var::AsString() const { |
203 if (!is_string()) { | 186 if (!is_string()) { |
204 PP_NOTREACHED(); | 187 PP_NOTREACHED(); |
205 return std::string(); | 188 return std::string(); |
206 } | 189 } |
207 | 190 |
208 if (!has_interface<PPB_Var_Interface_Type>()) | 191 if (!has_interface<PPB_Var>()) |
209 return std::string(); | 192 return std::string(); |
210 uint32_t len; | 193 uint32_t len; |
211 const char* str = | 194 const char* str = get_interface<PPB_Var>()->VarToUtf8(var_, &len); |
212 get_interface<PPB_Var_Interface_Type>()->VarToUtf8(var_, &len); | |
213 return std::string(str, len); | 195 return std::string(str, len); |
214 } | 196 } |
215 | 197 |
216 #ifndef PPAPI_VAR_REMOVE_SCRIPTING | |
217 Var::Var(Instance* instance, ScriptableObject* object) { | |
218 if (has_interface<PPB_Var_Deprecated>()) { | |
219 var_ = get_interface<PPB_Var_Deprecated>()->CreateObject( | |
220 instance->pp_instance(), object->GetClass(), object); | |
221 needs_release_ = true; | |
222 } else { | |
223 var_.type = PP_VARTYPE_NULL; | |
224 var_.padding = 0; | |
225 needs_release_ = false; | |
226 } | |
227 } | |
228 | |
229 ScriptableObject* Var::AsScriptableObject() const { | |
230 if (!is_object()) { | |
231 PP_NOTREACHED(); | |
232 } else if (has_interface<PPB_Var_Deprecated>()) { | |
233 void* object = NULL; | |
234 if (get_interface<PPB_Var_Deprecated>()->IsInstanceOf( | |
235 var_, ScriptableObject::GetClass(), &object)) { | |
236 return reinterpret_cast<ScriptableObject*>(object); | |
237 } | |
238 } | |
239 return NULL; | |
240 } | |
241 | |
242 bool Var::HasProperty(const Var& name, Var* exception) const { | |
243 if (!has_interface<PPB_Var_Deprecated>()) | |
244 return false; | |
245 return get_interface<PPB_Var_Deprecated>()->HasProperty( | |
246 var_, name.var_, OutException(exception).get()); | |
247 } | |
248 | |
249 bool Var::HasMethod(const Var& name, Var* exception) const { | |
250 if (!has_interface<PPB_Var_Deprecated>()) | |
251 return false; | |
252 return get_interface<PPB_Var_Deprecated>()->HasMethod( | |
253 var_, name.var_, OutException(exception).get()); | |
254 } | |
255 | |
256 Var Var::GetProperty(const Var& name, Var* exception) const { | |
257 if (!has_interface<PPB_Var_Deprecated>()) | |
258 return Var(); | |
259 return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->GetProperty( | |
260 var_, name.var_, OutException(exception).get())); | |
261 } | |
262 | |
263 void Var::GetAllPropertyNames(std::vector<Var>* properties, | |
264 Var* exception) const { | |
265 if (!has_interface<PPB_Var_Deprecated>()) | |
266 return; | |
267 PP_Var* props = NULL; | |
268 uint32_t prop_count = 0; | |
269 get_interface<PPB_Var_Deprecated>()->GetAllPropertyNames( | |
270 var_, &prop_count, &props, OutException(exception).get()); | |
271 if (!prop_count) | |
272 return; | |
273 properties->resize(prop_count); | |
274 for (uint32_t i = 0; i < prop_count; ++i) { | |
275 Var temp(PassRef(), props[i]); | |
276 (*properties)[i] = temp; | |
277 } | |
278 const PPB_Memory_Dev* memory_if = static_cast<const PPB_Memory_Dev*>( | |
279 pp::Module::Get()->GetBrowserInterface(PPB_MEMORY_DEV_INTERFACE)); | |
280 memory_if->MemFree(props); | |
281 } | |
282 | |
283 void Var::SetProperty(const Var& name, const Var& value, Var* exception) { | |
284 if (!has_interface<PPB_Var_Deprecated>()) | |
285 return; | |
286 get_interface<PPB_Var_Deprecated>()->SetProperty( | |
287 var_, name.var_, value.var_, OutException(exception).get()); | |
288 } | |
289 | |
290 void Var::RemoveProperty(const Var& name, Var* exception) { | |
291 if (!has_interface<PPB_Var_Deprecated>()) | |
292 return; | |
293 get_interface<PPB_Var_Deprecated>()->RemoveProperty( | |
294 var_, name.var_, OutException(exception).get()); | |
295 } | |
296 | |
297 Var Var::Call(const Var& method_name, uint32_t argc, Var* argv, | |
298 Var* exception) { | |
299 if (!has_interface<PPB_Var_Deprecated>()) | |
300 return Var(); | |
301 if (argc > 0) { | |
302 std::vector<PP_Var> args; | |
303 args.reserve(argc); | |
304 for (size_t i = 0; i < argc; i++) | |
305 args.push_back(argv[i].var_); | |
306 return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call( | |
307 var_, method_name.var_, argc, &args[0], OutException(exception).get())); | |
308 } else { | |
309 // Don't try to get the address of a vector if it's empty. | |
310 return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call( | |
311 var_, method_name.var_, 0, NULL, OutException(exception).get())); | |
312 } | |
313 } | |
314 | |
315 Var Var::Construct(uint32_t argc, Var* argv, Var* exception) const { | |
316 if (!has_interface<PPB_Var_Deprecated>()) | |
317 return Var(); | |
318 if (argc > 0) { | |
319 std::vector<PP_Var> args; | |
320 args.reserve(argc); | |
321 for (size_t i = 0; i < argc; i++) | |
322 args.push_back(argv[i].var_); | |
323 return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Construct( | |
324 var_, argc, &args[0], OutException(exception).get())); | |
325 } else { | |
326 // Don't try to get the address of a vector if it's empty. | |
327 return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Construct( | |
328 var_, 0, NULL, OutException(exception).get())); | |
329 } | |
330 } | |
331 | |
332 Var Var::Call(const Var& method_name, Var* exception) { | |
333 if (!has_interface<PPB_Var_Deprecated>()) | |
334 return Var(); | |
335 return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call( | |
336 var_, method_name.var_, 0, NULL, OutException(exception).get())); | |
337 } | |
338 | |
339 Var Var::Call(const Var& method_name, const Var& arg1, Var* exception) { | |
340 if (!has_interface<PPB_Var_Deprecated>()) | |
341 return Var(); | |
342 PP_Var args[1] = {arg1.var_}; | |
343 return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call( | |
344 var_, method_name.var_, 1, args, OutException(exception).get())); | |
345 } | |
346 | |
347 Var Var::Call(const Var& method_name, const Var& arg1, const Var& arg2, | |
348 Var* exception) { | |
349 if (!has_interface<PPB_Var_Deprecated>()) | |
350 return Var(); | |
351 PP_Var args[2] = {arg1.var_, arg2.var_}; | |
352 return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call( | |
353 var_, method_name.var_, 2, args, OutException(exception).get())); | |
354 } | |
355 | |
356 Var Var::Call(const Var& method_name, const Var& arg1, const Var& arg2, | |
357 const Var& arg3, Var* exception) { | |
358 if (!has_interface<PPB_Var_Deprecated>()) | |
359 return Var(); | |
360 PP_Var args[3] = {arg1.var_, arg2.var_, arg3.var_}; | |
361 return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call( | |
362 var_, method_name.var_, 3, args, OutException(exception).get())); | |
363 } | |
364 | |
365 Var Var::Call(const Var& method_name, const Var& arg1, const Var& arg2, | |
366 const Var& arg3, const Var& arg4, Var* exception) { | |
367 if (!has_interface<PPB_Var_Deprecated>()) | |
368 return Var(); | |
369 PP_Var args[4] = {arg1.var_, arg2.var_, arg3.var_, arg4.var_}; | |
370 return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call( | |
371 var_, method_name.var_, 4, args, OutException(exception).get())); | |
372 } | |
373 #endif | |
374 | |
375 std::string Var::DebugString() const { | 198 std::string Var::DebugString() const { |
376 char buf[256]; | 199 char buf[256]; |
377 if (is_undefined()) { | 200 if (is_undefined()) { |
378 snprintf(buf, sizeof(buf), "Var<UNDEFINED>"); | 201 snprintf(buf, sizeof(buf), "Var<UNDEFINED>"); |
379 } else if (is_null()) { | 202 } else if (is_null()) { |
380 snprintf(buf, sizeof(buf), "Var<NULL>"); | 203 snprintf(buf, sizeof(buf), "Var<NULL>"); |
381 } else if (is_bool()) { | 204 } else if (is_bool()) { |
382 snprintf(buf, sizeof(buf), AsBool() ? "Var<true>" : "Var<false>"); | 205 snprintf(buf, sizeof(buf), AsBool() ? "Var<true>" : "Var<false>"); |
383 } else if (is_int()) { | 206 } else if (is_int()) { |
384 // Note that the following static_cast is necessary because | 207 // Note that the following static_cast is necessary because |
(...skipping 12 matching lines...) Expand all Loading... |
397 str.append("..."); | 220 str.append("..."); |
398 } | 221 } |
399 snprintf(buf, sizeof(buf), format, str.c_str()); | 222 snprintf(buf, sizeof(buf), format, str.c_str()); |
400 } else if (is_object()) { | 223 } else if (is_object()) { |
401 snprintf(buf, sizeof(buf), "Var<OBJECT>"); | 224 snprintf(buf, sizeof(buf), "Var<OBJECT>"); |
402 } | 225 } |
403 return buf; | 226 return buf; |
404 } | 227 } |
405 | 228 |
406 } // namespace pp | 229 } // namespace pp |
OLD | NEW |