Fixed packet compression
This commit is contained in:
parent
707736d896
commit
16c2272fe4
@ -1,4 +1,3 @@
|
|||||||
#include <csignal>
|
|
||||||
#include <misc/memtracker.h>
|
#include <misc/memtracker.h>
|
||||||
#include "CompressionHandler.h"
|
#include "CompressionHandler.h"
|
||||||
#define QLZ_COMPRESSION_LEVEL 1
|
#define QLZ_COMPRESSION_LEVEL 1
|
||||||
@ -39,17 +38,38 @@ namespace ts::compression {
|
|||||||
void* buffer_ptr{nullptr};
|
void* buffer_ptr{nullptr};
|
||||||
size_t buffer_length{0};
|
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 thread_buffer qlz_buffer{};
|
||||||
|
thread_local qlz_states qlz_states{};
|
||||||
|
|
||||||
size_t qlz_decompressed_size(const void* payload, size_t payload_length) {
|
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;
|
return qlz_size_decompressed((char*) payload) + 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool qlz_decompress_payload(const void* payload, void* buffer, size_t* buffer_size) {
|
bool qlz_decompress_payload(const void* payload, void* buffer, size_t* buffer_size) {
|
||||||
|
if(!qlz_states.state_decompress) return false;
|
||||||
assert(payload != buffer);
|
assert(payload != buffer);
|
||||||
|
|
||||||
qlz_state_decompress state{};
|
size_t data_length = qlz_decompress((char*) payload, (char*) buffer, qlz_states.state_decompress);
|
||||||
size_t data_length = qlz_decompress((char*) payload, (char*) buffer, &state);
|
|
||||||
if(data_length <= 0)
|
if(data_length <= 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -60,16 +80,18 @@ namespace ts::compression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t qlz_compressed_size(const void* payload, size_t payload_length) {
|
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
|
//// "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) */
|
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) {
|
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(payload != buffer);
|
||||||
assert(*buffer_length >= qlz_compressed_size(payload, payload_length));
|
assert(*buffer_length >= qlz_compressed_size(payload, payload_length));
|
||||||
|
|
||||||
qlz_state_compress state{};
|
size_t compressed_length = qlz_compress(payload, (char*) buffer, payload_length, qlz_states.state_compress);
|
||||||
size_t compressed_length = qlz_compress(payload, (char*) buffer, payload_length, &state);
|
|
||||||
if(compressed_length > *buffer_length) terminate();
|
if(compressed_length > *buffer_length) terminate();
|
||||||
|
|
||||||
if(compressed_length <= 0)
|
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!)
|
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) + ")";
|
error = "Invalid packet size. (Calculated target length of " + to_string(expected_length) + ". Max length: " + to_string(this->max_packet_size) + ")";
|
||||||
return false;
|
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 header_length = packet->header().length() + packet->mac().length();
|
||||||
auto buffer = buffer::allocate_buffer(expected_length + header_length);
|
auto buffer = buffer::allocate_buffer(expected_length + header_length);
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
namespace ts {
|
namespace ts {
|
||||||
namespace compression {
|
namespace compression {
|
||||||
|
/* Attention: These methods does not validate the data! */
|
||||||
size_t qlz_decompressed_size(const void* payload, size_t payload_length);
|
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!
|
bool qlz_decompress_payload(const void* payload, void* buffer, size_t* buffer_size); //Attention: payload & buffer must be differen!
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <sql/SqlQuery.h>
|
#include <sql/SqlQuery.h>
|
||||||
|
|
||||||
|
#if 0
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct Column {
|
struct Column {
|
||||||
constexpr explicit Column(const std::string_view& name) : name{name} { }
|
constexpr explicit Column(const std::string_view& name) : name{name} { }
|
||||||
@ -166,4 +167,23 @@ int main() {
|
|||||||
std::string value{};
|
std::string value{};
|
||||||
insert.add_entry(2, value);
|
insert.add_entry(2, value);
|
||||||
insert.execute(nullptr);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user