Gnash 0.8.10dev
|
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