TEC
A lightweight C++ library enabling safe, efficient execution in multithreaded and concurrent systems.
Loading...
Searching...
No Matches
tec_nd_compress.hpp
Go to the documentation of this file.
1// Time-stamp: <Last changed 2026-02-11 16:47:05 by magnolia>
2/*----------------------------------------------------------------------
3------------------------------------------------------------------------
4Copyright (c) 2020-2026 The Emacs Cat (https://github.com/olddeuteronomy/tec).
5
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17------------------------------------------------------------------------
18----------------------------------------------------------------------*/
19
29#pragma once
30
31#include <cerrno>
32#include <cstddef>
33
34#if defined (_TEC_USE_ZLIB)
35#include <zlib.h>
36// TEC library optionally uses the Zlib library (http://zlib.net).
37// If used, Zlib is Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler.
38#endif
39
40#include "tec/tec_def.hpp" // IWYU pragma: keep
41#include "tec/tec_trace.hpp" // IWYU pragma: keep
42#include "tec/tec_status.hpp"
45
46
47namespace tec {
48
90protected:
91 int type_;
92 int level_;
93 size_t min_size_;
94
95public:
109 : type_{CompressionParams::kDefaultCompression}
110 , level_{CompressionParams::kDefaultCompressionLevel}
111 , min_size_{CompressionParams::kMinSize}
112 {}
113
128 explicit NdCompress(int _type,
129 int _level = CompressionParams::kDefaultCompressionLevel,
130 size_t _min_size = CompressionParams::kMinSize)
131 : type_{_type}
132 , level_{_level}
133 , min_size_{_min_size}
134 {}
135
161 virtual Status compress(NetData& nd) const {
162 TEC_ENTER("NdCompress::compress");
163#if defined (ZLIB_VERSION)
164 if (type_ == CompressionParams::kCompressionZlib) {
165 TEC_TRACE("Type={} Level={} MinSize={}", type_, level_, min_size_);
166 return compress_zlib(nd);
167 }
168#endif
169 // No compression required.
170 TEC_TRACE("OFF.");
171 nd.header.set_compression(CompressionParams::kNoCompression);
172 return {};
173 }
174
202 virtual Status uncompress(NetData& nd) const {
203 TEC_ENTER("NdCompress::uncompress");
204 int compression = nd.header.get_compression();
205 nd.rewind();
206 if (compression == CompressionParams::kNoCompression) {
207 // Nothing to do.
208 TEC_TRACE("OFF.");
209 return {};
210 }
211#if defined (ZLIB_VERSION)
212 if (compression == CompressionParams::kCompressionZlib) {
213 return uncompress_zlib(nd);
214 }
215#endif
216 return {ENOTSUP, Error::Kind::Unsupported};
217 }
218
219protected:
220
221 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
222 *
223 * ZLIB compression
224 *
225 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
226
227#if defined (ZLIB_VERSION)
228
239 virtual Status compress_zlib(NetData& nd) const {
240 TEC_ENTER("NdCompress::compress_zlib");
241 if (nd.header.size < min_size_) {
242 // Data too small -- no compression required.
243 nd.header.set_compression(CompressionParams::kNoCompression);
244 return {};
245 }
246 //
247 // Calculate output size.
248 //
249 auto size_compressed = ::compressBound(nd.header.size);
250 if (size_compressed == 0) {
251 return{EINVAL, Error::Kind::RuntimeErr};
252 }
253 //
254 // Prepare temp NetData.
255 //
256 NetData tmp;
257 tmp.header = nd.header;
258 tmp.header.size_uncompressed = nd.header.size;
259 tmp.header.set_compression(type_);
260 tmp.header.set_compression_level(level_);
261 // Prepare output buffer.
262 tmp.bytes().resize(size_compressed);
263 //
264 // Compressing.
265 //
266 TEC_TRACE("Compressing {} bytes...", nd.header.size);
267 auto result = ::compress2(
268 (Bytef*)tmp.bytes().ptr(0), &size_compressed,
269 (const Bytef*)nd.bytes().ptr(0), nd.size(),
270 level_);
271 if (result != Z_OK) {
272 return {EILSEQ, Error::Kind::RuntimeErr};
273 }
274 //
275 // Update input NetData inplace.
276 //
277 tmp.header.size = size_compressed;
278 nd.move_from(std::move(tmp), size_compressed);
279 TEC_TRACE("Compressed to {} bytes with ratio {}.",
280 size_compressed,
281 (double)nd.header.size_uncompressed / (double)nd.header.size);
282 return {};
283 }
284
293 virtual Status uncompress_zlib(NetData& nd) const {
294 TEC_ENTER("NdCompress::uncompress_zlib");
295 if (nd.header.get_compression() == CompressionParams::kNoCompression) {
296 // No uncompression required.
297 return {};
298 }
299 //
300 // Prepare temp NetData.
301 //
302 NetData tmp;
303 tmp.header = nd.header;
304 // Prepare output buffer.
305 uLongf dest_len = nd.header.size_uncompressed;
306 tmp.bytes().resize(dest_len);
307 //
308 // Uncompressing.
309 //
310 TEC_TRACE("Uncompressing {} bytes...", nd.size());
311 auto result = ::uncompress(
312 (Bytef*)tmp.data(), &dest_len,
313 (const Bytef*)nd.data(), nd.size());
314 if (result != Z_OK) {
315 return {EILSEQ, Error::Kind::RuntimeErr};
316 }
317 //
318 // Update input NetData inplace.
319 //
320 tmp.header.size = dest_len;
321 tmp.header.size_uncompressed = 0;
322 nd.move_from(std::move(tmp));
323 TEC_TRACE("Upcompressed to {} bytes.", nd.size());
324 return {};
325 }
326
327#endif // defined(ZLIB_VERSION)
328};
329
330} // namespace tec
const char * ptr(long pos) const
Returns a const pointer to a specific position in the buffer.
Definition tec_memfile.hpp:273
Compression wrapper for NetData objects with pluggable backends.
Definition tec_nd_compress.hpp:89
NdCompress(int _type, int _level=CompressionParams::kDefaultCompressionLevel, size_t _min_size=CompressionParams::kMinSize)
Constructs compressor with explicit settings.
Definition tec_nd_compress.hpp:128
virtual Status compress(NetData &nd) const
Compresses the payload of a NetData object in-place (if configured)
Definition tec_nd_compress.hpp:161
virtual Status uncompress(NetData &nd) const
Decompresses the payload of a NetData object in-place (if compressed)
Definition tec_nd_compress.hpp:202
NdCompress()
Default constructor — uses library-wide default compression settings.
Definition tec_nd_compress.hpp:108
size_t min_size_
Minimum payload size (in bytes) below which compression is skipped.
Definition tec_nd_compress.hpp:93
int level_
Compression level (meaning depends on backend — usually [1..9] for Zlib)
Definition tec_nd_compress.hpp:92
int type_
Compression algorithm identifier (from CompressionParams)
Definition tec_nd_compress.hpp:91
Lightweight binary serialization container optimized for network communication.
Definition tec_net_data.hpp:51
size_t size() const
Returns current logical size of the message (according to header)
Definition tec_net_data.hpp:127
void rewind()
Resets read position to the beginning of the buffer.
Definition tec_net_data.hpp:119
void move_from(NetData &&src, size_t size_to_shrink=0)
Efficiently moves content from another NetData instance.
Definition tec_net_data.hpp:111
Header header
Global message header.
Definition tec_net_data.hpp:54
const Bytes & bytes() const
Returns const reference to internal byte buffer.
Definition tec_net_data.hpp:85
#define TEC_ENTER(name)
Logs an entry message for a named context (e.g., function).
Definition tec_trace.hpp:211
#define TEC_TRACE(...)
Logs a formatted trace message.
Definition tec_trace.hpp:222
Definition tec_compression.hpp:34
@ RuntimeErr
Runtime error during execution.
@ Unsupported
The feature is unsupported.
uint32_t size_uncompressed
Original uncompressed payload size (for verification).
Definition tec_nd_types.hpp:147
constexpr void set_compression(int comp_type)
Set compression algorithm type.
Definition tec_nd_types.hpp:184
constexpr int get_compression() const
Extract compression algorithm type.
Definition tec_nd_types.hpp:176
uint32_t size
Total size of the serialized payload excluding this header (bytes).
Definition tec_nd_types.hpp:142
Compression parameters.
Common definitions and utilities for the tec namespace.
Lightweight binary serialization optimized for network communication.
Defines error handling types and utilities for the tec namespace.
TStatus< int, std::string > Status
Type alias for a default TStatus with int code and std::string description.
Definition tec_status.hpp:223
Provides a thread-safe tracing utility for debugging in the tec namespace.