Gnash  0.8.10
AbcBlock.h
Go to the documentation of this file.
00001 // 
00002 //   Copyright (C) 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 // The AS3 abc block format reader.
00020 //
00021 
00022 #ifndef GNASH_ABC_BLOCK_H
00023 #define GNASH_ABC_BLOCK_H
00024 
00025 #include "string_table.h"
00026 #include "MultiName.h"
00027 #include "Namespace.h"
00028 #include "as_value.h"
00029 
00030 #include <vector>
00031 #include <string>
00032 #include <boost/scoped_array.hpp>
00033 #include <stdexcept>
00034 
00035 namespace gnash {
00036     namespace abc {
00037         class AbcBlock;
00038         class Machine;
00039         class Class;
00040         class Method;
00041     }
00042     class SWFStream; // for read signature
00043     class ClasstHierarchy;
00044 }
00045 
00046 namespace gnash {
00047 
00049 namespace abc {
00050 
00052 //
00057 //
00060 //
00069 //
00072 class Trait
00073 {
00074 public:
00075 
00076     enum Kind
00077         {
00078                 KIND_SLOT = 0,
00079                 KIND_CONST = 6,
00080                 KIND_METHOD = 1,
00081                 KIND_GETTER = 2,
00082                 KIND_SETTER = 3,
00083                 KIND_CLASS = 4,
00084                 KIND_FUNCTION = 5
00085         };
00086 
00087         Trait()
00088         :
00089         _hasValue(false),
00090         _kind(KIND_SLOT),
00091         _slotID(0),
00092         _typeIndex(0),
00093         _classInfoIndex(0),
00094         _value(),
00095         _name(0),
00096         _globalName(),
00097         _namespace(0),
00098         _method(0),
00099         _valueSet(false),
00100         _classTarget(0),
00101         _methodTarget(0),
00102         _static(false)
00103         {}
00104 
00105         bool read(SWFStream* in, AbcBlock *block);
00106 
00107         bool finalize(AbcBlock* block, abc::Class* cl, bool do_static);
00108 
00109         bool finalize_mbody(AbcBlock* block, Method* m);
00110 
00111         void set_target(abc::Class* cl, bool do_static) {
00112         _classTarget = cl;
00113         _static = do_static;
00114     }
00115 
00116         void set_target(Method *m) {
00117         _classTarget = 0;
00118         _methodTarget = m;
00119     }
00120 
00121         bool finalize(AbcBlock* block)
00122         {
00123                 if (_classTarget) {
00124                         return finalize(block, _classTarget, _static);
00125         }
00126                 return finalize_mbody(block, _methodTarget);
00127         }
00128 
00129 private:
00130 
00131     friend class AbcBlock;
00132 
00133         bool _hasValue;
00134         Kind _kind;
00135         boost::uint32_t _slotID;
00136         boost::uint32_t _typeIndex;
00137         boost::uint32_t _classInfoIndex;
00138         as_value _value;
00139 
00140         URI _name;
00141     string_table::key _globalName;
00142 
00143         Namespace* _namespace;
00144         Method* _method;
00145         bool _valueSet;
00146 
00147         abc::Class* _classTarget;
00148         Method* _methodTarget;
00149         bool _static;
00150 
00151 };
00152 
00154 std::ostream& operator<<(std::ostream& o, const Trait::Kind k);
00155 
00156 namespace {
00157 
00158 template<typename T>
00159 inline void checkBounds(size_t i, const T& container)
00160 {
00161     if (i >= container.size()) {
00162         throw std::range_error("Attempt to access pool out of range");
00163     }
00164 }
00165 
00166 }
00167 
00168 
00170 //
00174 // 
00177 // 
00186 //
00188 //
00196 //
00198 //
00203 // 
00209 class AbcBlock
00210 {
00211 public:
00212     
00213     enum NamespaceConstant
00214         {
00215                 PRIVATE_NS = 0x05,
00216         CONSTANT_NS = 0x08,
00217                 PACKAGE_NS = 0x16,
00218                 PACKAGE_INTERNAL_NS = 0x17,
00219                 PROTECTED_NS = 0x18,
00220                 EXPLICIT_NS = 0x19,
00221                 STATIC_PROTECTED_NS = 0x1A
00222     };
00223 
00224     enum MethodConstant
00225     {
00226         METHOD_ARGS = 0x01,
00227                 METHOD_ACTIVATION = 0x02,
00228                 METHOD_MORE = 0x04,
00229                 METHOD_OPTIONAL_ARGS = 0x08,
00230                 METHOD_IGNORE = 0x10,
00231                 METHOD_NATIVE = 0x20,
00232                 METHOD_DEFAULT_NS = 0x40,
00233                 METHOD_ARG_NAMES = 0x80
00234     };
00235 
00236     enum InstanceConstant
00237     {
00238                 INSTANCE_SEALED = 0x01,
00239                 INSTANCE_FINAL = 0x02,
00240                 INSTANCE_INTERFACE = 0x04,
00241                 INSTANCE_DYNAMIC = 0x00,
00242                 INSTANCE_PROTECTED_NS = 0x08
00243     };
00244 
00245     enum PoolConstant
00246     {
00247                 POOL_STRING = 0x01,
00248                 POOL_INTEGER = 0x03,
00249                 POOL_UINTEGER = 0x04,
00250                 POOL_DOUBLE = 0x06,
00251                 POOL_NAMESPACE = 0x08,
00252                 POOL_FALSE = 0x0A,
00253                 POOL_TRUE = 0x0B,
00254                 POOL_NULL = 0x0C
00255         };
00256     
00257     typedef std::vector<Namespace*> NamespaceSet;
00258 
00259         AbcBlock();
00260 
00261     abc::Class* locateClass(MultiName &m);
00262 
00263         abc::Class* locateClass(const std::string& className);
00264 
00265     bool read(SWFStream& in);
00266 
00267         void update_global_name(unsigned int multiname_index);
00268 
00270     //
00272     const std::vector<abc::Class*>& scripts() const {
00273         return _scripts;
00274     }
00275 
00276     boost::uint32_t uIntegerPoolAt(size_t i) const {
00277         checkBounds(i, _uIntegerPool);
00278         return _uIntegerPool[i];
00279     }
00280 
00281     const std::string& stringPoolAt(size_t i) const {
00282         checkBounds(i, _stringPool);
00283         return _stringPool[i];
00284     }
00285 
00286     boost::int32_t integerPoolAt(size_t i) const {
00287         checkBounds(i, _integerPool);
00288         return _integerPool[i];
00289     }
00290 
00291     double doublePoolAt(size_t i) const {
00292         checkBounds(i, _doublePool);
00293         return _doublePool[i];
00294     }
00295 
00296     Method* methodPoolAt(size_t i) const {
00297         checkBounds(i, _methods);
00298         return _methods[i];
00299     }
00300 
00301     MultiName multinamePoolAt(size_t i) const {
00302         checkBounds(i, _multinamePool);
00303         return _multinamePool[i];
00304     }
00305 
00306     abc::Class* classPoolAt(size_t i) const {
00307         checkBounds(i, _classes);
00308         return _classes[i];
00309     }
00310 
00311     Namespace* namespacePoolAt(size_t i) const {
00312         checkBounds(i, _namespacePool);
00313         return _namespacePool[i];
00314     }
00315 
00316     void prepare(Machine* mach);
00317 
00318 private:
00319         
00320     friend class abc::Trait;
00321 
00322         bool pool_value(boost::uint32_t index, PoolConstant type, as_value &v);
00323 
00324         bool read_version();
00325         bool read_integer_constants();
00326         bool read_unsigned_integer_constants();
00327         bool read_double_constants();
00328         bool read_string_constants();
00329         bool read_namespaces();
00330         bool read_namespace_sets();
00331         bool read_multinames();
00332         bool read_method_infos();
00333         bool skip_metadata();
00334         bool read_instances();
00335         bool read_classes();
00336         bool read_scripts();
00337         bool read_method_bodies();
00338 
00339         void check_multiname_name(boost::uint32_t name);
00340 
00341         void check_multiname_namespace(boost::uint32_t ns);
00342 
00343         void check_multiname_namespaceset(boost::uint32_t nsset);
00344 
00345         void setMultinameNames(MultiName *n, abc::URI ABCName);
00346 
00347         void setNamespaceURI(Namespace *ns, abc::URI ABCName);
00348 
00349         std::vector<boost::int32_t> _integerPool;
00350         std::vector<boost::uint32_t> _uIntegerPool;
00351         std::vector<double> _doublePool;
00352         std::vector<std::string> _stringPool;
00353         std::vector<Namespace*> _namespacePool;
00354         std::vector<NamespaceSet> _namespaceSetPool;
00355         std::vector<Method*> _methods;
00356         std::vector<MultiName> _multinamePool;
00357         std::vector<Class*> _classes; 
00358         std::vector<Class*> _scripts;
00359 
00360         string_table* _stringTable;
00361         SWFStream* _stream; // Not stored beyond one read.
00362 
00363         abc::Class *mTheObject;
00364         ClassHierarchy *mCH;
00365 
00366         boost::uint32_t mVersion;
00367 
00368 
00369 };
00370 
00371 std::ostream& operator<<(std::ostream& o, AbcBlock::NamespaceConstant c);
00372 std::ostream& operator<<(std::ostream& o, AbcBlock::MethodConstant c);
00373 std::ostream& operator<<(std::ostream& o, AbcBlock::InstanceConstant c);
00374 std::ostream& operator<<(std::ostream& o, AbcBlock::PoolConstant c);
00375 
00376 } // namespace abc
00377 } // namespace gnash
00378 
00379 
00380 #endif 
00381