Nyx Node
Loading...
Searching...
No Matches
zlib.c
1/* NyxNode
2 * Author: Jérôme ODIER <jerome.odier@lpsc.in2p3.fr>
3 * SPDX-License-Identifier: GPL-2.0-only (Mongoose backend) or GPL-3.0+
4 */
5
6/*--------------------------------------------------------------------------------------------------------------------*/
7
8#ifdef HAVE_ZLIB
9# include <zlib.h>
10#else
11# include <string.h>
12#endif
13
14#include "../nyx_node_internal.h"
15
16/*--------------------------------------------------------------------------------------------------------------------*/
17#ifdef HAVE_ZLIB
18/*--------------------------------------------------------------------------------------------------------------------*/
19
20buff_t nyx_zlib_deflate(size_t *result_size, size_t size, BUFF_t buff)
21{
22 if(size == 0x00 || buff == NULL)
23 {
24 if(result_size != NULL)
25 {
26 *result_size = 0x00;
27 }
28
29 return NULL;
30 }
31
32 /*----------------------------------------------------------------------------------------------------------------*/
33
34 uLongf comp_size = compressBound(size);
35
36 Bytef *comp_buff = nyx_memory_alloc(comp_size);
37
38 /*----------------------------------------------------------------------------------------------------------------*/
39
40 int ret = compress2(comp_buff, &comp_size, buff, size, Z_BEST_COMPRESSION);
41
42 if(ret != Z_OK)
43 {
44 nyx_memory_free(comp_buff);
45
46 if(result_size != NULL)
47 {
48 *result_size = 0x00;
49 }
50
51 return NULL;
52 }
53
54 /*----------------------------------------------------------------------------------------------------------------*/
55
56 if(result_size != NULL)
57 {
58 *result_size = comp_size;
59 }
60
61 return comp_buff;
62
63 /*----------------------------------------------------------------------------------------------------------------*/
64}
65
66/*--------------------------------------------------------------------------------------------------------------------*/
67
68buff_t nyx_zlib_inflate(__NYX_NOTNULL__ size_t *result_size, size_t size, BUFF_t buff)
69{
70 if(result_size == NULL)
71 {
72 NYX_LOG_ERROR("Initial size not provided in `result_size`");
73
74 return NULL;
75 }
76
77 if(size == 0x00 || buff == NULL)
78 {
79 //(result_size != NULL)
80 {
81 *result_size = 0x00;
82 }
83
84 return NULL;
85 }
86
87 /*----------------------------------------------------------------------------------------------------------------*/
88
89 uLongf uncomp_size = *result_size;
90
91 Bytef *uncomp_buff = nyx_memory_alloc(*result_size);
92
93 /*----------------------------------------------------------------------------------------------------------------*/
94
95 int ret = uncompress(uncomp_buff, &uncomp_size, buff, size);
96
97 if(ret != Z_OK)
98 {
99 nyx_memory_free(uncomp_buff);
100
101 //(result_size != NULL)
102 {
103 *result_size = 0x00;
104 }
105
106 return NULL;
107 }
108
109 /*----------------------------------------------------------------------------------------------------------------*/
110
111 //(result_size != NULL)
112 {
113 *result_size = uncomp_size;
114 }
115
116 return uncomp_buff;
117
118 /*----------------------------------------------------------------------------------------------------------------*/
119}
120
121/*--------------------------------------------------------------------------------------------------------------------*/
122#else
123/*--------------------------------------------------------------------------------------------------------------------*/
124
125static const uint32_t ADLER_MOD = 65521u;
126
127static const uint32_t ADLER_N_MAX = 5552u;
128
129/*--------------------------------------------------------------------------------------------------------------------*/
130
131uint32_t internal_adler32(size_t src_size, BUFF_t src_buff)
132{
133 /*----------------------------------------------------------------------------------------------------------------*/
134
135 const uint8_t *p = (const uint8_t *) src_buff;
136
137 /*----------------------------------------------------------------------------------------------------------------*/
138
139 uint32_t a = 1u;
140 uint32_t b = 0u;
141
142 while(src_size > 0)
143 {
144 size_t t = ADLER_N_MAX < src_size ? ADLER_N_MAX : src_size;
145
146 src_size -= t;
147
148 for(; t >= 4; t -= 4)
149 {
150 a += *p++; b += a;
151 a += *p++; b += a;
152 a += *p++; b += a;
153 a += *p++; b += a;
154 }
155
156 for(; t > 0; t -= 1)
157 {
158 a += *p++; b += a;
159 }
160
161 a %= ADLER_MOD;
162 b %= ADLER_MOD;
163 }
164
165 /*----------------------------------------------------------------------------------------------------------------*/
166
167 return (b << 16) | (a << 0);
168}
169
170/*--------------------------------------------------------------------------------------------------------------------*/
171
172buff_t nyx_zlib_deflate(size_t *result_size, size_t size, BUFF_t buff)
173{
174 if(size == 0x00 || buff == NULL)
175 {
176 if(result_size != NULL)
177 {
178 *result_size = 0x00;
179 }
180
181 return NULL;
182 }
183
184 /*----------------------------------------------------------------------------------------------------------------*/
185
186 size_t n_blocks = size > 0 ? (size + 65534u) / 65535u : 1;
187
188 size_t dst_size = 2 + n_blocks * 5 + size + 4;
189
190 /*----------------------------------------------------------------------------------------------------------------*/
191
192 const uint8_t *src = (const uint8_t *) /*------------*/( buff );
193 /*-*/ uint8_t *dst = (/*-*/ uint8_t *) nyx_memory_alloc(dst_size);
194
195 uint8_t *result_buff = dst;
196
197 /*----------------------------------------------------------------------------------------------------------------*/
198
199 *dst++ = 0x78;
200 *dst++ = 0x01;
201
202 /*----------------------------------------------------------------------------------------------------------------*/
203
204 size_t rem = size;
205
206 do {
207 size_t chunk = 65535u < rem ? 65535u : rem;
208
209 /* LAST */
210
211 *dst++ = (uint8_t) (chunk == rem);
212
213 /* LENGTH */
214
215 *dst++ = (uint8_t) (chunk & 0xFF);
216 *dst++ = (uint8_t) (chunk >> 8);
217 *dst++ = (uint8_t) ((~chunk) & 0xFF);
218 *dst++ = (uint8_t) ((~chunk) >> 8);
219
220 /* PAYLOAD */
221
222 if(chunk > 0)
223 {
224 memcpy(dst, src, chunk);
225
226 dst += chunk;
227 src += chunk;
228 rem -= chunk;
229 }
230
231 } while(rem > 0);
232
233 /*----------------------------------------------------------------------------------------------------------------*/
234
235 uint32_t hash = internal_adler32(size, buff);
236
237 *dst++ = (uint8_t) (hash >> 24);
238 *dst++ = (uint8_t) (hash >> 16);
239 *dst++ = (uint8_t) (hash >> 8);
240 *dst++ = (uint8_t) (hash >> 0);
241
242 /*----------------------------------------------------------------------------------------------------------------*/
243
244 if(result_size != NULL)
245 {
246 *result_size = (size_t) (dst - result_buff);
247 }
248
249 return (buff_t) result_buff;
250}
251
252/*--------------------------------------------------------------------------------------------------------------------*/
253
254buff_t nyx_zlib_inflate(__NYX_NOTNULL__ size_t *result_size, __NYX_UNUSED__ size_t size, __NYX_UNUSED__ BUFF_t buff)
255{
256 NYX_LOG_ERROR("ZLib uncompression not supported");
257
258 if(result_size != NULL)
259 {
260 *result_size = 0x00;
261 }
262
263 return NULL;
264}
265
266/*--------------------------------------------------------------------------------------------------------------------*/
267#endif
268/*--------------------------------------------------------------------------------------------------------------------*/
269
270str_t nyx_zlib_base64_deflate(size_t *result_len, size_t size, BUFF_t buff)
271{
272 /*----------------------------------------------------------------------------------------------------------------*/
273
274 size_t comp_size;
275 buff_t comp_buff = nyx_zlib_deflate(&comp_size, size, buff);
276
277 if(comp_size > 0x00 && comp_buff != NULL)
278 {
279 str_t result_str = nyx_base64_encode(result_len, comp_size, comp_buff);
280
281 nyx_memory_free(comp_buff);
282
283 return result_str;
284 }
285
286 /*----------------------------------------------------------------------------------------------------------------*/
287
288 if(result_len != NULL)
289 {
290 *result_len = 0x00;
291 }
292
293 return NULL;
294}
295
296/*--------------------------------------------------------------------------------------------------------------------*/
297
298buff_t nyx_zlib_base64_inflate(__NYX_NOTNULL__ size_t *result_size, size_t len, STR_t str)
299{
300 /*----------------------------------------------------------------------------------------------------------------*/
301
302 size_t comp_size;
303 buff_t comp_buff = nyx_base64_decode(&comp_size, len, str);
304
305 if(comp_size > 0x00 && comp_buff != NULL)
306 {
307 buff_t result_buff = nyx_zlib_inflate(result_size, comp_size, comp_buff);
308
309 nyx_memory_free(comp_buff);
310
311 return result_buff;
312 }
313
314 /*----------------------------------------------------------------------------------------------------------------*/
315
316 if(result_size != NULL)
317 {
318 *result_size = 0x00;
319 }
320
321 return NULL;
322}
323
324/*--------------------------------------------------------------------------------------------------------------------*/
#define NYX_LOG_ERROR(fmt,...)
Logs an error message.
Definition nyx_node.h:219
#define STR_t
Alias for const char *.
Definition nyx_node.h:71
__NYX_NULLABLE__ buff_t nyx_memory_alloc(__NYX_ZEROABLE__ size_t size)
Similar to libc malloc except that a memory overflow causes the node to stop.
__NYX_ZEROABLE__ size_t nyx_memory_free(__NYX_NULLABLE__ buff_t buff)
Similar to libc free except that it returns the amount of memory freed.
#define buff_t
Alias for void *.
Definition nyx_node.h:67
#define BUFF_t
Alias for const void *.
Definition nyx_node.h:68
#define str_t
Alias for char *.
Definition nyx_node.h:70
__NYX_NULLABLE__ buff_t nyx_zlib_inflate(__NYX_NOTNULL__ size_t *result_size, __NYX_ZEROABLE__ size_t size, __NYX_NULLABLE__ BUFF_t buff)
Decompresses a buffer using the ZLib algorithm.
__NYX_NULLABLE__ buff_t nyx_zlib_base64_inflate(__NYX_NOTNULL__ size_t *result_size, __NYX_ZEROABLE__ size_t len, __NYX_NULLABLE__ STR_t str)
Decompresses a string using the ZLib+Base64 algorithm.
__NYX_NULLABLE__ buff_t nyx_zlib_deflate(__NYX_NULLABLE__ size_t *result_size, __NYX_ZEROABLE__ size_t size, __NYX_NULLABLE__ BUFF_t buff)
Compresses a buffer using the ZLib algorithm.
__NYX_NULLABLE__ str_t nyx_base64_encode(__NYX_NULLABLE__ size_t *result_len, __NYX_ZEROABLE__ size_t size, __NYX_NULLABLE__ BUFF_t buff)
Encodes a buffer using the Base64 algorithm.
__NYX_NULLABLE__ str_t nyx_zlib_base64_deflate(__NYX_NULLABLE__ size_t *result_len, __NYX_ZEROABLE__ size_t size, __NYX_NULLABLE__ BUFF_t buff)
Compresses a buffer using the ZLib+Base64 algorithm.
__NYX_NULLABLE__ buff_t nyx_base64_decode(__NYX_NULLABLE__ size_t *result_size, __NYX_ZEROABLE__ size_t len, __NYX_NULLABLE__ STR_t str)
Decodes a string using the Base64 algorithm.