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