as_value.h

Go to the documentation of this file.
00001 // 
00002 //   Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
00003 // 
00004 // This program is free software; you can redistribute it and/or modify
00005 // it under the terms of the GNU General Public License as published by
00006 // the Free Software Foundation; either version 3 of the License, or
00007 // (at your option) any later version.
00008 // 
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 // 
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00017 
00018 /* $Id: as__value_8h-source.html,v 1.3 2008/03/07 02:36:49 bjacques Exp $ */
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> // for inlined output operator
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 //#define PROPNAME(x) ( VM::get().getSWFVersion() < 7 ? boost::to_lower_copy(std::string(x)) : (x) )
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                 // Always make the exception type one greater than the normal type.
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         // Chad: Document
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         // These set_*()'s are more type-safe; should be used
00456         // in preference to generic overloaded set().  You are
00457         // more likely to get a warning/error if misused.
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         // Flag or unflag an as_value as an exception -- this gets flagged
00535         // when an as_value is 'thrown'.
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(); // set _ptr to NULL and _tgt to original target if destroyed
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         // TODO: make private. The rationale is that callers of this functions
00691         //       should use is_WHAT() instead, or changes in the available
00692         //       primitive value types will require modifications in all callers.
00693         //       This happened when adding MOVIECLIP.
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,  // UNDEFINED or NULL
00706                          double,        // NUMBER
00707                          bool,          // BOOLEAN
00708                          AsObjPtr,      // OBJECT,
00709 //                        AsFuncPtr,    // AS_FUNCTION
00710                          CharacterProxy,        // MOVIECLIP
00711                          std::string    // 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 } // namespace gnash
00767 
00768 #endif // GNASH_AS_VALUE_H
00769 
00770 // Local Variables:
00771 // mode: C++
00772 // indent-tabs-mode: t
00773 // End:
00774 

Generated on Thu Mar 6 18:25:06 2008 for Gnash by  doxygen 1.5.4