zlib support (#9)

Reviewed-on: #9
Co-authored-by: Persson-dev <sim16.prib@gmail.com>
Co-committed-by: Persson-dev <sim16.prib@gmail.com>
This commit was merged in pull request #9.
This commit is contained in:
2025-03-01 18:20:51 +00:00
committed by Simon Pribylski
parent 59aaf03421
commit 5beb5e92a7
9 changed files with 158 additions and 56 deletions

View File

@@ -4,8 +4,6 @@
#include <sp/common/VarInt.h>
#include <zlib.h>
#define COMPRESSION_THRESHOLD 64
namespace sp {
namespace zlib {
@@ -13,8 +11,8 @@ static DataBuffer Inflate(const std::uint8_t* source, std::size_t size, std::siz
DataBuffer result;
result.Resize(uncompressedSize);
uncompress(reinterpret_cast<Bytef*>(result.data()), reinterpret_cast<uLongf*>(&uncompressedSize),
reinterpret_cast<const Bytef*>(source), static_cast<uLong>(size));
uncompress(static_cast<Bytef*>(result.data()), static_cast<uLongf*>(&uncompressedSize), static_cast<const Bytef*>(source),
static_cast<uLong>(size));
assert(result.GetSize() == uncompressedSize);
return result;
@@ -25,35 +23,34 @@ static DataBuffer Deflate(const std::uint8_t* source, std::size_t size) {
uLongf compressedSize = size;
result.Resize(size); // Resize for the compressed data to fit into
compress(
reinterpret_cast<Bytef*>(result.data()), &compressedSize, reinterpret_cast<const Bytef*>(source), static_cast<uLong>(size));
compress(static_cast<Bytef*>(result.data()), &compressedSize, static_cast<const Bytef*>(source), static_cast<uLong>(size));
result.Resize(compressedSize); // Resize to cut useless data
return result;
}
DataBuffer Compress(const DataBuffer& buffer) {
DataBuffer Compress(const DataBuffer& buffer, std::size_t a_CompressionThreshold) {
DataBuffer packet;
if (buffer.GetSize() < COMPRESSION_THRESHOLD) {
if (buffer.GetSize() < a_CompressionThreshold) {
// Don't compress since it's a small packet
VarInt compressedDataLength = 0;
std::uint64_t packetLength = compressedDataLength.GetSerializedLength() + buffer.GetSize();
packet << packetLength;
packet << compressedDataLength;
packet << VarInt{0};
packet << buffer;
return packet;
}
DataBuffer compressedData = Deflate(buffer.data(), buffer.GetSize());
VarInt uncompressedDataLength = buffer.GetSize();
std::uint64_t packetLength = uncompressedDataLength.GetSerializedLength() + compressedData.GetSize();
packet << packetLength;
packet << uncompressedDataLength;
packet.WriteSome(compressedData.data(), compressedData.GetSize());
if (compressedData.GetSize() >= buffer.GetSize()) {
// the compression is overkill so we don't send the compressed buffer
packet << VarInt{0};
packet << buffer;
} else {
packet << uncompressedDataLength;
packet << compressedData;
}
return packet;
}
@@ -75,12 +72,18 @@ DataBuffer Decompress(DataBuffer& buffer, std::uint64_t packetLength) {
return Inflate(buffer.data() + buffer.GetReadOffset(), compressedLength, uncompressedLength.GetValue());
}
DataBuffer Decompress(DataBuffer& buffer) {
std::uint64_t packetLength;
buffer >> packetLength;
} // namespace zlib
return Decompress(buffer, packetLength);
namespace io {
DataBuffer MessageEncapsulator<option::ZlibCompress>::Encapsulate(const DataBuffer& a_Data, const option::ZlibCompress& a_Option) {
static constexpr std::size_t MAX_COMPRESS_THRESHOLD = VarInt::MAX_VALUE;
return zlib::Compress(a_Data, a_Option.m_Enabled ? a_Option.m_CompressionThreshold : MAX_COMPRESS_THRESHOLD);
}
} // namespace zlib
DataBuffer MessageEncapsulator<option::ZlibCompress>::Decapsulate(DataBuffer& a_Data, const option::ZlibCompress& a_Option) {
return zlib::Decompress(a_Data, a_Data.GetSize());
}
} // namespace io
} // namespace sp