1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
|
// Copyright 2012 The Chromium Authors
// 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 <stdint.h>
#include <string>
#include "ppapi/c/pp_var.h"
#include "ppapi/cpp/pass_ref.h"
#include "ppapi/cpp/resource.h"
/// @file
/// This file defines the API for handling the passing of data types between
/// your module and the page.
namespace pp {
/// A generic type used for passing data types between the module and the page.
class Var {
public:
/// Special value passed to constructor to make <code>NULL</code>.
struct Null {};
/// Default constructor. Creates a <code>Var</code> of type
/// <code>Undefined</code>.
Var();
/// A constructor used to create a <code>Var</code> of type <code>Null</code>.
Var(Null);
/// A constructor used to create a <code>Var</code> of type <code>Bool</code>.
///
/// @param[in] b A boolean value.
Var(bool b);
/// A constructor used to create a 32 bit integer <code>Var</code>.
///
/// @param[in] i A 32 bit integer value.
Var(int32_t i);
/// A constructor used to create a double value <code>Var</code>.
///
/// @param[in] d A double value.
Var(double d);
/// A constructor used to create a UTF-8 character <code>Var</code>.
Var(const char* utf8_str); // Must be encoded in UTF-8.
/// A constructor used to create a UTF-8 character <code>Var</code>.
Var(const std::string& utf8_str); // Must be encoded in UTF-8.
/// A constructor used to create a resource <code>Var</code>.
explicit Var(const pp::Resource& resource);
/// A constructor used when you have received a <code>Var</code> as a return
/// value that has had its reference count incremented for you.
///
/// You will not normally need to use this constructor because
/// the reference count will not normally be incremented for you.
Var(PassRef, const PP_Var& var) {
var_ = var;
is_managed_ = true;
}
/// A constructor that increments the reference count.
explicit Var(const PP_Var& var);
struct DontManage {};
/// This constructor is used when we've given a <code>PP_Var</code> as an
/// input argument from somewhere and that reference is managing the
/// reference count for us. The object will not have its reference count
/// increased or decreased by this class instance.
///
/// @param[in] var A <code>Var</code>.
Var(DontManage, const PP_Var& var) {
var_ = var;
is_managed_ = false;
}
/// A constructor for copying a <code>Var</code>.
Var(const Var& other);
/// Destructor.
virtual ~Var();
/// This function assigns one <code>Var</code> to another <code>Var</code>.
///
/// @param[in] other The <code>Var</code> to be assigned.
///
/// @return A resulting <code>Var</code>.
virtual Var& operator=(const Var& other);
/// This function compares object identity (rather than value identity) for
/// objects, dictionaries, and arrays
///
/// @param[in] other The <code>Var</code> to be compared to this Var.
///
/// @return true if the <code>other</code> <code>Var</code> is the same as
/// this <code>Var</code>, otherwise false.
bool operator==(const Var& other) const;
/// This function determines if this <code>Var</code> is an undefined value.
///
/// @return true if this <code>Var</code> is undefined, otherwise false.
bool is_undefined() const { return var_.type == PP_VARTYPE_UNDEFINED; }
/// This function determines if this <code>Var</code> is a null value.
///
/// @return true if this <code>Var</code> is null, otherwise false.
bool is_null() const { return var_.type == PP_VARTYPE_NULL; }
/// This function determines if this <code>Var</code> is a bool value.
///
/// @return true if this <code>Var</code> is a bool, otherwise false.
bool is_bool() const { return var_.type == PP_VARTYPE_BOOL; }
/// This function determines if this <code>Var</code> is a string value.
///
/// @return true if this <code>Var</code> is a string, otherwise false.
bool is_string() const { return var_.type == PP_VARTYPE_STRING; }
/// This function determines if this <code>Var</code> is an object.
///
/// @return true if this <code>Var</code> is an object, otherwise false.
bool is_object() const { return var_.type == PP_VARTYPE_OBJECT; }
/// This function determines if this <code>Var</code> is an array.
///
/// @return true if this <code>Var</code> is an array, otherwise false.
bool is_array() const { return var_.type == PP_VARTYPE_ARRAY; }
/// This function determines if this <code>Var</code> is a dictionary.
///
/// @return true if this <code>Var</code> is a dictionary, otherwise false.
bool is_dictionary() const { return var_.type == PP_VARTYPE_DICTIONARY; }
/// This function determines if this <code>Var</code> is a resource.
///
/// @return true if this <code>Var</code> is a resource, otherwise false.
bool is_resource() const { return var_.type == PP_VARTYPE_RESOURCE; }
/// This function determines if this <code>Var</code> is an integer value.
/// The <code>is_int</code> function returns 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 is_number().
///
/// @return true if this <code>Var</code> is an integer, otherwise false.
bool is_int() const { return var_.type == PP_VARTYPE_INT32; }
/// This function determines if this <code>Var</code> is a double value.
/// The <code>is_double</code> function returns 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 is_number().
///
/// @return true if this <code>Var</code> is a double, otherwise false.
bool is_double() const { return var_.type == PP_VARTYPE_DOUBLE; }
/// This function determines if this <code>Var</code> is a number.
///
/// @return true if this <code>Var</code> is an int32_t or double number,
/// otherwise false.
bool is_number() const {
return var_.type == PP_VARTYPE_INT32 ||
var_.type == PP_VARTYPE_DOUBLE;
}
/// This function determines if this <code>Var</code> is an ArrayBuffer.
bool is_array_buffer() const { return var_.type == PP_VARTYPE_ARRAY_BUFFER; }
/// AsBool() converts this <code>Var</code> to a bool. Assumes the
/// internal representation is_bool(). If it's not, it will assert in debug
/// mode, and return false.
///
/// @return A bool version of this <code>Var</code>.
bool AsBool() const;
/// AsInt() converts this <code>Var</code> to an int32_t. This function
/// is required 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
/// !is_double() before calling AsInt().
///
/// These functions will assert in debug mode and return 0 if the internal
/// representation is not is_number().
///
/// @return An int32_t version of this <code>Var</code>.
int32_t AsInt() const;
/// AsDouble() converts this <code>Var</code> to a double. This function is
/// necessary 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
/// !is_double() before calling AsInt().
///
/// These functions will assert in debug mode and return 0 if the internal
/// representation is not is_number().
///
/// @return An double version of this <code>Var</code>.
double AsDouble() const;
/// AsString() converts this <code>Var</code> to a string. If this object is
/// not a string, it will assert in debug mode, and return an empty string.
///
/// @return A string version of this <code>Var</code>.
std::string AsString() const;
/// Gets the resource contained in the var. If this object is not a resource,
/// it will assert in debug mode, and return a null resource.
///
/// @return The <code>pp::Resource</code> that is contained in the var.
pp::Resource AsResource() const;
/// This function returns the internal <code>PP_Var</code>
/// managed by this <code>Var</code> object.
///
/// @return A const reference to a <code>PP_Var</code>.
const PP_Var& pp_var() const {
return var_;
}
/// Detach() detaches from the internal <code>PP_Var</code> of this
/// object, keeping the reference count the same. This is used when returning
/// a <code>PP_Var</code> from an API function where the caller expects the
/// return value to have the reference count incremented for it.
///
/// @return A detached version of this object without affecting the reference
/// count.
PP_Var Detach() {
PP_Var ret = var_;
var_ = PP_MakeUndefined();
is_managed_ = true;
return ret;
}
/// DebugString() returns 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.
///
/// @return A string displaying the value of this <code>Var</code>. This
/// function is used for debugging.
std::string DebugString() const;
/// This class is used when calling the raw C PPAPI when using the C++
/// <code>Var</code> as a possible NULL exception. This class will handle
/// getting the address of the internal value out if it's non-NULL and
/// fixing up the reference count.
///
/// <strong>Warning:</strong> 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:
/// A constructor.
OutException(Var* v)
: output_(v),
originally_had_exception_(v && !v->is_undefined()) {
if (output_) {
temp_ = output_->var_;
} else {
temp_.padding = 0;
temp_.type = PP_VARTYPE_UNDEFINED;
}
}
/// Destructor.
~OutException() {
if (output_ && !originally_had_exception_)
*output_ = Var(PASS_REF, temp_);
}
PP_Var* get() {
if (output_)
return &temp_;
return NULL;
}
private:
Var* output_;
bool originally_had_exception_;
PP_Var temp_;
};
protected:
PP_Var var_;
// |is_managed_| indicates if the instance manages |var_|.
// You need to check if |var_| is refcounted to call Release().
bool is_managed_;
private:
// Prevent an arbitrary pointer argument from being implicitly converted to
// a bool at Var construction. If somebody makes such a mistake, they will
// get a compilation error.
Var(void* non_scriptable_object_pointer);
};
} // namespace pp
#endif // PPAPI_CPP_VAR_H_
|