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