Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
n_zlib.c
Go to the documentation of this file.
1
8#include "nilorea/n_zlib.h"
9#include "nilorea/n_log.h"
10#include "limits.h"
11
12#ifndef __windows__
13#include <arpa/inet.h>
14#else
15#include <stdint.h>
16#include <winsock2.h>
17#endif
18
24size_t GetMaxCompressedLen(size_t nLenSrc) {
25 size_t n16kBlocks = (nLenSrc + 16383) / 16384; // round up any fraction of a block
26 return (nLenSrc + 6 + (n16kBlocks * 5));
27} /* GetMaxCompressedLen */
28
37size_t CompressData(unsigned char* abSrc, size_t nLenSrc, unsigned char* abDst, size_t nLenDst) {
38 __n_assert(abSrc, return 0);
39 __n_assert(abDst, return 0);
40
41 if (nLenSrc == 0) {
42 n_log(LOG_ERR, "nLenSrc == 0");
43 return 0;
44 }
45 if (nLenDst == 0) {
46 n_log(LOG_ERR, "nLenDst == 0");
47 return 0;
48 }
49 if (nLenSrc > UINT_MAX) {
50 n_log(LOG_ERR, "nLenSrc is bigger than UINT_MAX");
51 return 0;
52 }
53 if (nLenDst > UINT_MAX) {
54 n_log(LOG_ERR, "nLenDst is bigger than UINT_MAX");
55 return 0;
56 }
57
58 z_stream zInfo;
59 memset(&zInfo, 0, sizeof(zInfo));
60 zInfo.total_in = zInfo.avail_in = (unsigned int)nLenSrc;
61 zInfo.total_out = zInfo.avail_out = (unsigned int)nLenDst;
62 zInfo.next_in = (unsigned char*)abSrc;
63 zInfo.next_out = abDst;
64
65 int nErr = 0;
66 size_t nRet = 0;
67 nErr = deflateInit(&zInfo, Z_DEFAULT_COMPRESSION); // zlib function
68 switch (nErr) {
69 case Z_OK:
70 // all is fine
71 break;
72 default:
73 n_log(LOG_ERR, "%s on string %p size %d", zError(nErr), abSrc, nLenSrc);
74 return 0;
75 }
76 nErr = deflate(&zInfo, Z_FINISH); // zlib function
77 if (nErr == Z_STREAM_END) {
78 nRet = zInfo.total_out;
79 } else {
80 n_log(LOG_ERR, "%s on string %p size %d", zError(nErr), abSrc, nLenSrc);
81 }
82 deflateEnd(&zInfo); // zlib function
83 return nRet;
84} /* CompressData */
85
94size_t UncompressData(unsigned char* abSrc, size_t nLenSrc, unsigned char* abDst, size_t nLenDst) {
95 __n_assert(abSrc, return 0);
96 __n_assert(abDst, return 0);
97
98 if (nLenSrc == 0) {
99 n_log(LOG_ERR, "nLenSrc == 0");
100 return 0;
101 }
102 if (nLenDst == 0) {
103 n_log(LOG_ERR, "nLenDst == 0");
104 return 0;
105 }
106 if (nLenSrc > UINT_MAX) {
107 n_log(LOG_ERR, "nLenSrc is bigger than UINT_MAX");
108 return 0;
109 }
110 if (nLenDst > UINT_MAX) {
111 n_log(LOG_ERR, "nLenDst is bigger than UINT_MAX");
112 return 0;
113 }
114
115 z_stream zInfo;
116 memset(&zInfo, 0, sizeof(zInfo));
117 zInfo.total_in = zInfo.avail_in = (unsigned int)nLenSrc;
118 zInfo.total_out = zInfo.avail_out = (unsigned int)nLenDst;
119 zInfo.next_in = (unsigned char*)abSrc;
120 zInfo.next_out = abDst;
121
122 int nErr = 0;
123 size_t nRet = 0;
124 nErr = inflateInit(&zInfo); // zlib function
125 switch (nErr) {
126 case Z_OK:
127 // all is fine
128 break;
129 default:
130 n_log(LOG_ERR, "%s on string %p size %d", zError(nErr), abSrc, nLenSrc);
131 return 0;
132 }
133 nErr = inflate(&zInfo, Z_FINISH); // zlib function
134 if (nErr == Z_STREAM_END) {
135 nRet = zInfo.total_out;
136 } else {
137 n_log(LOG_ERR, "%s on string %p size %d", zError(nErr), abSrc, nLenSrc);
138 }
139 inflateEnd(&zInfo); // zlib function
140 return nRet; // -1 or len of output
141} /* UncompressData */
142
149 __n_assert(src, return NULL);
150 __n_assert(src->data, return NULL);
151
152 if (src->length == 0) {
153 n_log(LOG_ERR, "length of src == 0");
154 return NULL;
155 }
156 if (src->written == 0) {
157 n_log(LOG_ERR, "written of src == 0");
158 return NULL;
159 }
160 if (src->length > UINT_MAX) {
161 n_log(LOG_ERR, "length of src > UINT_MAX");
162 return NULL;
163 }
164 if (src->written > UINT_MAX) {
165 n_log(LOG_ERR, "written of src > UINT_MAX");
166 return NULL;
167 }
168
169 /* storage for original string size + zipped string + padding */
170 size_t zip_max_size = GetMaxCompressedLen(src->length);
171
172 N_STR* zipped = new_nstr(4 + zip_max_size);
173
174 __n_assert(zipped, return NULL);
175 __n_assert(zipped->data, return NULL);
176
177 /* copying size */
178 uint32_t src_length = htonl((uint32_t)src->length);
179 memcpy(zipped->data, &src_length, sizeof(uint32_t));
180 char* dataptr = zipped->data + 4;
181
182 size_t compressed_size = CompressData((unsigned char*)src->data, src->written, (unsigned char*)dataptr, zip_max_size);
183 if (compressed_size == 0) {
184 free_nstr(&zipped);
185 n_log(LOG_ERR, "unable to zip string %p %d/%d bytes", src->data, src->written, src->length);
186 return NULL;
187 }
188 zipped->written = 4 + compressed_size;
189 n_log(LOG_DEBUG, "zip :%d original: %d", zipped->written, src->length);
190
191 return zipped;
192} /* zip_nstr */
193
200 __n_assert(src, return NULL);
201 __n_assert(src->data, return NULL);
202
203 if (src->length == 0) {
204 n_log(LOG_ERR, "length of src == 0");
205 return NULL;
206 }
207 if (src->written == 0) {
208 n_log(LOG_ERR, "written of src == 0");
209 return NULL;
210 }
211
212 uint32_t original_size = 0;
213 memcpy(&original_size, src->data, sizeof(uint32_t));
214 original_size = ntohl(original_size);
215 if (original_size == 0) {
216 n_log(LOG_ERR, "original_size == 0");
217 return NULL;
218 }
219 /* storage for original string size + zipped string + padding */
220 N_STR* unzipped = new_nstr(original_size);
221 __n_assert(unzipped, return NULL);
222 __n_assert(unzipped->data, return NULL);
223
224 /* copying size */
225 unzipped->written = UncompressData(((unsigned char*)src->data) + 4, src->written, (unsigned char*)unzipped->data, original_size);
226 if (unzipped->written == 0) {
227 n_log(LOG_ERR, "unable to unzip string %p %d/%d bytes", unzipped->data, unzipped->written, unzipped->length);
228 free_nstr(&unzipped);
229 return NULL;
230 }
231 n_log(LOG_DEBUG, "Size: zip: %d => unzip :%d original:%d", src->written, unzipped->written, original_size);
232
233 return unzipped;
234} /* unzip_nstr */
#define __n_assert(__ptr, __ret)
macro to assert things
Definition n_common.h:258
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition n_log.h:69
#define LOG_DEBUG
debug-level messages
Definition n_log.h:64
#define LOG_ERR
error conditions
Definition n_log.h:56
size_t written
size of the written data inside the string
Definition n_str.h:45
char * data
the string
Definition n_str.h:41
size_t length
length of string (in case we wanna keep information after the 0 end of string value)
Definition n_str.h:43
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
Definition n_str.h:176
N_STR * new_nstr(NSTRBYTE size)
create a new N_STR string
Definition n_str.c:180
A box including a string and his lenght.
Definition n_str.h:39
size_t GetMaxCompressedLen(size_t nLenSrc)
Return the maximum compressed size.
Definition n_zlib.c:24
size_t UncompressData(unsigned char *abSrc, size_t nLenSrc, unsigned char *abDst, size_t nLenDst)
Uncompress a string to another.
Definition n_zlib.c:94
N_STR * unzip_nstr(N_STR *src)
return an uncompressed version of src
Definition n_zlib.c:199
N_STR * zip_nstr(N_STR *src)
return a compressed version of src
Definition n_zlib.c:148
Generic log system.
ZLIB compression handler.