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