Gnash
0.8.10
|
00001 // 00002 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 00003 // Free Software Foundation, Inc 00004 // 00005 // This program is free software; you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation; either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with this program; if not, write to the Free Software 00017 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 00019 #ifndef GNASH_AS_VALUE_H 00020 #define GNASH_AS_VALUE_H 00021 00022 #include "dsodefs.h" 00023 #include "CharacterProxy.h" 00024 00025 #include <limits> 00026 #include <string> 00027 #include <boost/variant.hpp> 00028 #include <iosfwd> // for inlined output operator 00029 #include <boost/type_traits/is_floating_point.hpp> 00030 #include <boost/utility/enable_if.hpp> 00031 #include <boost/cstdint.hpp> 00032 00033 #include "utility.h" // UNUSED 00034 00035 // Forward declarations 00036 namespace gnash { 00037 class VM; 00038 class as_object; 00039 class Global_as; 00040 class fn_call; 00041 class as_function; 00042 class MovieClip; 00043 class DisplayObject; 00044 namespace amf { 00045 class Writer; 00046 } 00047 } 00048 00049 namespace gnash { 00050 00051 00052 // NaN constant for use in as_value implementation 00053 static const double NaN = std::numeric_limits<double>::quiet_NaN(); 00054 00055 // The following template works just like its C counterpart, with added 00056 // type safety (i.e., they will only compile for floating point arguments). 00057 template <typename T> 00058 inline bool 00059 isNaN(const T& num, typename boost::enable_if<boost::is_floating_point<T> >:: 00060 type* dummy = 0) 00061 { 00062 UNUSED(dummy); 00063 return num != num; 00064 } 00065 00066 template <typename T> 00067 inline bool 00068 isInf(const T& num) 00069 { 00070 return isNaN(num - num); 00071 } 00072 00073 00075 enum primitive_types 00076 { 00077 PTYPE_STRING, 00078 PTYPE_NUMBER, 00079 PTYPE_BOOLEAN 00080 }; 00081 00083 // 00085 // 00088 // 00091 // 00097 // 00103 // 00106 class as_value 00107 { 00108 00109 public: 00110 00111 // The exception type should always be one greater than the normal type. 00112 enum AsType 00113 { 00114 UNDEFINED, 00115 UNDEFINED_EXCEPT, 00116 NULLTYPE, 00117 NULLTYPE_EXCEPT, 00118 BOOLEAN, 00119 BOOLEAN_EXCEPT, 00120 STRING, 00121 STRING_EXCEPT, 00122 NUMBER, 00123 NUMBER_EXCEPT, 00124 OBJECT, 00125 OBJECT_EXCEPT, 00126 DISPLAYOBJECT, 00127 DISPLAYOBJECT_EXCEPT 00128 }; 00129 00131 DSOEXPORT as_value() 00132 : 00133 _type(UNDEFINED), 00134 _value(boost::blank()) 00135 { 00136 } 00137 00139 DSOEXPORT as_value(const as_value& v) 00140 : 00141 _type(v._type), 00142 _value(v._value) 00143 { 00144 } 00145 00146 ~as_value() {} 00147 00149 DSOEXPORT as_value(const char* str) 00150 : 00151 _type(STRING), 00152 _value(std::string(str)) 00153 {} 00154 00156 DSOEXPORT as_value(const std::string& str) 00157 : 00158 _type(STRING), 00159 _value(std::string(str)) 00160 {} 00161 00163 template <typename T> 00164 as_value(T val, typename boost::enable_if<boost::is_same<bool, T> >::type* 00165 dummy = 0) 00166 : 00167 _type(BOOLEAN), 00168 _value(val) 00169 { 00170 UNUSED(dummy); 00171 } 00172 00174 as_value(double num) 00175 : 00176 _type(NUMBER), 00177 _value(num) 00178 {} 00179 00181 as_value(as_object* obj) 00182 : 00183 _type(UNDEFINED) 00184 { 00185 set_as_object(obj); 00186 } 00187 00189 DSOEXPORT as_value& operator=(const as_value& v) 00190 { 00191 _type = v._type; 00192 _value = v._value; 00193 return *this; 00194 } 00195 00196 friend std::ostream& operator<<(std::ostream& o, const as_value&); 00197 00199 const char* typeOf() const; 00200 00202 bool is_function() const; 00203 00205 bool is_string() const { 00206 return _type == STRING; 00207 } 00208 00210 bool is_number() const { 00211 return _type == NUMBER; 00212 } 00213 00215 // 00217 bool is_object() const { 00218 return _type == OBJECT || _type == DISPLAYOBJECT; 00219 } 00220 00222 bool is_sprite() const { 00223 return _type == DISPLAYOBJECT; 00224 } 00225 00227 // 00232 // 00234 std::string to_string(int version = 7) const; 00235 00237 // 00239 double to_number(int version) const; 00240 00242 // 00244 bool to_bool(int version) const; 00245 00247 // 00249 // 00256 // 00260 as_object* to_object(VM& vm) const; 00261 00263 // 00266 as_object* get_object() const; 00267 00269 // 00272 // 00275 MovieClip* toMovieClip(bool skipRebinding = false) const; 00276 00278 // 00281 // 00292 DisplayObject* toDisplayObject(bool skipRebinding = false) const; 00293 00295 // 00298 as_function* to_function() const; 00299 00300 AsType defaultPrimitive(int version) const; 00301 00303 // 00305 // 00314 as_value to_primitive(AsType hint) const; 00315 00317 void set_string(const std::string& str); 00318 00320 void set_double(double val); 00321 00323 void set_bool(bool val); 00324 00326 void set_as_object(as_object* obj); 00327 00329 void set_undefined(); 00330 00332 void set_null(); 00333 00334 bool is_undefined() const { 00335 return (_type == UNDEFINED); 00336 } 00337 00338 bool is_null() const { 00339 return (_type == NULLTYPE); 00340 } 00341 00342 bool is_bool() const { 00343 return (_type == BOOLEAN); 00344 } 00345 00346 bool is_exception() const { 00347 return (_type == UNDEFINED_EXCEPT || _type == NULLTYPE_EXCEPT 00348 || _type == BOOLEAN_EXCEPT || _type == NUMBER_EXCEPT 00349 || _type == OBJECT_EXCEPT || _type == DISPLAYOBJECT_EXCEPT 00350 || _type == STRING_EXCEPT); 00351 } 00352 00353 // Flag or unflag an as_value as an exception -- this gets flagged 00354 // when an as_value is 'thrown'. 00355 void flag_exception() { 00356 if (!is_exception()) { 00357 _type = static_cast<AsType>(static_cast<int>(_type) + 1); 00358 } 00359 } 00360 00361 void unflag_exception() { 00362 if (is_exception()) { 00363 _type = static_cast<AsType>(static_cast<int>(_type) - 1); 00364 } 00365 } 00366 00368 // 00371 bool strictly_equals(const as_value& v) const; 00372 00374 // 00384 bool equals(const as_value& v, int version) const; 00385 00387 // 00389 void setReachable() const; 00390 00392 // 00407 bool writeAMF0(amf::Writer& w) const; 00408 00409 private: 00410 00412 // 00419 typedef boost::variant<boost::blank, 00420 double, 00421 bool, 00422 as_object*, 00423 CharacterProxy, 00424 std::string> 00425 AsValueType; 00426 00428 bool operator==(const as_value& v) const; 00429 00431 bool operator!=(const as_value& v) const; 00432 00434 // 00437 bool equalsSameType(const as_value& v) const; 00438 00439 AsType _type; 00440 00441 AsValueType _value; 00442 00444 // 00446 as_object* getObj() const; 00447 00449 // 00451 DisplayObject* getCharacter(bool skipRebinding = false) const; 00452 00454 // 00456 CharacterProxy getCharacterProxy() const; 00457 00459 // 00461 double getNum() const { 00462 assert(_type == NUMBER); 00463 return boost::get<double>(_value); 00464 } 00465 00467 // 00469 bool getBool() const { 00470 assert(_type == BOOLEAN); 00471 return boost::get<bool>(_value); 00472 } 00473 00475 // 00477 const std::string& getStr() const { 00478 assert(_type == STRING); 00479 return boost::get<std::string>(_value); 00480 } 00481 00482 }; 00483 00485 std::ostream& operator<<(std::ostream& os, const as_value& v); 00486 00488 // 00489 // Printing formats: 00490 // 00491 // If _val > 1, Print up to 15 significant digits, then switch 00492 // to scientific notation, rounding at the last place and 00493 // omitting trailing zeroes. 00494 // For values < 1, print up to 4 leading zeroes after the 00495 // decimal point, then switch to scientific notation with up 00496 // to 15 significant digits, rounding with no trailing zeroes 00497 // If the value is negative, just add a '-' to the start; this 00498 // does not affect the precision of the printed value. 00499 // 00500 // This almost corresponds to iomanip's std::setprecision(15) 00501 // format, except that iomanip switches to scientific notation 00502 // at e-05 not e-06, and always prints at least two digits for the exponent. 00503 std::string doubleToString(double val, int radix = 10); 00504 00508 // 00518 bool parseNonDecimalInt(const std::string& s, double& d, bool whole = true); 00519 00521 inline void 00522 setNaN(as_value& v) { 00523 v.set_double(NaN); 00524 } 00525 00526 } // namespace gnash 00527 00528 #endif // GNASH_AS_VALUE_H 00529 00530 // Local Variables: 00531 // mode: C++ 00532 // indent-tabs-mode: nil 00533 // End: 00534