gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] [SCM] Gnash branch, objecturi, updated. 4a1d447d3a71010a5


From: Sandro Santilli
Subject: [Gnash-commit] [SCM] Gnash branch, objecturi, updated. 4a1d447d3a71010a5cf138006fceae93570d81df
Date: Wed, 27 Oct 2010 16:15:23 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Gnash".

The branch, objecturi has been updated
       via  4a1d447d3a71010a5cf138006fceae93570d81df (commit)
       via  7b1ae9f0b3846d953a0d91ef4b02517f9917ebbf (commit)
       via  9f22daa6b6509b420b798b885c885a1e9f83e00a (commit)
       via  3d72440aa3f550b3d93aac6aa3eb84ec5d02cd3d (commit)
       via  afd2f99ccd0dde2a4e42948da4029459dd0fcc57 (commit)
       via  e5d16688f150dd64f6b279dac85ccd9545395279 (commit)
       via  f82b8f90c356e5d67044979e9f255572a0374288 (commit)
       via  052597c426e091866827c12074e727a9781b81f2 (commit)
       via  23bc396aabf94aead11b4f552b789e77a29eb1ef (commit)
       via  1d6558ab6b2bad9083b2aeae609c0f4b63171a30 (commit)
       via  f85abb39021eeded3f92c066851e26496e19e25d (commit)
       via  2ff9c91dec30598930a12f26975b1a90d17339af (commit)
       via  2fa2a0633d6c3ca5f0b583858c307437c643a00b (commit)
       via  42a8240d8e1d5f8ded1c28b294afc71f1924481c (commit)
       via  253687751e94195fecaaec6f5330eaf599388646 (commit)
       via  1ba6fd954c3088882a20f66f556926c5eee3ffe6 (commit)
       via  c1cc98de9ed2a38fb2c922800cc19b427481dec5 (commit)
       via  82d98c1e60ca6381845e35bab72b524756fcfa21 (commit)
       via  09a900a5d6d182d0e31bd716dabad66fe62a1175 (commit)
       via  20af1a489cf893f590fb5630caaece7b7a9e011c (commit)
       via  c965625df2dc52d39a20909b1f1b48209e10f247 (commit)
       via  b514a186cd0b8254c1888dbe7a687b44472aca18 (commit)
       via  734c54fea4fc23957581da11b43f757d6fd4d38c (commit)
       via  acd20fcc20ee7eed564480a139235fb8e71c1a04 (commit)
       via  0ab0cdb064e7254c956f1e8348cc57730d68ac00 (commit)
       via  f1fcdde71ae761ec4a9a90dc35a4a5fd71c0524f (commit)
       via  8f96b7ac52583741b4cd538d83ef882aaa79cfa2 (commit)
       via  c8400f6ea799e23eae5529d5e6af7667b4d65806 (commit)
       via  ae38f1240c04c7aee327202bf1d39173da341553 (commit)
       via  c4bf3d3d77c8090413a82cb84a30e3e270749a07 (commit)
       via  170b4df66f8a53b48596a7ea86ee8a2b48304950 (commit)
       via  43c270b65425806f98b6573d5b086a144306e289 (commit)
       via  37cd82a364ce637daf91b733c16f96deca664566 (commit)
       via  8940803f71a5247b41bf7428373ce570eb558ff2 (commit)
       via  dddbbd7b3816ce6934997923f4d9f85bcc4166b2 (commit)
      from  2f8fdcb28bbdd58ce232b01fac12c08f7becd2b8 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit//commit/?id=4a1d447d3a71010a5cf138006fceae93570d81df


commit 4a1d447d3a71010a5cf138006fceae93570d81df
Merge: 2f8fdcb 7b1ae9f
Author: Sandro Santilli <address@hidden>
Date:   Wed Oct 27 18:15:14 2010 +0200

    Merge branch 'master' into objecturi
    
    Conflicts:
    
        libcore/asobj/NetConnection_as.cpp

