|
From: <at...@us...> - 2007-10-29 23:07:47
|
Revision: 520
http://cadcdev.svn.sourceforge.net/cadcdev/?rev=520&view=rev
Author: atani
Date: 2007-10-29 16:07:45 -0700 (Mon, 29 Oct 2007)
Log Message:
-----------
support for pushing events out for received data.
Modified Paths:
--------------
tiki/examples/net/httpclient/src/main.cpp
tiki/include/Tiki/net/buffer.h
tiki/include/Tiki/net/http/useragent.h
tiki/include/Tiki/net/socket.h
tiki/include/Tiki/net/tcpsocket.h
tiki/src/base/object.cpp
tiki/src/net/http/cookiejar.cpp
tiki/src/net/http/useragent.cpp
tiki/src/net/socket.cpp
tiki/src/net/tcpsocket.cpp
Modified: tiki/examples/net/httpclient/src/main.cpp
===================================================================
--- tiki/examples/net/httpclient/src/main.cpp 2007-10-28 18:38:46 UTC (rev 519)
+++ tiki/examples/net/httpclient/src/main.cpp 2007-10-29 23:07:45 UTC (rev 520)
@@ -7,6 +7,7 @@
*/
#include <Tiki/tiki.h>
+#include <Tiki/object.h>
#include <Tiki/refcnt.h>
#include <Tiki/hid.h>
#include <Tiki/tikitime.h>
@@ -22,6 +23,27 @@
using namespace Tiki::Net::Http;
using namespace Tiki::GL;
+class EventReceiver : public Object {
+ public:
+ EventReceiver() {}
+ TIKI_OBJECT_DECLS( EventReceiver )
+
+ int progressUpdate(Selector *sel, Object *arg) {
+ SocketProgress *progress = reinterpret_cast<SocketProgress *>(arg);
+ if(progress->getBytesReceived() > 0) {
+ Debug::printf("Recv %d/%d\n", progress->getBytesReceived(), progress->getBytesExpected());
+ }
+ else {
+ Debug::printf("Sent %d/%d\n", progress->getBytesSent(), progress->getBytesExpected());
+ }
+ }
+};
+
+TIKI_OBJECT_NAME( EventReceiver )
+TIKI_OBJECT_BEGIN( Object, EventReceiver )
+TIKI_OBJECT_RECEIVER( "progressUpdate", EventReceiver::progressUpdate )
+TIKI_OBJECT_END( EventReceiver )
+
volatile bool g_quitting = false;
void tkCallback( const Hid::Event & evt, void * data ) {
if ( evt.type == Hid::Event::EvtQuit ) {
@@ -40,12 +62,16 @@
Tiki::Net::connect();
HttpUserAgent *useragent = new HttpUserAgent();
+ useragent->connect( "progressUpdate", new EventReceiver() );
useragent->setCookieJar(new CookieJar());
useragent->setIgnoreCookies(false);
useragent->getCookieJar()->loadFromXML("cookies.xml");
- //useragent->setProxyHost("proxy.example.com");
- //useragent->setProxyPort(80);
+ if(argc >= 3) {
+ useragent->setProxyHost(argv[1]);
+ useragent->setProxyPort(atoi(argv[2]));
+ }
+
Request *request = new Request();
request->setUrl("http://www.google.com/");
Modified: tiki/include/Tiki/net/buffer.h
===================================================================
--- tiki/include/Tiki/net/buffer.h 2007-10-28 18:38:46 UTC (rev 519)
+++ tiki/include/Tiki/net/buffer.h 2007-10-29 23:07:45 UTC (rev 520)
@@ -151,4 +151,4 @@
} // namespace Tiki
-#endif // __TIKI_NET_UDPPACKET_H
+#endif // __TIKI_NET_BUFFER_H
Modified: tiki/include/Tiki/net/http/useragent.h
===================================================================
--- tiki/include/Tiki/net/http/useragent.h 2007-10-28 18:38:46 UTC (rev 519)
+++ tiki/include/Tiki/net/http/useragent.h 2007-10-29 23:07:45 UTC (rev 520)
@@ -24,7 +24,7 @@
using std::string;
using std::list;
-class HttpUserAgent : public RefCnt {
+class HttpUserAgent : public Object {
public:
HttpUserAgent();
@@ -73,7 +73,10 @@
Response *get(Request *req);
Response *post(Request *req);
-
+
+ protected:
+ TIKI_OBJECT_DECLS( HttpUserAgent )
+
private:
string m_userAgentName;
string m_proxyHost;
Modified: tiki/include/Tiki/net/socket.h
===================================================================
--- tiki/include/Tiki/net/socket.h 2007-10-28 18:38:46 UTC (rev 519)
+++ tiki/include/Tiki/net/socket.h 2007-10-29 23:07:45 UTC (rev 520)
@@ -8,7 +8,7 @@
#ifndef __TIKI_NET_SOCKET_H
#define __TIKI_NET_SOCKET_H
-#include "Tiki/refcnt.h"
+#include "Tiki/object.h"
#include "Tiki/net/address.h"
#include "Tiki/net/buffer.h"
@@ -16,9 +16,9 @@
namespace Net {
-class Socket : public RefCnt
+class Socket : public Object
{
- public:
+ public:
Socket();
Socket(Address *address);
virtual ~Socket() {}
@@ -77,6 +77,9 @@
virtual bool isOpen() = 0;
+ protected:
+ TIKI_OBJECT_DECLS( Socket )
+
private:
RefPtr<Address> m_peerAddress;
RefPtr<Address> m_localAddress;
@@ -84,6 +87,30 @@
bool m_reuse;
};
+class SocketProgress : public Object {
+ public:
+ SocketProgress(size_t expected, size_t received, size_t sent) {
+ m_expected = expected;
+ m_received = received;
+ m_sent = sent;
+ }
+ size_t getBytesExpected() {
+ return m_expected;
+ }
+ size_t getBytesReceived() {
+ return m_received;
+ }
+ size_t getBytesSent() {
+ return m_sent;
+ }
+ protected:
+ TIKI_OBJECT_DECLS( Socket )
+ private:
+ size_t m_expected;
+ size_t m_received;
+ size_t m_sent;
+};
+
} // namespace Net
} // namespace Tiki
Modified: tiki/include/Tiki/net/tcpsocket.h
===================================================================
--- tiki/include/Tiki/net/tcpsocket.h 2007-10-28 18:38:46 UTC (rev 519)
+++ tiki/include/Tiki/net/tcpsocket.h 2007-10-29 23:07:45 UTC (rev 520)
@@ -32,12 +32,12 @@
class TCPSocket : public Socket
{
public:
- TCPSocket() : m_open(false) {};
- TCPSocket(Address *address) : Socket(address), m_open(false) {};
+ TCPSocket() : m_open(false), m_sendEvents(true) {};
+ TCPSocket(Address *address) : Socket(address), m_open(false), m_sendEvents(true) {};
#if TIKI_PLAT == TIKI_WIN32
- TCPSocket(Address *address, SOCKET socket) : Socket(address), m_open(true), m_socket(socket) {setNonBlocking(false);};
+ TCPSocket(Address *address, SOCKET socket) : Socket(address), m_open(true), m_sendEvents(true), m_socket(socket) {setNonBlocking(false);};
#else
- TCPSocket(RefPtr<Address> address, int socket) : Socket(address), m_open(true), m_socket(socket) {setNonBlocking(false);};
+ TCPSocket(RefPtr<Address> address, int socket) : Socket(address), m_open(true), m_sendEvents(true), m_socket(socket) {setNonBlocking(false);};
#endif
virtual ~TCPSocket() {}
@@ -67,8 +67,11 @@
virtual void setNonBlocking(bool blocking);
protected:
+ TIKI_OBJECT_DECLS( TCPSocket )
+
uint16 m_port;
bool m_open;
+ bool m_sendEvents;
#if TIKI_PLAT == TIKI_WIN32
SOCKET m_socket;
#else
Modified: tiki/src/base/object.cpp
===================================================================
--- tiki/src/base/object.cpp 2007-10-28 18:38:46 UTC (rev 519)
+++ tiki/src/base/object.cpp 2007-10-29 23:07:45 UTC (rev 520)
@@ -106,8 +106,10 @@
// Find the target method.
ReceiverMap::iterator i = m_receivers.find( msg );
if ( i == m_receivers.end() ) {
+#if defined(DEBUG_OBJECT)
Debug::printf( "WARNING: Selector %s performed on object %s ignored!\n",
msg.c_str(), m_className.c_str() );
+#endif
return -1;
}
@@ -128,6 +130,12 @@
Selector targetSel = target.second;
if ( targetSel == "" )
targetSel = msg;
+ if(targetObj == NULL) {
+#if defined(DEBUG_OBJECT)
+ Debug::printf("WARNING: Selector \'%s\' on object %s maps to NULL!\n", msg.c_str(), m_className.c_str());
+#endif
+ return -1;
+ }
return targetObj->perform( targetSel, this, arg );
}
Modified: tiki/src/net/http/cookiejar.cpp
===================================================================
--- tiki/src/net/http/cookiejar.cpp 2007-10-28 18:38:46 UTC (rev 519)
+++ tiki/src/net/http/cookiejar.cpp 2007-10-29 23:07:45 UTC (rev 520)
@@ -73,8 +73,6 @@
}
void CookieJar::addCookie(string httpLine, string host, string resource) {
-
- Tiki::Debug::printf("COOKIE: %s\n", httpLine.c_str());
Cookie *cookie;
string value = httpLine;
@@ -227,7 +225,6 @@
string name = node->ToElement()->Attribute("name");
TiXmlElement *valueNode = node->FirstChildElement("Value");
string valueEncoded(valueNode->GetText());
- Tiki::Debug::printf(valueNode->GetText());
Buffer buf(valueEncoded.length(), (uint8 *)valueEncoded.c_str());
Buffer *decoded = b64.decode(&buf);
string value = (char *)decoded->getData();
@@ -301,4 +298,4 @@
}; // namespace Net
-}; // namespace Tiki
\ No newline at end of file
+}; // namespace Tiki
Modified: tiki/src/net/http/useragent.cpp
===================================================================
--- tiki/src/net/http/useragent.cpp 2007-10-28 18:38:46 UTC (rev 519)
+++ tiki/src/net/http/useragent.cpp 2007-10-29 23:07:45 UTC (rev 520)
@@ -28,6 +28,11 @@
using std::istringstream;
using std::ios;
+TIKI_OBJECT_NAME( HttpUserAgent )
+TIKI_OBJECT_BEGIN( Object, HttpUserAgent )
+TIKI_OBJECT_OUTLET( "progressUpdate" )
+TIKI_OBJECT_END( HttpUserAgent )
+
HttpUserAgent::HttpUserAgent() {
#if TIKI_PLAT == TIKI_WIN32
m_userAgentName = "Tiki/1.0 (Windows)";
@@ -58,10 +63,6 @@
parseUrl(req->getUrl(), hostname, resource, port);
- string requestText;
- buildRequest(hostname, resource, port, "GET", req, requestText);
- //Tiki::Debug::printf("Request:\n%s", requestText.c_str());
-
TCPSocket *socket;
if(m_proxyHost.empty()) {
socket = new TCPSocket(new Address(hostname, port));
@@ -79,6 +80,9 @@
return response;
}
+ string requestText;
+ buildRequest(hostname, resource, port, "GET", req, requestText);
+
Tiki::Debug::printf("Sending request...\n");
Tiki::Debug::printf(requestText.c_str());
socket->send(requestText);
@@ -103,10 +107,6 @@
parseUrl(req->getUrl(), hostname, resource, port);
- string requestText;
- buildRequest(hostname, resource, port, "POST", req, requestText);
- //Tiki::Debug::printf("Request:\n%s", requestText.c_str());
-
TCPSocket *socket;
if(m_proxyHost.empty()) {
socket = new TCPSocket(new Address(hostname, port));
@@ -124,10 +124,23 @@
return response;
}
+ string requestText;
+ buildRequest(hostname, resource, port, "POST", req, requestText);
+
Tiki::Debug::printf("Sending request...\n");
socket->send(requestText);
-
+
+ size_t maxSize = requestText.length();
+ size_t sentSize = maxSize;
list<string> content = req->getContentPartNames();
+ for(list<string>::iterator iter = content.begin();
+ iter != content.end();
+ ++iter) {
+ Buffer *buf = req->getContentPart(*iter);
+ if(buf->getUsedDataLen() > 0) {
+ maxSize += buf->getUsedDataLen();
+ }
+ }
if(content.size() > 1 || req->isForcedMultiPartUpload()) {
string status = "";
socket->recv(status);
@@ -151,19 +164,26 @@
//Tiki::Debug::printf("CONTENT_HEADER:\n%s", headerText.c_str());
socket->send(headerText);
socket->send(buf);
+ sentSize += buf->getUsedDataLen();
+ SocketProgress *progress = new SocketProgress(maxSize, 0, sentSize);
+ emit( "progressUpdate", progress );
+ delete progress;
}
}
string footerText = "\r\n--";
footerText.append(req->getBoundaryMarker());
footerText.append("--\r\n");
- //Tiki::Debug::printf("CONTENT_FOOTER:\n%s", footerText.c_str());
socket->send(footerText);
}
else if(content.size() == 1) {
Buffer *buf = req->getContentPart(*content.begin());
if(buf->getUsedDataLen() > 0) {
socket->send(buf);
+ SocketProgress *progress = new SocketProgress(maxSize, 0, buf->getUsedDataLen());
+ emit( "progressUpdate", progress );
+ delete progress;
}
+
}
readResponse(response, socket);
@@ -286,24 +306,23 @@
string status = "";
socket->recv(status);
- Tiki::Debug::printf("%s\n", status.c_str());
-
- //Tiki::Debug::printf("Status: %s\n", status.c_str());
for(string::size_type i = 0; i < status.length(); i++) {
if(status.at(i) == ' ') {
response->setResultCode(atoi(status.c_str()+i + 1));
break;
}
}
-
+
+ size_t responseSize = -1;
+ size_t receivedSoFar = 0;
while(1) {
string line = "";
socket->recv(line);
+ receivedSoFar += line.size();
if(line.size() == 0) {
// done with headers
break;
}
- //Tiki::Debug::printf("HEADER_LINE: %s\n", line.c_str());
if(line.find(":") != string::npos) {
string field = line.substr(0, line.find(":"));
string value = line.substr(line.find(":") + 1);
@@ -316,12 +335,20 @@
m_cookieJar->addCookie(value, host, resource);
}
}
+ else if(!field.compare("Content-Length")) {
+ responseSize = atoi(value.c_str());
+ }
else {
response->setHeaderParam(field, value);
}
}
+ if(responseSize != -1) {
+ SocketProgress *progress = new SocketProgress(responseSize, receivedSoFar, 0);
+ emit( "progressUpdate", progress );
+ delete progress;
+ }
}
-
+
Buffer *fullBuf = new Buffer(1);
if(!response->getHeaderParam("Transfer-Encoding").compare("chunked")) {
@@ -344,20 +371,28 @@
sizestream.unsetf(ios::dec);
sizestream.setf(ios::skipws);
sizestream >> sizeDecoded;
+ responseSize = receivedSoFar + sizeDecoded;
- //Tiki::Debug::printf("chunk size: %d [%s]\n", sizeDecoded, size.c_str());
if(sizeDecoded > 0) {
-
Buffer *chunkBuf = new Buffer(sizeDecoded);
socket->recv(chunkBuf);
+ receivedSoFar += chunkBuf->getUsedDataLen();
+ SocketProgress *progress = new SocketProgress(responseSize, receivedSoFar, 0);
+ emit( "progressUpdate", progress );
+ delete progress;
if(chunkBuf->getUsedDataLen() < sizeDecoded)
{
- //Tiki::Debug::printf("Buffer underflow\n");
size_t needed = sizeDecoded - chunkBuf->getUsedDataLen();
while(needed > 0) {
Buffer *chunkBuf2 = new Buffer(needed);
socket->recv(chunkBuf2);
chunkBuf->append(chunkBuf2);
+ if(chunkBuf2->getUsedDataLen() > 0) {
+ receivedSoFar += chunkBuf2->getUsedDataLen();
+ SocketProgress *progress = new SocketProgress(responseSize, receivedSoFar, 0);
+ emit( "progressUpdate", progress );
+ delete progress;
+ }
needed -= chunkBuf2->getUsedDataLen();
delete chunkBuf2;
}
@@ -367,15 +402,17 @@
delete chunkBuf;
}
} while(sizeDecoded > 0);
- //Tiki::Debug::printf("total size: %d %x\n", totalSize, totalSize);
}
else if(response->getHeaderParam("Content-Length").compare("")) {
Tiki::Debug::printf("Encoding is inline\n");
size_t sizeDecoded = atoi(response->getHeaderParam("Content-Length").c_str());
- //Tiki::Debug::printf("decodedSize: %d\n", sizeDecoded);
Buffer *chunkBuf = new Buffer(sizeDecoded);
socket->recv(chunkBuf);
+ receivedSoFar += chunkBuf->getUsedDataLen();
+ SocketProgress *progress = new SocketProgress(responseSize, receivedSoFar, 0);
+ emit( "progressUpdate", progress );
+ delete progress;
if(chunkBuf->getUsedDataLen() < sizeDecoded)
{
sizeDecoded -= chunkBuf->getUsedDataLen();
@@ -383,6 +420,12 @@
Buffer *chunkBuf2 = new Buffer(sizeDecoded);
socket->recv(chunkBuf2);
chunkBuf->append(chunkBuf2);
+ if(chunkBuf2->getUsedDataLen() > 0) {
+ receivedSoFar += chunkBuf2->getUsedDataLen();
+ SocketProgress *progress = new SocketProgress(responseSize, receivedSoFar, 0);
+ emit( "progressUpdate", progress );
+ delete progress;
+ }
sizeDecoded -= chunkBuf2->getUsedDataLen();
delete chunkBuf2;
}
Modified: tiki/src/net/socket.cpp
===================================================================
--- tiki/src/net/socket.cpp 2007-10-28 18:38:46 UTC (rev 519)
+++ tiki/src/net/socket.cpp 2007-10-29 23:07:45 UTC (rev 520)
@@ -14,6 +14,15 @@
namespace Net {
+TIKI_OBJECT_NAME( Socket )
+TIKI_OBJECT_BEGIN( Object, Socket )
+TIKI_OBJECT_OUTLET( "progress" )
+TIKI_OBJECT_END( Socket )
+
+TIKI_OBJECT_NAME( SocketProgress )
+TIKI_OBJECT_BEGIN( Object, SocketProgress )
+TIKI_OBJECT_END( SocketProgress )
+
Socket::Socket()
{
m_localAddress = new Address();
Modified: tiki/src/net/tcpsocket.cpp
===================================================================
--- tiki/src/net/tcpsocket.cpp 2007-10-28 18:38:46 UTC (rev 519)
+++ tiki/src/net/tcpsocket.cpp 2007-10-29 23:07:45 UTC (rev 520)
@@ -18,18 +18,26 @@
namespace TCP {
+TIKI_OBJECT_NAME( TCPSocket )
+TIKI_OBJECT_BEGIN( Socket, TCPSocket )
+TIKI_OBJECT_OUTLET( "progress" )
+TIKI_OBJECT_END( TCPSocket )
+
void TCPSocket::send(Buffer *buffer) {
uint8 *data = buffer->getData();
size_t dataLen = buffer->getUsedDataLen();
int len;
+ size_t dataSent = 0;
do {
- //Tiki::Debug::printf("sending %d bytes\n", dataLen);
len = ::send(m_socket, (const char *)data, (int)dataLen, 0);
if(len > 0) {
- //Tiki::Debug::printf("sent %d bytes\n", len);
dataLen -= len;
data += len;
+ dataSent += len;
+ SocketProgress *progress = new SocketProgress(buffer->getUsedDataLen(), 0, dataSent);
+ emit( "progress", progress );
+ delete progress;
}
} while(dataLen > 0 && (len > 0 || errno == EINTR));
}
@@ -38,14 +46,17 @@
uint8 *data = (uint8 *)buffer.c_str();
size_t dataLen = buffer.length();
int len;
+ size_t dataSent = 0;
do {
- //Tiki::Debug::printf("sending %d bytes\n", dataLen);
len = ::send(m_socket, (const char *)data, (int)dataLen, 0);
if(len > 0) {
- //Tiki::Debug::printf("sent %d bytes\n", len);
dataLen -= len;
data += len;
+ dataSent += len;
+ SocketProgress *progress = new SocketProgress(buffer.length(), 0, dataSent);
+ emit( "progress", progress );
+ delete progress;
}
} while(dataLen > 0 && (len > 0 || errno == EINTR));
}
@@ -61,7 +72,6 @@
memset(tmp, 0, maxReadData);
int recvlen = 0;
errno = 0;
- //Tiki::Debug::printf("receiving %d bytes\n", data->getDataLen());
do {
recvlen = ::recv(m_socket, (char *)tmp, (int)maxReadData, 0);
#if TIKI_PLAT == TIKI_WIN32
@@ -70,7 +80,11 @@
} while(errno == EINTR);
#endif
if(recvlen > 0) {
- //Tiki::Debug::printf("received %d bytes\nerrno %d\n", recvlen, errno);
+ if(m_sendEvents) {
+ SocketProgress *progress = new SocketProgress(maxReadData, recvlen, 0);
+ emit( "progress", progress );
+ delete progress;
+ }
data->setData(tmp, recvlen);
}
else if(recvlen < 0) {
@@ -82,20 +96,27 @@
}
void TCPSocket::recv(string &data) {
- Buffer *recvBuf = new Buffer(1);
- data = "";
- while(isOpen()) {
- recvBuf->reset();
- recv(recvBuf);
- if(recvBuf->getUsedDataLen() > 0) {
- if(recvBuf->getData()[0] != '\n' && recvBuf->getData()[0] != '\r' ) {
- data.append((char *)recvBuf->getData());
- }
- else if(recvBuf->getData()[0] != '\r' ) {
- break;
- }
- }
- }
+ Buffer *recvBuf = new Buffer(1);
+ data = "";
+ m_sendEvents = false;
+ while(isOpen()) {
+ recvBuf->reset();
+ recv(recvBuf);
+ if(recvBuf->getUsedDataLen() > 0) {
+ if(recvBuf->getData()[0] != '\n' && recvBuf->getData()[0] != '\r' ) {
+ data.append((char *)recvBuf->getData());
+ }
+ else if(recvBuf->getData()[0] != '\r' ) {
+ if(data.length() > 0) {
+ SocketProgress *progress = new SocketProgress(data.length(), data.length(), 0);
+ emit( "progress", progress );
+ delete progress;
+ }
+ break;
+ }
+ }
+ }
+ m_sendEvents = true;
delete recvBuf;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|