diff options
Diffstat (limited to 'ppapi/cpp/var.h')
-rw-r--r-- | ppapi/cpp/var.h | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/ppapi/cpp/var.h b/ppapi/cpp/var.h new file mode 100644 index 0000000..9109fef --- /dev/null +++ b/ppapi/cpp/var.h @@ -0,0 +1,205 @@ +// Copyright (c) 2010 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_VAR_H_ +#define PPAPI_CPP_VAR_H_ + +#include <string> +#include <vector> + +#include "ppapi/c/pp_var.h" + +namespace pp { + +namespace deprecated { +class ScriptableObject; +} + +class Var { + public: + struct Null {}; // Special value passed to constructor to make NULL. + + Var(); // PP_Var of type Undefined. + Var(Null); // PP_Var of type Null. + Var(bool b); + Var(int32_t i); + Var(double d); + Var(const char* utf8_str); // Must be encoded in UTF-8. + Var(const std::string& utf8_str); // Must be encoded in UTF-8. + + // This magic constructor is used when we've gotten a PP_Var as a return + // value that has already been addref'ed for us. + struct PassRef {}; + Var(PassRef, PP_Var var) { + var_ = var; + needs_release_ = true; + } + + // TODO(brettw): remove DontManage when this bug is fixed + // http://code.google.com/p/chromium/issues/detail?id=52105 + // This magic constructor is used when we've given a PP_Var as an input + // argument from somewhere and that reference is managing the reference + // count for us. The object will not be AddRef'ed or Release'd by this + // class instance.. + struct DontManage {}; + Var(DontManage, PP_Var var) { + var_ = var; + needs_release_ = false; + } + + // Takes ownership of the given pointer. + Var(deprecated::ScriptableObject* object); + + Var(const Var& other); + + virtual ~Var(); + + Var& operator=(const Var& other); + + bool operator==(const Var& other) const; + + bool is_undefined() const { return var_.type == PP_VARTYPE_UNDEFINED; } + bool is_null() const { return var_.type == PP_VARTYPE_NULL; } + bool is_bool() const { return var_.type == PP_VARTYPE_BOOL; } + bool is_string() const { return var_.type == PP_VARTYPE_STRING; } + bool is_object() const { return var_.type == PP_VARTYPE_OBJECT; } + + // IsInt and IsDouble return the internal representation. The JavaScript + // runtime may convert between the two as needed, so the distinction may + // not be relevant in all cases (int is really an optimization inside the + // runtime). So most of the time, you will want to check IsNumber. + bool is_int() const { return var_.type == PP_VARTYPE_INT32; } + bool is_double() const { return var_.type == PP_VARTYPE_DOUBLE; } + bool is_number() const { + return var_.type == PP_VARTYPE_INT32 || + var_.type == PP_VARTYPE_DOUBLE; + } + + // Assumes the internal representation IsBool. If it's not, it will assert + // in debug mode, and return false. + bool AsBool() const; + + // AsInt and AsDouble implicitly convert between ints and doubles. This is + // because JavaScript doesn't have a concept of ints and doubles, only + // numbers. The distinction between the two is an optimization inside the + // compiler. Since converting from a double to an int may be lossy, if you + // care about the distinction, either always work in doubles, or check + // !IsDouble() before calling AsInt(). + // + // These functions will assert in debug mode and return 0 if the internal + // representation is not IsNumber(). + int32_t AsInt() const; + double AsDouble() const; + + // This assumes the object is of type string. If it's not, it will assert + // in debug mode, and return an empty string. + std::string AsString() const; + + // 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; + Var 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); + Var Call(const Var& method_name, uint32_t argc, Var* argv, + Var* exception = NULL); + Var Construct(uint32_t argc, Var* argv, Var* exception = NULL) const; + + // Convenience functions for calling functions with small # of args. + Var Call(const Var& method_name, Var* exception = NULL); + Var Call(const Var& method_name, const Var& arg1, Var* exception = NULL); + Var Call(const Var& method_name, const Var& arg1, const Var& arg2, + Var* exception = NULL); + Var Call(const Var& method_name, const Var& arg1, const Var& arg2, + const Var& arg3, Var* exception = NULL); + Var Call(const Var& method_name, const Var& arg1, const Var& arg2, + const Var& arg3, const Var& arg4, Var* exception = NULL); + + // Returns a const reference to the PP_Var managed by this Var object. + const PP_Var& pp_var() const { + return var_; + } + + // Detaches from the internal PP_Var of this object, keeping the reference + // count the same. This is used when returning a PP_Var from an API function + // where the caller expects the return value to be AddRef'ed for it. + PP_Var Detach() { + PP_Var ret = var_; + var_ = PP_MakeUndefined(); + needs_release_ = false; + return ret; + } + + // Prints a short description "Var<X>" that can be used for logging, where + // "X" is the underlying scalar or "UNDEFINED" or "OBJ" as it does not call + // into the browser to get the object description. + std::string DebugString() const; + + // 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, Var::OutException(exception).get()); + // } + class OutException { + public: + OutException(Var* v) + : output_(v), + originally_had_exception_(v && v->is_null()) { + if (output_) + temp_ = output_->var_; + else + 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. + Var(void* non_scriptable_object_pointer); + + PP_Var var_; + bool needs_release_; +}; + +} // namespace pp + +#endif // PPAPI_CPP_VAR_H_ |