#include "ZlibCompressor.h" #include namespace ZlibCpp { ZlibCompressor::ZlibCompressor(CompressionLevel level, DataFormat format, CompressionStrategy strategy) : level_(level), format_(format), strategy_(strategy), finished_(false) { Initialize(level, format, strategy); } ZlibCompressor::~ZlibCompressor() { if (initialized_) { Cleanup(); } } void ZlibCompressor::Initialize(CompressionLevel level, DataFormat format, CompressionStrategy strategy) { if (initialized_) { Cleanup(); } level_ = level; format_ = format; strategy_ = strategy; finished_ = false; // 计算窗口位数 int windowBits = 15; // 默认窗口大小 if (format == DataFormat::Gzip) { windowBits += 16; // Gzip格式 } else if (format == DataFormat::Raw) { windowBits = -windowBits; // 原始deflate格式 } int result = deflateInit2(&stream_, static_cast(level), Z_DEFLATED, windowBits, 8, // memLevel static_cast(strategy)); CheckResult(result, "deflateInit2"); initialized_ = true; } void ZlibCompressor::Reset() { if (!initialized_) { throw ZlibStreamException("压缩器未初始化"); } int result = deflateReset(&stream_); CheckResult(result, "deflateReset"); finished_ = false; } std::vector ZlibCompressor::Compress(const std::vector& input, bool flush) { return Compress(input.data(), input.size(), flush); } std::vector ZlibCompressor::Compress(const uint8_t* input, size_t input_size, bool flush) { if (finished_) { throw ZlibStreamException("压缩器已完成,无法继续压缩"); } int flush_mode = flush ? Z_SYNC_FLUSH : Z_NO_FLUSH; return CompressInternal(input, input_size, flush_mode); } std::vector ZlibCompressor::Finish() { if (finished_) { return {}; } finished_ = true; return CompressInternal(nullptr, 0, Z_FINISH); } std::vector ZlibCompressor::CompressInternal(const uint8_t* input, size_t input_size, int flush_mode) { if (!initialized_) { throw ZlibStreamException("压缩器未初始化"); } std::vector output; const size_t buffer_size = 8192; // 8KB缓冲区 uint8_t buffer[buffer_size]; stream_.next_in = const_cast(input); stream_.avail_in = static_cast(input_size); do { stream_.next_out = buffer; stream_.avail_out = buffer_size; int result = deflate(&stream_, flush_mode); if (result != Z_OK && result != Z_STREAM_END && result != Z_BUF_ERROR) { CheckResult(result, "deflate"); } size_t produced = buffer_size - stream_.avail_out; if (produced > 0) { size_t old_size = output.size(); output.resize(old_size + produced); std::copy(buffer, buffer + produced, output.begin() + old_size); } // 如果是Z_FINISH且返回Z_STREAM_END,表示压缩完成 if (flush_mode == Z_FINISH && result == Z_STREAM_END) { break; } } while (stream_.avail_out == 0); // 当输出缓冲区被填满时继续 return output; } std::vector ZlibCompressor::CompressData(const std::vector& input, CompressionLevel level, DataFormat format) { ZlibCompressor compressor(level, format); auto result = compressor.Compress(input); auto final = compressor.Finish(); result.insert(result.end(), final.begin(), final.end()); return result; } std::vector ZlibCompressor::CompressString(const std::string& input, CompressionLevel level, DataFormat format) { std::vector data(input.begin(), input.end()); return CompressData(data, level, format); } void ZlibCompressor::SetDictionary(const std::vector& dictionary) { if (!initialized_) { throw ZlibStreamException("压缩器未初始化"); } int result = deflateSetDictionary(&stream_, dictionary.data(), static_cast(dictionary.size())); CheckResult(result, "deflateSetDictionary"); } void ZlibCompressor::GetParams(CompressionLevel& level, CompressionStrategy& strategy) const { level = level_; strategy = strategy_; } void ZlibCompressor::SetParams(CompressionLevel level, CompressionStrategy strategy) { if (!initialized_) { throw ZlibStreamException("压缩器未初始化"); } int result = deflateParams(&stream_, static_cast(level), static_cast(strategy)); CheckResult(result, "deflateParams"); level_ = level; strategy_ = strategy; } void ZlibCompressor::Cleanup() { if (initialized_) { deflateEnd(&stream_); initialized_ = false; } } } // namespace ZlibCpp