as_object.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 #ifndef GNASH_AS_OBJECT_H
00019 #define GNASH_AS_OBJECT_H
00020 
00021 #ifdef HAVE_CONFIG_H
00022 #include "gnashconfig.h"
00023 #endif
00024 
00025 #include "tu_config.h"
00026 
00027 #include "string_table.h"
00028 #include "ref_counted.h" // for inheritance  (to drop)
00029 #include "GC.h" // for inheritance from GcResource (to complete)
00030 #include "PropertyList.h"
00031 #include "as_value.h" // for return of get_primitive_value
00032 #include "smart_ptr.h"
00033 #include "as_prop_flags.h" // for enum
00034 #include "GnashException.h"
00035 #include "event_id.h" // for event_id
00036 #include <sstream>
00037 
00038 #if defined(__GNUC__) && __GNUC__ > 2
00039 #  include <cxxabi.h>
00040 #endif
00041 
00042 #include <cmath>
00043 #include <utility> // for std::pair
00044 #include <set>
00045 
00046 // Forward declarations
00047 namespace gnash {
00048         class as_function;
00049         class sprite_instance;
00050         class character;
00051         class as_environment;
00052         class VM;
00053         class Machine;
00054 }
00055 
00056 namespace gnash {
00057 
00058 class asClass;
00059 class asName;
00060 
00063 //
00067 class DSOEXPORT as_object
00068         :
00069 #ifdef GNASH_USE_GC
00070         public GcResource
00071 #else
00072         public ref_counted
00073 #endif
00074 {
00075         friend class asClass;
00076         friend class Machine;
00077 
00078         typedef std::set<std::pair<string_table::key, string_table::key> > propNameSet;
00079 private:
00081         PropertyList _members;
00082 
00084         as_object& operator=(const as_object&)
00085         {
00086                 abort();
00087                 return *this;
00088         }
00089 
00093         //
00101         Property* findUpdatableProperty(string_table::key name, 
00102                 string_table::key nsname = 0);
00103 
00115         Property* findProperty(string_table::key name, string_table::key nsname,
00116                 as_object **owner = NULL);
00117 
00118 public:
00119 
00123         VM& getVM() const {
00124                 return _vm;
00125         }
00126 
00127 
00129         //
00135         void dump_members();
00136 
00138         //
00144         void dump_members(std::map<std::string, as_value>& to);
00145 
00147         as_object();
00148 
00152         as_object(as_object* proto);
00153 
00155         as_object(boost::intrusive_ptr<as_object> proto);
00156 
00158         //
00161         as_object(const as_object& other);
00162         
00164         virtual std::string get_text_value() const { return "[object Object]"; }
00165 
00169         virtual bool useCustomToString() const { return true; }
00170 
00172         //
00176         virtual double get_numeric_value() const {
00177                 std::string txt = get_text_value();
00178                 if ( ! txt.empty() ) return atof(txt.c_str());
00179                 else return 0; 
00180         }
00181 
00183         //
00191         virtual as_value get_primitive_value() const
00192         {
00193                 // Since as_value(const as_object*) doesn't exist
00194                 // we have to cast the value to non-const, or
00195                 // the as_value will result as beeing a BOOLEAN ! (?)
00196                 return as_value(const_cast<as_object*>(this)); 
00197         }
00198 
00200         //
00216         virtual void set_member(string_table::key key, const as_value& val,
00217                 string_table::key nsname = 0)
00218         {
00219                 return set_member_default(key, val, nsname);
00220         }
00221 
00223         //
00243         std::pair<bool,bool> update_member(string_table::key key, const as_value& val,
00244                 string_table::key nsname = 0);
00245 
00246         virtual bool on_event(const event_id& id );
00247 
00251         void reserveSlot(string_table::key name, string_table::key nsId,
00252                 unsigned short slotId);
00253 
00255         //
00274         void init_member(const std::string& name, const as_value& val, 
00275                 int flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum, 
00276                 string_table::key nsname = 0);
00277 
00279         //
00307         void init_member(string_table::key key, const as_value& val, 
00308                 int flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
00309                 string_table::key nsname = 0, int slotId = -1);
00310 
00313         //
00337         void init_property(const std::string& key, as_function& getter,
00338                 as_function& setter, int flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
00339                 string_table::key nsname = 0);
00340 
00343         //
00366         void init_property(string_table::key key, as_function& getter,
00367                 as_function& setter, int flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
00368                 string_table::key nsname = 0);
00369 
00370 
00399         bool init_destructive_property(string_table::key key, as_function& getter,
00400                 as_function& setter, int flags=as_prop_flags::dontEnum,
00401                 string_table::key nsname = 0);
00402 
00405         //
00417         void init_readonly_property(const std::string& key, as_function& getter,
00418                         int flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
00419                         string_table::key nsname = 0);
00420 
00422         //
00448         virtual bool get_member(string_table::key name, as_value* val,
00449                 string_table::key nsname = 0)
00450         {
00451                 return get_member_default(name, val, nsname);
00452         }
00453 
00455         //
00463         virtual as_object* get_path_element(string_table::key key);
00464 
00466         bool isQName() const { return false; /* TODO: Implement */ }
00467         bool isXML() const { return false; /* TODO */ }
00468         bool isDictionary() const { return false; /* TODO */ }
00469 
00476         as_object* get_super(); 
00477 
00482         as_function* get_constructor();
00483 
00485         //
00504         as_value getMember(string_table::key name, string_table::key nsname = 0);
00505 
00507         //
00526         as_value callMethod(string_table::key name);
00527         as_value callMethod(string_table::key name, const as_value& arg0);
00528         as_value callMethod(string_table::key name, const as_value& arg0, const as_value& arg1);
00529         as_value callMethod(string_table::key name, const as_value& arg0, const as_value& arg1, const as_value& arg2);
00530         as_value callMethod(string_table::key name, const as_value& arg0, const as_value& arg1, const as_value& arg2, const as_value& arg3);
00531 
00533         //
00553         std::pair<bool,bool> delProperty(string_table::key name, string_table::key nsname = 0);
00554 
00556         //
00572         Property* getOwnProperty(string_table::key name, string_table::key nsname = 0);
00573 
00581         Property *getByIndex(int index);
00582 
00597         int nextIndex(int index, as_object **owner = NULL);
00598 
00600         //
00619         bool set_member_flags(string_table::key name,
00620                         int setTrue, int setFalse=0, string_table::key nsname = 0);
00621 
00623         virtual sprite_instance* to_movie() { return NULL; }
00624 
00625         const sprite_instance* to_movie() const { return const_cast<as_object*>(this)->to_movie(); }
00626 
00628         virtual as_function* to_function() { return NULL; }
00629 
00631         virtual character* to_character() { return NULL; }
00632 
00633         const character* to_character() const { return const_cast<as_object*>(this)->to_character(); }
00634 
00636         //
00642         virtual bool isDateObject() { return false; }
00643 
00646         void add_interface(as_object* ctor);
00647 
00651         //
00655         bool instanceOf(as_function* ctor);
00656 
00660         //
00661         bool prototypeOf(as_object& instance);
00662 
00664         //
00676         void setPropFlags(as_value& props, int set_false, int set_true);
00677 
00678 #ifdef USE_DEBUGGER
00680         PropertyList &get_properties() { return _members; };
00681 #endif
00682 
00684         //
00687         void copyProperties(const as_object& o);
00688 
00690         void clearProperties()
00691         {
00692                 _members.clear();
00693         }
00694 
00698         //
00704         void enumerateProperties(as_environment& env) const;
00705 
00707         //
00714         virtual void enumerateNonProperties(as_environment&) const
00715         {
00716         }
00717 
00721         //
00727         void enumerateProperties(std::map<std::string, std::string>& to);
00728 
00730         //
00740         void getURLEncodedVars(std::string& data);
00741 
00743         //
00754         template <class V>
00755         void visitPropertyValues(V& visitor) const
00756         {
00757                 _members.visitValues(visitor, 
00758                         // Need const_cast due to getValue getting non-const ...
00759                         const_cast<as_object&>(*this));
00760         }
00761 
00762 
00766         //
00783         bool add_property(const std::string& key, as_function& getter,
00784                 as_function& setter);
00785 
00787         //
00793         boost::intrusive_ptr<as_object> get_prototype();
00794 
00795         const boost::intrusive_ptr<as_object> get_prototype() const {
00796                 // cast away constness
00797                 return const_cast<as_object*>(this)->get_prototype();
00798         }
00799 
00801         //
00807         void set_prototype(boost::intrusive_ptr<as_object> proto, int flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum);
00808 
00809         std::string asPropName(string_table::key name);
00810         
00813 
00814         static as_value tostring_method(const fn_call& fn);
00815 
00816         static as_value valueof_method(const fn_call& fn);
00817 
00819         
00820 protected:
00821 
00823         //
00843         bool get_member_default(string_table::key name, as_value* val, 
00844                 string_table::key nsname);
00845 
00847         //
00862         void set_member_default(string_table::key name, const as_value& val, 
00863                 string_table::key nsname);
00864 
00865 #ifdef GNASH_USE_GC
00867         //
00875         virtual void markReachableResources() const
00876         {
00877                 markAsObjectReachable();
00878         }
00879 
00881         void markAsObjectReachable() const
00882         {
00883                 _members.setReachable();
00884                 //if ( m_prototype.get() ) m_prototype->setReachable();
00885         }
00886 #endif // GNASH_USE_GC
00887 
00889         VM& _vm;
00890 
00891 private:
00892 
00895         std::list<as_object*> mInterfaces;
00896 
00898         //boost::intrusive_ptr<as_object> m_prototype;
00899 
00900 };
00901 
00908 template <typename T>
00909 boost::intrusive_ptr<T>
00910 ensureType (boost::intrusive_ptr<as_object> obj)
00911 {
00912         boost::intrusive_ptr<T> ret = boost::dynamic_pointer_cast<T>(obj);
00913 
00914         if (!ret) {
00915                 std::string     target = typeid(T).name(),
00916                                 source = typeid(*obj.get()).name();
00917 #if defined(__GNUC__) && __GNUC__ > 2
00918                 int status;
00919                 char* target_unmangled = 
00920                         abi::__cxa_demangle (target.c_str(), NULL, NULL,
00921                                              &status);
00922                 if (status == 0) {
00923                         target = target_unmangled;
00924                         free(target_unmangled);
00925                 }
00926 
00927                 char* source_unmangled =
00928                         abi::__cxa_demangle (source.c_str(), NULL, NULL,
00929                                              &status);
00930 
00931                 if (status == 0) {
00932                         source = source_unmangled;
00933                         free(source_unmangled);
00934                 }
00935 #endif // __GNUC__ > 2
00936 
00937                 std::string msg = "builtin method or gettersetter for " +
00938                         target + " called from " + source + " instance.";
00939 
00940                 throw ActionException(msg);
00941         }
00942         return ret;
00943 }
00944 
00945 
00946 
00947 } // namespace gnash
00948 
00949 #endif // GNASH_AS_OBJECT_H

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