gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] /srv/bzr/gnash/trunk r10475: More abstraction: NetConnect


From: Sandro Santilli
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r10475: More abstraction: NetConnection now uses ConnectionHandler instances
Date: Sat, 20 Dec 2008 11:59:33 +0100
User-agent: Bazaar (1.5)

------------------------------------------------------------
revno: 10475
committer: Sandro Santilli <address@hidden>
branch nick: trunk
timestamp: Sat 2008-12-20 11:59:33 +0100
message:
  More abstraction: NetConnection now uses ConnectionHandler instances
modified:
  libcore/asobj/NetConnection_as.cpp
  libcore/asobj/NetConnection_as.h
=== modified file 'libcore/asobj/NetConnection_as.cpp'
--- a/libcore/asobj/NetConnection_as.cpp        2008-12-19 17:55:44 +0000
+++ b/libcore/asobj/NetConnection_as.cpp        2008-12-20 10:59:33 +0000
@@ -78,6 +78,99 @@
     boost::uint32_t readNetworkLong(const boost::uint8_t* buf);
 
 }
+
+//---- ConnectionHandler 
--------------------------------------------------------------
+
+/// Abstract connection handler class
+//
+/// This class abstract operations on network connections,
+/// specifically RPC and streams fetching.
+///
+class ConnectionHandler
+{
+public:
+
+    /// @param methodName
+    ///     A string identifying the remote procedure to call
+    ///
+    /// @param responseHandler
+    ///     Object to invoke response methods on.
+    ///
+    /// @param args
+    ///     A vector of arguments
+    ///
+    /// @param firstArg
+    ///     Index of first argument in the args vector
+    ///
+    ///
+    /// @return true if the call is queued, false otherwise
+    ///
+    virtual void call(as_object* asCallback, const std::string& methodName,
+            const std::vector<as_value>& args, size_t firstArg)=0;
+
+    /// Get an stream by name
+    //
+    /// @param name
+    ///     Stream identifier
+    ///
+    virtual std::auto_ptr<IOChannel> getStream(const std::string& name);
+
+    /// Process pending traffic, out or in bound
+    //
+    /// Handles all networking for NetConnection::call() and dispatches
+    /// callbacks when needed. 
+    ///
+    /// Return true if wants to be advanced again, false otherwise.
+    ///
+    virtual bool advance()=0;
+
+    /// Return true if the connection has pending calls 
+    //
+    /// This will be used on NetConnection.close(): if current
+    /// connection has pending calls to process it will be
+    /// queued and only really dropped when advance returns
+    /// false
+    ///
+    virtual bool hasPendingCalls() const=0;
+
+    /// Mark reachable resources, if any. 
+    virtual void setReachable() const
+    {
+        // NOTE: usually this function gets
+        //       called *by* the _nc's setReachable
+        //       but we do this just to be safe
+        //       in case the _nc object is deleted
+        //       and doesn't properly drops us
+        //
+        _nc.setReachable();
+    }
+
+    virtual ~ConnectionHandler() {}
+
+protected:
+
+    /// Construct a connection handler bound to the given NetConnection object
+    //
+    /// The binding is used to notify statuses and errors
+    ///
+    ConnectionHandler(NetConnection_as& nc)
+        :
+        _nc(nc)
+    {}
+
+    // Object handling connection status messages
+    NetConnection_as& _nc;
+};
+
+std::auto_ptr<IOChannel>
+ConnectionHandler::getStream(const std::string&)
+{
+    log_unimpl("%s doesn't support fetching streams", typeName(*this));
+    return std::auto_ptr<IOChannel>(0);
+}
+
+//---- AMFQueue (HTTPConnectionHandler) 
-----------------------------------------------
+
 /// Queue of remoting calls 
 //
 /// This class in made to handle data and do defered processing for
@@ -92,10 +185,37 @@
 /// the identifier (which must be unique) and the callback object as an 
as_value
 ///
 /// @todo move this somewhere more appropriate, perhaps by merging with libamf.
