29 std::to_string(
static_cast<int>(algo)) +
30 ", threshold=" + std::to_string(threshold));
38 NETWORK_LOG_TRACE(
"[compression_pipeline] Size below threshold, skipping compression");
39 std::vector<uint8_t> result(input.begin(), input.end());
40 return ok<std::vector<uint8_t>>(std::move(result));
45 std::vector<uint8_t> result(input.begin(), input.end());
46 return ok<std::vector<uint8_t>>(std::move(result));
49#ifdef BUILD_LZ4_COMPRESSION
52 return compress_lz4(input);
56#ifdef BUILD_ZLIB_COMPRESSION
59 return compress_gzip(input);
63 return compress_deflate(input);
68 NETWORK_LOG_WARN(
"[compression_pipeline] Compression algorithm not available, returning uncompressed");
69 std::vector<uint8_t> result(input.begin(), input.end());
70 return ok<std::vector<uint8_t>>(std::move(result));
79 "Input data is empty");
84 std::vector<uint8_t> result(input.begin(), input.end());
85 return ok<std::vector<uint8_t>>(std::move(result));
88#ifdef BUILD_LZ4_COMPRESSION
91 return decompress_lz4(input);
95#ifdef BUILD_ZLIB_COMPRESSION
98 return decompress_gzip(input);
102 return decompress_deflate(input);
107 NETWORK_LOG_WARN(
"[compression_pipeline] Decompression algorithm not available, returning as-is");
108 std::vector<uint8_t> result(input.begin(), input.end());
109 return ok<std::vector<uint8_t>>(std::move(result));
115 NETWORK_LOG_DEBUG(
"[compression_pipeline] Set threshold=" + std::to_string(bytes));
123#ifdef BUILD_LZ4_COMPRESSION
127 int max_compressed_size = LZ4_compressBound(
static_cast<int>(input.size()));
128 if (max_compressed_size <= 0)
132 "Failed to calculate LZ4 compressed size bound");
136 std::vector<uint8_t> compressed(max_compressed_size + 4);
139 uint32_t original_size =
static_cast<uint32_t
>(input.size());
140 std::memcpy(compressed.data(), &original_size, 4);
143 int compressed_size = LZ4_compress_default(
144 reinterpret_cast<const char*
>(input.data()),
145 reinterpret_cast<char*
>(compressed.data() + 4),
146 static_cast<int>(input.size()),
147 max_compressed_size);
149 if (compressed_size <= 0)
151 NETWORK_LOG_WARN(
"[compression_pipeline] LZ4 compression failed, returning uncompressed");
152 std::vector<uint8_t> result(input.begin(), input.end());
153 return ok<std::vector<uint8_t>>(std::move(result));
157 if (
static_cast<size_t>(compressed_size + 4) >= input.size())
159 NETWORK_LOG_TRACE(
"[compression_pipeline] Compressed size not smaller, returning uncompressed");
160 std::vector<uint8_t> result(input.begin(), input.end());
161 return ok<std::vector<uint8_t>>(std::move(result));
165 compressed.resize(compressed_size + 4);
168 std::to_string(input.size()) +
" -> " +
169 std::to_string(compressed.size()) +
" bytes (" +
170 std::to_string(100 - (compressed.size() * 100 / input.size())) +
"% reduction)");
172 return ok<std::vector<uint8_t>>(std::move(compressed));
175 auto decompress_lz4(std::span<const uint8_t> input) -> Result<std::vector<uint8_t>>
178 if (input.size() < 4)
182 "Compressed data too small");
186 uint32_t original_size;
187 std::memcpy(&original_size, input.data(), 4);
190 if (original_size > 100 * 1024 * 1024)
194 "Decompressed size too large: " + std::to_string(original_size));
198 std::vector<uint8_t> decompressed(original_size);
201 int decompressed_size = LZ4_decompress_safe(
202 reinterpret_cast<const char*
>(input.data() + 4),
203 reinterpret_cast<char*
>(decompressed.data()),
204 static_cast<int>(input.size() - 4),
205 static_cast<int>(original_size));
207 if (decompressed_size < 0)
211 "LZ4 decompression failed");
214 if (
static_cast<size_t>(decompressed_size) != original_size)
218 "Decompressed size mismatch");
222 std::to_string(input.size()) +
" -> " +
223 std::to_string(decompressed.size()) +
" bytes");
225 return ok<std::vector<uint8_t>>(std::move(decompressed));
229#ifdef BUILD_ZLIB_COMPRESSION
230 auto compress_gzip(std::span<const uint8_t> input) -> Result<std::vector<uint8_t>>
233 stream.zalloc = Z_NULL;
234 stream.zfree = Z_NULL;
235 stream.opaque = Z_NULL;
238 if (deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
239 15 + 16, 8, Z_DEFAULT_STRATEGY) != Z_OK)
243 "Failed to initialize gzip compression");
246 stream.avail_in =
static_cast<uInt
>(input.size());
247 stream.next_in =
const_cast<Bytef*
>(
reinterpret_cast<const Bytef*
>(input.data()));
249 std::vector<uint8_t> compressed;
250 compressed.resize(deflateBound(&stream,
static_cast<uLong
>(input.size())));
252 stream.avail_out =
static_cast<uInt
>(compressed.size());
253 stream.next_out = compressed.data();
255 int ret =
deflate(&stream, Z_FINISH);
258 if (ret != Z_STREAM_END)
260 NETWORK_LOG_WARN(
"[compression_pipeline] gzip compression failed, returning uncompressed");
261 std::vector<uint8_t> result(input.begin(), input.end());
262 return ok<std::vector<uint8_t>>(std::move(result));
265 compressed.resize(stream.total_out);
268 if (compressed.size() >= input.size())
270 NETWORK_LOG_TRACE(
"[compression_pipeline] Compressed size not smaller, returning uncompressed");
271 std::vector<uint8_t> result(input.begin(), input.end());
272 return ok<std::vector<uint8_t>>(std::move(result));
276 std::to_string(input.size()) +
" -> " +
277 std::to_string(compressed.size()) +
" bytes (" +
278 std::to_string(100 - (compressed.size() * 100 / input.size())) +
"% reduction)");
280 return ok<std::vector<uint8_t>>(std::move(compressed));
283 auto decompress_gzip(std::span<const uint8_t> input) -> Result<std::vector<uint8_t>>
286 stream.zalloc = Z_NULL;
287 stream.zfree = Z_NULL;
288 stream.opaque = Z_NULL;
291 if (inflateInit2(&stream, 15 + 16) != Z_OK)
295 "Failed to initialize gzip decompression");
298 stream.avail_in =
static_cast<uInt
>(input.size());
299 stream.next_in =
const_cast<Bytef*
>(
reinterpret_cast<const Bytef*
>(input.data()));
302 std::vector<uint8_t> decompressed;
303 decompressed.resize(input.size() * 2);
305 stream.avail_out =
static_cast<uInt
>(decompressed.size());
306 stream.next_out = decompressed.data();
309 while ((ret = inflate(&stream, Z_NO_FLUSH)) == Z_OK)
312 size_t current_size = decompressed.size();
313 decompressed.resize(current_size * 2);
314 stream.avail_out =
static_cast<uInt
>(decompressed.size() - current_size);
315 stream.next_out = decompressed.data() + current_size;
320 if (ret != Z_STREAM_END)
324 "gzip decompression failed");
327 decompressed.resize(stream.total_out);
330 std::to_string(input.size()) +
" -> " +
331 std::to_string(decompressed.size()) +
" bytes");
333 return ok<std::vector<uint8_t>>(std::move(decompressed));
336 auto compress_deflate(std::span<const uint8_t> input) -> Result<std::vector<uint8_t>>
339 stream.zalloc = Z_NULL;
340 stream.zfree = Z_NULL;
341 stream.opaque = Z_NULL;
344 if (deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
345 15, 8, Z_DEFAULT_STRATEGY) != Z_OK)
349 "Failed to initialize deflate compression");
352 stream.avail_in =
static_cast<uInt
>(input.size());
353 stream.next_in =
const_cast<Bytef*
>(
reinterpret_cast<const Bytef*
>(input.data()));
355 std::vector<uint8_t> compressed;
356 compressed.resize(deflateBound(&stream,
static_cast<uLong
>(input.size())));
358 stream.avail_out =
static_cast<uInt
>(compressed.size());
359 stream.next_out = compressed.data();
361 int ret =
deflate(&stream, Z_FINISH);
364 if (ret != Z_STREAM_END)
366 NETWORK_LOG_WARN(
"[compression_pipeline] deflate compression failed, returning uncompressed");
367 std::vector<uint8_t> result(input.begin(), input.end());
368 return ok<std::vector<uint8_t>>(std::move(result));
371 compressed.resize(stream.total_out);
374 if (compressed.size() >= input.size())
376 NETWORK_LOG_TRACE(
"[compression_pipeline] Compressed size not smaller, returning uncompressed");
377 std::vector<uint8_t> result(input.begin(), input.end());
378 return ok<std::vector<uint8_t>>(std::move(result));
382 std::to_string(input.size()) +
" -> " +
383 std::to_string(compressed.size()) +
" bytes (" +
384 std::to_string(100 - (compressed.size() * 100 / input.size())) +
"% reduction)");
386 return ok<std::vector<uint8_t>>(std::move(compressed));
389 auto decompress_deflate(std::span<const uint8_t> input) -> Result<std::vector<uint8_t>>
392 stream.zalloc = Z_NULL;
393 stream.zfree = Z_NULL;
394 stream.opaque = Z_NULL;
397 if (inflateInit2(&stream, 15) != Z_OK)
401 "Failed to initialize deflate decompression");
404 stream.avail_in =
static_cast<uInt
>(input.size());
405 stream.next_in =
const_cast<Bytef*
>(
reinterpret_cast<const Bytef*
>(input.data()));
408 std::vector<uint8_t> decompressed;
409 decompressed.resize(input.size() * 2);
411 stream.avail_out =
static_cast<uInt
>(decompressed.size());
412 stream.next_out = decompressed.data();
415 while ((ret = inflate(&stream, Z_NO_FLUSH)) == Z_OK)
418 size_t current_size = decompressed.size();
419 decompressed.resize(current_size * 2);
420 stream.avail_out =
static_cast<uInt
>(decompressed.size() - current_size);
421 stream.next_out = decompressed.data() + current_size;
426 if (ret != Z_STREAM_END)
430 "deflate decompression failed");
433 decompressed.resize(stream.total_out);
436 std::to_string(input.size()) +
" -> " +
437 std::to_string(decompressed.size()) +
" bytes");
439 return ok<std::vector<uint8_t>>(std::move(decompressed));