#ifndef cmw_ReceiveBufferTCPCompressed_hh #define cmw_ReceiveBufferTCPCompressed_hh #include #include #include #include #include #include namespace cmw { template class ReceiveBufferTCPCompressed : public ReceiveBuffer { ::std::unique_ptr state_decompress; unsigned char* bufend; int32_t bytes_read; public: sock_type sock_; explicit ReceiveBufferTCPCompressed (int32_t size) : ReceiveBuffer (size + (size >> 3) + 400) , state_decompress(::new qlz_state_decompress()) , bufend(ReceiveBuffer::buf + ReceiveBuffer::bufsize) , bytes_read(0) {} bool GotPacket () { try { static int32_t compressedSize; if (bytes_read < 9) { bytes_read += Read(sock_ , this->buf + bytes_read , 9 - bytes_read ); if (bytes_read < 9) { return false; } this->packetLength = qlz_size_decompressed((char*) this->buf); if (this->packetLength > this->bufsize) { throw failure("ReceiveBufferTCPCompressed::GotPacket -- decompressed size too great"); } compressedSize = qlz_size_compressed((char*) this->buf); if (compressedSize > this->bufsize + 400) { throw failure("ReceiveBufferTCPCompressed::GotPacket -- compressed size too great"); } ::std::memcpy(bufend - compressedSize , this->buf , bytes_read ); } bytes_read += Read(sock_ , (bufend - compressedSize) + bytes_read , compressedSize - bytes_read ); if (bytes_read < compressedSize) { return false; } this->packetLength = qlz_decompress((char*) bufend - compressedSize , this->buf , state_decompress.get() ); bytes_read = this->index = 0; return true; } catch (...) { bytes_read = 0; throw; } } void Reset () { bytes_read = 0; memset(state_decompress.get(), 0, sizeof(qlz_state_decompress)); } void Debug () {} private: ReceiveBufferTCPCompressed (ReceiveBufferTCPCompressed const&); ReceiveBufferTCPCompressed& operator= (ReceiveBufferTCPCompressed const&); }; } #endif