00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef GNASH_AS_VALUE_H
00021 #define GNASH_AS_VALUE_H
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include "gnashconfig.h"
00025 #endif
00026
00027 #include "tu_config.h"
00028 #include "smart_ptr.h"
00029
00030 #include <cmath>
00031 #include <limits>
00032 #include <string>
00033 #include <boost/variant.hpp>
00034 #include <ostream>
00035
00036 #include "string_table.h"
00037
00038 namespace gnash {
00039
00040 class as_object;
00041 class fn_call;
00042 class as_function;
00043 class sprite_instance;
00044 class character;
00045 class asNamespace;
00046 class asName;
00047
00048 #ifndef HAVE_ISFINITE
00049 # ifndef isfinite
00050 # define isfinite finite
00051 # endif
00052 #endif
00053
00054 #ifndef NAN
00055 # define NAN (std::numeric_limits<double>::quiet_NaN())
00056 #endif
00057
00058 #ifndef INFINITY
00059 # define INFINITY (std::numeric_limits<double>::infinity())
00060 #endif
00061
00062
00063 #ifndef isnan
00064 # define isnan(x) \
00065 (sizeof (x) == sizeof (long double) ? isnan_ld (x) \
00066 : sizeof (x) == sizeof (double) ? isnan_d (x) \
00067 : isnan_f (x))
00068 static inline int isnan_f (float x) { return x != x; }
00069 static inline int isnan_d (double x) { return x != x; }
00070 static inline int isnan_ld (long double x) { return x != x; }
00071 #endif
00072
00073 #ifndef isinf
00074 # define isinf(x) \
00075 (sizeof (x) == sizeof (long double) ? isinf_ld (x) \
00076 : sizeof (x) == sizeof (double) ? isinf_d (x) \
00077 : isinf_f (x))
00078 static inline int isinf_f (float x) { return isnan (x - x); }
00079 static inline int isinf_d (double x) { return isnan (x - x); }
00080 static inline int isinf_ld (long double x) { return isnan (x - x); }
00081 #endif
00082
00087
00088 #define PROPNAME(x) ( x )
00089
00091 enum primitive_types
00092 {
00093 PTYPE_STRING,
00094 PTYPE_NUMBER,
00095 PTYPE_BOOLEAN
00096 };
00097
00099
00104 class DSOEXPORT as_value
00105 {
00106 public:
00107 enum type
00108 {
00109
00110
00112 UNDEFINED,
00113 UNDEFINED_EXCEPT,
00114
00116 NULLTYPE,
00117 NULLTYPE_EXCEPT,
00118
00120 BOOLEAN,
00121 BOOLEAN_EXCEPT,
00122
00124 STRING,
00125 STRING_EXCEPT,
00126
00128 NUMBER,
00129 NUMBER_EXCEPT,
00130
00132 OBJECT,
00133 OBJECT_EXCEPT,
00134
00136 AS_FUNCTION,
00137 AS_FUNCTION_EXCEPT,
00138
00140 MOVIECLIP,
00141 MOVIECLIP_EXCEPT
00142 };
00143
00145 as_value();
00146
00148 as_value(const as_value& v);
00149
00151 as_value(const char* str);
00152
00154 as_value(const std::string& str);
00155
00157 as_value(bool val);
00158
00160 as_value(int val);
00161
00163 as_value(unsigned int val);
00164
00166 as_value(float val);
00167
00169 as_value(double val);
00170
00172 as_value(long val);
00173
00175 as_value(unsigned long val);
00176
00178 as_value(asNamespace &) {}
00179
00181
00187 as_value(as_object* obj);
00188
00190 as_value(boost::intrusive_ptr<as_object> obj);
00191
00193 as_value(as_function* func);
00194
00195 ~as_value();
00196
00198
00201 static std::string doubleToString(double val, int radix=10);
00202
00204
00208 void drop_refs() {}
00209
00211 const char* typeOf() const;
00212
00214 primitive_types ptype() const;
00215
00216
00217 bool conforms_to(string_table::key name);
00218
00222 bool is_function() const
00223 {
00224 return m_type == AS_FUNCTION;
00225 }
00226
00228 bool is_as_function() const
00229 {
00230 return m_type == AS_FUNCTION;
00231 }
00232
00234
00240 bool is_string() const
00241 {
00242 return m_type == STRING;
00243 }
00244
00246
00252 bool is_number() const
00253 {
00254 return m_type == NUMBER;
00255 }
00256
00260 bool is_object() const
00261 {
00262 return m_type == OBJECT || m_type == AS_FUNCTION || m_type == MOVIECLIP;
00263 }
00264
00268 bool is_sprite() const
00269 {
00270 return m_type == MOVIECLIP;
00271 }
00272
00274
00279 std::string to_string() const;
00280
00281 std::string to_debug_string() const;
00282
00284
00294 std::string to_string_versioned(int version) const;
00295
00297
00302 double to_number() const;
00303
00305
00313 boost::int32_t to_int() const;
00314
00317
00324 template <typename T>
00325 T to_number () const
00326 {
00327 return static_cast<T>(to_number());
00328 }
00329
00331
00337 bool to_bool() const;
00338
00340
00343 bool to_bool_v7() const;
00344
00346
00349 bool to_bool_v6() const;
00350
00352
00355 bool to_bool_v5() const;
00356
00358
00370 boost::intrusive_ptr<as_object> to_object() const;
00371
00373
00377 sprite_instance* to_sprite(bool skipRebinding=false) const;
00378
00380
00395 character* to_character(bool skipRebinding=false) const;
00396
00400 as_function* to_as_function() const;
00401
00403
00412 as_value to_primitive() const;
00413
00415
00427 as_value to_primitive(type hint) const;
00428
00430
00435 void convert_to_number();
00436
00438 void convert_to_string();
00439
00441 void convert_to_boolean();
00442
00444
00453 void convert_to_string_versioned(int version);
00454
00455
00456
00457
00458
00459 void set_string(const std::string& str);
00460
00461 void set_std_string(const std::string& str)
00462 {
00463 set_string(str);
00464 }
00465
00466 void set_string(const char* str)
00467 {
00468 set_string(std::string(str));
00469 }
00470
00471 void set_double(double val);
00472
00473 void set_bool(bool val);
00474
00475 void set_sprite(sprite_instance& sp);
00476
00477 void set_character(character& sp);
00478
00479 void set_int(int val) { set_double(val); }
00480
00481 void set_nan() { set_double(NAN); }
00482
00484
00490 void set_as_object(as_object* obj);
00491
00492 void set_as_object(boost::intrusive_ptr<as_object> obj);
00493
00495 void set_as_function(as_function* func);
00496
00497 void set_undefined();
00498
00500 void set_null();
00501
00503
00506 bool operator==(const as_value& v) const
00507 {
00508 return strictly_equals(v);
00509 }
00510
00512
00515 bool operator!=(const as_value& v) const {
00516 return ! ( *this == v );
00517 }
00518
00519 void operator=(const as_value& v);
00520
00521 bool is_undefined() const { return (m_type == UNDEFINED); }
00522
00523 bool is_null() const { return (m_type == NULLTYPE); }
00524
00525 bool is_bool() const { return (m_type == BOOLEAN); }
00526
00527 bool is_exception() const
00528 { return (m_type == UNDEFINED_EXCEPT || m_type == NULLTYPE_EXCEPT
00529 || m_type == BOOLEAN_EXCEPT || m_type == NUMBER_EXCEPT
00530 || m_type == OBJECT_EXCEPT || m_type == AS_FUNCTION_EXCEPT
00531 || m_type == MOVIECLIP_EXCEPT || m_type == STRING_EXCEPT);
00532 }
00533
00534
00535
00536 void flag_exception()
00537 { if (!is_exception()) m_type = (type) ((int) m_type + 1); }
00538 void unflag_exception()
00539 { if (is_exception()) m_type = (type) ((int) m_type - 1); }
00540
00542
00546 bool strictly_equals(const as_value& v) const;
00547
00549
00562 bool equals(const as_value& v) const;
00563
00565 void string_concat(const std::string& str);
00566
00568
00571 void setReachable() const;
00572
00573 private:
00574
00576
00581 class CharacterProxy {
00582
00583 mutable character* _ptr;
00584
00585 mutable std::string _tgt;
00586
00587 static character* find_character_by_target(const std::string& target);
00588
00591 void checkDangling() const;
00592
00593 public:
00594
00596 CharacterProxy(character* sp)
00597 :
00598 _ptr(sp)
00599 {
00600 checkDangling();
00601 }
00602
00604
00613 CharacterProxy(const CharacterProxy& sp)
00614 {
00615 sp.checkDangling();
00616 _ptr=sp._ptr;
00617 if ( ! _ptr ) _tgt=sp._tgt;
00618 }
00619
00621
00630 CharacterProxy& operator=(const CharacterProxy& sp)
00631 {
00632 sp.checkDangling();
00633 _ptr=sp._ptr;
00634 if ( ! _ptr ) _tgt=sp._tgt;
00635 return *this;
00636 }
00637
00639
00642 character* get(bool skipRebinding=false) const
00643 {
00644 if ( skipRebinding ) return _ptr;
00645
00646 checkDangling();
00647 if ( _ptr ) return _ptr;
00648 else return find_character_by_target(_tgt);
00649 }
00650
00652 std::string getTarget() const;
00653
00655
00661 bool isDangling() const
00662 {
00663 checkDangling();
00664 return !_ptr;
00665 }
00666
00671 bool operator==(const CharacterProxy& sp) const
00672 {
00673 return get() == sp.get();
00674 }
00675
00677
00681 void setReachable() const;
00682 };
00683
00685
00688 bool equalsSameType(const as_value& v) const;
00689
00690
00691
00692
00693
00694
00695 type get_type() const { return m_type; }
00696
00697 type m_type;
00698
00699 typedef sprite_instance* SpritePtr;
00700 typedef character* CharacterPtr;
00701 typedef boost::intrusive_ptr<as_function> AsFunPtr;
00702 typedef boost::intrusive_ptr<as_object> AsObjPtr;
00703
00704 boost::variant<
00705 boost::blank,
00706 double,
00707 bool,
00708 AsObjPtr,
00709
00710 CharacterProxy,
00711 std::string
00712 > _value;
00713
00714
00716 AsFunPtr getFun() const;
00717
00719 AsObjPtr getObj() const;
00720
00722
00725 SpritePtr getSprite(bool skipRebinding=false) const;
00726
00728
00731 CharacterPtr getCharacter(bool skipRebinding=false) const;
00732
00734
00735 CharacterProxy getCharacterProxy() const;
00736
00738 double getNum() const
00739 {
00740 assert(m_type == NUMBER);
00741 return boost::get<double>(_value);
00742 }
00743
00745 bool getBool() const
00746 {
00747 assert(m_type == BOOLEAN);
00748 return boost::get<bool>(_value);
00749 }
00750
00752 const std::string& getStr() const
00753 {
00754 assert(m_type == STRING);
00755 return boost::get<std::string>(_value);
00756 }
00757
00758 };
00759
00760 typedef as_value (*as_c_function_ptr)(const fn_call& fn);
00761
00762 inline std::ostream& operator<< (std::ostream& os, const as_value& v) {
00763 return os << v.to_debug_string();
00764 }
00765
00766 }
00767
00768 #endif // GNASH_AS_VALUE_H
00769
00770
00771
00772
00773
00774