diff --cc libcore/asobj/NetConnection_as.cpp
index 620abee,afea87c..39c5d67
--- a/libcore/asobj/NetConnection_as.cpp
+++ b/libcore/asobj/NetConnection_as.cpp
@@@ -292,260 -252,293 +252,292 @@@ boo
  HTTPRemotingHandler::advance()
  {
  
- #ifdef GNASH_DEBUG_REMOTING
-     log_debug("advancing HTTPRemotingHandler");
- #endif
-     if (_connection) {
+     // If there is no active connection, check whether messages are waiting
+     if (!_connection) {
  
- #ifdef GNASH_DEBUG_REMOTING
-         log_debug("have connection");
- #endif
+         // If there is nothing to send, there's no more to do.
+         if (!queued_count) return false;
  
-         // Fill last chunk before reading in the next
-         size_t toRead = reply.capacity() - reply.size();
-         if (!toRead) toRead = NCCALLREPLYCHUNK;
+         log_debug("creating connection");
+ 
+         (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("Attempt to read %d bytes", toRead);
+         log_debug("NetConnection.call(): encoded args from %1% calls: %2%",
+             queued_count, hexify(_postdata.data(), _postdata.size(), false));
  #endif
+         queued_count = 0;
+ 
+         // TODO: it might be useful for a Remoting Handler to have a 
+         // StreamProvider member
+         const StreamProvider& sp =
+             getRunResources(_nc.owner()).streamProvider();
  
-         // 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.
-             const size_t newCapacity = reply.size() + toRead;
+         _connection.reset(sp.getStream(_url, postdata_str, 
_headers).release());
+ 
+         _postdata.resize(6);
+ 
+         return true;
+     }
+ 
+     // 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("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);
+     log_debug("Attempt to read %d bytes", toRead);
  #endif
  
-             reply.reserve(newCapacity);
+     // 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.
+         const size_t newCapacity = _reply.size() + toRead;
  
  #ifdef GNASH_DEBUG_REMOTING
-             log_debug(" after reserve, new capacity is %d", reply.capacity());
+         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
-         }
  
-         const int read =
-             _connection->readNonBlocking(reply.data() + reply.size(), toRead);
+         _reply.reserve(newCapacity);
+     }
+ 
+     const int read =
+         _connection->readNonBlocking(_reply.data() + _reply.size(), toRead);
  
-         if (read > 0) {
+     if (read > 0) {
  #ifdef GNASH_DEBUG_REMOTING
-             log_debug("read '%1%' bytes: %2%", read, 
-                     hexify(reply.data() + reply.size(), read, false));
+         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->bad()) {
-             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()) {
+         _reply.resize(_reply.size() + read);
+     }
  
-             if (reply.size() > 8) {
+     // 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->bad()) {
+         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);
+         return false;
+     }
+     
+     if (_connection->eof()) {
  
+         if (_reply.size() > 8) {
  
  #ifdef GNASH_DEBUG_REMOTING
-                 log_debug("hit eof");
+             log_debug("hit eof");
  #endif
-                 boost::uint16_t li;
-                 const boost::uint8_t *b = reply.data() + reply_start;
-                 const boost::uint8_t *end = reply.data() + reply.size();
-                 
-                 amf::Reader rd(b, end, getGlobal(_nc.owner()));
+             const boost::uint8_t *b = _reply.data() + _reply_start;
+             const boost::uint8_t *end = _reply.data() + _reply.size();
+             
+             amf::Reader rd(b, end, getGlobal(_nc.owner()));
  
-                 // parse header
-                 b += 2; // skip version indicator and client id
+             // parse header
+             b += 2; // skip version indicator and client id
  
-                 // NOTE: this looks much like parsing of an OBJECT_AMF0
-                 boost::int16_t si = readNetworkShort(b);
-                 b += 2; // number of headers
-                 uint8_t headers_ok = 1;
-                 if (si != 0) {
+             // NOTE: this looks much like parsing of an OBJECT_AMF0
+             const boost::uint16_t numheaders = amf::readNetworkShort(b);
+             b += 2; // number of headers
+ 
+             bool headers_ok = true;
+             if (numheaders != 0) {
  
  #ifdef GNASH_DEBUG_REMOTING
-                     log_debug("NetConnection::call(): amf headers "
-                             "section parsing");
+                 log_debug("NetConnection::call(): amf headers section 
parsing");
  #endif
-                     as_value tmp;
-                     for (size_t 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);
+                 as_value tmp;
+                 for (size_t i = numheaders; i > 0; --i) {
+                     if (b + 2 > end) {
+                         headers_ok = false;
+                         break;
+                     }
+                     const boost::uint16_t namelength = 
amf::readNetworkShort(b);
+                     b += 2;
+                     if (b + namelength > end) {
+                         headers_ok = false;
+                         break;
+                     }
+                     std::string headerName((char*)b, namelength);
  #ifdef GNASH_DEBUG_REMOTING
-                         log_debug("Header name %s", headerName);
+                     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(!rd(tmp)) {
-                             headers_ok = 0;
-                             break;
-                         }
+                     b += namelength;
+                     if (b + 5 > end) {
+                         headers_ok = false;
+                         break;
+                     }
+                     b += 5; // skip past bool and length long
+ 
+                     if (!rd(tmp)) {
+                         headers_ok = false;
+                         break;
+                     }
  #ifdef GNASH_DEBUG_REMOTING
-                         log_debug("Header value %s", tmp);
+                     log_debug("Header value %s", tmp);
  #endif
- 
-                         { // method call for each header
-                           // FIXME: it seems to me that the call should happen
-                             VM& vm = getVM(_nc.owner());
-                             const ObjectURI& key = getURI(vm, headerName);
+                     VM& vm = getVM(_nc.owner());
 -                    string_table& st = vm.getStringTable();
 -                    string_table::key key = st.find(headerName);
++                    const ObjectURI& key = getURI(vm, headerName);
  #ifdef GNASH_DEBUG_REMOTING
-                             log_debug("Calling NetConnection.%s(%s)",
-                                     headerName, tmp);
+                     log_debug("Calling NetConnection.%s(%s)", headerName, 
tmp);
  #endif
-                             callMethod(&_nc.owner(), key, tmp);
-                         }
-                     }
+                     callMethod(&_nc.owner(), 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<const char*>(b), si);
-                                 log_error("NetConnection::call(): invalid "
-                                         "reply message name (%s)", msg);
-                                 break;
-                             }
+             if (headers_ok) {
  
-                             std::string id(reinterpret_cast<const char*>(b),
-                                     ns);
+                 const boost::uint16_t numreplies = amf::readNetworkShort(b);
+                 b += 2; // number of replies
  
-                             std::string methodName(
-                                     reinterpret_cast<const char*>(b+ns+1),
-                                     si-ns-1);
+                 // TODO consider counting number of replies we
+                 // actually parse and doing something if it
+                 // doesn't match this value (does it matter?
+                 if (numreplies > 0) {
+                     // parse replies until we get a parse error or
+                     // we reach the end of the buffer
+                     while (b < end) {
  
-                             b += si;
+                         if (b + 2 > end) break;
  
-                             // 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;
+                         const boost::uint16_t replylength =
+                             amf::readNetworkShort(b);
+                         b += 2; 
  
-                             // 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
+                         if (replylength < 4) {
+                             // shortest valid response is '/1/a'
+                             log_error("NetConnection::call(): "
+                                     "reply message name too short");
+                             break;
+                         }
+                         if (b + replylength > end) break;
+ 
+                         // Reply message is: '/id/methodName'
+                         int ns = 1; // next slash position
+                         while (ns < replylength - 1 && *(b + ns) != '/') ++ns;
+                         if (ns >= replylength - 1) {
+                             std::string msg(reinterpret_cast<const char*>(b),
+                                     replylength);
+                             log_error("NetConnection::call(): invalid "
+                                     "reply message name (%s)", msg);
+                             break;
+                         }
  
- #ifdef GNASH_DEBUG_REMOTING
-                             log_debug("about to parse amf value");
- #endif
-                             // this updates b to point to the next unparsed 
byte
-                             as_value replyval;
-                             if (!rd(replyval)) {
-                                 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");
+                         std::string id(reinterpret_cast<const char*>(b + 1),
+                                 ns - 1);
+                         size_t callbackID = 0;
+                         try {
+                             callbackID = boost::lexical_cast<size_t>(id);
+                         }
+                         catch (const boost::bad_lexical_cast&) {
+                             log_error(_("Callback ID was not a number"));
+                             break;
+                         }
+ 
+                         const std::string methodName(
+                                 reinterpret_cast<const char*>(b + ns + 1),
+                                 replylength - ns - 1);
+ 
+                         b += replylength;
+ 
+                         // parse past unused string in header
+                         if (b + 2 > end) break;
+                         const boost::uint16_t unusedlength =
+                             amf::readNetworkShort(b);
+ 
+                         b += 2; 
+                         if (b + unusedlength > end) break;
+                         b += unusedlength;
+ 
+                         // 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;
+ #if GNASH_DEBUG_REMOTING
+                         const boost::uint32_t len = amf::readNetworkLong(b);
+                         log_debug("Reported reply length %s", len);
  #endif
+                         b += 4; // reply length
+ 
+                         // this updates b to point to the next unparsed byte
+                         as_value replyval;
+                         if (!rd(replyval)) {
+                             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;
+                         }
+ 
+                         // update variable to show how much we've parsed
+                         _reply_start = b - _reply.data();
  
-                             // update variable to show how much we've parsed
-                             reply_start = b - reply.data();
- 
-                             // if actionscript specified a callback object,
-                             // call it
-                             as_object* callback = pop_callback(id);
-                             if (callback) {
- 
-                                 ObjectURI 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 (?)
-                                     log_error("Unsupported HTTP Remoting "
-                                             "response callback: '%s' "
-                                             "(size %d)", methodName,
-                                             methodName.size());
-                                     continue;
-                                 }
+                         // if actionscript specified a callback object,
+                         // call it
+                         as_object* callback = popCallback(callbackID);
+                         if (callback) {
+ 
 -                            string_table::key methodKey;
++                            ObjectURI 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 (?)
+                                 log_error("Unsupported HTTP Remoting "
+                                         "response callback: '%s' "
+                                         "(size %d)", methodName,
+                                         methodName.size());
+                                 continue;
+                             }
  
  #ifdef GNASH_DEBUG_REMOTING
-                                 log_debug("calling onResult callback");
+                             log_debug("calling onResult callback");
  #endif
-                                 // FIXME check if above line can fail and we
-                                 // have to react
-                                 callMethod(callback, methodKey, replyval);
+                             // FIXME check if above line can fail and we
+                             // have to react
+                             callMethod(callback, methodKey, replyval);
  #ifdef GNASH_DEBUG_REMOTING
-                                 log_debug("callback called");
+                             log_debug("callback called");
  #endif
-                             } else {
-                                 log_error("Unknown HTTP Remoting response 
identifier '%s'", id);
-                             }
+                         } 
+                         else {
+                             log_error("Unknown HTTP Remoting response "
+                                     "identifier '%s'", id);
                          }
                      }
                  }
@@@ -644,27 -604,237 +603,237 @@@ HTTPRemotingHandler::call(as_object* as
      *(reinterpret_cast<uint32_t*>(buf.data() + total_size_offset)) = 
          htonl(buf.size() - 4 - total_size_offset);
  
- #ifdef GNASH_DEBUG_REMOTING
-     log_debug(_("NetConnection.call(): encoded args: %s"),
-             hexify(buf.data(), buf.size(), false));
- #endif
+     push_amf(buf);
  
      if (asCallback) {
- #ifdef GNASH_DEBUG_REMOTING
-         log_debug("calling enqueue with callback");
- #endif
-         enqueue(buf, callNumberString, asCallback);
+         pushCallback(callID, asCallback);
+     }
+ }
+ 
+ void
+ replyBWCheck(rtmp::RTMP& r, double txn)
+ {
+     SimpleBuffer buf;
+     amf::write(buf, "_result");
+     amf::write(buf, txn);
+     buf.appendByte(amf::NULL_AMF0);
+     amf::write(buf, 0.0);
+     r.call(buf);
+ }
+ 
+ class RTMPRemotingHandler : public ConnectionHandler
+ {
+ public:
+ 
+     RTMPRemotingHandler(NetConnection_as& nc, const URL& url)
+         :
+         ConnectionHandler(nc),
+         _connectionComplete(false),
+         _url(url)
+     {
+         // Throw exception if this fails.
+         const bool ret = _rtmp.connect(url);
+         if (!ret) throw GnashException("Connection failed");
+     }
+ 
+     virtual void call(as_object* asCallback, const std::string& methodName,
+             const std::vector<as_value>& args)
+     {
+         SimpleBuffer buf;
+         amf::Writer aw(buf);
+         aw.writeString(methodName);
+         const size_t id = asCallback ? callNo() : 0;
+         aw.writeNumber(id);
+         buf.appendByte(amf::NULL_AMF0);
+ 
+         for (size_t i = 0; i < args.size(); ++i) {
+             args[i].writeAMF0(aw);
+         }
+         _rtmp.call(buf);
+         if (asCallback) {
+             pushCallback(id, asCallback);
+         }
      }
+ 
+     bool hasPendingCalls() const {
+         return false;
+     }
+ 
+     virtual bool advance() {
+ 
+         _rtmp.update();
+ 
+         if (_rtmp.error() && !_connectionComplete) {
+             _nc.notifyStatus(NetConnection_as::CONNECT_FAILED);
+             return false;
+         }
+         if (_connectionComplete && _rtmp.error()) {
+             _nc.notifyStatus(NetConnection_as::CONNECT_CLOSED);
+             return false;
+         }
+ 
+         // Nothing to do yet, but we don't want to be dropped.
+         if (!_connectionComplete) {
+ 
+             if (!_rtmp.connected()) return true;
+             
+             _connectionComplete = true;
+             log_debug("Initial connection complete");
+ 
+             const RunResources& r = getRunResources(_nc.owner());
+             Global_as& gl = getGlobal(_nc.owner());
+  
+             // Connection object
+             as_object* o = createObject(gl);
+ 
+             const int flags = 0;
+             o->init_member("app", _url.path().substr(1), flags);
+ 
+             // TODO: check where it gets these data from.
+             o->init_member("flashVer", getVM(_nc.owner()).getPlayerVersion(),
+                     flags);
+             o->init_member("swfUrl", r.streamProvider().originalURL().str(),
+                     flags);
+             o->init_member("tcUrl", _url.str(), flags);
+ 
+             // TODO: implement this properly
+             o->init_member("fpad", false, flags);
+             o->init_member("capabilities", 15.0, flags);
+             o->init_member("audioCodecs", 3191.0, flags);
+             o->init_member("videoCodecs", 252.0, flags);
+             o->init_member("videoFunction", 1.0, flags);
+             o->init_member("pageUrl", as_value(), flags);
+ 
+             // Set up the callback object.
+             as_object* cb = createObject(getGlobal(_nc.owner()));
+             cb->init_member(NSV::PROP_ON_RESULT,
+                     gl.createFunction(local_onResult), 0);
+ 
+             cb->init_member("_conn", &_nc.owner(), 0);
+ 
+             std::vector<as_value> args;
+             args.push_back(o);
+ 
+             call(cb, "connect", args);
+ 
+             // Send bandwidth check; the pp appears to do this
+             // automatically.
+             sendServerBW(_rtmp);
+ 
+         }
+         
+         boost::shared_ptr<SimpleBuffer> b = _rtmp.getMessage();
+ 
+         if (b && !_nc.isConnected()) {
+             _nc.setConnected();
+         }
+ 
+         /// Retrieve messages.
+         while (b.get()) {
+             handleInvoke(b->data() + rtmp::RTMPHeader::headerSize,
+                     b->data() + b->size());
+             b = _rtmp.getMessage();
+         }
+ 
+         return true;
+     }
+ 
+ private:
+ 
+     void handleInvoke(const boost::uint8_t* payload, const boost::uint8_t* 
end);
+ 
+     rtmp::RTMP _rtmp;
+     bool _connectionComplete;
+     const URL _url;
+ 
+ };
+ 
+ void
+ RTMPRemotingHandler::handleInvoke(const boost::uint8_t* payload,
+         const boost::uint8_t* end)
+ {
+ 
+     assert(payload != end);
+ 
+     // make sure it is a string method name we start with
+     if (payload[0] != 0x02) {
+         log_error( "Sanity failed. no string method in invoke packet");
+         return;
+     }
+ 
+     ++payload;
+     std::string method = amf::readString(payload, end);
+ 
+     log_debug("Invoke: read method string %s", method);
+     if (*payload != amf::NUMBER_AMF0) return;
+     ++payload;
+ 
+     log_debug( "Server invoking <%s>", method);
      
-     else {
- #ifdef GNASH_DEBUG_REMOTING
-         log_debug("calling enqueue without callback");
 -    string_table& st = getStringTable(_nc.owner());
 -    const ObjectURI methodname(st.find(method));
++    VM& vm = getVM(_nc.owner());
++    const ObjectURI methodname = getURI(vm, method);
+ 
+     // _result means it's the answer to a remote method call initiated
+     // by us.
+     if (method == "_result") {
+         const double id = amf::readNumber(payload, end);
+         log_debug("Received result for method call %s",
+                 boost::io::group(std::setprecision(15), id));
+ 
+         as_value arg;
+ 
+         amf::Reader rd(payload, end, getGlobal(_nc.owner()));
+         // TODO: use all args and check the order! We currently only use
+         // the last one!
+         while (rd(arg)) {
+             log_debug("Value: %s", arg);
+         }
+ 
+         as_object* o = popCallback(id);
+         callMethod(o, NSV::PROP_ON_RESULT, arg);
+         return;
+     }
+     
+     /// These are remote function calls initiated by the server.
+     const double id = amf::readNumber(payload, end);
+     log_debug("Received server call %s %s",
+             boost::io::group(std::setprecision(15), id),
+             id ? "" : "(no reply expected)");
+ 
+     /// If the server sends this, we reply (the call should contain a
+     /// callback object!).
+     if (method == "_onbwcheck") {
+         if (id) replyBWCheck(_rtmp, id);
+         else {
+             log_error("Server called _onbwcheck without a callback");
+         }
+         return;
+     }
+ 
+     if (method == "_onbwdone") {
+ 
+         if (*payload != amf::NULL_AMF0) return;
+         ++payload;
+ #if GNASH_DEBUG_REMOTING
+         log_debug("AMF buffer for _onbwdone: %s\n",
+                 hexify(payload, end - payload, false));
  #endif
-         enqueue(buf);
+         double latency = amf::readNumber(payload, end);
+         double bandwidth = amf::readNumber(payload, end);
+         log_debug("Latency: %s, bandwidth %s", latency, bandwidth);
+         return;
      }
- }
  
- //----- NetConnection_as ----------------------------------------------------
+     if (method ==  "_error") {
+         _nc.notifyStatus(NetConnection_as::CALL_FAILED);
+         log_error( "rtmp server sent error");
+         return;
+     }
+     
+     // Call method on the NetConnection object.    
+     callMethod(&_nc.owner(), methodname);
+     
+ }
  
  NetConnection_as::NetConnection_as(as_object* owner)
      :
@@@ -1123,6 -1267,36 +1266,35 @@@ netconnection_addHeader(const fn_call& 
      return as_value();
  }
  
+ /// This creates a local callback function to handle the return from connect()
+ //
+ /// NetStream does this using a builtin function, but this is more complicated
+ /// because it needs the native NetConnection type.
+ //
+ /// This stores the NetConnection object so that it can be updated when
+ /// connect returns.
+ //
+ /// We don't know if this is the best way to do it, but:
+ //
+ /// 1. the connect call *does* return a callback ID.
+ as_value
+ local_onResult(const fn_call& fn)
+ {
+     as_object* obj = fn.this_ptr;
+ 
+     if (obj) {
 -        string_table& st = getStringTable(fn);
 -        const ObjectURI conn(st.find("_conn"));
++        const ObjectURI conn = getURI(getVM(fn), "_conn");
+         as_value f = getMember(*obj, conn);
+         as_object* nc = toObject(f, getVM(fn));
+         if (nc) {
+         }
+         const as_value arg = fn.nargs ? fn.arg(0) : as_value();
+         callMethod(nc, NSV::PROP_ON_STATUS, arg);
+     }
+     return as_value();
+ }
+ 
+ 
  std::pair<std::string, std::string>
  getStatusCodeInfo(NetConnection_as::StatusCode code)
  {
diff --cc libcore/asobj/flash/external/ExternalInterface_as.cpp
index 3b82cae,0d799c5..b462b87
--- a/libcore/asobj/flash/external/ExternalInterface_as.cpp
+++ b/libcore/asobj/flash/external/ExternalInterface_as.cpp
@@@ -108,14 -108,14 +108,13 @@@ public
  
      void operator()(const as_value& val) {
          VM& vm = getVM(_fn);
--        string_table& st = getStringTable(_fn);
  
          newAdd(_ret, "<property id=\"", vm);
          newAdd(_ret, static_cast<double>(_count), vm);
          newAdd(_ret, "\">", vm);
          as_object* ei = 
              _fn.env().find_object("flash.external.ExternalInterface");
--        const as_value& x = callMethod(ei, st.find("_toXML"), val);
++        const as_value& x = callMethod(ei, getURI(vm, "_toXML"), val);
          newAdd(_ret, x, vm);
          newAdd(_ret, "</property>", vm);
          ++_count;
@@@ -139,8 -139,8 +138,7 @@@ public
          VM& vm = getVM(_fn);
          as_object* ei = 
              _fn.env().find_object("flash.external.ExternalInterface");
--        string_table& st = getStringTable(_fn);
--        const as_value& x = callMethod(ei, st.find("_toXML"), val);
++        const as_value& x = callMethod(ei, getURI(vm, "_toXML"), val);
          newAdd(_ret, x, vm);
      }
  private:
@@@ -429,14 -429,14 +427,14 @@@ externalinterface_uArgumentsToXML(cons
      as_value ret("<arguments>");
  
      if (fn.nargs) {
--        as_object *obj = toObject(fn.arg(0), getVM(fn));
++        VM& vm = getVM(fn);
++        as_object *obj = toObject(fn.arg(0), vm);
          if (obj) {
              ArgsToXML tx(ret, fn);
              size_t size = arrayLength(*obj);
--            string_table& st = getStringTable(*obj);
              if (size) {
                  for (size_t i = 1; i < static_cast<size_t>(size); ++i) {
--                    tx(getOwnProperty(*obj, arrayKey(st, i)));
++                    tx(getOwnProperty(*obj, arrayKey(vm, i)));
                  }
              }
          }
@@@ -593,7 -593,7 +591,7 @@@ externalinterface_uObjectToXML(const fn
                  as_object* ei = 
                      fn.env().find_object("flash.external.ExternalInterface");
                  const as_value& val = getMember(*obj, *i); 
--                newAdd(ret, callMethod(ei, st.find("_toXML"), val), vm);
++                newAdd(ret, callMethod(ei, getURI(vm, "_toXML"), val), vm);
                  newAdd(ret, "</property>", vm);
              }
          }
@@@ -620,13 -620,13 +618,12 @@@ externalinterface_uToXML(const fn_call
  
          as_object* ei = 
              fn.env().find_object("flash.external.ExternalInterface");
--        string_table& st = getStringTable(fn);
          VM& vm = getVM(fn);
  
          const as_value& val = fn.arg(0);
          if (val.is_string()) {
              as_value ret = "<string>";
--            newAdd(ret, callMethod(ei, st.find("_escapeXML"), val), vm);
++            newAdd(ret, callMethod(ei, getURI(vm, "_escapeXML"), val), vm);
              newAdd(ret, "</string>", vm);
              return ret;
          }
@@@ -649,9 -649,9 +646,9 @@@
              as_object* obj = toObject(val, vm);
              assert(obj);
              if (hasOwnProperty(*obj, NSV::PROP_LENGTH)) {
--                return callMethod(ei, st.find("_arrayToXML"), val);
++                return callMethod(ei, getURI(vm, "_arrayToXML"), val);
              }
--            return callMethod(ei, st.find("_objectToXML"), val);
++            return callMethod(ei, getURI(vm, "_objectToXML"), val);
          }
      }
      return as_value("<null/>");
diff --cc libcore/vm/ASHandlers.cpp
index 2965c5a,d0a4283..78a3215
--- a/libcore/vm/ASHandlers.cpp
+++ b/libcore/vm/ASHandlers.cpp
@@@ -2805,7 -2808,7 +2805,7 @@@ ActionCallMethod(ActionExec& thread
          super = 0;
      }
      else {
-         super = obj->get_super(methodURI);
 -        super = obj->get_super(method_key);
++        super = obj->get_super(methURI);
      }
  
      fn_call call(this_ptr, env, args);

-----------------------------------------------------------------------

Summary of changes:
 gui/Makefile.am                                    |   11 +-
 gui/dump/README                                    |   26 +
 gui/dump/dump.cpp                                  |   47 +-
 gui/dump/dump.h                                    |    9 +-
 gui/fb/MouseDevice.cpp                             |    4 +-
 libbase/RTMP.cpp                                   |   42 +-
 libbase/RTMP.h                                     |    3 +
 libcore/AMFConverter.cpp                           |   12 +-
 libcore/PropertyList.h                             |   11 +-
 libcore/as_object.cpp                              |    3 +-
 libcore/asobj/NetConnection_as.cpp                 | 1018 ++++++++++++--------
 libcore/asobj/NetConnection_as.h                   |    6 +-
 libcore/asobj/TextField_as.cpp                     |    4 +-
 .../asobj/flash/external/ExternalInterface_as.cpp  |   21 +-
 libcore/swf/PlaceObject2Tag.cpp                    |    8 +-
 libcore/vm/ASHandlers.cpp                          |    2 +-
 libcore/vm/VM.cpp                                  |   12 +-
 packaging/deb.am                                   |   35 +-
 packaging/debian/python-gtk-gnash.dirs             |    2 +-
 packaging/debian/python-gtk-gnash.install          |    2 +-
 20 files changed, 754 insertions(+), 524 deletions(-)
 create mode 100644 gui/dump/README


hooks/post-receive
-- 
Gnash



reply via email to

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