#include #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(length); if (compress2(reinterpret_cast(buffer), &length, reinterpret_cast(const_cast(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(CHUNK); auto data_ptr = data.data(); do { stream.avail_in = std::min(static_cast(CHUNK), data.size() - (data_ptr - data.data())); stream.next_in = reinterpret_cast(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(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(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(bound); const auto size = ZSTD_decompress(buffer, bound, data.data(), data.size()); return std::string(buffer, size); } }