 Chromium Code Reviews
 Chromium Code Reviews Issue 6823016:
  Create a VarPrivate interface to contain the scripting helper functions of Var.  (Closed) 
  Base URL: svn://chrome-svn/chrome/trunk/src/
    
  
    Issue 6823016:
  Create a VarPrivate interface to contain the scripting helper functions of Var.  (Closed) 
  Base URL: svn://chrome-svn/chrome/trunk/src/| 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 #ifndef PPAPI_CPP_VAR_H_ | 5 #ifndef PPAPI_CPP_PRIVATE_VAR_PRIVATE_H_ | 
| 6 #define PPAPI_CPP_VAR_H_ | 6 #define PPAPI_CPP_PRIVATE_VAR_PRIVATE_H_ | 
| 7 | 7 | 
| 8 #include <string> | 8 #include "ppapi/cpp/var.h" | 
| 9 #include <vector> | |
| 10 | |
| 11 #include "ppapi/c/pp_module.h" | |
| 12 #include "ppapi/c/pp_var.h" | |
| 13 | 9 | 
| 14 namespace pp { | 10 namespace pp { | 
| 15 | 11 | 
| 16 class Instance; | 12 // VarPrivate is a version of Var that exposes the private scripting API. | 
| 13 // It's designed to be mostly interchangable with Var since most callers will | |
| 14 // be dealing with Vars from various places. | |
| 15 class VarPrivate : public Var { | |
| 16 public: | |
| 17 VarPrivate() : Var() {} | |
| 18 VarPrivate(Null) : Var(Null()) {} | |
| 19 VarPrivate(bool b) : Var(b) {} | |
| 20 VarPrivate(int32_t i) : Var(i) {} | |
| 21 VarPrivate(double d) : Var(d) {} | |
| 22 VarPrivate(const char* utf8_str) : Var(utf8_str) {} | |
| 23 VarPrivate(const std::string& utf8_str) : Var(utf8_str) {} | |
| 24 VarPrivate(PassRef, PP_Var var) : Var(PassRef(), var) {} | |
| 25 VarPrivate(DontManage, PP_Var var) : Var(DontManage(), var) {} | |
| 26 VarPrivate(Instance* instance, deprecated::ScriptableObject* object); | |
| 27 VarPrivate(const Var& other) : Var(other) {} | |
| 28 VarPrivate(const VarPrivate& other) : Var((const Var&)other) {} | |
| 
dmichael(do not use this one)
2011/04/08 22:16:28
Assuming we really do want conversion contructors,
 
brettw
2011/04/10 05:08:41
The conversion constructors are important for the
 
dmichael (off chromium)
2011/04/11 00:09:16
Makes sense.
 | |
| 17 | 29 | 
| 18 namespace deprecated { | 30 virtual ~VarPrivate() {} | 
| 19 class ScriptableObject; | |
| 20 } | |
| 21 | |
| 22 class Var { | |
| 23 public: | |
| 24 struct Null {}; // Special value passed to constructor to make NULL. | |
| 25 | |
| 26 Var(); // PP_Var of type Undefined. | |
| 27 Var(Null); // PP_Var of type Null. | |
| 28 Var(bool b); | |
| 29 Var(int32_t i); | |
| 30 Var(double d); | |
| 31 Var(const char* utf8_str); // Must be encoded in UTF-8. | |
| 32 Var(const std::string& utf8_str); // Must be encoded in UTF-8. | |
| 33 | |
| 34 // This magic constructor is used when we've gotten a PP_Var as a return | |
| 35 // value that has already been addref'ed for us. | |
| 36 struct PassRef {}; | |
| 37 Var(PassRef, PP_Var var) { | |
| 38 var_ = var; | |
| 39 needs_release_ = true; | |
| 40 } | |
| 41 | |
| 42 // TODO(brettw): remove DontManage when this bug is fixed | |
| 43 // http://code.google.com/p/chromium/issues/detail?id=52105 | |
| 44 // This magic constructor is used when we've given a PP_Var as an input | |
| 45 // argument from somewhere and that reference is managing the reference | |
| 46 // count for us. The object will not be AddRef'ed or Release'd by this | |
| 47 // class instance.. | |
| 48 struct DontManage {}; | |
| 49 Var(DontManage, PP_Var var) { | |
| 50 var_ = var; | |
| 51 needs_release_ = false; | |
| 52 } | |
| 53 | |
| 54 // Takes ownership of the given pointer. | |
| 55 Var(Instance* instance, deprecated::ScriptableObject* object); | |
| 56 | |
| 57 Var(const Var& other); | |
| 58 | |
| 59 virtual ~Var(); | |
| 60 | |
| 61 Var& operator=(const Var& other); | |
| 62 | |
| 63 bool operator==(const Var& other) const; | |
| 64 | |
| 65 bool is_undefined() const { return var_.type == PP_VARTYPE_UNDEFINED; } | |
| 66 bool is_null() const { return var_.type == PP_VARTYPE_NULL; } | |
| 67 bool is_bool() const { return var_.type == PP_VARTYPE_BOOL; } | |
| 68 bool is_string() const { return var_.type == PP_VARTYPE_STRING; } | |
| 69 bool is_object() const { return var_.type == PP_VARTYPE_OBJECT; } | |
| 70 | |
| 71 // IsInt and IsDouble return the internal representation. The JavaScript | |
| 72 // runtime may convert between the two as needed, so the distinction may | |
| 73 // not be relevant in all cases (int is really an optimization inside the | |
| 74 // runtime). So most of the time, you will want to check IsNumber. | |
| 75 bool is_int() const { return var_.type == PP_VARTYPE_INT32; } | |
| 76 bool is_double() const { return var_.type == PP_VARTYPE_DOUBLE; } | |
| 77 bool is_number() const { | |
| 78 return var_.type == PP_VARTYPE_INT32 || | |
| 79 var_.type == PP_VARTYPE_DOUBLE; | |
| 80 } | |
| 81 | |
| 82 // Assumes the internal representation IsBool. If it's not, it will assert | |
| 83 // in debug mode, and return false. | |
| 84 bool AsBool() const; | |
| 85 | |
| 86 // AsInt and AsDouble implicitly convert between ints and doubles. This is | |
| 87 // because JavaScript doesn't have a concept of ints and doubles, only | |
| 88 // numbers. The distinction between the two is an optimization inside the | |
| 89 // compiler. Since converting from a double to an int may be lossy, if you | |
| 90 // care about the distinction, either always work in doubles, or check | |
| 91 // !IsDouble() before calling AsInt(). | |
| 92 // | |
| 93 // These functions will assert in debug mode and return 0 if the internal | |
| 94 // representation is not IsNumber(). | |
| 95 int32_t AsInt() const; | |
| 96 double AsDouble() const; | |
| 97 | |
| 98 // This assumes the object is of type string. If it's not, it will assert | |
| 99 // in debug mode, and return an empty string. | |
| 100 std::string AsString() const; | |
| 101 | 31 | 
| 102 // This assumes the object is of type object. If it's not, it will assert in | 32 // This assumes the object is of type object. If it's not, it will assert in | 
| 103 // debug mode. If it is not an object or not a ScriptableObject type, returns | 33 // debug mode. If it is not an object or not a ScriptableObject type, returns | 
| 104 // NULL. | 34 // NULL. | 
| 105 deprecated::ScriptableObject* AsScriptableObject() const; | 35 deprecated::ScriptableObject* AsScriptableObject() const; | 
| 106 | 36 | 
| 107 bool HasProperty(const Var& name, Var* exception = NULL) const; | 37 bool HasProperty(const Var& name, Var* exception = NULL) const; | 
| 108 bool HasMethod(const Var& name, Var* exception = NULL) const; | 38 bool HasMethod(const Var& name, Var* exception = NULL) const; | 
| 109 Var GetProperty(const Var& name, Var* exception = NULL) const; | 39 VarPrivate GetProperty(const Var& name, Var* exception = NULL) const; | 
| 110 void GetAllPropertyNames(std::vector<Var>* properties, | 40 void GetAllPropertyNames(std::vector<Var>* properties, | 
| 111 Var* exception = NULL) const; | 41 Var* exception = NULL) const; | 
| 112 void SetProperty(const Var& name, const Var& value, Var* exception = NULL); | 42 void SetProperty(const Var& name, const Var& value, Var* exception = NULL); | 
| 113 void RemoveProperty(const Var& name, Var* exception = NULL); | 43 void RemoveProperty(const Var& name, Var* exception = NULL); | 
| 114 Var Call(const Var& method_name, uint32_t argc, Var* argv, | 44 VarPrivate Call(const Var& method_name, uint32_t argc, Var* argv, | 
| 115 Var* exception = NULL); | 45 Var* exception = NULL); | 
| 116 Var Construct(uint32_t argc, Var* argv, Var* exception = NULL) const; | 46 VarPrivate Construct(uint32_t argc, Var* argv, Var* exception = NULL) const; | 
| 117 | 47 | 
| 118 // Convenience functions for calling functions with small # of args. | 48 // Convenience functions for calling functions with small # of args. | 
| 119 Var Call(const Var& method_name, Var* exception = NULL); | 49 VarPrivate Call(const Var& method_name, Var* exception = NULL); | 
| 120 Var Call(const Var& method_name, const Var& arg1, Var* exception = NULL); | 50 VarPrivate Call(const Var& method_name, const Var& arg1, | 
| 121 Var Call(const Var& method_name, const Var& arg1, const Var& arg2, | 51 Var* exception = NULL); | 
| 122 Var* exception = NULL); | 52 VarPrivate Call(const Var& method_name, const Var& arg1, const Var& arg2, | 
| 123 Var Call(const Var& method_name, const Var& arg1, const Var& arg2, | 53 Var* exception = NULL); | 
| 124 const Var& arg3, Var* exception = NULL); | 54 VarPrivate Call(const Var& method_name, const Var& arg1, const Var& arg2, | 
| 125 Var Call(const Var& method_name, const Var& arg1, const Var& arg2, | 55 const Var& arg3, Var* exception = NULL); | 
| 126 const Var& arg3, const Var& arg4, Var* exception = NULL); | 56 VarPrivate Call(const Var& method_name, const Var& arg1, const Var& arg2, | 
| 127 | 57 const Var& arg3, const Var& arg4, Var* exception = NULL); | 
| 128 // Returns a const reference to the PP_Var managed by this Var object. | |
| 129 const PP_Var& pp_var() const { | |
| 130 return var_; | |
| 131 } | |
| 132 | |
| 133 // Detaches from the internal PP_Var of this object, keeping the reference | |
| 134 // count the same. This is used when returning a PP_Var from an API function | |
| 135 // where the caller expects the return value to be AddRef'ed for it. | |
| 136 PP_Var Detach() { | |
| 137 PP_Var ret = var_; | |
| 138 var_ = PP_MakeUndefined(); | |
| 139 needs_release_ = false; | |
| 140 return ret; | |
| 141 } | |
| 142 | |
| 143 // Prints a short description "Var<X>" that can be used for logging, where | |
| 144 // "X" is the underlying scalar or "UNDEFINED" or "OBJ" as it does not call | |
| 145 // into the browser to get the object description. | |
| 146 std::string DebugString() const; | |
| 147 | 58 | 
| 148 // For use when calling the raw C PPAPI when using the C++ Var as a possibly | 59 // For use when calling the raw C PPAPI when using the C++ Var as a possibly | 
| 149 // NULL exception. This will handle getting the address of the internal value | 60 // NULL exception. This will handle getting the address of the internal value | 
| 150 // out if it's non-NULL and fixing up the reference count. | 61 // out if it's non-NULL and fixing up the reference count. | 
| 151 // | 62 // | 
| 152 // Danger: this will only work for things with exception semantics, i.e. that | 63 // Danger: this will only work for things with exception semantics, i.e. that | 
| 153 // the value will not be changed if it's a non-undefined exception. Otherwise, | 64 // the value will not be changed if it's a non-undefined exception. Otherwise, | 
| 154 // this class will mess up the refcounting. | 65 // this class will mess up the refcounting. | 
| 155 // | 66 // | 
| 156 // This is a bit subtle: | 67 // This is a bit subtle: | 
| 157 // - If NULL is passed, we return NULL from get() and do nothing. | 68 // - If NULL is passed, we return NULL from get() and do nothing. | 
| 158 // | 69 // | 
| 159 // - If a undefined value is passed, we return the address of a undefined var | 70 // - If a undefined value is passed, we return the address of a undefined var | 
| 160 // from get and have the output value take ownership of that var. | 71 // from get and have the output value take ownership of that var. | 
| 161 // | 72 // | 
| 162 // - If a non-undefined value is passed, we return the address of that var | 73 // - If a non-undefined value is passed, we return the address of that var | 
| 163 // from get, and nothing else should change. | 74 // from get, and nothing else should change. | 
| 164 // | 75 // | 
| 165 // Example: | 76 // Example: | 
| 166 // void FooBar(a, b, Var* exception = NULL) { | 77 // void FooBar(a, b, Var* exception = NULL) { | 
| 167 // foo_interface->Bar(a, b, Var::OutException(exception).get()); | 78 // foo_interface->Bar(a, b, VarPrivate::OutException(exception).get()); | 
| 168 // } | 79 // } | 
| 169 class OutException { | 80 class OutException { | 
| 170 public: | 81 public: | 
| 171 OutException(Var* v) | 82 OutException(Var* v) | 
| 172 : output_(v), | 83 : output_(v), | 
| 173 originally_had_exception_(v && v->is_null()) { | 84 originally_had_exception_(v && v->is_null()) { | 
| 174 if (output_) { | 85 if (output_) { | 
| 175 temp_ = output_->var_; | 86 temp_ = output_->pp_var(); | 
| 176 } else { | 87 } else { | 
| 177 temp_.padding = 0; | 88 temp_.padding = 0; | 
| 178 temp_.type = PP_VARTYPE_UNDEFINED; | 89 temp_.type = PP_VARTYPE_UNDEFINED; | 
| 179 } | 90 } | 
| 180 } | 91 } | 
| 181 ~OutException() { | 92 ~OutException() { | 
| 182 if (output_ && !originally_had_exception_) | 93 if (output_ && !originally_had_exception_) | 
| 183 *output_ = Var(PassRef(), temp_); | 94 *output_ = Var(PassRef(), temp_); | 
| 184 } | 95 } | 
| 185 | 96 | 
| 186 PP_Var* get() { | 97 PP_Var* get() { | 
| 187 if (output_) | 98 if (output_) | 
| 188 return &temp_; | 99 return &temp_; | 
| 189 return NULL; | 100 return NULL; | 
| 190 } | 101 } | 
| 191 | 102 | 
| 192 private: | 103 private: | 
| 193 Var* output_; | 104 Var* output_; | 
| 194 bool originally_had_exception_; | 105 bool originally_had_exception_; | 
| 195 PP_Var temp_; | 106 PP_Var temp_; | 
| 196 }; | 107 }; | 
| 197 | 108 | 
| 198 private: | 109 private: | 
| 199 // Prevent an arbitrary pointer argument from being implicitly converted to | 110 // Prevent an arbitrary pointer argument from being implicitly converted to | 
| 200 // a bool at Var construction. If somebody makes such a mistake, (s)he will | 111 // a bool at Var construction. If somebody makes such a mistake, (s)he will | 
| 201 // get a compilation error. | 112 // get a compilation error. | 
| 202 Var(void* non_scriptable_object_pointer); | 113 VarPrivate(void* non_scriptable_object_pointer); | 
| 203 | |
| 204 PP_Var var_; | |
| 205 bool needs_release_; | |
| 206 }; | 114 }; | 
| 207 | 115 | 
| 208 } // namespace pp | 116 } // namespace pp | 
| 209 | 117 | 
| 210 #endif // PPAPI_CPP_VAR_H_ | 118 #endif // PPAPI_CPP_PRIVATE_VAR_PRIVATE_H_ | 
| OLD | NEW |