summaryrefslogtreecommitdiffstats
path: root/ppapi/cpp
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-11 04:27:47 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-11 04:27:47 +0000
commit9b6db26fcc22a7a4ec0510a93733b2e190d9e649 (patch)
treefff3f2610cab083b3093ab1052cad6202335ff59 /ppapi/cpp
parentb648e91bd6c911ed26d6c65048c4a597040359ed (diff)
downloadchromium_src-9b6db26fcc22a7a4ec0510a93733b2e190d9e649.zip
chromium_src-9b6db26fcc22a7a4ec0510a93733b2e190d9e649.tar.gz
chromium_src-9b6db26fcc22a7a4ec0510a93733b2e190d9e649.tar.bz2
Create a VarPrivate interface to contain the scripting helper functions of Var.
Currently, the old functions are left in Var. When people have a chance to move to this new API, we can delete them from Var. This also adds new enums for ARRAY and DICTIONARY vars, and makes the var C++ wrapper forward-compatible with them by refcounting any enums that it doesn't know about. Review URL: http://codereview.chromium.org/6823016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81068 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/cpp')
-rw-r--r--ppapi/cpp/dev/scriptable_object_deprecated.h3
-rw-r--r--ppapi/cpp/private/var_private.cc186
-rw-r--r--ppapi/cpp/private/var_private.h117
-rw-r--r--ppapi/cpp/var.cc7
-rw-r--r--ppapi/cpp/var.h8
5 files changed, 313 insertions, 8 deletions
diff --git a/ppapi/cpp/dev/scriptable_object_deprecated.h b/ppapi/cpp/dev/scriptable_object_deprecated.h
index 42ab466..3099977 100644
--- a/ppapi/cpp/dev/scriptable_object_deprecated.h
+++ b/ppapi/cpp/dev/scriptable_object_deprecated.h
@@ -11,8 +11,8 @@ struct PPP_Class_Deprecated;
namespace pp {
class Var;
+class VarPrivate;
}
-using pp::Var;
namespace pp {
@@ -77,6 +77,7 @@ class ScriptableObject {
private:
friend class ::pp::Var;
+ friend class ::pp::VarPrivate;
static const PPP_Class_Deprecated* GetClass();
// Unimplemented, copy and assigmnent is not allowed.
diff --git a/ppapi/cpp/private/var_private.cc b/ppapi/cpp/private/var_private.cc
new file mode 100644
index 0000000..c3da55d
--- /dev/null
+++ b/ppapi/cpp/private/var_private.cc
@@ -0,0 +1,186 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/private/var_private.h"
+
+#include "ppapi/c/dev/ppb_var_deprecated.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/logging.h"
+#include "ppapi/cpp/module_impl.h"
+#include "ppapi/cpp/dev/scriptable_object_deprecated.h"
+
+namespace pp {
+
+namespace {
+
+template <> const char* interface_name<PPB_Var_Deprecated>() {
+ return PPB_VAR_DEPRECATED_INTERFACE;
+}
+
+} // namespace
+
+using namespace deprecated;
+
+VarPrivate::VarPrivate(Instance* instance, ScriptableObject* object) {
+ if (has_interface<PPB_Var_Deprecated>()) {
+ var_ = get_interface<PPB_Var_Deprecated>()->CreateObject(
+ instance->pp_instance(), object->GetClass(), object);
+ needs_release_ = true;
+ } else {
+ var_.type = PP_VARTYPE_NULL;
+ var_.padding = 0;
+ needs_release_ = false;
+ }
+}
+
+ScriptableObject* VarPrivate::AsScriptableObject() const {
+ if (!is_object()) {
+ PP_NOTREACHED();
+ } else if (has_interface<PPB_Var_Deprecated>()) {
+ void* object = NULL;
+ if (get_interface<PPB_Var_Deprecated>()->IsInstanceOf(
+ var_, ScriptableObject::GetClass(), &object)) {
+ return reinterpret_cast<ScriptableObject*>(object);
+ }
+ }
+ return NULL;
+}
+
+bool VarPrivate::HasProperty(const Var& name, Var* exception) const {
+ if (!has_interface<PPB_Var_Deprecated>())
+ return false;
+ return get_interface<PPB_Var_Deprecated>()->HasProperty(
+ var_, name.pp_var(), OutException(exception).get());
+}
+
+bool VarPrivate::HasMethod(const Var& name, Var* exception) const {
+ if (!has_interface<PPB_Var_Deprecated>())
+ return false;
+ return get_interface<PPB_Var_Deprecated>()->HasMethod(
+ var_, name.pp_var(), OutException(exception).get());
+}
+
+VarPrivate VarPrivate::GetProperty(const Var& name, Var* exception) const {
+ if (!has_interface<PPB_Var_Deprecated>())
+ return Var();
+ return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->GetProperty(
+ var_, name.pp_var(), OutException(exception).get()));
+}
+
+void VarPrivate::GetAllPropertyNames(std::vector<Var>* properties,
+ Var* exception) const {
+ if (!has_interface<PPB_Var_Deprecated>())
+ return;
+ PP_Var* props = NULL;
+ uint32_t prop_count = 0;
+ get_interface<PPB_Var_Deprecated>()->GetAllPropertyNames(
+ var_, &prop_count, &props, OutException(exception).get());
+ if (!prop_count)
+ return;
+ properties->resize(prop_count);
+ for (uint32_t i = 0; i < prop_count; ++i) {
+ Var temp(PassRef(), props[i]);
+ (*properties)[i] = temp;
+ }
+ Module::Get()->core()->MemFree(props);
+}
+
+void VarPrivate::SetProperty(const Var& name, const Var& value,
+ Var* exception) {
+ if (!has_interface<PPB_Var_Deprecated>())
+ return;
+ get_interface<PPB_Var_Deprecated>()->SetProperty(
+ var_, name.pp_var(), value.pp_var(), OutException(exception).get());
+}
+
+void VarPrivate::RemoveProperty(const Var& name, Var* exception) {
+ if (!has_interface<PPB_Var_Deprecated>())
+ return;
+ get_interface<PPB_Var_Deprecated>()->RemoveProperty(
+ var_, name.pp_var(), OutException(exception).get());
+}
+
+VarPrivate VarPrivate::Call(const Var& method_name, uint32_t argc, Var* argv,
+ Var* exception) {
+ if (!has_interface<PPB_Var_Deprecated>())
+ return Var();
+ if (argc > 0) {
+ std::vector<PP_Var> args;
+ args.reserve(argc);
+ for (size_t i = 0; i < argc; i++)
+ args.push_back(argv[i].pp_var());
+ return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
+ var_, method_name.pp_var(), argc, &args[0],
+ OutException(exception).get()));
+ } else {
+ // Don't try to get the address of a vector if it's empty.
+ return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
+ var_, method_name.pp_var(), 0, NULL,
+ OutException(exception).get()));
+ }
+}
+
+VarPrivate VarPrivate::Construct(uint32_t argc, Var* argv,
+ Var* exception) const {
+ if (!has_interface<PPB_Var_Deprecated>())
+ return Var();
+ if (argc > 0) {
+ std::vector<PP_Var> args;
+ args.reserve(argc);
+ for (size_t i = 0; i < argc; i++)
+ args.push_back(argv[i].pp_var());
+ return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Construct(
+ var_, argc, &args[0], OutException(exception).get()));
+ } else {
+ // Don't try to get the address of a vector if it's empty.
+ return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Construct(
+ var_, 0, NULL, OutException(exception).get()));
+ }
+}
+
+VarPrivate VarPrivate::Call(const Var& method_name, Var* exception) {
+ if (!has_interface<PPB_Var_Deprecated>())
+ return Var();
+ return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
+ var_, method_name.pp_var(), 0, NULL, OutException(exception).get()));
+}
+
+VarPrivate VarPrivate::Call(const Var& method_name, const Var& arg1,
+ Var* exception) {
+ if (!has_interface<PPB_Var_Deprecated>())
+ return Var();
+ PP_Var args[1] = {arg1.pp_var()};
+ return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
+ var_, method_name.pp_var(), 1, args, OutException(exception).get()));
+}
+
+VarPrivate VarPrivate::Call(const Var& method_name, const Var& arg1,
+ const Var& arg2, Var* exception) {
+ if (!has_interface<PPB_Var_Deprecated>())
+ return Var();
+ PP_Var args[2] = {arg1.pp_var(), arg2.pp_var()};
+ return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
+ var_, method_name.pp_var(), 2, args, OutException(exception).get()));
+}
+
+VarPrivate VarPrivate::Call(const Var& method_name, const Var& arg1,
+ const Var& arg2, const Var& arg3, Var* exception) {
+ if (!has_interface<PPB_Var_Deprecated>())
+ return Var();
+ PP_Var args[3] = {arg1.pp_var(), arg2.pp_var(), arg3.pp_var()};
+ return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
+ var_, method_name.pp_var(), 3, args, OutException(exception).get()));
+}
+
+VarPrivate VarPrivate::Call(const Var& method_name, const Var& arg1,
+ const Var& arg2, const Var& arg3, const Var& arg4,
+ Var* exception) {
+ if (!has_interface<PPB_Var_Deprecated>())
+ return Var();
+ PP_Var args[4] = {arg1.pp_var(), arg2.pp_var(), arg3.pp_var(), arg4.pp_var()};
+ return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
+ var_, method_name.pp_var(), 4, args, OutException(exception).get()));
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/private/var_private.h b/ppapi/cpp/private/var_private.h
new file mode 100644
index 0000000..55068bc
--- /dev/null
+++ b/ppapi/cpp/private/var_private.h
@@ -0,0 +1,117 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_PRIVATE_VAR_PRIVATE_H_
+#define PPAPI_CPP_PRIVATE_VAR_PRIVATE_H_
+
+#include "ppapi/cpp/var.h"
+
+namespace pp {
+
+// VarPrivate is a version of Var that exposes the private scripting API.
+// It's designed to be mostly interchangable with Var since most callers will
+// be dealing with Vars from various places.
+class VarPrivate : public Var {
+ public:
+ VarPrivate() : Var() {}
+ VarPrivate(Null) : Var(Null()) {}
+ VarPrivate(bool b) : Var(b) {}
+ VarPrivate(int32_t i) : Var(i) {}
+ VarPrivate(double d) : Var(d) {}
+ VarPrivate(const char* utf8_str) : Var(utf8_str) {}
+ VarPrivate(const std::string& utf8_str) : Var(utf8_str) {}
+ VarPrivate(PassRef, PP_Var var) : Var(PassRef(), var) {}
+ VarPrivate(DontManage, PP_Var var) : Var(DontManage(), var) {}
+ VarPrivate(Instance* instance, deprecated::ScriptableObject* object);
+ VarPrivate(const Var& other) : Var(other) {}
+
+ virtual ~VarPrivate() {}
+
+ // This assumes the object is of type object. If it's not, it will assert in
+ // debug mode. If it is not an object or not a ScriptableObject type, returns
+ // NULL.
+ deprecated::ScriptableObject* AsScriptableObject() const;
+
+ bool HasProperty(const Var& name, Var* exception = NULL) const;
+ bool HasMethod(const Var& name, Var* exception = NULL) const;
+ VarPrivate GetProperty(const Var& name, Var* exception = NULL) const;
+ void GetAllPropertyNames(std::vector<Var>* properties,
+ Var* exception = NULL) const;
+ void SetProperty(const Var& name, const Var& value, Var* exception = NULL);
+ void RemoveProperty(const Var& name, Var* exception = NULL);
+ VarPrivate Call(const Var& method_name, uint32_t argc, Var* argv,
+ Var* exception = NULL);
+ VarPrivate Construct(uint32_t argc, Var* argv, Var* exception = NULL) const;
+
+ // Convenience functions for calling functions with small # of args.
+ VarPrivate Call(const Var& method_name, Var* exception = NULL);
+ VarPrivate Call(const Var& method_name, const Var& arg1,
+ Var* exception = NULL);
+ VarPrivate Call(const Var& method_name, const Var& arg1, const Var& arg2,
+ Var* exception = NULL);
+ VarPrivate Call(const Var& method_name, const Var& arg1, const Var& arg2,
+ const Var& arg3, Var* exception = NULL);
+ VarPrivate Call(const Var& method_name, const Var& arg1, const Var& arg2,
+ const Var& arg3, const Var& arg4, Var* exception = NULL);
+
+ // For use when calling the raw C PPAPI when using the C++ Var as a possibly
+ // NULL exception. This will handle getting the address of the internal value
+ // out if it's non-NULL and fixing up the reference count.
+ //
+ // Danger: this will only work for things with exception semantics, i.e. that
+ // the value will not be changed if it's a non-undefined exception. Otherwise,
+ // this class will mess up the refcounting.
+ //
+ // This is a bit subtle:
+ // - If NULL is passed, we return NULL from get() and do nothing.
+ //
+ // - If a undefined value is passed, we return the address of a undefined var
+ // from get and have the output value take ownership of that var.
+ //
+ // - If a non-undefined value is passed, we return the address of that var
+ // from get, and nothing else should change.
+ //
+ // Example:
+ // void FooBar(a, b, Var* exception = NULL) {
+ // foo_interface->Bar(a, b, VarPrivate::OutException(exception).get());
+ // }
+ class OutException {
+ public:
+ OutException(Var* v)
+ : output_(v),
+ originally_had_exception_(v && v->is_null()) {
+ if (output_) {
+ temp_ = output_->pp_var();
+ } else {
+ temp_.padding = 0;
+ temp_.type = PP_VARTYPE_UNDEFINED;
+ }
+ }
+ ~OutException() {
+ if (output_ && !originally_had_exception_)
+ *output_ = Var(PassRef(), temp_);
+ }
+
+ PP_Var* get() {
+ if (output_)
+ return &temp_;
+ return NULL;
+ }
+
+ private:
+ Var* output_;
+ bool originally_had_exception_;
+ PP_Var temp_;
+ };
+
+ private:
+ // Prevent an arbitrary pointer argument from being implicitly converted to
+ // a bool at Var construction. If somebody makes such a mistake, (s)he will
+ // get a compilation error.
+ VarPrivate(void* non_scriptable_object_pointer);
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_PRIVATE_VAR_PRIVATE_H_
diff --git a/ppapi/cpp/var.cc b/ppapi/cpp/var.cc
index 09a91d8..00ef401 100644
--- a/ppapi/cpp/var.cc
+++ b/ppapi/cpp/var.cc
@@ -35,7 +35,7 @@ template <> const char* interface_name<PPB_Var_Deprecated>() {
// cross-process calls depending on the plugin. This is an optimization so we
// only do refcounting on the necessary objects.
inline bool NeedsRefcounting(const PP_Var& var) {
- return var.type == PP_VARTYPE_STRING || var.type == PP_VARTYPE_OBJECT;
+ return var.type > PP_VARTYPE_DOUBLE;
}
} // namespace
@@ -167,11 +167,8 @@ bool Var::operator==(const Var& other) const {
if (var_.value.as_id == other.var_.value.as_id)
return true;
return AsString() == other.AsString();
- // TODO(neb): Document that this is === and not ==, unlike strings.
- case PP_VARTYPE_OBJECT:
+ default: // Objects, arrays, dictionaries.
return var_.value.as_id == other.var_.value.as_id;
- default:
- return false;
}
}
diff --git a/ppapi/cpp/var.h b/ppapi/cpp/var.h
index 0154fd3..e113761 100644
--- a/ppapi/cpp/var.h
+++ b/ppapi/cpp/var.h
@@ -60,6 +60,8 @@ class Var {
Var& operator=(const Var& other);
+ // For objects, dictionaries, and arrays, this operator compares object
+ // identity rather than value identity.
bool operator==(const Var& other) const;
bool is_undefined() const { return var_.type == PP_VARTYPE_UNDEFINED; }
@@ -195,14 +197,16 @@ class Var {
PP_Var temp_;
};
+ protected:
+ PP_Var var_;
+ bool needs_release_;
+
private:
// Prevent an arbitrary pointer argument from being implicitly converted to
// a bool at Var construction. If somebody makes such a mistake, (s)he will
// get a compilation error.
Var(void* non_scriptable_object_pointer);
- PP_Var var_;
- bool needs_release_;
};
} // namespace pp