| 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 |