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. |