Gnash  0.8.11dev
AbcBlock.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012
3 // Free Software Foundation, Inc.
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 
19 // The AS3 abc block format reader.
20 //
21 
22 #ifndef GNASH_ABC_BLOCK_H
23 #define GNASH_ABC_BLOCK_H
24 
25 #include "string_table.h"
26 #include "MultiName.h"
27 #include "Namespace.h"
28 #include "as_value.h"
29 
30 #include <vector>
31 #include <string>
32 #include <boost/scoped_array.hpp>
33 #include <stdexcept>
34 
35 namespace gnash {
36  namespace abc {
37  class AbcBlock;
38  class Machine;
39  class Class;
40  class Method;
41  }
42  class SWFStream; // for read signature
43  class ClasstHierarchy;
44 }
45 
46 namespace gnash {
47 
49 namespace abc {
50 
52 //
57 //
60 //
69 //
72 class Trait
73 {
74 public:
75 
76  enum Kind
77  {
78  KIND_SLOT = 0,
85  };
86 
88  :
89  _hasValue(false),
90  _kind(KIND_SLOT),
91  _slotID(0),
92  _typeIndex(0),
93  _classInfoIndex(0),
94  _value(),
95  _name(0),
96  _globalName(),
97  _namespace(0),
98  _method(0),
99  _valueSet(false),
100  _classTarget(0),
101  _methodTarget(0),
102  _static(false)
103  {}
104 
105  bool read(SWFStream* in, AbcBlock *block);
106 
107  bool finalize(AbcBlock* block, abc::Class* cl, bool do_static);
108 
109  bool finalize_mbody(AbcBlock* block, Method* m);
110 
111  void set_target(abc::Class* cl, bool do_static) {
112  _classTarget = cl;
113  _static = do_static;
114  }
115 
116  void set_target(Method *m) {
117  _classTarget = 0;
118  _methodTarget = m;
119  }
120 
121  bool finalize(AbcBlock* block)
122  {
123  if (_classTarget) {
124  return finalize(block, _classTarget, _static);
125  }
126  return finalize_mbody(block, _methodTarget);
127  }
128 
129 private:
130 
131  friend class AbcBlock;
132 
133  bool _hasValue;
134  Kind _kind;
135  boost::uint32_t _slotID;
136  boost::uint32_t _typeIndex;
137  boost::uint32_t _classInfoIndex;
138  as_value _value;
139 
140  URI _name;
141  string_table::key _globalName;
142 
143  Namespace* _namespace;
144  Method* _method;
145  bool _valueSet;
146 
147  abc::Class* _classTarget;
148  Method* _methodTarget;
149  bool _static;
150 
151 };
152 
154 std::ostream& operator<<(std::ostream& o, const Trait::Kind k);
155 
156 namespace {
157 
158 template<typename T>
159 inline void checkBounds(size_t i, const T& container)
160 {
161  if (i >= container.size()) {
162  throw std::range_error("Attempt to access pool out of range");
163  }
164 }
165 
166 }
167 
168 
170 //
174 //
177 //
186 //
188 //
196 //
198 //
203 //
209 class AbcBlock
210 {
211 public:
212 
214  {
215  PRIVATE_NS = 0x05,
216  CONSTANT_NS = 0x08,
217  PACKAGE_NS = 0x16,
219  PROTECTED_NS = 0x18,
220  EXPLICIT_NS = 0x19,
222  };
223 
225  {
226  METHOD_ARGS = 0x01,
228  METHOD_MORE = 0x04,
234  };
235 
237  {
243  };
244 
246  {
247  POOL_STRING = 0x01,
248  POOL_INTEGER = 0x03,
250  POOL_DOUBLE = 0x06,
252  POOL_FALSE = 0x0A,
253  POOL_TRUE = 0x0B,
254  POOL_NULL = 0x0C
255  };
256 
257  typedef std::vector<Namespace*> NamespaceSet;
258 
259  AbcBlock();
260 
262 
263  abc::Class* locateClass(const std::string& className);
264 
265  bool read(SWFStream& in);
266 
267  void update_global_name(unsigned int multiname_index);
268 
270  //
272  const std::vector<abc::Class*>& scripts() const {
273  return _scripts;
274  }
275 
276  boost::uint32_t uIntegerPoolAt(size_t i) const {
277  checkBounds(i, _uIntegerPool);
278  return _uIntegerPool[i];
279  }
280 
281  const std::string& stringPoolAt(size_t i) const {
282  checkBounds(i, _stringPool);
283  return _stringPool[i];
284  }
285 
286  boost::int32_t integerPoolAt(size_t i) const {
287  checkBounds(i, _integerPool);
288  return _integerPool[i];
289  }
290 
291  double doublePoolAt(size_t i) const {
292  checkBounds(i, _doublePool);
293  return _doublePool[i];
294  }
295 
296  Method* methodPoolAt(size_t i) const {
297  checkBounds(i, _methods);
298  return _methods[i];
299  }
300 
301  MultiName multinamePoolAt(size_t i) const {
302  checkBounds(i, _multinamePool);
303  return _multinamePool[i];
304  }
305 
306  abc::Class* classPoolAt(size_t i) const {
307  checkBounds(i, _classes);
308  return _classes[i];
309  }
310 
311  Namespace* namespacePoolAt(size_t i) const {
312  checkBounds(i, _namespacePool);
313  return _namespacePool[i];
314  }
315 
316  void prepare(Machine* mach);
317 
318 private:
319 
320  friend class abc::Trait;
321 
322  bool pool_value(boost::uint32_t index, PoolConstant type, as_value &v);
323 
324  bool read_version();
325  bool read_integer_constants();
326  bool read_unsigned_integer_constants();
327  bool read_double_constants();
328  bool read_string_constants();
329  bool read_namespaces();
330  bool read_namespace_sets();
331  bool read_multinames();
332  bool read_method_infos();
333  bool skip_metadata();
334  bool read_instances();
335  bool read_classes();
336  bool read_scripts();
337  bool read_method_bodies();
338 
339  void check_multiname_name(boost::uint32_t name);
340 
341  void check_multiname_namespace(boost::uint32_t ns);
342 
343  void check_multiname_namespaceset(boost::uint32_t nsset);
344 
345  void setMultinameNames(MultiName *n, abc::URI ABCName);
346 
347  void setNamespaceURI(Namespace *ns, abc::URI ABCName);
348 
349  std::vector<boost::int32_t> _integerPool;
350  std::vector<boost::uint32_t> _uIntegerPool;
351  std::vector<double> _doublePool;
352  std::vector<std::string> _stringPool;
353  std::vector<Namespace*> _namespacePool;
354  std::vector<NamespaceSet> _namespaceSetPool;
355  std::vector<Method*> _methods;
356  std::vector<MultiName> _multinamePool;
357  std::vector<Class*> _classes;
358  std::vector<Class*> _scripts;
359 
360  string_table* _stringTable;
361  SWFStream* _stream; // Not stored beyond one read.
362 
363  abc::Class *mTheObject;
364  ClassHierarchy *mCH;
365 
366  boost::uint32_t mVersion;
367 
368 
369 };
370 
371 std::ostream& operator<<(std::ostream& o, AbcBlock::NamespaceConstant c);
372 std::ostream& operator<<(std::ostream& o, AbcBlock::MethodConstant c);
373 std::ostream& operator<<(std::ostream& o, AbcBlock::InstanceConstant c);
374 std::ostream& operator<<(std::ostream& o, AbcBlock::PoolConstant c);
375 
376 } // namespace abc
377 } // namespace gnash
378 
379 
380 #endif
381