diff options
author | Stijn Buys <ingar@osirion.org> | 2008-05-30 19:56:10 +0000 |
---|---|---|
committer | Stijn Buys <ingar@osirion.org> | 2008-05-30 19:56:10 +0000 |
commit | 8933b795003f8ad202fce6e553191be8932a37b6 (patch) | |
tree | bfb460cbf9261b44deabfd469046a14a95c8d16c /src/core/netconnection.cc | |
parent | f71901eeab126bb4b7e2552dd2edf0b34632c683 (diff) |
zlib support
Diffstat (limited to 'src/core/netconnection.cc')
-rw-r--r-- | src/core/netconnection.cc | 94 |
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; |