LogIt++
Header-only, macro-first C++ logging library
Loading...
Searching...
No Matches
CompressionUtils.hpp
Go to the documentation of this file.
1#pragma once
2#ifndef LOGIT_CPP_HEADER_LOGIT_CPP_LOGIT_DETAIL_COMPRESSIONUTILS_HPP_INCLUDED
3#define LOGIT_CPP_HEADER_LOGIT_CPP_LOGIT_DETAIL_COMPRESSIONUTILS_HPP_INCLUDED
4
7
8#include <cstddef>
9#include <string>
10
11#if defined(LOGIT_HAS_ZLIB)
12# include <zlib.h>
13#endif
14
15#if defined(LOGIT_HAS_ZSTD)
16# include <zstd.h>
17#endif
18
19namespace logit {
20namespace detail {
21
28inline bool compress_string_gzip(const std::string& input, std::string& output, int level) {
29#if defined(LOGIT_HAS_ZLIB)
30 z_stream zs;
31 zs.zalloc = Z_NULL;
32 zs.zfree = Z_NULL;
33 zs.opaque = Z_NULL;
34 zs.next_in = reinterpret_cast<Bytef*>(const_cast<char*>(input.data()));
35 zs.avail_in = static_cast<uInt>(input.size());
36 zs.next_out = Z_NULL;
37 zs.avail_out = 0;
38
39 if (level < 1) level = 1;
40 if (level > 9) level = 9;
41
42 int window_bits = 15 + 16;
43 if (deflateInit2(&zs, level, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
44 return false;
45 }
46
47 output.clear();
48
49 int ret = Z_OK;
50 std::size_t offset = 0;
51 const std::size_t buf_size = 32768;
52
53 do {
54 output.resize(offset + buf_size);
55 zs.next_out = reinterpret_cast<Bytef*>(&output[offset]);
56 zs.avail_out = static_cast<uInt>(buf_size);
57
58 ret = deflate(&zs, Z_FINISH);
59 if (ret == Z_STREAM_ERROR) {
60 deflateEnd(&zs);
61 return false;
62 }
63
64 offset = zs.total_out;
65 } while (ret != Z_STREAM_END);
66
67 output.resize(zs.total_out);
68 deflateEnd(&zs);
69 return true;
70#else
71 (void)input; (void)output; (void)level;
72 return false;
73#endif
74}
75
80inline bool decompress_string_gzip(const std::string& input, std::string& output) {
81#if defined(LOGIT_HAS_ZLIB)
82 z_stream zs;
83 zs.zalloc = Z_NULL;
84 zs.zfree = Z_NULL;
85 zs.opaque = Z_NULL;
86 zs.next_in = reinterpret_cast<Bytef*>(const_cast<char*>(input.data()));
87 zs.avail_in = static_cast<uInt>(input.size());
88 zs.next_out = Z_NULL;
89 zs.avail_out = 0;
90
91 int window_bits = 15 + 32; // automatic header detection (gzip/zlib)
92 if (inflateInit2(&zs, window_bits) != Z_OK) {
93 return false;
94 }
95
96 output.clear();
97
98 int ret = Z_OK;
99 std::size_t offset = 0;
100 const std::size_t buf_size = 32768;
101
102 do {
103 output.resize(offset + buf_size);
104 zs.next_out = reinterpret_cast<Bytef*>(&output[offset]);
105 zs.avail_out = static_cast<uInt>(buf_size);
106
107 ret = inflate(&zs, Z_NO_FLUSH);
108 if (ret == Z_STREAM_ERROR || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR) {
109 inflateEnd(&zs);
110 return false;
111 }
112
113 offset = zs.total_out;
114 } while (ret != Z_STREAM_END);
115
116 output.resize(zs.total_out);
117 inflateEnd(&zs);
118 return true;
119#else
120 (void)input; (void)output;
121 return false;
122#endif
123}
124
131inline bool compress_string_zstd(const std::string& input, std::string& output, int level) {
132#if defined(LOGIT_HAS_ZSTD)
133 if (level < 1) level = 1;
134 if (level > 19) level = 19;
135
136 std::size_t bound = ZSTD_compressBound(input.size());
137 output.resize(bound);
138
139 std::size_t result = ZSTD_compress(
140 &output[0], output.size(),
141 input.data(), input.size(),
142 level);
143
144 if (ZSTD_isError(result)) {
145 output.clear();
146 return false;
147 }
148
149 output.resize(result);
150 return true;
151#else
152 (void)input; (void)output; (void)level;
153 return false;
154#endif
155}
156
161inline bool decompress_string_zstd(const std::string& input, std::string& output) {
162#if defined(LOGIT_HAS_ZSTD)
163 std::size_t const d_size = ZSTD_getFrameContentSize(input.data(), input.size());
164 if (d_size == ZSTD_CONTENTSIZE_ERROR || d_size == ZSTD_CONTENTSIZE_UNKNOWN) {
165 return false;
166 }
167
168 output.resize(d_size);
169 std::size_t const result = ZSTD_decompress(
170 &output[0], output.size(),
171 input.data(), input.size());
172
173 if (ZSTD_isError(result)) {
174 output.clear();
175 return false;
176 }
177
178 output.resize(result);
179 return true;
180#else
181 (void)input; (void)output;
182 return false;
183#endif
184}
185
186} // namespace detail
187} // namespace logit
188
189#endif // LOGIT_CPP_HEADER_LOGIT_CPP_LOGIT_DETAIL_COMPRESSIONUTILS_HPP_INCLUDED
bool decompress_string_zstd(const std::string &input, std::string &output)
Decompress zstd-compressed bytes.
bool compress_string_gzip(const std::string &input, std::string &output, int level)
Compress a string with gzip.
bool decompress_string_gzip(const std::string &input, std::string &output)
Decompress gzip-compressed bytes.
bool compress_string_zstd(const std::string &input, std::string &output, int level)
Compress a string with zstd.
The primary namespace for the LogIt++ library.