[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r11050: Migrated SharedObject and St
From: |
Sharad Desai |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r11050: Migrated SharedObject and Stage classes to new hierarchy |
Date: |
Tue, 09 Jun 2009 09:51:03 -0600 |
User-agent: |
Bazaar (1.13.1) |
------------------------------------------------------------
revno: 11050
committer: Sharad Desai <address@hidden>
branch nick: trunk
timestamp: Tue 2009-06-09 09:51:03 -0600
message:
Migrated SharedObject and Stage classes to new hierarchy
removed:
libcore/asobj/SharedObject_as.cpp
libcore/asobj/SharedObject_as.h
libcore/asobj/Stage_as.cpp
libcore/asobj/Stage_as.h
modified:
libcore/ClassHierarchy.cpp
libcore/asobj/Global.cpp
libcore/asobj/Makefile.am
libcore/asobj/flash.am
libcore/asobj/flash/display/Stage_as.cpp
libcore/asobj/flash/display/Stage_as.h
libcore/asobj/flash/display/display.am
libcore/asobj/flash/net/SharedObject_as.cpp
libcore/asobj/flash/net/SharedObject_as.h
libcore/asobj/flash/net/net.am
libcore/movie_root.cpp
libcore/vm/VM.cpp
------------------------------------------------------------
revno: 11040.1.1
committer: Sharad Desai <address@hidden>
branch nick: desaiMig
timestamp: Mon 2009-06-08 15:22:11 -0600
message:
Migrated SharedObject_as and Stage_as classes
removed:
libcore/asobj/SharedObject_as.cpp
libcore/asobj/SharedObject_as.h
libcore/asobj/Stage_as.cpp
libcore/asobj/Stage_as.h
modified:
libcore/ClassHierarchy.cpp
libcore/asobj/Global.cpp
libcore/asobj/Makefile.am
libcore/asobj/flash.am
libcore/asobj/flash/display/Stage_as.cpp
libcore/asobj/flash/display/Stage_as.h
libcore/asobj/flash/display/display.am
libcore/asobj/flash/net/SharedObject_as.cpp
libcore/asobj/flash/net/SharedObject_as.h
libcore/asobj/flash/net/net.am
=== modified file 'libcore/ClassHierarchy.cpp'
--- a/libcore/ClassHierarchy.cpp 2009-06-09 11:38:31 +0000
+++ b/libcore/ClassHierarchy.cpp 2009-06-09 15:51:03 +0000
@@ -47,9 +47,9 @@
#include "NetConnection_as.h"
#include "NetStream_as.h"
#include "Selection_as.h"
-#include "SharedObject_as.h"
+#include "flash/net/SharedObject_as.h"
#include "Sound_as.h"
-#include "Stage_as.h"
+#include "flash/display/Stage_as.h"
#include "System_as.h"
#include "flash/text/TextSnapshot_as.h"
#include "TextFormat_as.h"
=== modified file 'libcore/asobj/Global.cpp'
--- a/libcore/asobj/Global.cpp 2009-06-09 11:38:31 +0000
+++ b/libcore/asobj/Global.cpp 2009-06-09 15:51:03 +0000
@@ -50,8 +50,8 @@
#include "movie_definition.h"
#include "NetConnection_as.h"
#include "NetStream_as.h"
-#include "SharedObject_as.h"
-#include "Stage_as.h"
+#include "flash/net/SharedObject_as.h"
+#include "flash/display/Stage_as.h"
#include "System_as.h"
#include "TextFormat_as.h"
#include "flash/text/TextSnapshot_as.h"
=== modified file 'libcore/asobj/Makefile.am'
--- a/libcore/asobj/Makefile.am 2009-06-09 11:38:31 +0000
+++ b/libcore/asobj/Makefile.am 2009-06-09 15:51:03 +0000
@@ -72,7 +72,6 @@
Number_as.cpp \
PlayHead.cpp \
Selection_as.cpp \
- SharedObject_as.cpp\
Namespace_as.cpp \
Sound_as.cpp \
Stage_as.cpp \
@@ -106,7 +105,6 @@
Number_as.h \
PlayHead.h \
Selection_as.h \
- SharedObject_as.h \
Sound_as.h \
Stage_as.h \
System_as.h \
=== removed file 'libcore/asobj/SharedObject_as.cpp'
--- a/libcore/asobj/SharedObject_as.cpp 2009-06-03 16:05:40 +0000
+++ b/libcore/asobj/SharedObject_as.cpp 1970-01-01 00:00:00 +0000
@@ -1,1108 +0,0 @@
-// SharedObject_as.cpp: ActionScript "SharedObject" class, for Gnash.
-//
-// Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-//
-
-#ifdef HAVE_CONFIG_H
-#include "gnashconfig.h" // USE_SOL_READ_ONLY
-#endif
-
-#include "GnashSystemNetHeaders.h"
-#include "GnashFileUtilities.h" // stat
-#include "SimpleBuffer.h"
-#include "as_value.h"
-#include "amf.h"
-#include "element.h"
-#include "sol.h"
-#include "movie_root.h"
-#include "SharedObject_as.h"
-#include "as_object.h" // for inheritance
-#include "log.h"
-#include "fn_call.h"
-#include "smart_ptr.h" // for boost intrusive_ptr
-#include "builtin_function.h" // need builtin_function
-#include "Object.h" // for getObjectInterface
-#include "VM.h"
-#include "Property.h"
-#include "string_table.h"
-#include "URLAccessManager.h"
-#include "URL.h"
-#include "rc.h" // for use of rcfile
-
-#include <boost/tokenizer.hpp>
-#include <boost/scoped_array.hpp>
-#include <boost/shared_ptr.hpp>
-
-// Undefine this to use the Element-based AMF0 decoder/encoder.
-// May be useful to test libamf.
-#define BUFFERED_AMF_SOL
-
-namespace {
-gnash::RcInitFile& rcfile = gnash::RcInitFile::getDefaultInstance();
-}
-
-using namespace amf;
-
-namespace gnash {
-
-// Forward declarations
-namespace {
-
- as_value sharedobject_connect(const fn_call& fn);
- as_value sharedobject_send(const fn_call& fn);
- as_value sharedobject_flush(const fn_call& fn);
- as_value sharedobject_close(const fn_call& fn);
- as_value sharedobject_getsize(const fn_call& fn);
- as_value sharedobject_setFps(const fn_call& fn);
- as_value sharedobject_clear(const fn_call& fn);
- as_value sharedobject_deleteAll(const fn_call& fn);
- as_value sharedobject_getDiskUsage(const fn_call& fn);
- as_value sharedobject_getRemote(const fn_call& fn);
- as_value sharedobject_data(const fn_call& fn);
-
- as_value sharedobject_getLocal(const fn_call& fn);
- as_value sharedobject_ctor(const fn_call& fn);
-
- as_object* readSOL(VM& vm, const std::string& filespec);
-
- as_object* getSharedObjectInterface();
- void attachSharedObjectStaticInterface(as_object& o);
- void flushSOL(SharedObjectLibrary::SoLib::value_type& sol);
- bool validateName(const std::string& solName);
-}
-
-// Serializer helper
-namespace {
-
-class PropsSerializer : public AbstractPropertyVisitor
-{
-public:
-
- PropsSerializer(SOL& sol, VM& vm)
- :
- _sol(sol),
- _st(vm.getStringTable())
- {};
-
- void accept(string_table::key key, const as_value& val)
- {
- AMF amf;
- boost::shared_ptr<amf::Element> el;
-
- const std::string& name = _st.string_table::value(key);
-
- //log_debug("Serializing SharedObject property %s:%s", name, val);
-
- if (val.is_string()) {
- std::string str;
- if (!val.is_undefined()) {
- str = val.to_string();
- }
- el.reset(new amf::Element(name, str));
- }
- if (val.is_bool()) {
- bool flag = val.to_bool();
- el.reset(new amf::Element(name, flag));
- }
- if (val.is_number()) {
- double dub;
- if (val.is_undefined()) {
- dub = 0.0;
- } else {
- dub = val.to_number();
- }
- el.reset(new amf::Element(name, dub));
- }
-
- if (el) {
- _sol.addObj(el);
- }
- }
-
-private:
-
- SOL& _sol;
- string_table& _st;
-};
-
-/// Class used to serialize properties of an object to a buffer in SOL format
-class SOLPropsBufSerializer : public AbstractPropertyVisitor
-{
-
- typedef std::map<as_object*, size_t> PropertiesOffsetTable;
-
-public:
-
- SOLPropsBufSerializer(SimpleBuffer& buf, VM& vm,
- PropertiesOffsetTable& offsetTable)
- :
- _buf(buf),
- _vm(vm),
- _st(vm.getStringTable()),
- _offsetTable(offsetTable),
- _error(false)
- {};
-
- bool success() const { return !_error; }
-
- virtual void accept(string_table::key key, const as_value& val)
- {
- if ( _error ) return;
-
- if ( val.is_function() )
- {
- log_debug("SOL: skip serialization of FUNCTION property");
- return;
- }
-
- // Test conducted with AMFPHP:
- // '__proto__' and 'constructor' members
- // of an object don't get back from an 'echo-service'.
- // Dunno if they are not serialized or just not sent back.
- // A '__constructor__' member gets back, but only if
- // not a function. Actually no function gets back.
- //
- if ( key == NSV::PROP_uuPROTOuu || key == NSV::PROP_CONSTRUCTOR )
- {
-#ifdef GNASH_DEBUG_AMF_SERIALIZE
- log_debug(" skip serialization of specially-named property %s",
- _st.value(key));
-#endif
- return;
- }
-
- // write property name
- const std::string& name = _st.value(key);
-#ifdef GNASH_DEBUG_AMF_SERIALIZE
- log_debug(" serializing property %s", name);
-#endif
- boost::uint16_t namelen = name.size();
- _buf.appendNetworkShort(namelen);
- _buf.append(name.c_str(), namelen);
- // Strict array are never encoded in SharedObject
- if ( ! val.writeAMF0(_buf, _offsetTable, _vm, false) )
- {
- log_error("Problems serializing an object's member %s=%s",
- name, val);
- _error = true;
- }
-
- _buf.appendByte(0); // SOL-specific
- }
-
-private:
-
- SimpleBuffer& _buf;
-
- VM& _vm;
-
- string_table& _st;
-
- PropertiesOffsetTable& _offsetTable;
-
- bool _error;
-};
-
-} // anonymous namespace
-
-class SharedObject_as: public as_object
-{
-public:
-
- ~SharedObject_as();
-
- SharedObject_as()
- :
- as_object(getSharedObjectInterface()),
- _data(0)
- {
- }
-
- bool flush(int space = 0) const;
-
- const std::string& getFilespec() const {
- return _sol.getFilespec();
- }
-
- void setFilespec(const std::string& s) {
- _sol.setFilespec(s);
- }
-
- const std::string& getObjectName() const {
- return _sol.getObjectName();
- }
-
- void setObjectName(const std::string& s) {
- _sol.setObjectName(s);
- }
-
- /// This isn't correct, as the default implementation doesn't use SOL
- /// for reading.
- size_t size() const {
- return _sol.fileSize();
- }
-
- void setData(as_object* data) {
-
- assert(data);
- _data = data;
-
- const int flags = as_prop_flags::dontDelete |
- as_prop_flags::readOnly;
-
- init_property(NSV::PROP_DATA, &sharedobject_data, &sharedobject_data,
- flags);
-
- }
-
- as_object* data() {
- return _data;
- }
-
- const as_object* data() const {
- return _data;
- }
-
-protected:
-
- void markReachableResources() const {
- if (_data) _data->setReachable();
- }
-
-private:
-
- as_object* _data;
-
- SOL _sol;
-};
-
-
-SharedObject_as::~SharedObject_as()
-{
-}
-
-
-bool
-SharedObject_as::flush(int space) const
-{
-
- /// This is called on on destruction of the SharedObject, or (allegedly)
- /// on a call to SharedObject.data, so _data is not guaranteed to exist.
- //
- /// The function should never be called from SharedObject.flush() when
- /// _data is 0.
- if (!_data) return false;
-
- if (space > 0) {
- log_unimpl("SharedObject.flush() called with a minimum disk space "
- "argument (%d), which is currently ignored", space);
- }
-
- const std::string& filespec = _sol.getFilespec();
-
- if (!mkdirRecursive(filespec))
- {
- log_error("Couldn't create dir for flushing SharedObject %s",
filespec);
- return false;
- }
-
-#ifdef USE_SOL_READONLY
- log_debug(_("SharedObject %s not flushed (compiled as read-only mode)"),
- filespec);
- return false;
-#endif
-
- if (rcfile.getSOLReadOnly() ) {
- log_security("Attempting to write object %s when it's SOL "
- "Read Only is set! Refusing...", filespec);
- return false;
- }
-
-#ifdef BUFFERED_AMF_SOL
-
- gnash::SimpleBuffer buf;
- // see http://osflash.org/documentation/amf/envelopes/sharedobject
-
- // length field filled in later
- buf.append("\x00\xbf\x00\x00\x00\x00TCSO\x00\x04\x00\x00\x00\x00", 16);
-
- // append object name
- std::string object_name = getObjectName();
- boost::uint16_t len = object_name.length();
- buf.appendNetworkShort(len);
- buf.append(object_name.c_str(), len);
-
- // append padding
- buf.append("\x00\x00\x00\x00", 4);
-
- // append properties of object
- VM& vm = getVM();
-
- std::map<as_object*, size_t> offsetTable;
- SOLPropsBufSerializer props(buf, vm, offsetTable);
- _data->visitPropertyValues(props);
- if ( ! props.success() )
- {
- log_error("Could not serialize object");
- return false;
- }
-
- // fix length field
- *(reinterpret_cast<uint32_t*>(buf.data() + 2)) = htonl(buf.size() - 6);
-
- // TODO write file
- std::ofstream ofs(filespec.c_str(), std::ios::binary);
- if (!ofs) {
- log_error("SharedObject::flush(): Failed opening file '%s' in "
- "binary mode", filespec.c_str());
- return false;
- }
-
- if (ofs.write(reinterpret_cast<const char*>(buf.data()),
buf.size()).fail())
- {
- log_error("Error writing %d bytes to output file %s",
- buf.size(), filespec.c_str());
- ofs.close();
- return false;
- }
- ofs.close();
-
-#else // amf::SOL-based serialization
-
- // append properties of object
- VM& vm = getVM();
-
- SOL sol;
- PropsSerializer props(sol, vm);
- _data->visitPropertyValues(props);
- // We only want to access files in this directory
- bool ret = sol.writeFile(filespec, getObjectName().c_str());
- if ( ! ret )
- {
- log_error("writing SharedObject file to %s", filespec);
- return false;
- }
-#endif
-
- log_security("SharedObject '%s' written to filesystem.", filespec);
- return true;
-}
-
-
-SharedObjectLibrary::SharedObjectLibrary(VM& vm)
- :
- _vm(vm)
-{
- _solSafeDir = rcfile.getSOLSafeDir();
- if (_solSafeDir.empty()) {
- log_debug("Empty SOLSafeDir directive: we'll use '/tmp'");
- _solSafeDir = "/tmp/";
- }
-
- // Check if the base dir exists here
- struct stat statbuf;
- if ( -1 == stat(_solSafeDir.c_str(), &statbuf) )
- {
- log_debug("Invalid SOL safe dir %s: %s. Will try to create on "
- "flush/exit.", _solSafeDir, std::strerror(errno));
- }
-
- // Which URL we should use here is under research.
- // The reference player uses the URL from which definition
- // of the call to SharedObject.getLocal was parsed.
- //
- // There is in Gnash support for tracking action_buffer
- // urls but not yet an interface to fetch it from fn_call;
- // also, it's not clear how good would the model be (think
- // of movie A loading movie B creating the SharedObject).
- //
- // What we'll do for now is use the URL of the initially
- // loaded SWF, so that in the A loads B scenario above the
- // domain would be the one of A, not B.
- //
- // NOTE: using the base url RunInfo::baseURL() would mean
- // blindly trusting the SWF publisher as base url is changed
- // by the 'base' attribute of OBJECT or EMBED tags trough
- // -P base=xxx
- //
- const movie_root& mr = _vm.getRoot();
- const std::string& swfURL = mr.getOriginalURL();
-
- URL url(swfURL);
-
- // Remember the hostname of our SWF URL. This can be empty if loaded
- // from the filesystem
- _baseDomain = url.hostname();
-
- const std::string& urlPath = url.path();
-
- // Get the path part. If loaded from the filesystem, the pp stupidly
- // removes the first directory.
- if (!_baseDomain.empty()) {
- _basePath = urlPath;
- }
- else if (!urlPath.empty()) {
- // _basePath should be empty if there are no slashes or just one.
- std::string::size_type pos = urlPath.find('/', 1);
- if (pos != std::string::npos) {
- _basePath = urlPath.substr(pos);
- }
- }
-
-}
-
-void
-SharedObjectLibrary::markReachableResources() const
-{
- for (SoLib::const_iterator it = _soLib.begin(), itE = _soLib.end();
- it != itE; ++it)
- {
- SharedObject_as* sh = it->second;
- sh->setReachable();
- }
-}
-
-/// The SharedObjectLibrary keeps all known SharedObjects alive. They must
-/// be flushed on clear(). This is called at the latest by the dtor, which
-/// is called at the latest by VM's dtor (currently earlier to avoid problems
-/// with the GC).
-void
-SharedObjectLibrary::clear()
-{
- std::for_each(_soLib.begin(), _soLib.end(), &flushSOL);
- _soLib.clear();
-}
-
-SharedObjectLibrary::~SharedObjectLibrary()
-{
- clear();
-}
-
-SharedObject_as*
-SharedObjectLibrary::getLocal(const std::string& objName,
- const std::string& root)
-{
- assert (!objName.empty());
-
- // already warned about it at construction time
- if (_solSafeDir.empty()) return 0;
-
- if (rcfile.getSOLLocalDomain() && !_baseDomain.empty())
- {
- log_security("Attempting to open SOL file from non "
- "localhost-loaded SWF");
- return 0;
- }
-
- // Check that the name is valid; if not, return null
- if (!validateName(objName)) return 0;
-
- // The 'root' argument, otherwise known as localPath, specifies where
- // in the SWF path the SOL should be stored. It cannot be outside this
- // path.
- std::string requestedPath;
-
- // If a root is specified, check it first for validity
- if (!root.empty()) {
-
- const movie_root& mr = _vm.getRoot();
- const std::string& swfURL = mr.getOriginalURL();
- // The specified root may or may not have a domain. If it doesn't,
- // this constructor will add the SWF's domain.
- URL localPath(root, swfURL);
-
- StringNoCaseEqual noCaseCompare;
-
- // All we care about is whether the domains match. They may be
- // empty filesystem-loaded.
- if (!noCaseCompare(localPath.hostname(), _baseDomain)) {
- log_security(_("SharedObject path %s is outside the SWF domain "
- "%s. Cannot access this object."), localPath,
- _baseDomain);
- return 0;
- }
-
- requestedPath = localPath.path();
-
- // The domains match. Now check that the path is a sub-path of
- // the SWF's URL. It is done by case-insensitive string comparison,
- // so a double slash in the requested path will fail.
- if (!noCaseCompare(requestedPath,
- _basePath.substr(0, requestedPath.size()))) {
- log_security(_("SharedObject path %s is not part of the SWF path "
- "%s. Cannot access this object."), requestedPath,
- _basePath);
- return 0;
- }
-
- }
-
- // A leading slash is added later
- std::ostringstream solPath;
-
- // If the domain name is empty, the SWF was loaded from the filesystem.
- // Use "localhost".
- solPath << (_baseDomain.empty() ? "localhost" : _baseDomain);
-
- // Paths should start with a '/', so we shouldn't have to add another
- // one.
- assert(requestedPath.empty() ? _basePath[0] == '/' :
- requestedPath[0] == '/');
-
- // If no path was requested, use the SWF's path.
- solPath << (requestedPath.empty() ? _basePath : requestedPath) << "/"
- << objName;
-
- // TODO: normalize key!
-
- const std::string& key = solPath.str();
-
- // If the shared object was already opened, use it.
- SoLib::iterator it = _soLib.find(key);
- if ( it != _soLib.end() )
- {
- log_debug("SharedObject %s already known, returning it", key);
- return it->second;
- }
-
- log_debug("SharedObject %s not loaded. Loading it now", key);
-
- // Otherwise create a new one and register to the lib
- SharedObject_as* obj = new SharedObject_as;
- _soLib[key] = obj;
-
- obj->setObjectName(objName);
-
- std::string newspec = _solSafeDir;
- newspec += "/";
- newspec += key;
- newspec += ".sol";
- obj->setFilespec(newspec);
-
- log_debug("SharedObject path: %s", newspec);
-
- boost::intrusive_ptr<as_object> data = readSOL(_vm, newspec);
-
- /// Don't set to 0, or it will initialize a property.
- if (data) obj->setData(data.get());
-
- return obj;
-}
-
-void
-sharedobject_class_init(as_object& global)
-{
- static boost::intrusive_ptr<builtin_function> cl;
-
- if (cl == NULL) {
- cl=new builtin_function(&sharedobject_ctor,
getSharedObjectInterface());
- attachSharedObjectStaticInterface(*cl);
- }
-
- // Register _global.SharedObject
- global.init_member("SharedObject", cl.get());
-}
-
-void
-registerSharedObjectNative(as_object& o)
-{
- VM& vm = o.getVM();
-
- // ASnative table registration
- vm.registerNative(sharedobject_connect, 2106, 0);
- vm.registerNative(sharedobject_send, 2106, 1);
- vm.registerNative(sharedobject_flush, 2106, 2);
- vm.registerNative(sharedobject_close, 2106, 3);
- vm.registerNative(sharedobject_getsize, 2106, 4);
- vm.registerNative(sharedobject_setFps, 2106, 5);
- vm.registerNative(sharedobject_clear, 2106, 6);
-
- // FIXME: getRemote and getLocal use both these methods,
- // but aren't identical with either of them.
- // TODO: The first method looks in a library and returns either a
- // SharedObject or null. The second takes a new SharedObject as
- // its first argument and populates its data member (more or less
- // like readSOL). This is only important for ASNative compatibility.
- vm.registerNative(sharedobject_getLocal, 2106, 202);
- vm.registerNative(sharedobject_getRemote, 2106, 203);
- vm.registerNative(sharedobject_getLocal, 2106, 204);
- vm.registerNative(sharedobject_getRemote, 2106, 205);
-
- vm.registerNative(sharedobject_deleteAll, 2106, 206);
- vm.registerNative(sharedobject_getDiskUsage, 2106, 207);
-}
-
-
-/// SharedObject AS interface
-namespace {
-
-void
-attachSharedObjectInterface(as_object& o)
-{
-
- VM& vm = o.getVM();
-
- const int flags = as_prop_flags::dontEnum |
- as_prop_flags::dontDelete |
- as_prop_flags::onlySWF6Up;
-
- o.init_member("connect", vm.getNative(2106, 0), flags);
- o.init_member("send", vm.getNative(2106, 1), flags);
- o.init_member("flush", vm.getNative(2106, 2), flags);
- o.init_member("close", vm.getNative(2106, 3), flags);
- o.init_member("getSize", vm.getNative(2106, 4), flags);
- o.init_member("setFps", vm.getNative(2106, 5), flags);
- o.init_member("clear", vm.getNative(2106, 6), flags);
-
-}
-
-
-void
-attachSharedObjectStaticInterface(as_object& o)
-{
- VM& vm = o.getVM();
-
- const int flags = 0;
-
- o.init_member("getLocal",
- new builtin_function(sharedobject_getLocal), flags);
- o.init_member("getRemote",
- new builtin_function(sharedobject_getRemote), flags);
-
- const int hiddenOnly = as_prop_flags::dontEnum;
-
- o.init_member("deleteAll", vm.getNative(2106, 206), hiddenOnly);
- o.init_member("getDiskUsage", vm.getNative(2106, 207), hiddenOnly);
-}
-
-
-as_object*
-getSharedObjectInterface()
-{
-
- static boost::intrusive_ptr<as_object> o;
- if ( ! o ) {
- o = new as_object(getObjectInterface());
- attachSharedObjectInterface(*o);
- }
- return o.get();
-}
-
-
-as_value
-sharedobject_clear(const fn_call& fn)
-{
- boost::intrusive_ptr<SharedObject_as> obj =
- ensureType<SharedObject_as>(fn.this_ptr);
- UNUSED(obj);
-
- LOG_ONCE(log_unimpl (__FUNCTION__));
-
- return as_value();
-}
-
-as_value
-sharedobject_connect(const fn_call& fn)
-{
- boost::intrusive_ptr<SharedObject_as> obj =
- ensureType<SharedObject_as>(fn.this_ptr);
- UNUSED(obj);
-
- LOG_ONCE(log_unimpl("SharedObject.connect"));
- return as_value();
-}
-
-as_value
-sharedobject_close(const fn_call& fn)
-{
- boost::intrusive_ptr<SharedObject_as> obj =
- ensureType<SharedObject_as>(fn.this_ptr);
- UNUSED(obj);
-
- LOG_ONCE(log_unimpl("SharedObject.close"));
- return as_value();
-}
-
-as_value
-sharedobject_setFps(const fn_call& fn)
-{
- boost::intrusive_ptr<SharedObject_as> obj =
- ensureType<SharedObject_as>(fn.this_ptr);
- UNUSED(obj);
-
- LOG_ONCE(log_unimpl("SharedObject.setFps"));
- return as_value();
-}
-
-as_value
-sharedobject_send(const fn_call& fn)
-{
- boost::intrusive_ptr<SharedObject_as> obj =
- ensureType<SharedObject_as>(fn.this_ptr);
- UNUSED(obj);
-
- LOG_ONCE(log_unimpl("SharedObject.send"));
- return as_value();
-}
-
-as_value
-sharedobject_flush(const fn_call& fn)
-{
-
- GNASH_REPORT_FUNCTION;
-
- boost::intrusive_ptr<SharedObject_as> obj =
- ensureType<SharedObject_as>(fn.this_ptr);
-
- IF_VERBOSE_ASCODING_ERRORS(
- if (fn.nargs > 1)
- {
- std::ostringstream ss;
- fn.dump_args(ss);
- log_aserror(_("Arguments to SharedObject.flush(%s) will be "
- "ignored"), ss.str());
- }
- );
-
- int space = 0;
- if (fn.nargs) {
- space = fn.arg(0).to_int();
- }
-
- /// If there is no data member, returns undefined.
- if (!obj->data()) return as_value();
-
- // If there is an object data member, returns the success of flush().
- return as_value(obj->flush(space));
-}
-
-// Set the file name
-as_value
-sharedobject_getLocal(const fn_call& fn)
-{
-
- VM& vm = fn.env().getVM();
- int swfVersion = vm.getSWFVersion();
-
- as_value objNameVal;
- if (fn.nargs > 0) objNameVal = fn.arg(0);
- std::string objName = objNameVal.to_string_versioned(swfVersion);
- if ( objName.empty() )
- {
- IF_VERBOSE_ASCODING_ERRORS(
- std::ostringstream ss;
- fn.dump_args(ss);
- log_aserror("SharedObject.getLocal(%s): %s",
- _("missing object name"));
- );
- as_value ret;
- ret.set_null();
- return ret;
- }
-
- std::string root;
- if (fn.nargs > 1)
- {
- root = fn.arg(1).to_string_versioned(swfVersion);
- }
-
- log_debug("SO name:%s, root:%s", objName, root);
-
- SharedObject_as* obj = vm.getSharedObjectLibrary().getLocal(objName, root);
-
- as_value ret(obj);
- log_debug("SharedObject.getLocal returning %s", ret);
- return ret;
-}
-
-/// Undocumented
-as_value
-sharedobject_getRemote(const fn_call& fn)
-{
- boost::intrusive_ptr<SharedObject_as> obj =
- ensureType<SharedObject_as>(fn.this_ptr);
-
- UNUSED(obj);
-
- LOG_ONCE(log_unimpl("SharedObject.getRemote()"));
- return as_value();
-}
-
-
-/// Undocumented
-//
-/// Takes a URL argument and deletes all SharedObjects under that URL.
-as_value
-sharedobject_deleteAll(const fn_call& fn)
-{
- boost::intrusive_ptr<SharedObject_as> obj =
- ensureType<SharedObject_as>(fn.this_ptr);
-
- UNUSED(obj);
-
- LOG_ONCE(log_unimpl("SharedObject.deleteAll()"));
- return as_value();
-}
-
-/// Undocumented
-//
-/// Should be quite obvious what it does.
-as_value
-sharedobject_getDiskUsage(const fn_call& fn)
-{
- boost::intrusive_ptr<SharedObject_as> obj =
- ensureType<SharedObject_as>(fn.this_ptr);
-
- UNUSED(obj);
-
- LOG_ONCE(log_unimpl("SharedObject.getDiskUsage()"));
- return as_value();
-}
-
-
-as_value
-sharedobject_data(const fn_call& fn)
-{
- boost::intrusive_ptr<SharedObject_as> obj =
- ensureType<SharedObject_as>(fn.this_ptr);
- return as_value(obj->data());
-}
-
-as_value
-sharedobject_getsize(const fn_call& fn)
-{
- boost::intrusive_ptr<SharedObject_as> obj =
- ensureType<SharedObject_as>(fn.this_ptr);
- return as_value(obj->size());
-}
-
-as_value
-sharedobject_ctor(const fn_call& /* fn */)
-{
- boost::intrusive_ptr<as_object> obj = new SharedObject_as;
-
- return as_value(obj.get()); // will keep alive
-}
-
-/// Return true if the name is a valid SOL name.
-//
-/// The official docs claim that '%' is also an invalid DisplayObject,
-/// but that is incorrect (see actionscript.all/SharedObject.as)
-bool
-validateName(const std::string& solName)
-{
- // A double forward slash isn't allowed
- std::string::size_type pos = solName.find("//");
- if (pos != std::string::npos) return false;
-
- // These DisplayObjects are also illegal
- pos = solName.find_first_of(",~;\"'<&>?#:\\ ");
-
- return (pos == std::string::npos);
-}
-
-as_object*
-readSOL(VM& vm, const std::string& filespec)
-{
-
-#ifdef BUFFERED_AMF_SOL
-
- // The 'data' member is initialized only on getLocal() (and probably
- // getRemote()): i.e. when there is some data, or when it's ready to
- // be added.
- as_object* data = new as_object(getObjectInterface());
-
- struct stat st;
-
- if (stat(filespec.c_str(), &st) != 0)
- {
- // No existing SOL file. A new one will be created.
- log_debug("No existing SOL %s found. Will create on flush/exit.",
- filespec);
- return data;
- }
-
- if (st.st_size < 28)
- {
- // A SOL file exists, but it was invalid. Count it as not existing.
- log_error("SharedObject::readSOL: SOL file %s is too short "
- "(only %s bytes long) to be valid.", filespec, st.st_size);
- return data;
- }
-
- boost::scoped_array<boost::uint8_t> sbuf(new boost::uint8_t[st.st_size]);
- const boost::uint8_t *buf = sbuf.get();
- const boost::uint8_t *end = buf + st.st_size;
-
- try
- {
- std::ifstream ifs(filespec.c_str(), std::ios::binary);
- ifs.read(reinterpret_cast<char*>(sbuf.get()), st.st_size);
-
- // TODO check initial bytes, and print warnings if they are fishy
-
- buf += 16; // skip const-length headers
-
- // skip past name TODO add sanity check
- buf += ntohs(*(reinterpret_cast<const boost::uint16_t*>(buf)));
- buf += 2;
-
- buf += 4; // skip past padding
-
- if (buf >= end)
- {
- // In this case there is no data member.
- log_error("SharedObject::readSOL: file ends before data segment");
- return data;
- }
-
- std::vector<as_object*> objRefs;
-
- while (buf < end)
- {
- log_debug("SharedObject::readSOL: reading property name at "
- "byte %s", buf - sbuf.get());
- // read property name
- boost::uint16_t len =
- ntohs(*(reinterpret_cast<const boost::uint16_t*>(buf)));
- buf += 2;
-
- if( buf + len >= end )
- {
- log_error("SharedObject::readSOL: premature end of input");
- break;
- }
- if ( ! len ) {
- log_error("SharedObject::readSOL: empty property name");
- break;
- }
- std::string prop_name(reinterpret_cast<const char*>(buf), len);
- buf += len;
-
- // read value
- as_value as;
- if (!as.readAMF0(buf, end, -1, objRefs, vm)) {
- log_error("SharedObject::readSOL: Parsing SharedObject '%s'",
- filespec);
- return false;
- }
-
- log_debug("parsed sol member named '%s' (len %s), value '%s'",
- prop_name, len, as);
-
- // set name/value as a member of this (SharedObject) object
- string_table& st = vm.getStringTable();
- data->set_member(st.find(prop_name), as);
-
- buf += 1; // skip null byte after each property
- }
- return data;
- }
- catch (std::exception& e)
- {
- log_error("SharedObject::readSOL: Reading SharedObject %s: %s",
- filespec, e.what());
- return 0;
- }
-
-#else
- SOL sol;
- log_security("Opening SharedObject file: %s", filespec);
- if (sol.readFile(filespec) == false) {
- log_security("empty or non-existing SOL file \"%s\", will be "
- "created on flush/exit", filespec);
- return false;
- }
-
- std::vector<boost::shared_ptr<amf::Element> >::const_iterator it, e;
- std::vector<boost::shared_ptr<amf::Element> > els = sol.getElements();
- log_debug("Read %d AMF objects from %s", els.size(), filespec);
-
- as_value as = getMember(NSV::PROP_DATA);
- boost::intrusive_ptr<as_object> ptr = as.to_object();
-
- for (it = els.begin(), e = els.end(); it != e; it++) {
- boost::shared_ptr<amf::Element> el = *it;
-
-#if 0 // this would be using as_value::as_value(const Element&)
-
- std::string name(el->getName());
- as_value val(*el);
- ptr->set_member(st.find(name), val);
-
-#else // this is original code
-
- switch (el->getType())
- {
- case Element::NUMBER_AMF0:
- {
- double dub = *(reinterpret_cast<double*>(el->getData()));
- ptr->set_member(st.string_table::find(el->getName()),
- as_value(dub));
- break;
- }
-
- case Element::BOOLEAN_AMF0:
- ptr->set_member(st.string_table::find(el->getName()),
- as_value(el->to_bool()));
- break;
-
- case Element::STRING_AMF0:
- {
- if (el->getLength() == 0) {
- ptr->set_member(st.string_table::find(el->getName()), "");
- break;
- }
-
- std::string str(reinterpret_cast<const char*>(el->getData()),
- el->getLength());
- ptr->set_member(st.string_table::find(el->getName()), str);
- break;
- }
-
- case Element::OBJECT_AMF0:
- // TODO: implement!
- log_unimpl("Reading OBJECT type from SharedObject");
- //data.convert_to_object();
- //ptr->set_member(st.string_table::find(el->name), data);
- return false;
- break;
-
- default:
- // TODO: what about other types?
- log_unimpl("Reading SOL type %d", el->getType());
- return false;
- break;
- }
-
-#endif
-
- }
-
- return true;
-#endif
-}
-
-
-void
-flushSOL(SharedObjectLibrary::SoLib::value_type& sol)
-{
- sol.second->flush();
-}
-
-} // anonymous namespace
-} // end of gnash namespace
=== removed file 'libcore/asobj/SharedObject_as.h'
--- a/libcore/asobj/SharedObject_as.h 2009-01-22 20:10:39 +0000
+++ b/libcore/asobj/SharedObject_as.h 1970-01-01 00:00:00 +0000
@@ -1,84 +0,0 @@
-//
-// Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-//
-
-#ifndef GNASH_ASOBJ_SHAREDOBJECT_H
-#define GNASH_ASOBJ_SHAREDOBJECT_H
-
-#include <string>
-#include <map>
-
-// Forward declarations
-namespace gnash {
- class as_object;
- class SharedObject_as;
- class VM;
-}
-
-namespace gnash {
-
-class SharedObjectLibrary
-{
-public:
-
- typedef std::map<std::string, SharedObject_as*> SoLib;
-
- SharedObjectLibrary(VM& vm);
-
- ~SharedObjectLibrary();
-
- /// Return a local shared object with given name and with given root
- //
- /// May return NULL if name is invalid or can't access the given root
- ///
- SharedObject_as* getLocal(const std::string& name, const std::string&
root);
-
- void markReachableResources() const;
-
- // Drop all library items
- void clear();
-
-private:
-
- VM& _vm;
-
- /// Domain component of the VM SWF url
- std::string _baseDomain;
-
- /// Path component of the VM SWF url
- std::string _basePath;
-
- /// Base SOL dir
- std::string _solSafeDir;
-
- SoLib _soLib;
-};
-
-/// Initialize the global SharedObject class
-void sharedobject_class_init(as_object& global);
-
-void registerSharedObjectNative(as_object& o);
-
-
-} // end of gnash namespace
-
-#endif
-
-// local Variables:
-// mode: C++
-// indent-tabs-mode: t
-// End:
=== removed file 'libcore/asobj/Stage_as.cpp'
--- a/libcore/asobj/Stage_as.cpp 2009-03-02 12:12:43 +0000
+++ b/libcore/asobj/Stage_as.cpp 1970-01-01 00:00:00 +0000
@@ -1,301 +0,0 @@
-// Stage_as.cpp: All the world is one, for Gnash.
-//
-// Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-//
-
-#ifdef HAVE_CONFIG_H
-#include "gnashconfig.h"
-#endif
-
-#include "Stage_as.h"
-#include "movie_root.h"
-#include "as_object.h" // for inheritance
-#include "log.h"
-#include "fn_call.h"
-#include "smart_ptr.h" // for boost intrusive_ptr
-#include "builtin_function.h" // need builtin_function
-#include "VM.h"
-#include "Object.h" // for getObjectInterface()
-#include "AsBroadcaster.h" // for initializing self as a broadcaster
-#include "namedStrings.h"
-#include "StringPredicates.h"
-
-#include <string>
-
-namespace gnash {
-
-static as_value stage_scalemode_getset(const fn_call& fn);
-static as_value stage_align_getset(const fn_call& fn);
-static as_value stage_showMenu_getset(const fn_call& fn);
-static as_value stage_width_getset(const fn_call& fn);
-static as_value stage_height_getset(const fn_call& fn);
-static as_value stage_displaystate_getset(const fn_call& fn);
-static const char* getScaleModeString(movie_root::ScaleMode sm);
-static const char* getDisplayStateString(movie_root::DisplayState ds);
-
-void registerStageNative(as_object& o)
-{
- VM& vm = o.getVM();
-
- vm.registerNative(stage_scalemode_getset, 666, 1);
- vm.registerNative(stage_scalemode_getset, 666, 2);
- vm.registerNative(stage_align_getset, 666, 3);
- vm.registerNative(stage_align_getset, 666, 4);
- vm.registerNative(stage_width_getset, 666, 5);
- vm.registerNative(stage_width_getset, 666, 6);
- vm.registerNative(stage_height_getset, 666, 7);
- vm.registerNative(stage_height_getset, 666, 8);
- vm.registerNative(stage_showMenu_getset, 666, 9);
- vm.registerNative(stage_showMenu_getset, 666, 10);
-}
-
-static void
-attachStageInterface(as_object& o)
-{
- const int version = o.getVM().getSWFVersion();
-
- if ( version < 5 ) return;
-
- o.init_property("scaleMode", &stage_scalemode_getset,
&stage_scalemode_getset);
- o.init_property("align", &stage_align_getset, &stage_align_getset);
- o.init_property("width", &stage_width_getset, &stage_width_getset);
- o.init_property("height", &stage_height_getset, &stage_height_getset);
- o.init_property("showMenu", &stage_showMenu_getset,
&stage_showMenu_getset);
- o.init_property("displayState", &stage_displaystate_getset,
&stage_displaystate_getset);
-
-}
-
-
-Stage_as::Stage_as()
- :
- as_object(getObjectInterface())
-{
- attachStageInterface(*this);
-
- const int swfversion = _vm.getSWFVersion();
- if ( swfversion > 5 )
- {
- AsBroadcaster::initialize(*this);
- }
-}
-
-
-void
-Stage_as::notifyFullScreen(bool fs)
-{
- // Should we notify resize here, or does movie_root do it anyway
- // when the gui changes size?
- log_debug("notifying Stage listeners about fullscreen state");
- callMethod(NSV::PROP_BROADCAST_MESSAGE, "onFullScreen", fs);
-}
-
-
-void
-Stage_as::notifyResize()
-{
- log_debug("notifying Stage listeners about a resize");
- callMethod(NSV::PROP_BROADCAST_MESSAGE, "onResize");
-}
-
-
-const char*
-getDisplayStateString(movie_root::DisplayState ds)
-{
- static const char* displayStateName[] = {
- "normal",
- "fullScreen" };
-
- return displayStateName[ds];
-}
-
-
-const char*
-getScaleModeString(movie_root::ScaleMode sm)
-{
- static const char* modeName[] = {
- "showAll",
- "noScale",
- "exactFit",
- "noBorder" };
-
- return modeName[sm];
-}
-
-
-as_value
-stage_scalemode_getset(const fn_call& fn)
-{
-
- boost::intrusive_ptr<as_object> obj=ensureType<as_object>(fn.this_ptr);
-
- movie_root& m = obj->getVM().getRoot();
-
- if ( fn.nargs == 0 ) // getter
- {
- return as_value(getScaleModeString(m.getStageScaleMode()));
- }
- else // setter
- {
- // Defaults to showAll if the string is invalid.
- movie_root::ScaleMode mode = movie_root::showAll;
-
- const std::string& str = fn.arg(0).to_string();
-
- StringNoCaseEqual noCaseCompare;
-
- if ( noCaseCompare(str, "noScale") ) mode = movie_root::noScale;
- else if ( noCaseCompare(str, "exactFit") ) mode =
movie_root::exactFit;
- else if ( noCaseCompare(str, "noBorder") ) mode =
movie_root::noBorder;
-
- if ( m.getStageScaleMode() == mode ) return as_value(); // nothing to
do
-
- m.setStageScaleMode(mode);
- return as_value();
- }
-}
-
-as_value
-stage_width_getset(const fn_call& fn)
-{
- boost::intrusive_ptr<as_object> obj=ensureType<as_object>(fn.this_ptr);
-
- if ( fn.nargs > 0 ) // setter
- {
- IF_VERBOSE_ASCODING_ERRORS(
- log_aserror(_("Stage.width is a read-only property!"));
- );
- return as_value();
- }
-
- // getter
- movie_root& m = obj->getVM().getRoot();
- return as_value(m.getStageWidth());
-}
-
-as_value
-stage_height_getset(const fn_call& fn)
-{
- boost::intrusive_ptr<as_object> obj=ensureType<as_object>(fn.this_ptr);
-
- if ( fn.nargs > 0 ) // setter
- {
- IF_VERBOSE_ASCODING_ERRORS(
- log_aserror(_("Stage.height is a read-only property!"));
- );
- return as_value();
- }
-
- // getter
- movie_root& m = obj->getVM().getRoot();
- return as_value(m.getStageHeight());
-}
-
-
-as_value
-stage_align_getset(const fn_call& fn)
-{
- boost::intrusive_ptr<as_object> obj=ensureType<as_object>(fn.this_ptr);
-
- movie_root& m = obj->getVM().getRoot();
-
- if ( fn.nargs == 0 ) // getter
- {
- return as_value (m.getStageAlignMode());
- }
- else // setter
- {
- const std::string& str = fn.arg(0).to_string();
- short am = 0;
-
- // Easy enough to do bitwise - std::bitset is not
- // really necessary!
- if (str.find_first_of("lL") != std::string::npos)
- {
- am |= 1 << movie_root::STAGE_ALIGN_L;
- }
-
- if (str.find_first_of("tT") != std::string::npos)
- {
- am |= 1 << movie_root::STAGE_ALIGN_T;
- }
-
- if (str.find_first_of("rR") != std::string::npos)
- {
- am |= 1 << movie_root::STAGE_ALIGN_R;
- }
-
- if (str.find_first_of("bB") != std::string::npos)
- {
- am |= 1 << movie_root::STAGE_ALIGN_B;
- }
-
- m.setStageAlignment(am);
-
- return as_value();
- }
-}
-
-as_value
-stage_showMenu_getset(const fn_call& fn)
-{
- boost::intrusive_ptr<Stage_as> stage =
ensureType<Stage_as>(fn.this_ptr);
-
- if ( fn.nargs == 0 ) // getter
- {
- LOG_ONCE(log_unimpl("Stage.showMenu getter"));
- return as_value();
- }
- else // setter
- {
- LOG_ONCE(log_unimpl("Stage.showMenu setter"));
- return as_value();
- }
-}
-
-as_value
-stage_displaystate_getset(const fn_call& fn)
-{
- boost::intrusive_ptr<as_object> obj=ensureType<as_object>(fn.this_ptr);
-
- movie_root& m = obj->getVM().getRoot();
-
- if (!fn.nargs) {
- return getDisplayStateString(m.getStageDisplayState());
- }
-
- StringNoCaseEqual noCaseCompare;
-
- const std::string& str = fn.arg(0).to_string();
- if (noCaseCompare(str, "normal")) {
- m.setStageDisplayState(movie_root::DISPLAYSTATE_NORMAL);
- }
- else if (noCaseCompare(str, "fullScreen")) {
- m.setStageDisplayState(movie_root::DISPLAYSTATE_FULLSCREEN);
- }
-
- // If invalid, do nothing.
- return as_value();
-}
-
-// extern (used by Global.cpp)
-void stage_class_init(as_object& global)
-{
- static boost::intrusive_ptr<as_object> obj = new Stage_as();
- global.init_member("Stage", obj.get());
-}
-
-} // end of gnash namespace
=== removed file 'libcore/asobj/Stage_as.h'
--- a/libcore/asobj/Stage_as.h 2009-03-02 12:12:43 +0000
+++ b/libcore/asobj/Stage_as.h 1970-01-01 00:00:00 +0000
@@ -1,69 +0,0 @@
-//
-// Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-//
-
-#ifndef GNASH_ASOBJ_STAGE_H
-#define GNASH_ASOBJ_STAGE_H
-
-#include "as_object.h" // for inheritance
-#include "movie_root.h" // for access to scaleMode
-
-#include <list>
-
-namespace gnash {
-
-/// This is the Stage ActionScript object.
-//
-/// Some Stage methods are implemented in movie_root, because
-/// it provides the interface to the Gui and/or all the values
-/// required are necessarily in movie_root:
-///
-/// - scaleMode
-/// - width
-/// - height
-/// - displayState
-/// - alignMode
-//
-/// Most functions are ASnative, which means they cannot rely on
-/// the existence of a load-on-demand Stage object. Only resize events
-/// appear to need this (not ASnative). The ASnative functions
-/// are available from SWF5
-
-class Stage_as: public as_object
-{
-
-public:
-
- Stage_as();
-
- /// Notify all listeners about a resize event
- void notifyResize();
-
- void notifyFullScreen(bool fs);
-
-};
-
-/// Register native functions with the VM.
-void registerStageNative(as_object& o);
-
-/// Initialize the global Stage class
-void stage_class_init(as_object& global);
-
-} // end of gnash namespace
-
-#endif
-
=== modified file 'libcore/asobj/flash.am'
--- a/libcore/asobj/flash.am 2009-06-09 11:38:31 +0000
+++ b/libcore/asobj/flash.am 2009-06-09 15:51:03 +0000
@@ -46,10 +46,8 @@
asobj/Number_as.cpp \
asobj/PlayHead.cpp \
asobj/Selection_as.cpp \
- asobj/SharedObject_as.cpp\
asobj/Namespace_as.cpp \
asobj/Sound_as.cpp \
- asobj/Stage_as.cpp \
asobj/System_as.cpp \
asobj/TextFormat_as.cpp \
asobj/MovieClipLoader.cpp\
@@ -79,9 +77,7 @@
asobj/Number_as.h \
asobj/PlayHead.h \
asobj/Selection_as.h \
- asobj/SharedObject_as.h \
asobj/Sound_as.h \
- asobj/Stage_as.h \
asobj/System_as.h \
asobj/TextFormat_as.h \
asobj/String_as.h \
=== modified file 'libcore/asobj/flash/display/Stage_as.cpp'
--- a/libcore/asobj/flash/display/Stage_as.cpp 2009-05-28 17:10:05 +0000
+++ b/libcore/asobj/flash/display/Stage_as.cpp 2009-06-09 15:51:03 +0000
@@ -28,8 +28,46 @@
#include "builtin_function.h" // need builtin_function
#include "GnashException.h" // for ActionException
+// ADDED
+#include "movie_root.h"
+#include "as_object.h" // for inheritance
+#include "VM.h"
+#include "Object.h" // for getObjectInterface()
+#include "AsBroadcaster.h" // for initializing self as a broadcaster
+#include "namedStrings.h"
+#include "StringPredicates.h"
+
+#include <string>
+// END ADDED SECTION
+
namespace gnash {
+static as_value stage_scalemode_getset(const fn_call& fn);
+static as_value stage_align_getset(const fn_call& fn);
+static as_value stage_showMenu_getset(const fn_call& fn);
+static as_value stage_width_getset(const fn_call& fn);
+static as_value stage_height_getset(const fn_call& fn);
+static as_value stage_displaystate_getset(const fn_call& fn);
+static const char* getScaleModeString(movie_root::ScaleMode sm);
+static const char* getDisplayStateString(movie_root::DisplayState ds);
+
+void registerStageNative(as_object& o)
+{
+ VM& vm = o.getVM();
+
+ vm.registerNative(stage_scalemode_getset, 666, 1);
+ vm.registerNative(stage_scalemode_getset, 666, 2);
+ vm.registerNative(stage_align_getset, 666, 3);
+ vm.registerNative(stage_align_getset, 666, 4);
+ vm.registerNative(stage_width_getset, 666, 5);
+ vm.registerNative(stage_width_getset, 666, 6);
+ vm.registerNative(stage_height_getset, 666, 7);
+ vm.registerNative(stage_height_getset, 666, 8);
+ vm.registerNative(stage_showMenu_getset, 666, 9);
+ vm.registerNative(stage_showMenu_getset, 666, 10);
+}
+
+
// Forward declarations
namespace {
as_value stage_addChildAt(const fn_call& fn);
@@ -49,19 +87,225 @@
void attachStageInterface(as_object& o);
void attachStageStaticInterface(as_object& o);
as_object* getStageInterface();
-
-}
-
-class Stage_as : public as_object
-{
-
-public:
-
- Stage_as()
- :
- as_object(getStageInterface())
- {}
-};
+
+// ADDED
+
+}
+
+Stage_as::Stage_as()
+ :
+ as_object(getObjectInterface())
+{
+ attachStageInterface(*this);
+
+ const int swfversion = _vm.getSWFVersion();
+ if ( swfversion > 5 )
+ {
+ AsBroadcaster::initialize(*this);
+ }
+}
+
+void
+Stage_as::notifyFullScreen(bool fs)
+{
+ // Should we notify resize here, or does movie_root do it anyway
+ // when the gui changes size?
+ log_debug("notifying Stage listeners about fullscreen state");
+ callMethod(NSV::PROP_BROADCAST_MESSAGE, "onFullScreen", fs);
+}
+
+
+void
+Stage_as::notifyResize()
+{
+ log_debug("notifying Stage listeners about a resize");
+ callMethod(NSV::PROP_BROADCAST_MESSAGE, "onResize");
+}
+
+// ADDED
+const char*
+getDisplayStateString(movie_root::DisplayState ds)
+{
+ static const char* displayStateName[] = {
+ "normal",
+ "fullScreen" };
+
+ return displayStateName[ds];
+}
+
+// ADDED
+const char*
+getScaleModeString(movie_root::ScaleMode sm)
+{
+ static const char* modeName[] = {
+ "showAll",
+ "noScale",
+ "exactFit",
+ "noBorder" };
+
+ return modeName[sm];
+}
+
+// ADDED
+as_value
+stage_scalemode_getset(const fn_call& fn)
+{
+
+ boost::intrusive_ptr<as_object> obj=ensureType<as_object>(fn.this_ptr);
+
+ movie_root& m = obj->getVM().getRoot();
+
+ if ( fn.nargs == 0 ) // getter
+ {
+ return as_value(getScaleModeString(m.getStageScaleMode()));
+ }
+ else // setter
+ {
+ // Defaults to showAll if the string is invalid.
+ movie_root::ScaleMode mode = movie_root::showAll;
+
+ const std::string& str = fn.arg(0).to_string();
+
+ StringNoCaseEqual noCaseCompare;
+
+ if ( noCaseCompare(str, "noScale") ) mode = movie_root::noScale;
+ else if ( noCaseCompare(str, "exactFit") ) mode =
movie_root::exactFit;
+ else if ( noCaseCompare(str, "noBorder") ) mode =
movie_root::noBorder;
+
+ if ( m.getStageScaleMode() == mode ) return as_value(); // nothing to
do
+
+ m.setStageScaleMode(mode);
+ return as_value();
+ }
+}
+
+
+// ADDED
+as_value
+stage_width_getset(const fn_call& fn)
+{
+ boost::intrusive_ptr<as_object> obj=ensureType<as_object>(fn.this_ptr);
+
+ if ( fn.nargs > 0 ) // setter
+ {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror(_("Stage.width is a read-only property!"));
+ );
+ return as_value();
+ }
+
+ // getter
+ movie_root& m = obj->getVM().getRoot();
+ return as_value(m.getStageWidth());
+}
+
+// ADDED
+as_value
+stage_height_getset(const fn_call& fn)
+{
+ boost::intrusive_ptr<as_object> obj=ensureType<as_object>(fn.this_ptr);
+
+ if ( fn.nargs > 0 ) // setter
+ {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror(_("Stage.height is a read-only property!"));
+ );
+ return as_value();
+ }
+
+ // getter
+ movie_root& m = obj->getVM().getRoot();
+ return as_value(m.getStageHeight());
+}
+
+// ADDED
+as_value
+stage_align_getset(const fn_call& fn)
+{
+ boost::intrusive_ptr<as_object> obj=ensureType<as_object>(fn.this_ptr);
+
+ movie_root& m = obj->getVM().getRoot();
+
+ if ( fn.nargs == 0 ) // getter
+ {
+ return as_value (m.getStageAlignMode());
+ }
+ else // setter
+ {
+ const std::string& str = fn.arg(0).to_string();
+ short am = 0;
+
+ // Easy enough to do bitwise - std::bitset is not
+ // really necessary!
+ if (str.find_first_of("lL") != std::string::npos)
+ {
+ am |= 1 << movie_root::STAGE_ALIGN_L;
+ }
+
+ if (str.find_first_of("tT") != std::string::npos)
+ {
+ am |= 1 << movie_root::STAGE_ALIGN_T;
+ }
+
+ if (str.find_first_of("rR") != std::string::npos)
+ {
+ am |= 1 << movie_root::STAGE_ALIGN_R;
+ }
+
+ if (str.find_first_of("bB") != std::string::npos)
+ {
+ am |= 1 << movie_root::STAGE_ALIGN_B;
+ }
+
+ m.setStageAlignment(am);
+
+ return as_value();
+ }
+}
+
+// ADDED
+as_value
+stage_showMenu_getset(const fn_call& fn)
+{
+ boost::intrusive_ptr<Stage_as> stage =
ensureType<Stage_as>(fn.this_ptr);
+
+ if ( fn.nargs == 0 ) // getter
+ {
+ LOG_ONCE(log_unimpl("Stage.showMenu getter"));
+ return as_value();
+ }
+ else // setter
+ {
+ LOG_ONCE(log_unimpl("Stage.showMenu setter"));
+ return as_value();
+ }
+}
+
+// ADDED
+as_value
+stage_displaystate_getset(const fn_call& fn)
+{
+ boost::intrusive_ptr<as_object> obj=ensureType<as_object>(fn.this_ptr);
+
+ movie_root& m = obj->getVM().getRoot();
+
+ if (!fn.nargs) {
+ return getDisplayStateString(m.getStageDisplayState());
+ }
+
+ StringNoCaseEqual noCaseCompare;
+
+ const std::string& str = fn.arg(0).to_string();
+ if (noCaseCompare(str, "normal")) {
+ m.setStageDisplayState(movie_root::DISPLAYSTATE_NORMAL);
+ }
+ else if (noCaseCompare(str, "fullScreen")) {
+ m.setStageDisplayState(movie_root::DISPLAYSTATE_FULLSCREEN);
+ }
+
+ // If invalid, do nothing.
+ return as_value();
+}
// extern (used by Global.cpp)
void stage_class_init(as_object& global)
@@ -82,6 +326,18 @@
void
attachStageInterface(as_object& o)
{
+ const int version = o.getVM().getSWFVersion();
+
+ if ( version < 5 ) return;
+
+ o.init_property("scaleMode", &stage_scalemode_getset,
&stage_scalemode_getset);
+ o.init_property("align", &stage_align_getset, &stage_align_getset);
+ o.init_property("width", &stage_width_getset, &stage_width_getset);
+ o.init_property("height", &stage_height_getset, &stage_height_getset);
+ o.init_property("showMenu", &stage_showMenu_getset,
&stage_showMenu_getset);
+ o.init_property("displayState", &stage_displaystate_getset,
&stage_displaystate_getset);
+
+
o.init_member("addChildAt", new builtin_function(stage_addChildAt));
o.init_member("addEventListener", new
builtin_function(stage_addEventListener));
o.init_member("dispatchEvent", new builtin_function(stage_dispatchEvent));
=== modified file 'libcore/asobj/flash/display/Stage_as.h'
--- a/libcore/asobj/flash/display/Stage_as.h 2009-05-28 17:29:17 +0000
+++ b/libcore/asobj/flash/display/Stage_as.h 2009-06-08 21:22:11 +0000
@@ -24,15 +24,55 @@
#include "gnashconfig.h"
#endif
+// ADDED
+#include "as_object.h" // for inheritance
+#include "movie_root.h" // for access to scaleMode
+
+#include <list>
// Forward declarations
class as_object;
namespace gnash {
+
+// ADDED
+/// This is the Stage ActionScript object.
+//
+/// Some Stage methods are implemented in movie_root, because
+/// it provides the interface to the Gui and/or all the values
+/// required are necessarily in movie_root:
+///
+/// - scaleMode
+/// - width
+/// - height
+/// - displayState
+/// - alignMode
+//
+/// Most functions are ASnative, which means they cannot rely on
+/// the existence of a load-on-demand Stage object. Only resize events
+/// appear to need this (not ASnative). The ASnative functions
+/// are available from SWF5
+
+class Stage_as: public as_object
+{
+
+public:
+
+ Stage_as();
+
+ /// Notify all listeners about a resize event
+ void notifyResize();
+
+ void notifyFullScreen(bool fs);
+
+};
/// Initialize the global Stage class
void stage_class_init(as_object& global);
+// ADDED
+void registerStageNative(as_object& o);
+
} // gnash namespace
// GNASH_ASOBJ3_STAGE_H
=== modified file 'libcore/asobj/flash/display/display.am'
--- a/libcore/asobj/flash/display/display.am 2009-06-07 18:12:15 +0000
+++ b/libcore/asobj/flash/display/display.am 2009-06-08 21:22:11 +0000
@@ -184,10 +184,10 @@
endif
# FIXME: already exists
-# if BUILD_STAGE_AS3
-# DISPLAY_SOURCES += asobj/flash/display/Stage_as.cpp
+if BUILD_STAGE_AS3
+DISPLAY_SOURCES += asobj/flash/display/Stage_as.cpp
DISPLAY_HEADERS += asobj/flash/display/Stage_as.h
-# endif
+endif
libgnashasobjs_la_SOURCES += $(DISPLAY_SOURCES) $(DISPLAY_SOURCES_AS2)
noinst_HEADERS += $(DISPLAY_HEADERS) $(DISPLAY_HEADERS_AS2) \
=== modified file 'libcore/asobj/flash/net/SharedObject_as.cpp'
--- a/libcore/asobj/flash/net/SharedObject_as.cpp 2009-05-28 17:12:46
+0000
+++ b/libcore/asobj/flash/net/SharedObject_as.cpp 2009-06-08 21:22:11
+0000
@@ -21,48 +21,600 @@
#include "gnashconfig.h"
#endif
-#include "net/SharedObject_as.h"
+#include "flash/net/SharedObject_as.h"
#include "log.h"
#include "fn_call.h"
#include "smart_ptr.h" // for boost intrusive_ptr
#include "builtin_function.h" // need builtin_function
#include "GnashException.h" // for ActionException
+// ADDED
+#include "GnashSystemNetHeaders.h"
+#include "GnashFileUtilities.h" // stat
+#include "SimpleBuffer.h"
+#include "as_value.h"
+#include "amf.h"
+#include "element.h"
+#include "sol.h"
+#include "movie_root.h"
+#include "as_object.h" // for inheritance
+#include "Object.h" // for getObjectInterface
+#include "VM.h"
+#include "Property.h"
+#include "string_table.h"
+#include "URLAccessManager.h"
+#include "URL.h"
+#include "rc.h" // for use of rcfile
+
+#include <boost/tokenizer.hpp>
+#include <boost/scoped_array.hpp>
+#include <boost/shared_ptr.hpp>
+
+// Undefine this to use the Element-based AMF0 decoder/encoder.
+// May be useful to test libamf.
+#define BUFFERED_AMF_SOL
+
+namespace {
+gnash::RcInitFile& rcfile = gnash::RcInitFile::getDefaultInstance();
+}
+
+using namespace amf;
+
namespace gnash {
// Forward declarations
namespace {
- as_value sharedobject_close(const fn_call& fn);
- as_value sharedobject_connect(const fn_call& fn);
- as_value sharedobject_flush(const fn_call& fn);
- as_value sharedobject_getLocal(const fn_call& fn);
- as_value sharedobject_getRemote(const fn_call& fn);
- as_value sharedobject_send(const fn_call& fn);
- as_value sharedobject_setDirty(const fn_call& fn);
- as_value sharedobject_setProperty(const fn_call& fn);
- as_value sharedobject_asyncError(const fn_call& fn);
- as_value sharedobject_netStatus(const fn_call& fn);
- as_value sharedobject_sync(const fn_call& fn);
- as_value sharedobject_ctor(const fn_call& fn);
- void attachSharedObjectInterface(as_object& o);
- void attachSharedObjectStaticInterface(as_object& o);
+ as_value sharedobject_close(const fn_call& fn);
+ as_value sharedobject_connect(const fn_call& fn);
+ as_value sharedobject_flush(const fn_call& fn);
+ as_value sharedobject_getLocal(const fn_call& fn);
+ as_value sharedobject_getRemote(const fn_call& fn);
+ as_value sharedobject_send(const fn_call& fn);
+ as_value sharedobject_setDirty(const fn_call& fn);
+ as_value sharedobject_setProperty(const fn_call& fn);
+ as_value sharedobject_asyncError(const fn_call& fn);
+ as_value sharedobject_netStatus(const fn_call& fn);
+ as_value sharedobject_sync(const fn_call& fn);
+ as_value sharedobject_ctor(const fn_call& fn);
+ void attachSharedObjectInterface(as_object& o);
+ void attachSharedObjectStaticInterface(as_object& o);
as_object* getSharedObjectInterface();
+ // ADDED
+ as_value sharedobject_getsize(const fn_call& fn);
+ as_value sharedobject_setFps(const fn_call& fn);
+ as_value sharedobject_clear(const fn_call& fn);
+ as_value sharedobject_deleteAll(const fn_call& fn);
+ as_value sharedobject_getDiskUsage(const fn_call& fn);
+ as_value sharedobject_data(const fn_call& fn);
+
+ as_object* readSOL(VM& vm, const std::string& filespec);
+
+ as_object* getSharedObjectInterface();
+ void flushSOL(SharedObjectLibrary::SoLib::value_type& sol);
+ bool validateName(const std::string& solName);
+
+
}
-class SharedObject_as : public as_object
-{
-
-public:
+// ADDED
+// Serializer helper
+class PropsSerializer : public AbstractPropertyVisitor
+{
+public:
+
+ PropsSerializer(SOL& sol, VM& vm)
+ :
+ _sol(sol),
+ _st(vm.getStringTable())
+ {};
+
+ void accept(string_table::key key, const as_value& val)
+ {
+ AMF amf;
+ boost::shared_ptr<amf::Element> el;
+
+ const std::string& name = _st.string_table::value(key);
+
+ //log_debug("Serializing SharedObject property %s:%s", name, val);
+
+ if (val.is_string()) {
+ std::string str;
+ if (!val.is_undefined()) {
+ str = val.to_string();
+ }
+ el.reset(new amf::Element(name, str));
+ }
+ if (val.is_bool()) {
+ bool flag = val.to_bool();
+ el.reset(new amf::Element(name, flag));
+ }
+ if (val.is_number()) {
+ double dub;
+ if (val.is_undefined()) {
+ dub = 0.0;
+ } else {
+ dub = val.to_number();
+ }
+ el.reset(new amf::Element(name, dub));
+ }
+
+ if (el) {
+ _sol.addObj(el);
+ }
+ }
+
+private:
+
+ SOL& _sol;
+ string_table& _st;
+};
+
+/// Class used to serialize properties of an object to a buffer in SOL format
+class SOLPropsBufSerializer : public AbstractPropertyVisitor
+{
+
+ typedef std::map<as_object*, size_t> PropertiesOffsetTable;
+
+public:
+
+ SOLPropsBufSerializer(SimpleBuffer& buf, VM& vm,
+ PropertiesOffsetTable& offsetTable)
+ :
+ _buf(buf),
+ _vm(vm),
+ _st(vm.getStringTable()),
+ _offsetTable(offsetTable),
+ _error(false)
+ {};
+
+ bool success() const { return !_error; }
+
+ virtual void accept(string_table::key key, const as_value& val)
+ {
+ if ( _error ) return;
+
+ if ( val.is_function() )
+ {
+ log_debug("SOL: skip serialization of FUNCTION property");
+ return;
+ }
+
+ // Test conducted with AMFPHP:
+ // '__proto__' and 'constructor' members
+ // of an object don't get back from an 'echo-service'.
+ // Dunno if they are not serialized or just not sent back.
+ // A '__constructor__' member gets back, but only if
+ // not a function. Actually no function gets back.
+ //
+ if ( key == NSV::PROP_uuPROTOuu || key == NSV::PROP_CONSTRUCTOR )
+ {
+#ifdef GNASH_DEBUG_AMF_SERIALIZE
+ log_debug(" skip serialization of specially-named property %s",
+ _st.value(key));
+#endif
+ return;
+ }
+
+ // write property name
+ const std::string& name = _st.value(key);
+#ifdef GNASH_DEBUG_AMF_SERIALIZE
+ log_debug(" serializing property %s", name);
+#endif
+ boost::uint16_t namelen = name.size();
+ _buf.appendNetworkShort(namelen);
+ _buf.append(name.c_str(), namelen);
+ // Strict array are never encoded in SharedObject
+ if ( ! val.writeAMF0(_buf, _offsetTable, _vm, false) )
+ {
+ log_error("Problems serializing an object's member %s=%s",
+ name, val);
+ _error = true;
+ }
+
+ _buf.appendByte(0); // SOL-specific
+ }
+
+private:
+
+ SimpleBuffer& _buf;
+
+ VM& _vm;
+
+ string_table& _st;
+
+ PropertiesOffsetTable& _offsetTable;
+
+ bool _error;
+};
+
+// MODIFIED
+class SharedObject_as: public as_object
+{
+public:
+
+ ~SharedObject_as();
SharedObject_as()
:
- as_object(getSharedObjectInterface())
- {}
+ as_object(getSharedObjectInterface()),
+ _data(0)
+ {
+ }
+
+ bool flush(int space = 0) const;
+
+ const std::string& getFilespec() const {
+ return _sol.getFilespec();
+ }
+
+ void setFilespec(const std::string& s) {
+ _sol.setFilespec(s);
+ }
+
+ const std::string& getObjectName() const {
+ return _sol.getObjectName();
+ }
+
+ void setObjectName(const std::string& s) {
+ _sol.setObjectName(s);
+ }
+
+ /// This isn't correct, as the default implementation doesn't use SOL
+ /// for reading.
+ size_t size() const {
+ return _sol.fileSize();
+ }
+
+ void setData(as_object* data) {
+
+ assert(data);
+ _data = data;
+
+ const int flags = as_prop_flags::dontDelete |
+ as_prop_flags::readOnly;
+
+ init_property(NSV::PROP_DATA, &sharedobject_data, &sharedobject_data,
+ flags);
+
+ }
+
+ as_object* data() {
+ return _data;
+ }
+
+ const as_object* data() const {
+ return _data;
+ }
+
+protected:
+
+ void markReachableResources() const {
+ if (_data) _data->setReachable();
+ }
+
+private:
+
+ as_object* _data;
+
+ SOL _sol;
};
+SharedObject_as::~SharedObject_as()
+{
+}
+
+bool
+SharedObject_as::flush(int space) const
+{
+
+ /// This is called on on destruction of the SharedObject, or (allegedly)
+ /// on a call to SharedObject.data, so _data is not guaranteed to exist.
+ //
+ /// The function should never be called from SharedObject.flush() when
+ /// _data is 0.
+ if (!_data) return false;
+
+ if (space > 0) {
+ log_unimpl("SharedObject.flush() called with a minimum disk space "
+ "argument (%d), which is currently ignored", space);
+ }
+
+ const std::string& filespec = _sol.getFilespec();
+
+ if (!mkdirRecursive(filespec))
+ {
+ log_error("Couldn't create dir for flushing SharedObject %s",
filespec);
+ return false;
+ }
+
+#ifdef USE_SOL_READONLY
+ log_debug(_("SharedObject %s not flushed (compiled as read-only mode)"),
+ filespec);
+ return false;
+#endif
+
+ if (rcfile.getSOLReadOnly() ) {
+ log_security("Attempting to write object %s when it's SOL "
+ "Read Only is set! Refusing...", filespec);
+ return false;
+ }
+
+#ifdef BUFFERED_AMF_SOL
+
+ gnash::SimpleBuffer buf;
+ // see http://osflash.org/documentation/amf/envelopes/sharedobject
+
+ // length field filled in later
+ buf.append("\x00\xbf\x00\x00\x00\x00TCSO\x00\x04\x00\x00\x00\x00", 16);
+
+ // append object name
+ std::string object_name = getObjectName();
+ boost::uint16_t len = object_name.length();
+ buf.appendNetworkShort(len);
+ buf.append(object_name.c_str(), len);
+
+ // append padding
+ buf.append("\x00\x00\x00\x00", 4);
+
+ // append properties of object
+ VM& vm = getVM();
+
+ std::map<as_object*, size_t> offsetTable;
+ SOLPropsBufSerializer props(buf, vm, offsetTable);
+ _data->visitPropertyValues(props);
+ if ( ! props.success() )
+ {
+ log_error("Could not serialize object");
+ return false;
+ }
+
+ // fix length field
+ *(reinterpret_cast<uint32_t*>(buf.data() + 2)) = htonl(buf.size() - 6);
+
+ // TODO write file
+ std::ofstream ofs(filespec.c_str(), std::ios::binary);
+ if (!ofs) {
+ log_error("SharedObject::flush(): Failed opening file '%s' in "
+ "binary mode", filespec.c_str());
+ return false;
+ }
+
+ if (ofs.write(reinterpret_cast<const char*>(buf.data()),
buf.size()).fail())
+ {
+ log_error("Error writing %d bytes to output file %s",
+ buf.size(), filespec.c_str());
+ ofs.close();
+ return false;
+ }
+ ofs.close();
+
+#else // amf::SOL-based serialization
+
+ // append properties of object
+ VM& vm = getVM();
+
+ SOL sol;
+ PropsSerializer props(sol, vm);
+ _data->visitPropertyValues(props);
+ // We only want to access files in this directory
+ bool ret = sol.writeFile(filespec, getObjectName().c_str());
+ if ( ! ret )
+ {
+ log_error("writing SharedObject file to %s", filespec);
+ return false;
+ }
+#endif
+
+ log_security("SharedObject '%s' written to filesystem.", filespec);
+ return true;
+}
+
+SharedObjectLibrary::SharedObjectLibrary(VM& vm)
+ :
+ _vm(vm)
+{
+ _solSafeDir = rcfile.getSOLSafeDir();
+ if (_solSafeDir.empty()) {
+ log_debug("Empty SOLSafeDir directive: we'll use '/tmp'");
+ _solSafeDir = "/tmp/";
+ }
+
+ // Check if the base dir exists here
+ struct stat statbuf;
+ if ( -1 == stat(_solSafeDir.c_str(), &statbuf) )
+ {
+ log_debug("Invalid SOL safe dir %s: %s. Will try to create on "
+ "flush/exit.", _solSafeDir, std::strerror(errno));
+ }
+
+ // Which URL we should use here is under research.
+ // The reference player uses the URL from which definition
+ // of the call to SharedObject.getLocal was parsed.
+ //
+ // There is in Gnash support for tracking action_buffer
+ // urls but not yet an interface to fetch it from fn_call;
+ // also, it's not clear how good would the model be (think
+ // of movie A loading movie B creating the SharedObject).
+ //
+ // What we'll do for now is use the URL of the initially
+ // loaded SWF, so that in the A loads B scenario above the
+ // domain would be the one of A, not B.
+ //
+ // NOTE: using the base url RunInfo::baseURL() would mean
+ // blindly trusting the SWF publisher as base url is changed
+ // by the 'base' attribute of OBJECT or EMBED tags trough
+ // -P base=xxx
+ //
+ const movie_root& mr = _vm.getRoot();
+ const std::string& swfURL = mr.getOriginalURL();
+
+ URL url(swfURL);
+
+ // Remember the hostname of our SWF URL. This can be empty if loaded
+ // from the filesystem
+ _baseDomain = url.hostname();
+
+ const std::string& urlPath = url.path();
+
+ // Get the path part. If loaded from the filesystem, the pp stupidly
+ // removes the first directory.
+ if (!_baseDomain.empty()) {
+ _basePath = urlPath;
+ }
+ else if (!urlPath.empty()) {
+ // _basePath should be empty if there are no slashes or just one.
+ std::string::size_type pos = urlPath.find('/', 1);
+ if (pos != std::string::npos) {
+ _basePath = urlPath.substr(pos);
+ }
+ }
+
+}
+
+void
+SharedObjectLibrary::markReachableResources() const
+{
+ for (SoLib::const_iterator it = _soLib.begin(), itE = _soLib.end();
+ it != itE; ++it)
+ {
+ SharedObject_as* sh = it->second;
+ sh->setReachable();
+ }
+}
+
+/// The SharedObjectLibrary keeps all known SharedObjects alive. They must
+/// be flushed on clear(). This is called at the latest by the dtor, which
+/// is called at the latest by VM's dtor (currently earlier to avoid problems
+/// with the GC).
+void
+SharedObjectLibrary::clear()
+{
+ std::for_each(_soLib.begin(), _soLib.end(), &flushSOL);
+ _soLib.clear();
+}
+
+SharedObjectLibrary::~SharedObjectLibrary()
+{
+ clear();
+}
+
+SharedObject_as*
+SharedObjectLibrary::getLocal(const std::string& objName,
+ const std::string& root)
+{
+ assert (!objName.empty());
+
+ // already warned about it at construction time
+ if (_solSafeDir.empty()) return 0;
+
+ if (rcfile.getSOLLocalDomain() && !_baseDomain.empty())
+ {
+ log_security("Attempting to open SOL file from non "
+ "localhost-loaded SWF");
+ return 0;
+ }
+
+ // Check that the name is valid; if not, return null
+ if (!validateName(objName)) return 0;
+
+ // The 'root' argument, otherwise known as localPath, specifies where
+ // in the SWF path the SOL should be stored. It cannot be outside this
+ // path.
+ std::string requestedPath;
+
+ // If a root is specified, check it first for validity
+ if (!root.empty()) {
+
+ const movie_root& mr = _vm.getRoot();
+ const std::string& swfURL = mr.getOriginalURL();
+ // The specified root may or may not have a domain. If it doesn't,
+ // this constructor will add the SWF's domain.
+ URL localPath(root, swfURL);
+
+ StringNoCaseEqual noCaseCompare;
+
+ // All we care about is whether the domains match. They may be
+ // empty filesystem-loaded.
+ if (!noCaseCompare(localPath.hostname(), _baseDomain)) {
+ log_security(_("SharedObject path %s is outside the SWF domain "
+ "%s. Cannot access this object."), localPath,
+ _baseDomain);
+ return 0;
+ }
+
+ requestedPath = localPath.path();
+
+ // The domains match. Now check that the path is a sub-path of
+ // the SWF's URL. It is done by case-insensitive string comparison,
+ // so a double slash in the requested path will fail.
+ if (!noCaseCompare(requestedPath,
+ _basePath.substr(0, requestedPath.size()))) {
+ log_security(_("SharedObject path %s is not part of the SWF path "
+ "%s. Cannot access this object."), requestedPath,
+ _basePath);
+ return 0;
+ }
+
+ }
+
+ // A leading slash is added later
+ std::ostringstream solPath;
+
+ // If the domain name is empty, the SWF was loaded from the filesystem.
+ // Use "localhost".
+ solPath << (_baseDomain.empty() ? "localhost" : _baseDomain);
+
+ // Paths should start with a '/', so we shouldn't have to add another
+ // one.
+ assert(requestedPath.empty() ? _basePath[0] == '/' :
+ requestedPath[0] == '/');
+
+ // If no path was requested, use the SWF's path.
+ solPath << (requestedPath.empty() ? _basePath : requestedPath) << "/"
+ << objName;
+
+ // TODO: normalize key!
+
+ const std::string& key = solPath.str();
+
+ // If the shared object was already opened, use it.
+ SoLib::iterator it = _soLib.find(key);
+ if ( it != _soLib.end() )
+ {
+ log_debug("SharedObject %s already known, returning it", key);
+ return it->second;
+ }
+
+ log_debug("SharedObject %s not loaded. Loading it now", key);
+
+ // Otherwise create a new one and register to the lib
+ SharedObject_as* obj = new SharedObject_as;
+ _soLib[key] = obj;
+
+ obj->setObjectName(objName);
+
+ std::string newspec = _solSafeDir;
+ newspec += "/";
+ newspec += key;
+ newspec += ".sol";
+ obj->setFilespec(newspec);
+
+ log_debug("SharedObject path: %s", newspec);
+
+ boost::intrusive_ptr<as_object> data = readSOL(_vm, newspec);
+
+ /// Don't set to 0, or it will initialize a property.
+ if (data) obj->setData(data.get());
+
+ return obj;
+}
+
+
+// UNCHANGED
// extern (used by Global.cpp)
-void sharedobject_class_init(as_object& global)
+void
+sharedobject_class_init(as_object& global)
{
static boost::intrusive_ptr<builtin_function> cl;
@@ -80,25 +632,60 @@
void
attachSharedObjectInterface(as_object& o)
{
- o.init_member("close", new builtin_function(sharedobject_close));
- o.init_member("connect", new builtin_function(sharedobject_connect));
- o.init_member("flush", new builtin_function(sharedobject_flush));
- o.init_member("getLocal", new builtin_function(sharedobject_getLocal));
- o.init_member("getRemote", new builtin_function(sharedobject_getRemote));
- o.init_member("send", new builtin_function(sharedobject_send));
- o.init_member("setDirty", new builtin_function(sharedobject_setDirty));
- o.init_member("setProperty", new
builtin_function(sharedobject_setProperty));
- o.init_member("asyncError", new builtin_function(sharedobject_asyncError));
- o.init_member("netStatus", new builtin_function(sharedobject_netStatus));
- o.init_member("sync", new builtin_function(sharedobject_sync));
+ //VM& vm = o.getVM();
+
+ o.init_member("close", new builtin_function(sharedobject_close));
+ o.init_member("connect", new builtin_function(sharedobject_connect));
+ o.init_member("flush", new builtin_function(sharedobject_flush));
+ o.init_member("getLocal", new builtin_function(sharedobject_getLocal));
+ o.init_member("getRemote", new
builtin_function(sharedobject_getRemote));
+ o.init_member("send", new builtin_function(sharedobject_send));
+ o.init_member("setDirty", new builtin_function(sharedobject_setDirty));
+ o.init_member("setProperty", new
builtin_function(sharedobject_setProperty));
+ o.init_member("asyncError", new
builtin_function(sharedobject_asyncError));
+ o.init_member("netStatus", new
builtin_function(sharedobject_netStatus));
+ o.init_member("sync", new builtin_function(sharedobject_sync));
+
+ // ADDED
+ o.init_member("getSize", new builtin_function(sharedobject_getsize));
+ o.init_member("setFps", new builtin_function(sharedobject_setFps));
+ o.init_member("clear", new builtin_function(sharedobject_clear));
+
}
void
attachSharedObjectStaticInterface(as_object& o)
{
-
-}
-
+ // MODIFIED
+ VM& vm = o.getVM();
+
+ const int flags = 0;
+
+ o.init_member("getLocal",
+ new builtin_function(sharedobject_getLocal), flags);
+ o.init_member("getRemote",
+ new builtin_function(sharedobject_getRemote), flags);
+
+ const int hiddenOnly = as_prop_flags::dontEnum;
+
+ o.init_member("deleteAll", vm.getNative(2106, 206), hiddenOnly);
+ o.init_member("getDiskUsage", vm.getNative(2106, 207), hiddenOnly);
+}
+
+// ADDED
+as_value
+sharedobject_clear(const fn_call& fn)
+{
+ boost::intrusive_ptr<SharedObject_as> obj =
+ ensureType<SharedObject_as>(fn.this_ptr);
+ UNUSED(obj);
+
+ LOG_ONCE(log_unimpl (__FUNCTION__));
+
+ return as_value();
+}
+
+// UNCHANGED
as_object*
getSharedObjectInterface()
{
@@ -110,6 +697,7 @@
return o.get();
}
+// UNCHANGED
as_value
sharedobject_close(const fn_call& fn)
{
@@ -120,6 +708,7 @@
return as_value();
}
+// UNCHANGED
as_value
sharedobject_connect(const fn_call& fn)
{
@@ -130,26 +719,76 @@
return as_value();
}
+// MODIFIED
as_value
sharedobject_flush(const fn_call& fn)
{
- boost::intrusive_ptr<SharedObject_as> ptr =
+ GNASH_REPORT_FUNCTION;
+
+ boost::intrusive_ptr<SharedObject_as> obj =
ensureType<SharedObject_as>(fn.this_ptr);
- UNUSED(ptr);
- log_unimpl (__FUNCTION__);
- return as_value();
+
+ IF_VERBOSE_ASCODING_ERRORS(
+ if (fn.nargs > 1)
+ {
+ std::ostringstream ss;
+ fn.dump_args(ss);
+ log_aserror(_("Arguments to SharedObject.flush(%s) will be "
+ "ignored"), ss.str());
+ }
+ );
+
+ int space = 0;
+ if (fn.nargs) {
+ space = fn.arg(0).to_int();
+ }
+
+ /// If there is no data member, returns undefined.
+ if (!obj->data()) return as_value();
+
+ // If there is an object data member, returns the success of flush().
+ return as_value(obj->flush(space));
}
+// MODIFIED
as_value
sharedobject_getLocal(const fn_call& fn)
{
- boost::intrusive_ptr<SharedObject_as> ptr =
- ensureType<SharedObject_as>(fn.this_ptr);
- UNUSED(ptr);
- log_unimpl (__FUNCTION__);
- return as_value();
+ VM& vm = fn.env().getVM();
+ int swfVersion = vm.getSWFVersion();
+
+ as_value objNameVal;
+ if (fn.nargs > 0) objNameVal = fn.arg(0);
+ std::string objName = objNameVal.to_string_versioned(swfVersion);
+ if ( objName.empty() )
+ {
+ IF_VERBOSE_ASCODING_ERRORS(
+ std::ostringstream ss;
+ fn.dump_args(ss);
+ log_aserror("SharedObject.getLocal(%s): %s",
+ _("missing object name"));
+ );
+ as_value ret;
+ ret.set_null();
+ return ret;
+ }
+
+ std::string root;
+ if (fn.nargs > 1)
+ {
+ root = fn.arg(1).to_string_versioned(swfVersion);
+ }
+
+ log_debug("SO name:%s, root:%s", objName, root);
+
+ SharedObject_as* obj = vm.getSharedObjectLibrary().getLocal(objName, root);
+
+ as_value ret(obj);
+ log_debug("SharedObject.getLocal returning %s", ret);
+ return ret;
}
+// UNCHANGED
as_value
sharedobject_getRemote(const fn_call& fn)
{
@@ -160,6 +799,7 @@
return as_value();
}
+// UNCHANGED
as_value
sharedobject_send(const fn_call& fn)
{
@@ -170,6 +810,7 @@
return as_value();
}
+// UNCHANGED
as_value
sharedobject_setDirty(const fn_call& fn)
{
@@ -180,6 +821,7 @@
return as_value();
}
+// UNCHANGED
as_value
sharedobject_setProperty(const fn_call& fn)
{
@@ -190,6 +832,7 @@
return as_value();
}
+// UNCHANGED
as_value
sharedobject_asyncError(const fn_call& fn)
{
@@ -200,6 +843,7 @@
return as_value();
}
+// UNCHANGED
as_value
sharedobject_netStatus(const fn_call& fn)
{
@@ -210,6 +854,7 @@
return as_value();
}
+// UNCHANGED
as_value
sharedobject_sync(const fn_call& fn)
{
@@ -220,6 +865,7 @@
return as_value();
}
+// UNCHANGED
as_value
sharedobject_ctor(const fn_call& fn)
{
@@ -228,7 +874,304 @@
return as_value(obj.get()); // will keep alive
}
+// ADDED
+/// Undocumented
+/// Takes a URL argument and deletes all SharedObjects under that URL.
+as_value
+sharedobject_deleteAll(const fn_call& fn)
+{
+ boost::intrusive_ptr<SharedObject_as> obj =
+ ensureType<SharedObject_as>(fn.this_ptr);
+
+ UNUSED(obj);
+
+ LOG_ONCE(log_unimpl("SharedObject.deleteAll()"));
+ return as_value();
+}
+
+// ADDED
+/// Undocumented
+/// Should be quite obvious what it does.
+as_value
+sharedobject_getDiskUsage(const fn_call& fn)
+{
+ boost::intrusive_ptr<SharedObject_as> obj =
+ ensureType<SharedObject_as>(fn.this_ptr);
+
+ UNUSED(obj);
+
+ LOG_ONCE(log_unimpl("SharedObject.getDiskUsage()"));
+ return as_value();
+}
+
+// ADDED
+as_value
+sharedobject_data(const fn_call& fn)
+{
+ boost::intrusive_ptr<SharedObject_as> obj =
+ ensureType<SharedObject_as>(fn.this_ptr);
+ return as_value(obj->data());
+}
+
+// ADDED
+as_value
+sharedobject_getsize(const fn_call& fn)
+{
+ boost::intrusive_ptr<SharedObject_as> obj =
+ ensureType<SharedObject_as>(fn.this_ptr);
+ return as_value(obj->size());
+}
+
+// ADDED
+as_value
+sharedobject_setFps(const fn_call& fn)
+{
+ boost::intrusive_ptr<SharedObject_as> obj =
+ ensureType<SharedObject_as>(fn.this_ptr);
+ UNUSED(obj);
+
+ LOG_ONCE(log_unimpl("SharedObject.setFps"));
+ return as_value();
+}
+
+// ADDED
+as_object*
+readSOL(VM& vm, const std::string& filespec)
+{
+
+#ifdef BUFFERED_AMF_SOL
+
+ // The 'data' member is initialized only on getLocal() (and probably
+ // getRemote()): i.e. when there is some data, or when it's ready to
+ // be added.
+ as_object* data = new as_object(getObjectInterface());
+
+ struct stat st;
+
+ if (stat(filespec.c_str(), &st) != 0)
+ {
+ // No existing SOL file. A new one will be created.
+ log_debug("No existing SOL %s found. Will create on flush/exit.",
+ filespec);
+ return data;
+ }
+
+ if (st.st_size < 28)
+ {
+ // A SOL file exists, but it was invalid. Count it as not existing.
+ log_error("SharedObject::readSOL: SOL file %s is too short "
+ "(only %s bytes long) to be valid.", filespec, st.st_size);
+ return data;
+ }
+
+ boost::scoped_array<boost::uint8_t> sbuf(new boost::uint8_t[st.st_size]);
+ const boost::uint8_t *buf = sbuf.get();
+ const boost::uint8_t *end = buf + st.st_size;
+
+ try
+ {
+ std::ifstream ifs(filespec.c_str(), std::ios::binary);
+ ifs.read(reinterpret_cast<char*>(sbuf.get()), st.st_size);
+
+ // TODO check initial bytes, and print warnings if they are fishy
+
+ buf += 16; // skip const-length headers
+
+ // skip past name TODO add sanity check
+ buf += ntohs(*(reinterpret_cast<const boost::uint16_t*>(buf)));
+ buf += 2;
+
+ buf += 4; // skip past padding
+
+ if (buf >= end)
+ {
+ // In this case there is no data member.
+ log_error("SharedObject::readSOL: file ends before data segment");
+ return data;
+ }
+
+ std::vector<as_object*> objRefs;
+
+ while (buf < end)
+ {
+ log_debug("SharedObject::readSOL: reading property name at "
+ "byte %s", buf - sbuf.get());
+ // read property name
+ boost::uint16_t len =
+ ntohs(*(reinterpret_cast<const boost::uint16_t*>(buf)));
+ buf += 2;
+
+ if( buf + len >= end )
+ {
+ log_error("SharedObject::readSOL: premature end of input");
+ break;
+ }
+ if ( ! len ) {
+ log_error("SharedObject::readSOL: empty property name");
+ break;
+ }
+ std::string prop_name(reinterpret_cast<const char*>(buf), len);
+ buf += len;
+
+ // read value
+ as_value as;
+ if (!as.readAMF0(buf, end, -1, objRefs, vm)) {
+ log_error("SharedObject::readSOL: Parsing SharedObject '%s'",
+ filespec);
+ return false;
+ }
+
+ log_debug("parsed sol member named '%s' (len %s), value '%s'",
+ prop_name, len, as);
+
+ // set name/value as a member of this (SharedObject) object
+ string_table& st = vm.getStringTable();
+ data->set_member(st.find(prop_name), as);
+
+ buf += 1; // skip null byte after each property
+ }
+ return data;
+ }
+ catch (std::exception& e)
+ {
+ log_error("SharedObject::readSOL: Reading SharedObject %s: %s",
+ filespec, e.what());
+ return 0;
+ }
+
+#else
+ SOL sol;
+ log_security("Opening SharedObject file: %s", filespec);
+ if (sol.readFile(filespec) == false) {
+ log_security("empty or non-existing SOL file \"%s\", will be "
+ "created on flush/exit", filespec);
+ return false;
+ }
+
+ std::vector<boost::shared_ptr<amf::Element> >::const_iterator it, e;
+ std::vector<boost::shared_ptr<amf::Element> > els = sol.getElements();
+ log_debug("Read %d AMF objects from %s", els.size(), filespec);
+
+ as_value as = getMember(NSV::PROP_DATA);
+ boost::intrusive_ptr<as_object> ptr = as.to_object();
+
+ for (it = els.begin(), e = els.end(); it != e; it++) {
+ boost::shared_ptr<amf::Element> el = *it;
+
+#if 0 // this would be using as_value::as_value(const Element&)
+
+ std::string name(el->getName());
+ as_value val(*el);
+ ptr->set_member(st.find(name), val);
+
+#else // this is original code
+
+ switch (el->getType())
+ {
+ case Element::NUMBER_AMF0:
+ {
+ double dub = *(reinterpret_cast<double*>(el->getData()));
+ ptr->set_member(st.string_table::find(el->getName()),
+ as_value(dub));
+ break;
+ }
+
+ case Element::BOOLEAN_AMF0:
+ ptr->set_member(st.string_table::find(el->getName()),
+ as_value(el->to_bool()));
+
+ case Element::STRING_AMF0:
+ {
+ if (el->getLength() == 0) {
+ ptr->set_member(st.string_table::find(el->getName()), "");
+ break;
+ }
+
+ std::string str(reinterpret_cast<const char*>(el->getData()),
+ el->getLength());
+ ptr->set_member(st.string_table::find(el->getName()), str);
+ break;
+ }
+
+ case Element::OBJECT_AMF0:
+ // TODO: implement!
+ log_unimpl("Reading OBJECT type from SharedObject");
+ //data.convert_to_object();
+ //ptr->set_member(st.string_table::find(el->name), data);
+ return false;
+ break;
+
+ default:
+ // TODO: what about other types?
+ log_unimpl("Reading SOL type %d", el->getType());
+ return false;
+ break;
+ }
+
+#endif
+
+ }
+
+ return true;
+#endif
+}
+
+// ADDED
+void
+flushSOL(SharedObjectLibrary::SoLib::value_type& sol)
+{
+ sol.second->flush();
+}
+
+// ADDED
+/// Return true if the name is a valid SOL name.
+/// The official docs claim that '%' is also an invalid DisplayObject,
+/// but that is incorrect (see actionscript.all/SharedObject.as)
+bool
+validateName(const std::string& solName)
+{
+ // A double forward slash isn't allowed
+ std::string::size_type pos = solName.find("//");
+ if (pos != std::string::npos) return false;
+
+ // These DisplayObjects are also illegal
+ pos = solName.find_first_of(",~;\"'<&>?#:\\ ");
+
+ return (pos == std::string::npos);
+}
+
+
+
} // anonymous namespace
+
+void
+registerSharedObjectNative(as_object& o)
+{
+ VM& vm = o.getVM();
+
+ // ASnative table registration
+ vm.registerNative(sharedobject_connect, 2106, 0);
+ vm.registerNative(sharedobject_send, 2106, 1);
+ vm.registerNative(sharedobject_flush, 2106, 2);
+ vm.registerNative(sharedobject_close, 2106, 3);
+ vm.registerNative(sharedobject_getsize, 2106, 4);
+ vm.registerNative(sharedobject_setFps, 2106, 5);
+ vm.registerNative(sharedobject_clear, 2106, 6);
+
+ // FIXME: getRemote and getLocal use both these methods,
+ // but aren't identical with either of them.
+ // TODO: The first method looks in a library and returns either a
+ // SharedObject or null. The second takes a new SharedObject as
+ // its first argument and populates its data member (more or less
+ // like readSOL). This is only important for ASNative compatibility.
+ vm.registerNative(sharedobject_getLocal, 2106, 202);
+ vm.registerNative(sharedobject_getRemote, 2106, 203);
+ vm.registerNative(sharedobject_getLocal, 2106, 204);
+ vm.registerNative(sharedobject_getRemote, 2106, 205);
+
+ vm.registerNative(sharedobject_deleteAll, 2106, 206);
+ vm.registerNative(sharedobject_getDiskUsage, 2106, 207);
+}
} // gnash namespace
// local Variables:
=== modified file 'libcore/asobj/flash/net/SharedObject_as.h'
--- a/libcore/asobj/flash/net/SharedObject_as.h 2009-05-28 17:29:17 +0000
+++ b/libcore/asobj/flash/net/SharedObject_as.h 2009-06-08 21:22:11 +0000
@@ -24,19 +24,81 @@
#include "gnashconfig.h"
#endif
-
-namespace gnash {
+#include <string>
+#include <map>
+
+// Forward declarations
+namespace gnash {
+ class as_object;
+ class SharedObject_as;
+ class VM;
+}
+
+namespace gnash {
+
+class SharedObjectLibrary
+{
+public:
+
+ typedef std::map<std::string, SharedObject_as*> SoLib;
+
+ SharedObjectLibrary(VM& vm);
+
+ ~SharedObjectLibrary();
+
+ /// Return a local shared object with given name and with given root
+ //
+ /// May return NULL if name is invalid or can't access the given root
+ ///
+ SharedObject_as* getLocal(const std::string& name, const std::string&
root);
+
+ void markReachableResources() const;
+
+ // Drop all library items
+ void clear();
+
+private:
+
+ VM& _vm;
+
+ /// Domain component of the VM SWF url
+ std::string _baseDomain;
+
+ /// Path component of the VM SWF url
+ std::string _basePath;
+
+ /// Base SOL dir
+ std::string _solSafeDir;
+
+ SoLib _soLib;
+};
+
+/// Initialize the global SharedObject class
+void sharedobject_class_init(as_object& global);
+
+void registerSharedObjectNative(as_object& o);
+
+
+} // end of gnash namespace
+
+#endif
+
+
+/*namespace gnash {
// Forward declarations
class as_object;
/// Initialize the global SharedObject class
void sharedobject_class_init(as_object& global);
+void attachSharedObjectInterface(as_object& o);
+void attachSharedObjectStaticInterface(as_object& o);
+
} // gnash namespace
// GNASH_ASOBJ3_SHAREDOBJECT_H
-#endif
+#endif*/
// local Variables:
// mode: C++
=== modified file 'libcore/asobj/flash/net/net.am'
--- a/libcore/asobj/flash/net/net.am 2009-06-07 18:12:15 +0000
+++ b/libcore/asobj/flash/net/net.am 2009-06-08 21:22:11 +0000
@@ -80,7 +80,7 @@
FIXME: already exists
if BUILD_SHAREDOBJECT_AS3
-# NET_SOURCES += asobj/flash/net/SharedObject_as.cpp
+NET_SOURCES += asobj/flash/net/SharedObject_as.cpp
NET_HEADERS += asobj/flash/net/SharedObject_as.h
endif
=== modified file 'libcore/movie_root.cpp'
--- a/libcore/movie_root.cpp 2009-06-08 21:40:22 +0000
+++ b/libcore/movie_root.cpp 2009-06-09 15:51:03 +0000
@@ -27,7 +27,7 @@
#include "render.h"
#include "VM.h"
#include "ExecutableCode.h"
-#include "Stage_as.h"
+#include "flash/display/Stage_as.h"
#include "URL.h"
#include "namedStrings.h"
#include "GnashException.h"
=== modified file 'libcore/vm/VM.cpp'
--- a/libcore/vm/VM.cpp 2009-05-29 06:50:02 +0000
+++ b/libcore/vm/VM.cpp 2009-06-09 15:51:03 +0000
@@ -22,7 +22,7 @@
#endif
#include "VM.h"
-#include "SharedObject_as.h" // for SharedObjectLibrary
+#include "flash/net/SharedObject_as.h" // for SharedObjectLibrary
#include "smart_ptr.h" // GNASH_USE_GC
#include "builtin_function.h"
#include "movie_definition.h"
- [Gnash-commit] /srv/bzr/gnash/trunk r11050: Migrated SharedObject and Stage classes to new hierarchy,
Sharad Desai <=