summaryrefslogtreecommitdiffstats
path: root/src/Net/Connection.cpp
diff options
context:
space:
mode:
authorMatthias Schiffer <matthias@gamezock.de>2008-06-25 02:02:21 +0200
committerMatthias Schiffer <matthias@gamezock.de>2008-06-25 02:02:21 +0200
commitc97168bd5113fe726de42a4249df58c679e42240 (patch)
tree9802e84fc817f190e4595ac78c3f3f81f1a8d890 /src/Net/Connection.cpp
parent6aedcd087462eb198958229f3c9785da6ac52cf3 (diff)
downloadmad-c97168bd5113fe726de42a4249df58c679e42240.tar
mad-c97168bd5113fe726de42a4249df58c679e42240.zip
Neuen Receive-Stack implementiert
Diffstat (limited to 'src/Net/Connection.cpp')
-rw-r--r--src/Net/Connection.cpp128
1 files changed, 69 insertions, 59 deletions
diff --git a/src/Net/Connection.cpp b/src/Net/Connection.cpp
index 31821ac..768d827 100644
--- a/src/Net/Connection.cpp
+++ b/src/Net/Connection.cpp
@@ -18,71 +18,88 @@
*/
#include "Connection.h"
-#include "Packet.h"
namespace Mad {
namespace Net {
-bool Connection::send(const Packet &packet) {
+void Connection::packetHeaderReceiveHandler(const void *data, unsigned long length) {
+ if(length != sizeof(Packet::Data))
+ return; // Error... disconnect?
+
+ header = *reinterpret_cast<const Packet::Data*>(data);
+
+ if(header.length == 0) {
+ signal(this, Packet(header.type, header.requestId));
+
+ enterReceiveLoop();
+ }
+ else {
+ rawReceive(header.length, sigc::mem_fun(this, &Connection::packetDataReceiveHandler));
+ }
+}
+
+void Connection::packetDataReceiveHandler(const void *data, unsigned long length) {
+ if(length != header.length)
+ return; // Error... disconnect?
+
+ signal(this, Packet(header.type, header.requestId, data, length));
+
+ enterReceiveLoop();
+}
+
+void Connection::doReceive() {
if(!isConnected())
- return false;
+ return;
+
+ if(!dataPending())
+ return;
- const unsigned char *data = reinterpret_cast<const unsigned char*>(packet.getRawData());
- unsigned long dataLength = packet.getRawDataLength();
+ if(receiveComplete())
+ return;
- while(dataLength > 0) {
- ssize_t ret = gnutls_record_send(getSession(), data, dataLength);
+ ssize_t ret = gnutls_record_recv(getSession(), transR.data+transR.transmitted, transR.length-transR.transmitted);
+
+ if(ret < 0) {
+ if(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN)
+ return;
- if(ret < 0) {
- if(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN)
- continue;
-
- return false;
- }
+ // Error... disconnect?
+ return;
+ }
+
+ transR.transmitted += ret;
+
+ if(receiveComplete()) {
+ transR.notify(transR.data, transR.length);
- data += ret;
- dataLength -= ret;
+ delete [] transR.data;
+ transR.data = 0;
}
+}
+
+bool Connection::rawReceive(unsigned long length,
+ const sigc::slot<void,const void*,unsigned long> &notify)
+{
+ if(!isConnected())
+ return false;
+
+ if(!receiveComplete())
+ return false;
+
+ transR.data = new unsigned char[length];
+ transR.length = length;
+ transR.transmitted = 0;
+ transR.notify = notify;
return true;
}
-bool Connection::receive() {
- unsigned char *headerData = reinterpret_cast<unsigned char*>(&header);
- ssize_t ret;
-
+bool Connection::rawSend(const unsigned char *data, unsigned long length) {
if(!isConnected())
return false;
- while(true) {
- if(!dataPending())
- return false;
-
- if(read < sizeof(Packet::Data)) {
- ret = gnutls_record_recv(getSession(), headerData+read, sizeof(Packet::Data)-read);
-
- if(ret < 0) {
- if(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN)
- continue;
-
- return false;
- }
-
- read += ret;
-
- if(read < sizeof(Packet::Data))
- continue;
-
- if(!header.length) {
- signal(this, Packet(header.type, header.requestId));
-
- return true;
- }
-
- data = new unsigned char[header.length];
- }
-
- ret = gnutls_record_recv(getSession(), data+read-sizeof(Packet::Data), header.length+sizeof(Packet::Data)-read);
+ while(length > 0) {
+ ssize_t ret = gnutls_record_send(getSession(), data, length);
if(ret < 0) {
if(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN)
@@ -91,18 +108,11 @@ bool Connection::receive() {
return false;
}
- read += ret;
-
- if(read < header.length+sizeof(Packet::Data))
- continue;
-
- signal(this, Packet(header.type, header.requestId, data, header.length));
-
- delete [] data;
- data = 0;
-
- return true;
+ data += ret;
+ length -= ret;
}
+
+ return true;
}
}