Fixed packet compression

This commit is contained in:
WolverinDEV 2020-04-15 15:02:18 +02:00
parent 707736d896
commit 16c2272fe4
3 changed files with 51 additions and 5 deletions

View File

@ -1,4 +1,3 @@
#include <csignal>
#include <misc/memtracker.h>
#include "CompressionHandler.h"
#define QLZ_COMPRESSION_LEVEL 1
@ -39,17 +38,38 @@ namespace ts::compression {
void* buffer_ptr{nullptr};
size_t buffer_length{0};
};
class qlz_states {
public:
qlz_states() noexcept {
this->state_compress = (qlz_state_compress*) malloc(sizeof(qlz_state_compress));
this->state_decompress = (qlz_state_decompress*) malloc(sizeof(qlz_state_decompress));
}
~qlz_states() {
::free(this->state_compress);
::free(this->state_decompress);
}
qlz_state_compress* state_compress{nullptr};
qlz_state_decompress* state_decompress{nullptr};
private:
};
thread_local thread_buffer qlz_buffer{};
thread_local qlz_states qlz_states{};
size_t qlz_decompressed_size(const void* payload, size_t payload_length) {
if(payload_length < 9) return 0; /* payload too small */
return qlz_size_decompressed((char*) payload) + 400;
}
bool qlz_decompress_payload(const void* payload, void* buffer, size_t* buffer_size) {
if(!qlz_states.state_decompress) return false;
assert(payload != buffer);
qlz_state_decompress state{};
size_t data_length = qlz_decompress((char*) payload, (char*) buffer, &state);
size_t data_length = qlz_decompress((char*) payload, (char*) buffer, qlz_states.state_decompress);
if(data_length <= 0)
return false;
@ -60,16 +80,18 @@ namespace ts::compression {
}
size_t qlz_compressed_size(const void* payload, size_t payload_length) {
assert(payload_length >= 9);
//// "Always allocate size + 400 bytes for the destination buffer when compressing." <= http://www.quicklz.com/manual.html
return max(min(payload_length * 2, (size_t) (payload_length + 400ULL)), (size_t) 24ULL); /* at least 12 bytes (QLZ header) */
}
bool qlz_compress_payload(const void* payload, size_t payload_length, void* buffer, size_t* buffer_length) {
if(!qlz_states.state_compress) return false;
assert(payload != buffer);
assert(*buffer_length >= qlz_compressed_size(payload, payload_length));
qlz_state_compress state{};
size_t compressed_length = qlz_compress(payload, (char*) buffer, payload_length, &state);
size_t compressed_length = qlz_compress(payload, (char*) buffer, payload_length, qlz_states.state_compress);
if(compressed_length > *buffer_length) terminate();
if(compressed_length <= 0)
@ -99,6 +121,9 @@ bool CompressionHandler::decompress(protocol::BasicPacket* packet, std::string &
if(expected_length > this->max_packet_size){ //Max 16MB. (97% Compression!)
error = "Invalid packet size. (Calculated target length of " + to_string(expected_length) + ". Max length: " + to_string(this->max_packet_size) + ")";
return false;
} else if(expected_length == 0) {
error = "Failed to calculate decompressed packet length";
return false;
}
auto header_length = packet->header().length() + packet->mac().length();
auto buffer = buffer::allocate_buffer(expected_length + header_length);

View File

@ -4,6 +4,7 @@
namespace ts {
namespace compression {
/* Attention: These methods does not validate the data! */
size_t qlz_decompressed_size(const void* payload, size_t payload_length);
bool qlz_decompress_payload(const void* payload, void* buffer, size_t* buffer_size); //Attention: payload & buffer must be differen!

View File

@ -7,6 +7,7 @@
#include <cassert>
#include <sql/SqlQuery.h>
#if 0
template <typename T>
struct Column {
constexpr explicit Column(const std::string_view& name) : name{name} { }
@ -166,4 +167,23 @@ int main() {
std::string value{};
insert.add_entry(2, value);
insert.execute(nullptr);
}
#endif
struct A {
A() {}
~A() = default;
};
#include <set>
int main() {
std::set<int> elements{};
if(!elements.empty()) {
auto it = elements.begin();
const int* last_element{&*(it++)}; /* if elements would be empty this would be undefined behaviour */
while(it != elements.end()) {
const auto now = *it++;
const auto diff = last_element - now;
}
}
}