iw5-mod/src/utils/compression.cpp
2022-01-16 10:42:09 +01:00

89 lines
2.2 KiB
C++

#include <std_include.hpp>
#include "memory.hpp"
#include "compression.hpp"
namespace utils::compression
{
std::string zlib::compress(const std::string& data)
{
memory::allocator allocator;
unsigned long length = compressBound(data.size());
const auto buffer = allocator.allocate_array<char>(length);
if (compress2(reinterpret_cast<Bytef*>(buffer), &length,
reinterpret_cast<Bytef*>(const_cast<char*>(data.data())), data.size(),
Z_BEST_COMPRESSION) != Z_OK)
{
return {};
}
return std::string(buffer, length);
}
std::string zlib::decompress(const std::string& data)
{
z_stream stream;
ZeroMemory(&stream, sizeof(stream));
std::string buffer;
if (inflateInit(&stream) != Z_OK)
{
return {};
}
int ret;
memory::allocator allocator;
const auto dest = allocator.allocate_array<uint8_t>(CHUNK);
auto data_ptr = data.data();
do
{
stream.avail_in = std::min(static_cast<size_t>(CHUNK), data.size() - (data_ptr - data.data()));
stream.next_in = reinterpret_cast<const uint8_t*>(data_ptr);
data_ptr += stream.avail_in;
do
{
stream.avail_out = CHUNK;
stream.next_out = dest;
ret = inflate(&stream, Z_NO_FLUSH);
if (ret != Z_OK && ret != Z_STREAM_END)
{
inflateEnd(&stream);
return {};
}
buffer.append(reinterpret_cast<const char*>(dest), CHUNK - stream.avail_out);
}
while (stream.avail_out == 0);
}
while (ret != Z_STREAM_END);
inflateEnd(&stream);
return buffer;
}
std::string zstd::compress(const std::string& data)
{
memory::allocator allocator;
const auto bound = ZSTD_compressBound(data.size());
auto* buffer = allocator.allocate_array<char>(bound);
const auto size = ZSTD_compress(buffer, bound, data.data(), data.size(), ZSTD_maxCLevel());
return std::string(buffer, size);
}
std::string zstd::decompress(const std::string& data)
{
memory::allocator allocator;
const auto bound = size_t(ZSTD_getFrameContentSize(data.data(), data.size()));
auto* buffer = allocator.allocate_array<char>(bound);
const auto size = ZSTD_decompress(buffer, bound, data.data(), data.size());
return std::string(buffer, size);
}
}