Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-05-30 19:56:10 +0000
committerStijn Buys <ingar@osirion.org>2008-05-30 19:56:10 +0000
commit8933b795003f8ad202fce6e553191be8932a37b6 (patch)
treebfb460cbf9261b44deabfd469046a14a95c8d16c /src/core/netconnection.cc
parentf71901eeab126bb4b7e2552dd2edf0b34632c683 (diff)
zlib support
Diffstat (limited to 'src/core/netconnection.cc')
-rw-r--r--src/core/netconnection.cc94
1 files changed, 74 insertions, 20 deletions
diff --git a/src/core/netconnection.cc b/src/core/netconnection.cc
index aa3db1a..6606a9f 100644
--- a/src/core/netconnection.cc
+++ b/src/core/netconnection.cc
@@ -4,6 +4,8 @@
the terms of the GNU General Public License version 2
*/
+#include <zlib.h>
+
#include <sstream>
#include "sys/sys.h"
@@ -20,6 +22,10 @@ NetConnection::NetConnection()
{
connection_timeout = core::application()->time();
connection_state = Connecting;
+
+ receive_compressed = false;
+ received_compressed_size = 0;
+ compressed_size = 0;
}
NetConnection::~NetConnection()
@@ -135,13 +141,13 @@ void NetConnection::receive()
ssize_t bytes_received;
- memset(recvbuf, '\0', BLOCKSIZE);
+ memset(recvbuf, 0, BLOCKSIZE);
bytes_received = ::recv(connection_fd, recvbuf, BLOCKSIZE-1, 0);
Stats::network_bytes_received += bytes_received;
connection_timeout = core::application()->time();
if (bytes_received == 0) {
- con_print << "^BDisconnected.";
+ con_print << "^BDisconnected." << std::endl;
abort();
return;
} else if (bytes_received < 0) {
@@ -151,26 +157,74 @@ void NetConnection::receive()
return;
}
- std::string datablock;
- datablock.assign(recvbuf);
+ const char *c = recvbuf;
+
+ while (bytes_received) {
+ if (receive_compressed) {
+ zrecvbuf[received_compressed_size] = *c;
+ received_compressed_size++;
+
+ if (received_compressed_size == compressed_size) {
+ // uncompress
+ char zunbuf[BLOCKSIZE];
+ memset(zunbuf, 0, sizeof(zunbuf));
+ size_t zunbuf_size = BLOCKSIZE - 1;
+
+ int status = uncompress((Bytef *) zunbuf, &zunbuf_size, (Bytef *) zrecvbuf, compressed_size);
+
+ if (status != Z_OK) {
+ con_warn << "zlib error " << status << " uncompressing incoming datablock!\n";
+ } else {
+ const char *zc = zunbuf;
+ while (*zc) {
+ if (( *zc == '\n') || (*zc == '\r')) {
+ if (messageblock.size()) {
+ recvq.push_back(messageblock);
+ messageblock.clear();
+ }
+ } else {
+ if (messageblock.size() < FRAMESIZE) {
+ messageblock += *zc;
+ } else {
+ con_warn << "Incoming uncompressed message exceeds " << FRAMESIZE << " bytes!\n";
+ messageblock.clear();
+ }
+ }
+ zc++;
+ }
+ }
- while (datablock.size()) {
- // scan the datablock for enters
- if (datablock[0] == '\n' || datablock[0] == '\r') {
- if (messageblock.size() >= FRAMESIZE) {
- con_warn << "Incoming message exceeds " << FRAMESIZE << " bytes!\n";
- messageblock.clear();
- } else if (messageblock.size()) {
- recvq.push_back(messageblock);
- //con_debug << "Incoming message '" << messageblock << "'" << std::endl;
+ // reset
+ receive_compressed = false;
+ received_compressed_size = 0;
+ compressed_size = 0;
+ }
+ } else if (!messageblock.size() && (bytes_received > 3 ) && ( *c == '\xff') && (*(c+1) == '\xff')) {
+
+ receive_compressed = true;
+ received_compressed_size = 0;
+ compressed_size = *(c+2) + (*(c+3) << 8);
+ c += 3;
+ bytes_received -= 3;
+ memset(zrecvbuf, 0, sizeof(zrecvbuf));
+
+ } else if (( *c == '\n') || (*c == '\r')) {
+ if (messageblock.size()) {
+ recvq.push_back(messageblock);
messageblock.clear();
}
} else {
- messageblock.append(datablock.substr(0,1));
+ if (messageblock.size() < FRAMESIZE) {
+ messageblock += *c;
+ } else {
+ con_warn << "Incoming message exceeds " << FRAMESIZE << " bytes!\n";
+ messageblock.clear();
+ }
}
- datablock.erase(0,1);
+ c++;
+ bytes_received--;
}
- datablock.clear();
+
}
void NetConnection::frame(float seconds)
@@ -232,10 +286,10 @@ void NetConnection::transmit()
} else {
return;
}
- } else if (sendq.size() > FRAMESIZE) {
- con_warn << "Outgoing message exceeds " << FRAMESIZE << " bytes!\n";
- //sendq.clear();
- //return;
+ } else if (sendq.size() >= BLOCKSIZE - 16) {
+ con_warn << "Outgoing data exceeds " << BLOCKSIZE - 16 << " bytes!\n";
+ sendq.clear();
+ return;
}
ssize_t bytes_sent = 0;