gnash-commit
[Top][All Lists]
Advanced

[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.\$$


reply via email to

[Prev in Thread] Current Thread [Next in Thread]