[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r11948: More tests for LocalConnecti
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r11948: More tests for LocalConnection and SharedObject, fixes to |
Date: |
Mon, 15 Feb 2010 15:21:34 +0100 |
User-agent: |
Bazaar (2.0.3) |
------------------------------------------------------------
revno: 11948 [merge]
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Mon 2010-02-15 15:21:34 +0100
message:
More tests for LocalConnection and SharedObject, fixes to
SharedObject.getSize() and removal of empty SharedObjects.
modified:
libcore/AMF.cpp
libcore/AMF.h
libcore/Makefile.am
libcore/asobj/flash/net/SharedObject_as.cpp
libcore/asobj/flash/net/SharedObject_as.h
testsuite/actionscript.all/SharedObject.as
testsuite/misc-ming.all/LC-Receive.as
testsuite/misc-ming.all/LC-Send.as
testsuite/simultaneous-testrunner.sh
=== modified file 'libcore/AMF.cpp'
--- a/libcore/AMF.cpp 2010-02-10 13:57:22 +0000
+++ b/libcore/AMF.cpp 2010-02-15 10:46:53 +0000
@@ -333,7 +333,7 @@
}
void
-Writer::writeData(boost::uint8_t* data, size_t length)
+Writer::writeData(const boost::uint8_t* data, size_t length)
{
_buf.append(data, length);
}
=== modified file 'libcore/AMF.h'
--- a/libcore/AMF.h 2010-02-10 13:58:27 +0000
+++ b/libcore/AMF.h 2010-02-15 10:46:53 +0000
@@ -112,7 +112,7 @@
bool writePropertyName(const std::string& name);
/// Write custom data for special cases.
- void writeData(boost::uint8_t* data, size_t length);
+ void writeData(const boost::uint8_t* data, size_t length);
private:
=== modified file 'libcore/Makefile.am'
--- a/libcore/Makefile.am 2010-02-08 20:38:34 +0000
+++ b/libcore/Makefile.am 2010-02-15 13:24:24 +0000
@@ -29,7 +29,6 @@
# Only enable if we're configured with --enable-mp3
AM_CPPFLAGS = \
-I$(top_srcdir)/libnet \
- -I$(top_srcdir)/libamf \
-I$(top_srcdir)/backend \
-I$(top_srcdir)/libcore/swf \
-I$(top_srcdir)/libcore/abc \
=== modified file 'libcore/asobj/flash/net/SharedObject_as.cpp'
--- a/libcore/asobj/flash/net/SharedObject_as.cpp 2010-02-10 09:21:47
+0000
+++ b/libcore/asobj/flash/net/SharedObject_as.cpp 2010-02-15 13:45:41
+0000
@@ -19,7 +19,7 @@
//
#ifdef HAVE_CONFIG_H
-#include "gnashconfig.h" // USE_SOL_READ_ONLY
+#include "gnashconfig.h"
#endif
#include "smart_ptr.h" // GNASH_USE_GC
@@ -45,10 +45,11 @@
#include "NetConnection_as.h"
#include "Object.h"
#include "AMF.h"
-#include "sol.h"
+#include "GnashAlgorithm.h"
#include <boost/scoped_array.hpp>
#include <boost/shared_ptr.hpp>
+#include <cstdio>
namespace {
gnash::RcInitFile& rcfile = gnash::RcInitFile::getDefaultInstance();
@@ -64,7 +65,7 @@
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_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);
@@ -73,11 +74,23 @@
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_value sharedobject_setdirty(const fn_call& fn);
- as_value sharedobject_setproperty(const fn_call& fn);
as_object* readSOL(VM& vm, const std::string& filespec);
+ /// Encode the SharedObject data.
+ //
+ /// @param name The name of the SharedObject.
+ /// @param data The data object to encode.
+ /// @param buf The SimpleBuffer to encode the data to.
+ bool encodeData(const std::string& name, as_object& data,
+ SimpleBuffer& buf);
+
+ /// Encode the 2 header bytes and data length field.
+ //
+ /// @param size The genuine size of the object data.
+ /// @param buf The SimpleBuffer to encode the data to.
+ void encodeHeader(const size_t size, SimpleBuffer& buf);
+
void attachSharedObjectInterface(as_object& o);
void attachSharedObjectStaticInterface(as_object& o);
void flushSOL(SharedObjectLibrary::SoLib::value_type& sol);
@@ -95,21 +108,34 @@
public:
- SOLPropsBufSerializer(AMF::Writer w, VM& vm)
+ SOLPropsBufSerializer(AMF::Writer w, string_table& st)
:
_writer(w),
- _vm(vm),
- _st(vm.getStringTable()),
- _error(false)
- {};
+ _st(st),
+ _error(false),
+ _count(0)
+ {}
- bool success() const { return !_error; }
+ /// Check if the object data was successfully encoded.
+ //
+ /// Success means that no encoding errors were encountered and at least one
+ /// property was encoded.
+ bool success() const {
+ return !_error && _count;
+ }
+ /// Visitor called for each property to serialize.
+ //
+ /// SOL serialization calls this for all existing properties, whether
+ /// visible or not.
+ //
+ /// accept() returns false if the visitor should stop, true if it should
+ /// go on to the next property.
virtual bool accept(const ObjectURI& uri, const as_value& val)
{
assert(!_error);
- if ( val.is_function()) {
+ if (val.is_function()) {
log_debug("SOL: skip serialization of FUNCTION property");
return true;
}
@@ -117,49 +143,52 @@
const string_table::key key = getName(uri);
// Test conducted with AMFPHP:
- // '__proto__' and 'constructor' members
- // of an object don't get back from an 'echo-service'.
+ // '__proto__' and 'constructor' members of an object are not returned
+ // 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
+ // A '__constructor__' member is returned, but only if
+ // not a function; no functions are returned at all.
+ if (key == NSV::PROP_uuPROTOuu || key == NSV::PROP_CONSTRUCTOR) {
return true;
}
// write property name
const std::string& name = _st.value(key);
-#ifdef GNASH_DEBUG_AMF_SERIALIZE
- log_debug(" serializing property %s", name);
-#endif
+
_writer.writePropertyName(name);
+
// Strict array are never encoded in SharedObject
- if (!val.writeAMF0(_writer))
- {
+ if (!val.writeAMF0(_writer)) {
log_error("Problems serializing an object's member %s=%s",
name, val);
_error = true;
- // Stop visiting....
+ // Stop visiting.
return false;
}
+ // This is SOL specific.
boost::uint8_t end(0);
_writer.writeData(&end, 1);
+ ++_count;
return true;
}
private:
AMF::Writer _writer;
- VM& _vm;
+
+ /// String table for looking up property names as strings.
string_table& _st;
+
+ /// Whether an error has been encountered.
bool _error;
+
+ /// How many properties have been encoded.
+ //
+ /// A boolean would do just as nicely, but we may want to use the count
+ /// info.
+ size_t _count;
};
} // anonymous namespace
@@ -168,45 +197,61 @@
{
public:
- ~SharedObject_as();
-
SharedObject_as(as_object& owner)
:
_owner(owner),
_data(0),
- _persistence(0),
_connected(false)
{
}
+ virtual ~SharedObject_as();
+
+ /// The as_object that owns this Relay.
as_object& owner() {
return _owner;
}
+ /// Write the data as a SOL file.
+ //
+ /// If there is no data to write, the file is removed.
bool flush(int space = 0) const;
+ /// The filename of this SharedObject.
const std::string& getFilespec() const {
- return _sol.getFilespec();
+ return _filename;
}
+ /// Set the filename of the SharedObject.
void setFilespec(const std::string& s) {
- _sol.setFilespec(s);
- }
-
- const std::string& getObjectName() const {
- return _sol.getObjectName();
- }
-
+ _filename = s;
+ }
+
+ /// Set the name of this SharedObject.
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();
- }
-
+ _name = s;
+ }
+
+ /// Return the size of the data plus header.
+ size_t size() const {
+ if (!_data) return 0;
+ SimpleBuffer buf;
+
+ // The header comprises 2 bytes and a length field of 4 bytes.
+ if (encodeData(_name, *_data, buf)) {
+ return buf.size() + 6;
+ }
+ return 0;
+ }
+
+ /// Set the data object.
+ //
+ /// It seems much cleaner not to implement this as a getter/setter as it
+ /// currently is, but it is shown that flush() does not call data if
+ /// data is a getter-setter. This suggests that flush does not access
+ /// the data object directly, which in turn suggests it's not a real
+ /// property. This is the only test that fails if the data object is a
+ /// simple object property.
void setData(as_object* data) {
assert(data);
@@ -220,40 +265,37 @@
}
- as_object* data() {
- return _data;
- }
-
- const as_object* data() const {
- return _data;
- }
-
- bool getPersistence() const { return _persistence; };
- void setPersistence(bool flag) { _persistence = flag; };
-
- /// Process the close() method.
+ /// Get the data object.
+ as_object* data() const {
+ return _data;
+ }
+
+ /// Close the SharedObject
+ //
+ /// Note that this currently does nothing.
void close();
- /// Process the connect(uri) method.
- void connect(NetConnection_as *obj, const std::string& uri);
-
- void setURI(const std::string &url) { _uri = url; }
- const std::string& getURI() const { return _uri; }
-
- bool isConnected() const { return _connected; };
- void isConnected(bool x) { _connected = x; };
-
- // Override from Relay.
+ /// Are we connected?
+ bool connected() const { return _connected; }
+
+ /// Override from Relay.
virtual void setReachable();
private:
+ /// The as_object to which this Relay belongs.
as_object& _owner;
+
+ /// An object to store and access the actual data.
as_object* _data;
- bool _persistence;
- amf::SOL _sol;
+
+ std::string _name;
+
+ std::string _filename;
+
+ /// Are we connected? (No).
bool _connected;
- std::string _uri;
+
};
@@ -262,6 +304,9 @@
}
+/// Returns false if the data cannot be written to file.
+//
+/// If there is no data, the file is removed and the function returns true.
bool
SharedObject_as::flush(int space) const
{
@@ -278,10 +323,9 @@
"argument (%d), which is currently ignored", space);
}
- const std::string& filespec = _sol.getFilespec();
+ const std::string& filespec = getFilespec();
- if (!mkdirRecursive(filespec))
- {
+ if (!mkdirRecursive(filespec)) {
log_error("Couldn't create dir for flushing SharedObject %s",
filespec);
return false;
}
@@ -292,56 +336,43 @@
return false;
#endif
- if (rcfile.getSOLReadOnly() ) {
+ if (rcfile.getSOLReadOnly()) {
log_security("Attempting to write object %s when it's SOL "
"Read Only is set! Refusing...", filespec);
return false;
}
- 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(_owner);
-
- // Do not encode strict arrays!
- AMF::Writer w(buf, false);
-
- SOLPropsBufSerializer props(w, vm);
- _data->visitProperties<Exists>(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);
-
- // Write file
+ // Open 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;
}
+
+ // Encode data part.
+ SimpleBuffer buf;
+ if (!encodeData(_name, *_data, buf)) {
+ std::remove(filespec.c_str());
+ return true;
+ }
+
+ // Encode header part.
+ SimpleBuffer header;
+ encodeHeader(buf.size(), header);
- if (ofs.write(reinterpret_cast<const char*>(buf.data()),
buf.size()).fail())
- {
+ // Write header
+ ofs.write(reinterpret_cast<const char*>(header.data()), header.size());
+ if (!ofs) {
+ log_error("Error writing SOL header");
+ return false;
+ }
+
+ // Write AMF data
+ ofs.write(reinterpret_cast<const char*>(buf.data()), buf.size());
+ if (!ofs) {
log_error("Error writing %d bytes to output file %s",
buf.size(), filespec.c_str());
- ofs.close();
return false;
}
ofs.close();
@@ -350,25 +381,15 @@
return true;
}
-/// Process the close() method.
void
SharedObject_as::close()
{
}
-/// Process the connect(uri) method.
-void
-SharedObject_as::connect(NetConnection_as* /*obj*/, const std::string& /*uri*/)
-{
- GNASH_REPORT_FUNCTION;
-
-}
-
SharedObjectLibrary::SharedObjectLibrary(VM& vm)
:
_vm(vm)
{
- GNASH_REPORT_FUNCTION;
_solSafeDir = rcfile.getSOLSafeDir();
if (_solSafeDir.empty()) {
@@ -436,12 +457,8 @@
void
SharedObjectLibrary::markReachableResources() const
{
- for (SoLib::const_iterator it = _soLib.begin(), itE = _soLib.end();
- it != itE; ++it)
- {
- SharedObject_as* sh = it->second;
- sh->setReachable();
- }
+ foreachSecond(_soLib.begin(), _soLib.end(),
+ std::mem_fun(&SharedObject_as::setReachable));
}
/// The SharedObjectLibrary keeps all known SharedObjects alive. They must
@@ -548,7 +565,6 @@
log_debug("SharedObject %s not loaded. Loading it now", key);
-
// Otherwise create a new one and register to the lib
SharedObject_as* sh = createSharedObject(*_vm.getGlobal());
if (!sh) return 0;
@@ -574,64 +590,6 @@
return &sh->owner();
}
-as_object*
-SharedObjectLibrary::getRemote(const std::string& objName,
- const std::string& uri, const std::string& persistence)
-{
- GNASH_REPORT_FUNCTION;
-
- assert (!objName.empty());
-
- // 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;
- std::ostringstream solPath;
- URL url(uri);
-
- const std::string& key = url.path();
-
- // 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->owner();
- }
-
- log_debug("SharedObject %s not loaded. Loading it now", key);
-
- // Otherwise create a new one and register to the lib
- SharedObject_as* sh = createSharedObject(*_vm.getGlobal());
- if (!sh) return 0;
-
- _soLib[key] = sh;
-
- sh->setObjectName(objName);
-
- // Not persistence on either the client or the server
- if (persistence == "false") {
- sh->setPersistence(false);
- }
- // Persistence only on the server
- if (persistence == "true") {
- sh->setPersistence(true);
- }
-
- if (persistence[0] == '/') {
- sh->setPersistence(true);
- as_object* localdata = getLocal(objName, url.path());
- if (localdata) {
- sh->setData(localdata);
- }
- }
-
- return &sh->owner();
-}
void
sharedobject_class_init(as_object& where, const ObjectURI& uri)
@@ -656,7 +614,7 @@
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_getSize, 2106, 4);
vm.registerNative(sharedobject_setFps, 2106, 5);
vm.registerNative(sharedobject_clear, 2106, 6);
@@ -673,8 +631,6 @@
vm.registerNative(sharedobject_deleteAll, 2106, 206);
vm.registerNative(sharedobject_getDiskUsage, 2106, 207);
- vm.registerNative(sharedobject_setdirty, 2106, 208);
- vm.registerNative(sharedobject_setproperty, 2106, 209);
}
@@ -698,9 +654,6 @@
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);
-
- o.init_member("setDirty", vm.getNative(2106, 7), flags);
- o.init_member("setProperty", vm.getNative(2106, 8), flags);
}
@@ -712,8 +665,7 @@
const int flags = 0;
Global_as& gl = getGlobal(o);
- o.init_member("getLocal",
- gl.createFunction(sharedobject_getLocal), flags);
+ o.init_member("getLocal", gl.createFunction(sharedobject_getLocal), flags);
o.init_member("getRemote",
gl.createFunction(sharedobject_getRemote), flags);
@@ -736,34 +688,11 @@
}
as_value
-sharedobject_setdirty(const fn_call& fn)
-{
- SharedObject_as* obj = ensure<ThisIsNative<SharedObject_as> >(fn);
- UNUSED(obj);
-
- LOG_ONCE(log_unimpl (__FUNCTION__));
-
- return as_value();
-}
-
-as_value
-sharedobject_setproperty(const fn_call& fn)
-{
- GNASH_REPORT_FUNCTION;
- SharedObject_as* obj = ensure<ThisIsNative<SharedObject_as> >(fn);
- UNUSED(obj);
-
- LOG_ONCE(log_unimpl (__FUNCTION__));
-
- return as_value();
-}
-
-as_value
sharedobject_connect(const fn_call& fn)
{
- GNASH_REPORT_FUNCTION;
SharedObject_as* obj = ensure<ThisIsNative<SharedObject_as> >(fn);
+
UNUSED(obj);
if (fn.nargs < 1) {
@@ -774,45 +703,8 @@
return as_value();
}
- // Although the ActionScript spec says connect() takes two
- // arguments, the HAXE implementation only supports one.
- // So we have to make sure the NetCnnection object we get
- // passed is already had the URI specified to connect to.
- if (fn.nargs > 1) {
-#if 0
- const as_value& uri = fn.arg(1);
- const VM& vm = getVM(fn);
- const std::string& uriStr = uri.to_string(vm.getSWFVersion());
-#endif
- }
-
- NetConnection_as* nc;
- if (!isNativeType(fn.arg(0).to_object(getGlobal(fn)), nc)) {
- return as_value();
- }
-
- // This is always set without validification.fooc->setURI(uriStr);
- std::string str = nc->getURI();
- //obj->setPath(str);
- URL uri = nc->getURI();
- Network *net = new Network;
-
- net->setProtocol(uri.protocol());
- net->setHost(uri.hostname());
- net->setPort(strtol(uri.port().c_str(), NULL, 0) & 0xffff);
-
- // Check first arg for validity
- if (getSWFVersion(fn) > 6) {
- nc->connect();
- } else {
- if (fn.nargs > 0) {
- std::stringstream ss; fn.dump_args(ss);
- log_unimpl("SharedObject.connect(%s): args after the first are "
- "not supported", ss.str());
- }
- nc->connect();
- }
-
+ LOG_ONCE(log_unimpl("SharedObject.connect()"));
+
return as_value();
}
@@ -839,17 +731,13 @@
as_value
sharedobject_send(const fn_call& fn)
{
- GNASH_REPORT_FUNCTION;
-
SharedObject_as* obj = ensure<ThisIsNative<SharedObject_as> >(fn);
-
- if (!obj->isConnected()) {
- //obj->connectToServer(obj->getURI());
- }
-
+ UNUSED(obj);
+ LOG_ONCE(log_unimpl("SharedObject.send"));
return as_value();
}
+/// Returns false only if there was a failure writing data to file.
as_value
sharedobject_flush(const fn_call& fn)
{
@@ -883,17 +771,17 @@
as_value
sharedobject_getLocal(const fn_call& fn)
{
- int swfVersion = getSWFVersion(fn);
+ const int swfVersion = getSWFVersion(fn);
as_value objNameVal;
if (fn.nargs > 0) objNameVal = fn.arg(0);
+
const std::string objName = objNameVal.to_string(swfVersion);
if (objName.empty()) {
IF_VERBOSE_ASCODING_ERRORS(
std::ostringstream ss;
fn.dump_args(ss);
- log_aserror("SharedObject.getLocal(%s): %s",
- _("missing object name"));
+ log_aserror("SharedObject.getLocal(%s): missing object name");
);
as_value ret;
ret.set_null();
@@ -901,8 +789,7 @@
}
std::string root;
- if (fn.nargs > 1)
- {
+ if (fn.nargs > 1) {
root = fn.arg(1).to_string(swfVersion);
}
@@ -918,60 +805,14 @@
}
as_value
-sharedobject_getRemote(const fn_call& fn)
+sharedobject_getRemote(const fn_call& /*fn*/)
{
- GNASH_REPORT_FUNCTION;
-
- int swfVersion = getSWFVersion(fn);
- as_value objNameVal;
-
- if (fn.nargs > 0) {
- objNameVal = fn.arg(0);
- }
-
- std::string objName = objNameVal.to_string(swfVersion);
- if (objName.empty()) {
- IF_VERBOSE_ASCODING_ERRORS(
- std::ostringstream ss;
- fn.dump_args(ss);
- log_aserror("SharedObject.getRemote(%s): %s",
- _("missing object name"));
- );
- as_value ret;
- ret.set_null();
- return ret;
- }
-
- std::string root;
-
- // TODO: this certainly shouldn't be a string. The behaviour is different
- // according to the type:
- // null or false not persistent.
- // true persistent.
- // string (URL) something else.
- // We can implement this by making the interface cope with those different
- // cases and just checking the argument type here.
- std::string persistence;
- if (fn.nargs > 1) {
- root = fn.arg(1).to_string(swfVersion);
- persistence = fn.arg(2).to_string(swfVersion);
- }
-
- log_debug("SO name:%s, root:%s, persistence: %s", objName, root,
persistence);
-
- VM& vm = getVM(fn);
-
- as_object* obj = vm.getSharedObjectLibrary().getRemote(objName, root,
- persistence);
-
- as_value ret(obj);
- log_debug("SharedObject.getRemote returning %s", ret);
-
- return ret;
+ LOG_ONCE(log_unimpl("SharedObject.getRemote()"));
+ return as_value();
}
-/// Undocumented
+/// Officially undocumented.
//
/// Takes a URL argument and deletes all SharedObjects under that URL.
as_value
@@ -1010,7 +851,7 @@
}
as_value
-sharedobject_getsize(const fn_call& fn)
+sharedobject_getSize(const fn_call& fn)
{
SharedObject_as* obj = ensure<ThisIsNative<SharedObject_as> >(fn);
return as_value(obj->size());
@@ -1059,20 +900,22 @@
return data;
}
- if (st.st_size < 28) {
+ const size_t size = st.st_size;
+
+ if (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 "
+ log_error("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]);
+
+ boost::scoped_array<boost::uint8_t> sbuf(new boost::uint8_t[size]);
const boost::uint8_t *buf = sbuf.get();
- const boost::uint8_t *end = buf + st.st_size;
+ const boost::uint8_t *end = buf + size;
try {
std::ifstream ifs(filespec.c_str(), std::ios::binary);
- ifs.read(reinterpret_cast<char*>(sbuf.get()), st.st_size);
+ ifs.read(reinterpret_cast<char*>(sbuf.get()), size);
// TODO check initial bytes, and print warnings if they are fishy
@@ -1086,7 +929,7 @@
if (buf >= end) {
// In this case there is no data member.
- log_error("SharedObject::readSOL: file ends before data segment");
+ log_error("readSOL: file ends before data segment");
return data;
}
@@ -1094,7 +937,7 @@
while (buf != end) {
- log_debug("SharedObject::readSOL: reading property name at "
+ log_debug("readSOL: reading property name at "
"byte %s", buf - sbuf.get());
// read property name
@@ -1108,7 +951,7 @@
buf += 2;
if (!len) {
- log_error("SharedObject::readSOL: empty property name");
+ log_error("readSOL: empty property name");
break;
}
@@ -1144,7 +987,7 @@
}
catch (std::exception& e) {
- log_error("SharedObject::readSOL: Reading SharedObject %s: %s",
+ log_error("readSOL: Reading SharedObject %s: %s",
filespec, e.what());
return 0;
}
@@ -1155,7 +998,6 @@
void
flushSOL(SharedObjectLibrary::SoLib::value_type& sol)
{
-// GNASH_REPORT_FUNCTION;
sol.second->flush();
}
@@ -1175,5 +1017,59 @@
return &static_cast<SharedObject_as&>(*o->relay());;
}
+/// Encode header data.
+//
+/// Note that the separation of header and data here is arbitrary.
+void
+encodeHeader(const size_t size, SimpleBuffer& buf)
+{
+ const boost::uint8_t header[] = { 0x00, 0xbf };
+
+ // Initial header byters
+ buf.append(header, arraySize(header));
+
+ // Size of data plus 14 (complete size of data after size field).
+ buf.appendNetworkLong(size);
+}
+
+/// This writes everything after the 'length' field of the SOL data.
+bool
+encodeData(const std::string& name, as_object& data, SimpleBuffer& buf)
+{
+ // Write the remaining header-like information.
+ const boost::uint8_t magic[] = { 'T', 'C', 'S', 'O',
+ 0x00, 0x04, 0x00, 0x00, 0x00, 0x00 };
+
+ // Magic SharedObject bytes.
+ buf.append(magic, arraySize(magic));
+
+ // SharedObject name
+ const boost::uint16_t len = name.length();
+ buf.appendNetworkShort(len);
+ buf.append(name.c_str(), len);
+
+ // Padding
+ const boost::uint8_t padding[] = { 0, 0, 0, 0 };
+ buf.append(padding, arraySize(padding));
+
+ // see http://osflash.org/documentation/amf/envelopes/sharedobject
+ // Do not encode strict arrays!
+ AMF::Writer w(buf, false);
+ string_table& st = getStringTable(data);
+
+ SOLPropsBufSerializer props(w, st);
+
+ // Visit all existing properties.
+ data.visitProperties<Exists>(props);
+
+ if (!props.success()) {
+ // There are good reasons for this to fail, so it's not an error. Real
+ // errors are logged during serialization.
+ log_debug("Did not serialize object");
+ return false;
+ }
+ return true;
+}
+
} // anonymous namespace
} // end of gnash namespace
=== modified file 'libcore/asobj/flash/net/SharedObject_as.h'
--- a/libcore/asobj/flash/net/SharedObject_as.h 2010-01-11 06:41:38 +0000
+++ b/libcore/asobj/flash/net/SharedObject_as.h 2010-02-15 08:21:35 +0000
@@ -50,14 +50,6 @@
///
as_object* getLocal(const std::string& name, const std::string& root);
- /// Return a remote shared object with given name
- ///
- /// @param persistence false
- /// May return NULL if name is invalid or can't access the given root
- ///
- as_object* getRemote(const std::string& name, const std::string& uri,
- const std::string& persistence);
-
void markReachableResources() const;
// Drop all library items
=== modified file 'testsuite/actionscript.all/SharedObject.as'
--- a/testsuite/actionscript.all/SharedObject.as 2010-01-11 06:41:38
+0000
+++ b/testsuite/actionscript.all/SharedObject.as 2010-02-15 11:44:49
+0000
@@ -75,14 +75,18 @@
// FIXME: Test code that will soon be a formal test case.
so = SharedObject.getLocal("level1/level2/settings", "/");
-
+#if OUTPUT_VERSION > 5
+check_equals (so.getSize(), 297);
+#endif
check(so instanceof SharedObject);
// Private data
so.name = "Joe";
so.age = 20;
so.pet = "Dog";
-
+#if OUTPUT_VERSION > 5
+check_equals (so.getSize(), 297);
+#endif
// public data that gets written
#if OUTPUT_VERSION > 5
check(so.hasOwnProperty("data"));
@@ -103,6 +107,7 @@
so.data.localSecPath = "";
so.data.localSecPathTime = 1.19751160683e+12;
+
// Verify that a new getLocal call using
// the same "id" returns the same in-memory object.
so.data.tmp = "custom value";
@@ -111,6 +116,11 @@
check_equals(so2.data.toString(), "[object Object]");
check_equals(so, so2);
+#if OUTPUT_VERSION > 5
+check_equals (so2.getSize(), 318);
+check_equals (so.getSize(), 318);
+#endif
+
// Check SOL names validity.
so2bis = SharedObject.getLocal("level1//level2/settings", "/");
check_equals(typeof(so2bis), 'null'); // invalid path
@@ -169,11 +179,19 @@
delete so.data.tmp;
+#if OUTPUT_VERSION > 5
+check_equals(so.getSize(), 297);
+#endif
+
// But a getLocal call using a *different* "id" returns
// a different SharedObject...
so3 = SharedObject.getLocal("level1/level2/settings3", "/");
check(so3 != so);
+#if OUTPUT_VERSION > 5
+check_equals (so3.getSize(), 0);
+#endif
+
// Doesn't make much sense to test the rest for SWF5
#if OUTPUT_VERSION > 5
@@ -185,7 +203,9 @@
newso = SharedObject.getLocal("level1/level2/settings", "/");
check_equals (typeof(newso), 'object');
trace(newso.getSize());
-xcheck_equals (newso.getSize(), 297);
+#if OUTPUT_VERSION > 5
+check_equals (newso.getSize(), 297);
+#endif
if (typeof(newso.data) != 'undefined') {
trace("New Shared Object, checking data...");
@@ -226,6 +246,7 @@
note("Some of the following tests (all preceded by a 'checking' message) will
fail when run over the network. Only the tests where an object is expected
should fail");
so4 = SharedObject.getLocal("Another-one", "/subdir");
+check_equals (so4.getSize(), undefined);
check_equals(typeof(so4), "null");
check(so4 != so3);
check_equals(typeof(so4.data), 'undefined');
@@ -350,7 +371,7 @@
// END OF TESTS
//------------------------------------------
-check_totals(116);
+check_totals(123);
#else
=== modified file 'testsuite/misc-ming.all/LC-Receive.as'
--- a/testsuite/misc-ming.all/LC-Receive.as 2010-02-10 13:56:32 +0000
+++ b/testsuite/misc-ming.all/LC-Receive.as 2010-02-15 12:47:09 +0000
@@ -70,13 +70,21 @@
check_equals(typeof(c), "object");
};
-// Exit in 3 seconds.
+var i = 0;
+
+lc.stress = function(arg1, arg2, arg3) {
+ check_equals(arg1, i);
+ ++i;
+ lc.send("recv", "stressTestCheck", arg1, arg2, arg3);
+};
+
+// Exit in 2 seconds.
lc.endTests = function() {
totals();
- trace("Finished tests. Alerting LC-Send and exiting in 3 seconds");
+ trace("Finished tests. Alerting LC-Send and exiting in 2 seconds");
trace("ENDOFTEST");
lc.send("recv", "finished");
- setInterval(exit, 3000);
+ setInterval(exit, 2000);
};
exit = function() {
=== modified file 'testsuite/misc-ming.all/LC-Send.as'
--- a/testsuite/misc-ming.all/LC-Send.as 2010-02-10 13:56:32 +0000
+++ b/testsuite/misc-ming.all/LC-Send.as 2010-02-15 12:47:09 +0000
@@ -4,6 +4,36 @@
lc = new LocalConnection;
lc.connect("recv");
+
+var i = 0;
+
+stressTest = function() {
+ var arg1 = i;
+ var arg2 = { a:5, b:"A string, not too short, but also not really long" };
+ var arg3 = new Array(i);
+ lc.send("lc576", "stress", arg1, arg2, arg3);
+};
+
+lc.stressTestCheck = function(arg1, arg2, arg3) {
+ check_equals(arg1, i);
+ check_equals(typeof(arg2), "object");
+ check_equals(arg2.a, 5);
+ check_equals(arg2.b, "A string, not too short, but also not really long");
+ check_equals(arg3.length, i);
+ if (i < 1000) {
+ ++i;
+ stressTest();
+ }
+ else {
+ endTests();
+ };
+
+};
+
+endTests = function() {
+ lc.send("lc576", "endTests");
+};
+
runtests = function() {
// This should not result in a call.
@@ -55,7 +85,7 @@
check_equals(typeof(c), "object");
lc.send("lc576", "test7", c);
- lc.send("lc576", "endTests");
+ stressTest();
};
getit = function()
@@ -73,11 +103,11 @@
runtests();
};
-// Called when LC-Send has finished. Exit in 3 seconds.
+// Called when LC-Send has finished. Exit in 2 seconds.
lc.finished = function() {
- trace("Received finish signal from LC-Receive. Exiting in 3 seconds");
+ trace("Received finish signal from LC-Receive. Exiting in 2 seconds");
trace("ENDOFTEST");
- setInterval(exit, 3000);
+ setInterval(exit, 2000);
};
exit = function() {
=== modified file 'testsuite/simultaneous-testrunner.sh'
--- a/testsuite/simultaneous-testrunner.sh 2010-02-10 11:43:33 +0000
+++ b/testsuite/simultaneous-testrunner.sh 2010-02-15 12:47:09 +0000
@@ -50,7 +50,7 @@
echo "export ${REPLY}"
done
-timeout=10
+timeout=40
cat << EOF
outlog1=${top_builddir}/testoutlog.\$$
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r11948: More tests for LocalConnection and SharedObject, fixes to,
Benjamin Wolsey <=