-class AMFQueue {
+class AMFQueue : public ConnectionHandler {
+
+public:
+
+    AMFQueue(NetConnection_as& nc, URL url);
+
+    // See dox in ConnectionHandler
+    virtual bool hasPendingCalls() const
+    {
+        return _connection || queued_count;
+    }
+
+    // See dox in ConnectionHandler
+    virtual bool advance();
+
+    void setReachable() const
+    {
+        for (CallbacksMap::const_iterator i=callbacks.begin(),
+                e=callbacks.end(); i!=e; ++i)
+        {
+            i->second->setReachable();
+        }
+        ConnectionHandler::setReachable();
+    }
+
+    // See dox in NetworkHandler class
+    virtual void call(as_object* asCallback, const std::string& methodName,
+            const std::vector<as_value>& args, size_t firstArg);
+
 private:
 
-    NetConnection_as& _nc;
     static const int NCCALLREPLYCHUNK=1024*200;
 
     typedef std::map<std::string, boost::intrusive_ptr<as_object> > 
@@ -109,6 +229,7 @@
     int reply_start;
     int queued_count;
     unsigned int ticker;
+    unsigned int _numCalls; // === queued_count ?
 
     // Quick hack to send Content-Type: application/x-amf
     // TODO: check if we should take headers on a per-call basis
@@ -116,10 +237,48 @@
     //
     NetworkAdapter::RequestHeaders _headers;
 
-public:
-    AMFQueue(NetConnection_as& nc, URL url)
+    void push_amf(const SimpleBuffer &amf) 
+    {
+        //GNASH_REPORT_FUNCTION;
+
+        postdata.append(amf.data(), amf.size());
+        queued_count++;
+    }
+
+    void push_callback(const std::string& id,
+            boost::intrusive_ptr<as_object> callback) {
+        callbacks.insert(std::pair<std::string,
+                boost::intrusive_ptr<as_object> >(id, callback));
+    }
+
+    boost::intrusive_ptr<as_object> pop_callback(std::string id)
+    {
+        CallbacksMap::iterator it = callbacks.find(id);
+        if (it != callbacks.end()) {
+            boost::intrusive_ptr<as_object> callback = it->second;
+            callbacks.erase(it);
+            return callback;
+        }
+        else {
+            return 0;
+        }
+    }
+
+    void enqueue(const SimpleBuffer &amf, const std::string& identifier,
+            boost::intrusive_ptr<as_object> callback) {
+        push_amf(amf);
+        push_callback(identifier, callback);
+    };
+
+    void enqueue(const SimpleBuffer &amf) {
+        push_amf(amf);
+    };
+    
+};
+
+AMFQueue::AMFQueue(NetConnection_as& nc, URL url)
         :
-        _nc(nc),
+        ConnectionHandler(nc),
         postdata(),
         url(url),
         _connection(0),
@@ -128,378 +287,310 @@
         queued_count(0),
         ticker(0),
         _numCalls(0) // TODO: replace by queued count ?
-    {
-        // leave space for header
-        postdata.append("\000\000\000\000\000\000", 6);
-        assert(reply.size() == 0);
-
-        _headers["Content-Type"] = "application/x-amf";
-    }
-
-    bool hasPendingCalls() const
-    {
-        return _connection || queued_count;
-    }
-
-    void enqueue(const SimpleBuffer &amf, const std::string& identifier,
-            boost::intrusive_ptr<as_object> callback) {
-        push_amf(amf);
-        push_callback(identifier, callback);
-    };
-
-    void enqueue(const SimpleBuffer &amf) {
-        push_amf(amf);
-    };
-    
-    // tick is called automatically on intervals (hopefully only between
-    // actionscript frames)
-    //
-    // it handles all networking for NetConnection::call() and dispatches
-    // callbacks when needed
-    //
-    // @return true if wants to be called again false when done
-    //
-    bool tick()
-    {
-
-#ifdef GNASH_DEBUG_REMOTING
-        log_debug("tick running");
-#endif
-        if(_connection)
-        {
-
-            VM& vm = _nc.getVM();
-
-#ifdef GNASH_DEBUG_REMOTING
-            log_debug("have connection");
-#endif
-
-            // Fill last chunk before reading in the next
-            size_t toRead = reply.capacity()-reply.size();
-            if ( ! toRead ) toRead = NCCALLREPLYCHUNK;
-
-#ifdef GNASH_DEBUG_REMOTING
-            log_debug("Attempt to read %d bytes", toRead);
-#endif
-
-            //
-            // See if we need to allocate more bytes for the next
-            // read chunk
-            //
-            if ( reply.capacity() < reply.size()+toRead )
-            {
-                // if _connection->size() >= 0, reserve for it, so
-                // if HTTP Content-Length response header is correct
-                // we'll be allocating only once for all.
-                size_t newCapacity = reply.size()+toRead;
-
-#ifdef GNASH_DEBUG_REMOTING
-                log_debug("NetConnection.call: reply buffer capacity (%d) "
-                          "is too small to accept next %d bytes of chunk "
-                          "(current size is %d). Reserving %d bytes.",
-                    reply.capacity(), toRead, reply.size(), newCapacity);
-#endif
-
-                reply.reserve(newCapacity);
-
-#ifdef GNASH_DEBUG_REMOTING
-                log_debug(" after reserve, new capacity is %d", 
reply.capacity());
-#endif
-            }
-
-            int read = _connection->readNonBlocking(reply.data() + 
reply.size(), toRead);
-            if(read > 0) {
-#ifdef GNASH_DEBUG_REMOTING
-                log_debug("read '%1%' bytes: %2%", read, 
-                        hexify(reply.data() + reply.size(), read, false));
-#endif
-                reply.resize(reply.size()+read);
-            }
-
-            // There is no way to tell if we have a whole amf reply without
-            // parsing everything
-            //
-            // The reply format has a header field which specifies the
-            // number of bytes in the reply, but potlatch sends 0xffffffff
-            // and works fine in the proprietary player
-            //
-            // For now we just wait until we have the full reply.
-            //
-            // FIXME make this parse on other conditions, including: 1) when
-            // the buffer is full, 2) when we have a "length in bytes" value
-            // thas is satisfied
-
-            if(_connection->get_error())
-            {
-                log_debug("connection is in error condition, calling "
-                        "NetConnection.onStatus");
-                reply.resize(0);
-                reply_start = 0;
-                // reset connection before calling the callback
-                _connection.reset();
-
-                // This is just a guess, but is better than sending
-                // 'undefined'
-                _nc.notifyStatus(NetConnection_as::CALL_FAILED);
-            }
-            else if(_connection->eof() )
-            {
-                if ( reply.size() > 8)
+{
+    // leave space for header
+    postdata.append("\000\000\000\000\000\000", 6);
+    assert(reply.size() == 0);
+
+    _headers["Content-Type"] = "application/x-amf";
+}
+
+bool
+AMFQueue::advance()
+{
+
+#ifdef GNASH_DEBUG_REMOTING
+    log_debug("advancing AMFQueue");
+#endif
+    if(_connection)
+    {
+
+        VM& vm = _nc.getVM();
+
+#ifdef GNASH_DEBUG_REMOTING
+        log_debug("have connection");
+#endif
+
+        // Fill last chunk before reading in the next
+        size_t toRead = reply.capacity()-reply.size();
+        if ( ! toRead ) toRead = NCCALLREPLYCHUNK;
+
+#ifdef GNASH_DEBUG_REMOTING
+        log_debug("Attempt to read %d bytes", toRead);
+#endif
+
+        //
+        // See if we need to allocate more bytes for the next
+        // read chunk
+        //
+        if ( reply.capacity() < reply.size()+toRead )
+        {
+            // if _connection->size() >= 0, reserve for it, so
+            // if HTTP Content-Length response header is correct
+            // we'll be allocating only once for all.
+            size_t newCapacity = reply.size()+toRead;
+
+#ifdef GNASH_DEBUG_REMOTING
+            log_debug("NetConnection.call: reply buffer capacity (%d) "
+                      "is too small to accept next %d bytes of chunk "
+                      "(current size is %d). Reserving %d bytes.",
+                reply.capacity(), toRead, reply.size(), newCapacity);
+#endif
+
+            reply.reserve(newCapacity);
+
+#ifdef GNASH_DEBUG_REMOTING
+            log_debug(" after reserve, new capacity is %d", reply.capacity());
+#endif
+        }
+
+        int read = _connection->readNonBlocking(reply.data() + reply.size(), 
toRead);
+        if(read > 0) {
+#ifdef GNASH_DEBUG_REMOTING
+            log_debug("read '%1%' bytes: %2%", read, 
+                    hexify(reply.data() + reply.size(), read, false));
+#endif
+            reply.resize(reply.size()+read);
+        }
+
+        // There is no way to tell if we have a whole amf reply without
+        // parsing everything
+        //
+        // The reply format has a header field which specifies the
+        // number of bytes in the reply, but potlatch sends 0xffffffff
+        // and works fine in the proprietary player
+        //
+        // For now we just wait until we have the full reply.
+        //
+        // FIXME make this parse on other conditions, including: 1) when
+        // the buffer is full, 2) when we have a "length in bytes" value
+        // thas is satisfied
+
+        if(_connection->get_error())
+        {
+            log_debug("connection is in error condition, calling "
+                    "NetConnection.onStatus");
+            reply.resize(0);
+            reply_start = 0;
+            // reset connection before calling the callback
+            _connection.reset();
+
+            // This is just a guess, but is better than sending
+            // 'undefined'
+            _nc.notifyStatus(NetConnection_as::CALL_FAILED);
+        }
+        else if(_connection->eof() )
+        {
+            if ( reply.size() > 8)
+            {
+                std::vector<as_object*> objRefs;
+
+#ifdef GNASH_DEBUG_REMOTING
+                log_debug("hit eof");
+#endif
+                boost::int16_t si;
+                boost::uint16_t li;
+                boost::uint8_t *b = reply.data() + reply_start;
+                boost::uint8_t *end = reply.data() + reply.size();
+
+                // parse header
+                b += 2; // skip version indicator and client id
+
+                // NOTE: this looks much like parsing of an OBJECT_AMF0
+                si = readNetworkShort(b); b += 2; // number of headers
+                uint8_t headers_ok = 1;
+                if (si != 0)
                 {
-                    std::vector<as_object*> objRefs;
-
 #ifdef GNASH_DEBUG_REMOTING
-                    log_debug("hit eof");
+                    log_debug("NetConnection::call(): amf headers "
+                            "section parsing");
 #endif
-                    boost::int16_t si;
-                    boost::uint16_t li;
-                    boost::uint8_t *b = reply.data() + reply_start;
-                    boost::uint8_t *end = reply.data() + reply.size();
-
-                    // parse header
-                    b += 2; // skip version indicator and client id
-
-                    // NOTE: this looks much like parsing of an OBJECT_AMF0
-                    si = readNetworkShort(b); b += 2; // number of headers
-                    uint8_t headers_ok = 1;
-                    if (si != 0)
+                    as_value tmp;
+                    for(int i = si; i > 0; --i)
                     {
+                        if(b + 2 > end) {
+                            headers_ok = 0;
+                            break;
+                        }
+                        si = readNetworkShort(b); b += 2; // name length
+                        if(b + si > end) {
+                            headers_ok = 0;
+                            break;
+                        }
+                        std::string headerName((char*)b, si); // end-b);
 #ifdef GNASH_DEBUG_REMOTING
-                        log_debug("NetConnection::call(): amf headers "
-                                "section parsing");
+                        log_debug("Header name %s", headerName);
 #endif
-                        as_value tmp;
-                        for(int i = si; i > 0; --i)
+                        b += si;
+                        if ( b + 5 > end ) {
+                            headers_ok = 0;
+                            break;
+                        }
+                        b += 5; // skip past bool and length long
+                        if( !tmp.readAMF0(b, end, -1, objRefs, vm) )
                         {
-                            if(b + 2 > end) {
-                                headers_ok = 0;
-                                break;
-                            }
-                            si = readNetworkShort(b); b += 2; // name length
-                            if(b + si > end) {
-                                headers_ok = 0;
-                                break;
-                            }
-                            std::string headerName((char*)b, si); // end-b);
-#ifdef GNASH_DEBUG_REMOTING
-                            log_debug("Header name %s", headerName);
-#endif
-                            b += si;
-                            if ( b + 5 > end ) {
-                                headers_ok = 0;
-                                break;
-                            }
-                            b += 5; // skip past bool and length long
-                            if( !tmp.readAMF0(b, end, -1, objRefs, vm) )
+                            headers_ok = 0;
+                            break;
+                        }
+#ifdef GNASH_DEBUG_REMOTING
+                        log_debug("Header value %s", tmp);
+#endif
+
+                        { // method call for each header
+                          // FIXME: it seems to me that the call should happen
+                            VM& vm = _nc.getVM();
+                            string_table& st = vm.getStringTable();
+                            string_table::key key = st.find(headerName);
+#ifdef GNASH_DEBUG_REMOTING
+                            log_debug("Calling NetConnection.%s(%s)",
+                                    headerName, tmp);
+#endif
+                            _nc.callMethod(key, tmp);
+                        }
+                    }
+                }
+
+                if(headers_ok == 1) {
+
+                    si = readNetworkShort(b); b += 2; // number of replies
+
+                    // TODO consider counting number of replies we
+                    // actually parse and doing something if it
+                    // doesn't match this value (does it matter?
+                    if(si > 0) {
+                        // parse replies until we get a parse error or we 
reach the end of the buffer
+                        while(b < end) {
+                            if(b + 2 > end) break;
+                            si = readNetworkShort(b); b += 2; // reply length
+                            if(si < 4) { // shorted valid response is '/1/a'
+                                log_error("NetConnection::call(): reply 
message name too short");
+                                break;
+                            }
+                            if(b + si > end) break;
+
+                            // Reply message is: '/id/methodName'
+
+                            int ns = 1; // next slash position
+                            while (ns<si-1 && *(b+ns) != '/') ++ns;
+                            if ( ns >= si-1 ) {
+                                std::string msg(reinterpret_cast<char*>(b), 
si);
+                                log_error("NetConnection::call(): invalid 
reply message name (%s)", msg);
+                                break;
+                            }
+
+                            std::string id(reinterpret_cast<char*>(b), ns);
+                            std::string 
methodName(reinterpret_cast<char*>(b+ns+1), si-ns-1);
+
+                            b += si;
+
+                            // parse past unused string in header
+                            if(b + 2 > end) break;
+                            si = readNetworkShort(b); b += 2; // reply length
+                            if(b + si > end) break;
+                            b += si;
+
+                            // this field is supposed to hold the
+                            // total number of bytes in the rest of
+                            // this particular reply value, but
+                            // openstreetmap.org (which works great
+                            // in the adobe player) sends
+                            // 0xffffffff. So we just ignore it
+                            if(b + 4 > end) break;
+                            li = readNetworkLong(b); b += 4; // reply length
+
+#ifdef GNASH_DEBUG_REMOTING
+                            log_debug("about to parse amf value");
+#endif
+                            // this updates b to point to the next unparsed 
byte
+                            as_value reply_as_value;
+                            if ( ! reply_as_value.readAMF0(b, end, -1, 
objRefs, vm) )
                             {
-                                headers_ok = 0;
+                                log_error("parse amf failed");
+                                // this will happen if we get
+                                // bogus data, or if the data runs
+                                // off the end of the buffer
+                                // provided, or if we get data we
+                                // don't know how to parse
                                 break;
                             }
 #ifdef GNASH_DEBUG_REMOTING
-                            log_debug("Header value %s", tmp);
-#endif
-
-                            { // method call for each header
-                              // FIXME: it seems to me that the call should 
happen
-                                VM& vm = _nc.getVM();
-                                string_table& st = vm.getStringTable();
-                                string_table::key key = st.find(headerName);
-#ifdef GNASH_DEBUG_REMOTING
-                                log_debug("Calling NetConnection.%s(%s)",
-                                        headerName, tmp);
-#endif
-                                _nc.callMethod(key, tmp);
-                            }
-                        }
-                    }
-
-                    if(headers_ok == 1) {
-
-                        si = readNetworkShort(b); b += 2; // number of replies
-
-                        // TODO consider counting number of replies we
-                        // actually parse and doing something if it
-                        // doesn't match this value (does it matter?
-                        if(si > 0) {
-                            // parse replies until we get a parse error or we 
reach the end of the buffer
-                            while(b < end) {
-                                if(b + 2 > end) break;
-                                si = readNetworkShort(b); b += 2; // reply 
length
-                                if(si < 4) { // shorted valid response is 
'/1/a'
-                                    log_error("NetConnection::call(): reply 
message name too short");
-                                    break;
-                                }
-                                if(b + si > end) break;
-
-                                // Reply message is: '/id/methodName'
-
-                                int ns = 1; // next slash position
-                                while (ns<si-1 && *(b+ns) != '/') ++ns;
-                                if ( ns >= si-1 ) {
-                                    std::string 
msg(reinterpret_cast<char*>(b), si);
-                                    log_error("NetConnection::call(): invalid 
reply message name (%s)", msg);
-                                    break;
-                                }
-
-                                std::string id(reinterpret_cast<char*>(b), ns);
-                                std::string 
methodName(reinterpret_cast<char*>(b+ns+1), si-ns-1);
-
-                                b += si;
-
-                                // parse past unused string in header
-                                if(b + 2 > end) break;
-                                si = readNetworkShort(b); b += 2; // reply 
length
-                                if(b + si > end) break;
-                                b += si;
-
-                                // this field is supposed to hold the
-                                // total number of bytes in the rest of
-                                // this particular reply value, but
-                                // openstreetmap.org (which works great
-                                // in the adobe player) sends
-                                // 0xffffffff. So we just ignore it
-                                if(b + 4 > end) break;
-                                li = readNetworkLong(b); b += 4; // reply 
length
-
-#ifdef GNASH_DEBUG_REMOTING
-                                log_debug("about to parse amf value");
-#endif
-                                // this updates b to point to the next 
unparsed byte
-                                as_value reply_as_value;
-                                if ( ! reply_as_value.readAMF0(b, end, -1, 
objRefs, vm) )
-                                {
-                                    log_error("parse amf failed");
-                                    // this will happen if we get
-                                    // bogus data, or if the data runs
-                                    // off the end of the buffer
-                                    // provided, or if we get data we
-                                    // don't know how to parse
-                                    break;
-                                }
-#ifdef GNASH_DEBUG_REMOTING
-                                log_debug("parsed amf");
-#endif
-
-                                // update variable to show how much we've 
parsed
-                                reply_start = b - reply.data();
-
-                                // if actionscript specified a callback 
object, call it
-                                boost::intrusive_ptr<as_object> callback = 
pop_callback(id);
-                                if(callback) {
-
-                                    string_table::key methodKey;
-                                    if ( methodName == "onResult" ) {
-                                        methodKey = NSV::PROP_ON_RESULT;
-                                    } else if ( methodName == "onStatus" ) {
-                                        methodKey = NSV::PROP_ON_STATUS;
-                                    } else {
-                                        // NOTE: the pp is known to actually 
invoke the custom
-                                        //       method, but with 7 undefined 
arguments (?)
-                                        //methodKey = 
_nc.getVM().getStringTable().find(methodName);
-                                        log_error("Unsupported HTTP Remoting 
response callback: '%s' (size %d)", methodName, methodName.size());
-                                        continue;
-                                    }
-
-#ifdef GNASH_DEBUG_REMOTING
-                                    log_debug("calling onResult callback");
-#endif
-                                    // FIXME check if above line can fail and 
we have to react
-                                    callback->callMethod(methodKey, 
reply_as_value);
-#ifdef GNASH_DEBUG_REMOTING
-                                    log_debug("callback called");
-#endif
+                            log_debug("parsed amf");
+#endif
+
+                            // update variable to show how much we've parsed
+                            reply_start = b - reply.data();
+
+                            // if actionscript specified a callback object, 
call it
+                            boost::intrusive_ptr<as_object> callback = 
pop_callback(id);
+                            if(callback) {
+
+                                string_table::key methodKey;
+                                if ( methodName == "onResult" ) {
+                                    methodKey = NSV::PROP_ON_RESULT;
+                                } else if ( methodName == "onStatus" ) {
+                                    methodKey = NSV::PROP_ON_STATUS;
                                 } else {
-                                    log_error("Unknown HTTP Remoting response 
identifier '%s'", id);
+                                    // NOTE: the pp is known to actually 
invoke the custom
+                                    //       method, but with 7 undefined 
arguments (?)
+                                    //methodKey = 
_nc.getVM().getStringTable().find(methodName);
+                                    log_error("Unsupported HTTP Remoting 
response callback: '%s' (size %d)", methodName, methodName.size());
+                                    continue;
                                 }
+
+#ifdef GNASH_DEBUG_REMOTING
+                                log_debug("calling onResult callback");
+#endif
+                                // FIXME check if above line can fail and we 
have to react
+                                callback->callMethod(methodKey, 
reply_as_value);
+#ifdef GNASH_DEBUG_REMOTING
+                                log_debug("callback called");
+#endif
+                            } else {
+                                log_error("Unknown HTTP Remoting response 
identifier '%s'", id);
                             }
                         }
                     }
                 }
-                else
-                {
-                    log_error("Response from remoting service < 8 bytes");
-                }
+            }
+            else
+            {
+                log_error("Response from remoting service < 8 bytes");
+            }
 
 #ifdef GNASH_DEBUG_REMOTING
-                log_debug("deleting connection");
+            log_debug("deleting connection");
 #endif
-                _connection.reset();
-                reply.resize(0);
-                reply_start = 0;
-            }
+            _connection.reset();
+            reply.resize(0);
+            reply_start = 0;
         }
+    }
 
-        if(!_connection && queued_count > 0) {
+    if(!_connection && queued_count > 0) {
 //#ifdef GNASH_DEBUG_REMOTING
-            log_debug("creating connection");
+        log_debug("creating connection");
 //#endif
-            // set the "number of bodies" header
-            (reinterpret_cast<boost::uint16_t*>(postdata.data() + 4))[0] = 
htons(queued_count);
-            std::string postdata_str(reinterpret_cast<char*>(postdata.data()), 
postdata.size());
-#ifdef GNASH_DEBUG_REMOTING
-            log_debug("NetConnection.call(): encoded args from %1% calls: 
%2%", queued_count, hexify(postdata.data(), postdata.size(), false));
-#endif
-            queued_count = 0;
-
-            
_connection.reset(StreamProvider::getDefaultInstance().getStream(url, 
postdata_str, _headers).release());
-            postdata.resize(6);
-#ifdef GNASH_DEBUG_REMOTING
-            log_debug("connection created");
-#endif
-        }
-
-        if (_connection == 0) {
-            // nothing more to do
-            return false;
-        }
-
-        return true;
-    };
-
-    void markReachableResources() const
-    {
-        for (CallbacksMap::const_iterator i=callbacks.begin(),
-                e=callbacks.end(); i!=e; ++i)
-        {
-            i->second->setReachable();
-        }
-    }
-
-    void call(as_object* asCallback, const std::string& methodName,
-            const std::vector<as_value>& args, size_t firstArg);
-
-private:
-
-    void push_amf(const SimpleBuffer &amf) 
-    {
-        //GNASH_REPORT_FUNCTION;
-
-        postdata.append(amf.data(), amf.size());
-        queued_count++;
-    }
-
-    void push_callback(const std::string& id,
-            boost::intrusive_ptr<as_object> callback) {
-        callbacks.insert(std::pair<std::string,
-                boost::intrusive_ptr<as_object> >(id, callback));
-    }
-
-    boost::intrusive_ptr<as_object> pop_callback(std::string id)
-    {
-        CallbacksMap::iterator it = callbacks.find(id);
-        if (it != callbacks.end()) {
-            boost::intrusive_ptr<as_object> callback = it->second;
-            //boost::intrusive_ptr<as_object> callback;
-            //callback = it.second;
-            callbacks.erase(it);
-            return callback;
-        }
-        else {
-            return 0;
-        }
-    }
-
-    unsigned int _numCalls;
+        // set the "number of bodies" header
+        (reinterpret_cast<boost::uint16_t*>(postdata.data() + 4))[0] = 
htons(queued_count);
+        std::string postdata_str(reinterpret_cast<char*>(postdata.data()), 
postdata.size());
+#ifdef GNASH_DEBUG_REMOTING
+        log_debug("NetConnection.call(): encoded args from %1% calls: %2%", 
queued_count, hexify(postdata.data(), postdata.size(), false));
+#endif
+        queued_count = 0;
+
+        _connection.reset(StreamProvider::getDefaultInstance().getStream(url, 
postdata_str, _headers).release());
+        postdata.resize(6);
+#ifdef GNASH_DEBUG_REMOTING
+        log_debug("connection created");
+#endif
+    }
+
+    if (_connection == 0) {
+        // nothing more to do
+        return false;
+    }
+
+    return true;
 };
 
 void
@@ -572,10 +663,8 @@
     }
 }
 
-/// \class NetConnection
-/// \brief Opens a local connection through which you can play
-/// back video (FLV) files from an HTTP address or from the local file
-/// system, using curl.
+//----- NetConnection_as ----------------------------------------------------
+
 NetConnection_as::NetConnection_as()
     :
     as_object(getNetConnectionInterface()),
@@ -612,7 +701,7 @@
 // here to have AMFQueue definition available
 NetConnection_as::~NetConnection_as()
 {
-    for (std::list<AMFQueue*>::iterator
+    for (std::list<ConnectionHandler*>::iterator
             i=_callQueues.begin(), e=_callQueues.end();
             i!=e; ++i)
     {
@@ -624,12 +713,12 @@
 void
 NetConnection_as::markReachableResources() const
 {
-    if ( _currentCallQueue.get() ) _currentCallQueue->markReachableResources();
-    for (std::list<AMFQueue*>::const_iterator
+    if ( _currentCallQueue.get() ) _currentCallQueue->setReachable();
+    for (std::list<ConnectionHandler*>::const_iterator
             i=_callQueues.begin(), e=_callQueues.end();
             i!=e; ++i)
     {
-        (*i)->markReachableResources();
+        (*i)->setReachable();
     }
     markAsObjectReachable();
 }
@@ -918,19 +1007,19 @@
 
     while ( ! _callQueues.empty() )
     {
-        AMFQueue* que = _callQueues.front();
-        if ( ! que->tick() )
+        ConnectionHandler* ch = _callQueues.front();
+        if ( ! ch->advance() )
         {
-            log_debug("AMFQueue done, dropping");
+            log_debug("ConnectionHandler done, dropping");
             _callQueues.pop_front();
-            delete que;
+            delete ch;
         }
         else break; // queues handling is serialized
     }
 
     if ( _currentCallQueue.get() ) 
     {
-        _currentCallQueue->tick();
+        _currentCallQueue->advance();
     }
 
     // ticking of the queue might have triggered creation

=== modified file 'libcore/asobj/NetConnection_as.h'
--- a/libcore/asobj/NetConnection_as.h  2008-12-19 18:07:34 +0000
+++ b/libcore/asobj/NetConnection_as.h  2008-12-20 10:59:33 +0000
@@ -28,7 +28,7 @@
 
 // Forward declarations
 namespace gnash {
-       class AMFQueue;
+       class ConnectionHandler;
 }
 
 namespace gnash {
@@ -110,14 +110,14 @@
     /// will perform a POST request containing all calls
     /// to the same uri and dispatch results.
     ///
-       std::list<AMFQueue*> _callQueues;
+       std::list<ConnectionHandler*> _callQueues;
 
     /// Queue of calls gathered during a single movie advancement
     //
     /// For HTTP based remoting, these calls will be performed
     /// by a single POST operation.
     ///
-    std::auto_ptr<AMFQueue> _currentCallQueue; 
+    std::auto_ptr<ConnectionHandler> _currentCallQueue; 
 
        /// the url prefix optionally passed to connect()
        std::string _uri;


reply via email to

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