46class GzipCodec :
public CompressionCodec {
53 explicit GzipCodec(
int compression_level = Z_DEFAULT_COMPRESSION)
54 : level_(compression_level) {}
66 [[nodiscard]] expected<std::vector<uint8_t>>
compress(
67 const uint8_t* data,
size_t size)
const override {
74 if (size > (std::numeric_limits<uInt>::max)()) {
75 return Error{ErrorCode::INTERNAL_ERROR,
76 "GZIP: input exceeds uInt limit"};
80 stream.next_in =
const_cast<Bytef*
>(data);
81 stream.avail_in =
static_cast<uInt
>(size);
84 int ret = deflateInit2(&stream,
91 return Error{ErrorCode::INTERNAL_ERROR,
92 "GZIP: deflateInit2 failed (zlib error " +
93 std::to_string(ret) +
")"};
97 uLong bound = deflateBound(&stream,
static_cast<uLong
>(size));
98 std::vector<uint8_t> out(bound);
100 stream.next_out = out.data();
101 stream.avail_out =
static_cast<uInt
>(out.size());
103 ret = deflate(&stream, Z_FINISH);
104 if (ret != Z_STREAM_END) {
106 return Error{ErrorCode::INTERNAL_ERROR,
107 "GZIP: deflate failed (zlib error " +
108 std::to_string(ret) +
")"};
111 size_t compressed_size = stream.total_out;
114 out.resize(compressed_size);
130 [[nodiscard]] expected<std::vector<uint8_t>>
decompress(
131 const uint8_t* data,
size_t size,
132 size_t uncompressed_size)
const override {
134 static constexpr size_t MAX_DECOMPRESS_SIZE = 256 * 1024 * 1024;
135 if (uncompressed_size > MAX_DECOMPRESS_SIZE)
136 return Error{ErrorCode::INVALID_ARGUMENT,
"Decompression size exceeds 256 MB limit"};
138 if (uncompressed_size == 0) {
139 return std::vector<uint8_t>{};
143 if (size > (std::numeric_limits<uInt>::max)()) {
144 return Error{ErrorCode::INTERNAL_ERROR,
145 "GZIP: compressed input exceeds uInt limit"};
148 if (uncompressed_size > (std::numeric_limits<uInt>::max)()) {
149 return Error{ErrorCode::INTERNAL_ERROR,
150 "GZIP: uncompressed size exceeds uInt limit"};
153 std::vector<uint8_t> out(uncompressed_size);
156 stream.next_in =
const_cast<Bytef*
>(data);
157 stream.avail_in =
static_cast<uInt
>(size);
158 stream.next_out = out.data();
159 stream.avail_out =
static_cast<uInt
>(out.size());
162 int ret = inflateInit2(&stream, 15 + 16);
164 return Error{ErrorCode::CORRUPT_PAGE,
165 "GZIP: inflateInit2 failed (zlib error " +
166 std::to_string(ret) +
")"};
169 ret = inflate(&stream, Z_FINISH);
170 if (ret != Z_STREAM_END) {
172 return Error{ErrorCode::CORRUPT_PAGE,
173 "GZIP: inflate failed (zlib error " +
174 std::to_string(ret) +
175 (stream.msg ? std::string(
", ") + stream.msg
176 : std::string()) +
")"};
179 size_t decompressed_size = stream.total_out;
182 if (decompressed_size != uncompressed_size) {
183 return Error{ErrorCode::CORRUPT_PAGE,
184 "GZIP: decompressed " +
185 std::to_string(decompressed_size) +
186 " bytes but expected " +
187 std::to_string(uncompressed_size)};
197 [[nodiscard]]
Compression codec_type()
const override {
198 return Compression::GZIP;
202 [[nodiscard]]
const char* name()
const override {
225inline void register_gzip_codec(
int level = Z_DEFAULT_COMPRESSION) {
void register_codec(std::unique_ptr< CompressionCodec > codec)
Register a codec, transferring ownership to the registry.
static CodecRegistry & instance()
Access the process-wide singleton instance.
Compression codec interface and registry for Signet Forge.
Compression
Parquet compression codecs.
expected< std::vector< uint8_t > > decompress(Compression codec, const uint8_t *data, size_t size, size_t uncompressed_size)
Decompress data using the specified codec via the global CodecRegistry.
expected< std::vector< uint8_t > > compress(Compression codec, const uint8_t *data, size_t size)
Compress data using the specified codec via the global CodecRegistry.