Gnash  0.8.11dev
ImportAssetsTag.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2005, 2006, 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 #ifndef GNASH_SWF_IMPORTASSETSTAG_H
20 #define GNASH_SWF_IMPORTASSETSTAG_H
21 
22 #include <vector>
23 #include <utility>
24 #include <string>
25 #include <memory>
26 
27 #include "ControlTag.h"
28 #include "Movie.h"
29 #include "MovieClip.h"
30 #include "SWFStream.h"
31 #include "MovieFactory.h"
32 #include "log.h"
33 #include "StreamProvider.h"
34 
35 namespace gnash {
36 namespace SWF {
37 
39 {
40 public:
41 
42  typedef std::pair<int, std::string> Import;
43  typedef std::vector<Import> Imports;
44 
45  static void loader(SWFStream& in, TagType tag, movie_definition& m,
46  const RunResources& r)
47  {
49 
50  boost::intrusive_ptr<ControlTag> p(new ImportAssetsTag(tag, in, m, r));
51  m.addControlTag(p);
52  }
53 
54 
56  //
60  virtual void executeState(MovieClip* m, DisplayList& /*l*/) const {
61  Movie* mov = m->get_root();
62  for (Imports::const_iterator it = _imports.begin(), e = _imports.end();
63  it != e; ++it) {
64  mov->addCharacter(it->first);
65  }
66  }
67 
68 private:
69 
71  const RunResources& r)
72  {
73  read(t, in, m, r);
74  }
75 
76  void read(TagType t, SWFStream& in, movie_definition& m,
77  const RunResources& r) {
78 
79  std::string source_url;
80  in.read_string(source_url);
81 
82  // Resolve relative urls against baseurl
83  URL abs_url(source_url, r.streamProvider().baseURL());
84 
85  unsigned char import_version = 0;
86 
87  if (t == SWF::IMPORTASSETS2) {
88  in.ensureBytes(2);
89  import_version = in.read_uint(8);
90  boost::uint8_t reserved = in.read_uint(8);
91  UNUSED(reserved);
92  }
93 
94  in.ensureBytes(2);
95  const boost::uint16_t count = in.read_u16();
96 
98  log_parse(_(" import: version = %u, source_url = %s (%s), "
99  "count = %d"), import_version, abs_url.str(), source_url,
100  count);
101  );
102 
103  // Try to load the source movie into the movie library.
104  boost::intrusive_ptr<movie_definition> source_movie;
105 
106  try {
107  source_movie = MovieFactory::makeMovie(abs_url, r);
108  }
109  catch (gnash::GnashException& e) {
110  log_error(_("Exception: %s"), e.what());
111  }
112 
113  if (!source_movie) {
114  // Give up on imports.
115  log_error(_("can't import movie from url %s"), abs_url.str());
116  return;
117  }
118 
119  // Quick consistency check, we might as well do
120  // something smarter, if we agree on semantic
121  if (source_movie == &m) {
123  log_swferror(_("Movie attempts to import symbols from "
124  "itself."));
125  );
126  return;
127  }
128 
129  // Get the imports.
130  for (size_t i = 0; i < count; ++i)
131  {
132  in.ensureBytes(2);
133  const boost::uint16_t id = in.read_u16();
134 
135  // We don't consider 0 valid.
136  if (!id) continue;
137 
138  std::string symbolName;
139  in.read_string(symbolName);
141  log_parse(_(" import: id = %d, name = %s"), id, symbolName);
142  );
143  _imports.push_back(std::make_pair(id, symbolName));
144  }
145 
146  m.importResources(source_movie, _imports);
147  }
148 
149 private:
150 
151  Imports _imports;
152 
153 };
154 
155 } // namespace SWF
156 } // namespace gnash
157 
158 #endif