Gnash  0.8.11dev
as_value.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 // Free Software Foundation, Inc
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 
19 #ifndef GNASH_AS_VALUE_H
20 #define GNASH_AS_VALUE_H
21 
22 #include <limits>
23 #include <string>
24 #include <boost/variant.hpp>
25 #include <iosfwd> // for inlined output operator
26 #include <boost/utility/enable_if.hpp>
27 #include <boost/cstdint.hpp>
28 
29 #include "utility.h" // for UNUSED
30 #include "dsodefs.h" // for DSOTEXPORT
31 #include "CharacterProxy.h"
32 #include "GnashNumeric.h" // for isNaN
33 
34 
35 // Forward declarations
36 namespace gnash {
37  class VM;
38  class as_object;
39  class Global_as;
40  class fn_call;
41  class as_function;
42  class MovieClip;
43  class DisplayObject;
44  namespace amf {
45  class Writer;
46  }
47 }
48 
49 namespace gnash {
50 
51 
52 // NaN constant for use in as_value implementation
53 static const double NaN = std::numeric_limits<double>::quiet_NaN();
54 
55 template <typename T>
56 inline bool
57 isInf(const T& num)
58 {
59  return isNaN(num - num);
60 }
61 
62 
65 {
69 };
70 
72 //
74 //
77 //
80 //
86 //
92 //
95 class as_value
96 {
97 
98 public:
99 
100  // The exception type should always be one greater than the normal type.
101  enum AsType
102  {
117  };
118 
121  :
122  _type(UNDEFINED),
123  _value(boost::blank())
124  {
125  }
126 
129  :
130  _type(v._type),
131  _value(v._value)
132  {
133  }
134 
136 
138  DSOEXPORT as_value(const char* str)
139  :
140  _type(STRING),
141  _value(std::string(str))
142  {}
143 
145  DSOEXPORT as_value(const std::string& str)
146  :
147  _type(STRING),
148  _value(std::string(str))
149  {}
150 
152  template <typename T>
153  as_value(T val, typename boost::enable_if<boost::is_same<bool, T> >::type*
154  dummy = 0)
155  :
156  _type(BOOLEAN),
157  _value(val)
158  {
159  UNUSED(dummy);
160  }
161 
163  as_value(double num)
164  :
165  _type(NUMBER),
166  _value(num)
167  {}
168 
171  :
172  _type(UNDEFINED)
173  {
174  set_as_object(obj);
175  }
176 
179  {
180  _type = v._type;
181  _value = v._value;
182  return *this;
183  }
184 
185  friend std::ostream& operator<<(std::ostream& o, const as_value&);
186 
188  const char* typeOf() const;
189 
191  bool is_function() const;
192 
194  bool is_string() const {
195  return _type == STRING;
196  }
197 
199  bool is_number() const {
200  return _type == NUMBER;
201  }
202 
204  //
206  bool is_object() const {
207  return _type == OBJECT || _type == DISPLAYOBJECT;
208  }
209 
211  bool is_sprite() const {
212  return _type == DISPLAYOBJECT;
213  }
214 
216  //
221  //
223  DSOTEXPORT std::string to_string(int version = 7) const;
224 
226  //
228  double to_number(int version) const;
229 
231  //
233  DSOTEXPORT bool to_bool(int version) const;
234 
236  //
238  //
245  //
249  as_object* to_object(VM& vm) const;
250 
252  //
255  as_object* get_object() const;
256 
258  //
261  //
264  MovieClip* toMovieClip(bool skipRebinding = false) const;
265 
267  //
270  //
281  DisplayObject* toDisplayObject(bool skipRebinding = false) const;
282 
284  //
287  as_function* to_function() const;
288 
289  AsType defaultPrimitive(int version) const;
290 
292  //
294  //
303  as_value to_primitive(AsType hint) const;
304 
306  void set_string(const std::string& str);
307 
309  void set_double(double val);
310 
312  void set_bool(bool val);
313 
315  void set_as_object(as_object* obj);
316 
318  void set_undefined();
319 
321  void set_null();
322 
323  bool is_undefined() const {
324  return (_type == UNDEFINED);
325  }
326 
327  bool is_null() const {
328  return (_type == NULLTYPE);
329  }
330 
331  bool is_bool() const {
332  return (_type == BOOLEAN);
333  }
334 
335  bool is_exception() const {
336  return (_type == UNDEFINED_EXCEPT || _type == NULLTYPE_EXCEPT
337  || _type == BOOLEAN_EXCEPT || _type == NUMBER_EXCEPT
338  || _type == OBJECT_EXCEPT || _type == DISPLAYOBJECT_EXCEPT
339  || _type == STRING_EXCEPT);
340  }
341 
342  // Flag or unflag an as_value as an exception -- this gets flagged
343  // when an as_value is 'thrown'.
344  void flag_exception() {
345  if (!is_exception()) {
346  _type = static_cast<AsType>(static_cast<int>(_type) + 1);
347  }
348  }
349 
351  if (is_exception()) {
352  _type = static_cast<AsType>(static_cast<int>(_type) - 1);
353  }
354  }
355 
357  //
360  DSOTEXPORT bool strictly_equals(const as_value& v) const;
361 
363  //
373  DSOEXPORT bool equals(const as_value& v, int version) const;
374 
376  //
378  void setReachable() const;
379 
381  //
396  bool writeAMF0(amf::Writer& w) const;
397 
398 private:
399 
401  //
408  typedef boost::variant<boost::blank,
409  double,
410  bool,
411  as_object*,
413  std::string>
414  AsValueType;
415 
417  bool operator==(const as_value& v) const;
418 
420  bool operator!=(const as_value& v) const;
421 
423  //
426  bool equalsSameType(const as_value& v) const;
427 
428  AsType _type;
429 
430  AsValueType _value;
431 
433  //
435  as_object* getObj() const;
436 
438  //
440  DisplayObject* getCharacter(bool skipRebinding = false) const;
441 
443  //
445  CharacterProxy getCharacterProxy() const;
446 
448  //
450  double getNum() const {
451  assert(_type == NUMBER);
452  return boost::get<double>(_value);
453  }
454 
456  //
458  bool getBool() const {
459  assert(_type == BOOLEAN);
460  return boost::get<bool>(_value);
461  }
462 
464  //
466  const std::string& getStr() const {
467  assert(_type == STRING);
468  return boost::get<std::string>(_value);
469  }
470 
471 };
472 
474 DSOTEXPORT std::ostream& operator<<(std::ostream& os, const as_value& v);
475 
477 //
478 // Printing formats:
479 //
480 // If _val > 1, Print up to 15 significant digits, then switch
481 // to scientific notation, rounding at the last place and
482 // omitting trailing zeroes.
483 // For values < 1, print up to 4 leading zeroes after the
484 // decimal point, then switch to scientific notation with up
485 // to 15 significant digits, rounding with no trailing zeroes
486 // If the value is negative, just add a '-' to the start; this
487 // does not affect the precision of the printed value.
488 //
489 // This almost corresponds to iomanip's std::setprecision(15)
490 // format, except that iomanip switches to scientific notation
491 // at e-05 not e-06, and always prints at least two digits for the exponent.
492 std::string doubleToString(double val, int radix = 10);
493 
497 //
507 bool parseNonDecimalInt(const std::string& s, double& d, bool whole = true);
508 
510 inline void
512  v.set_double(NaN);
513 }
514 
515 } // namespace gnash
516 
517 #endif // GNASH_AS_VALUE_H
518 
519 // Local Variables:
520 // mode: C++
521 // indent-tabs-mode: nil
522 // End:
523