Nilorea Library
C utilities for networking, threading, graphics
n_zlib.c
Go to the documentation of this file.
1
9#include "nilorea/n_zlib.h"
10#include "nilorea/n_log.h"
11#include "limits.h"
12
13#ifndef __windows__
14#include <arpa/inet.h>
15#else
16#include <stdint.h>
17#include <winsock2.h>
18#endif
19
20
26int GetMaxCompressedLen( unsigned int nLenSrc )
27{
28 unsigned int n16kBlocks = (nLenSrc+16383) / 16384; // round up any fraction of a block
29 return ( nLenSrc + 6 + (n16kBlocks*5) );
30} /* GetMaxCompressedLen */
31
32
33
42int CompressData( unsigned char *abSrc, unsigned int nLenSrc, unsigned char *abDst, unsigned int nLenDst )
43{
44 __n_assert( abSrc, return -1 );
45 __n_assert( abDst, return -1 );
46
47 if( nLenSrc == 0 )
48 {
49 n_log( LOG_ERR, "nLenSrc (%d) <= 0", nLenSrc );
50 return -1 ;
51 }
52 if( nLenDst == 0 )
53 {
54 n_log( LOG_ERR, "nLenDst (%d) <= 0", nLenDst );
55 return -1 ;
56 }
57
58 z_stream zInfo ;
59 memset( &zInfo, 0, sizeof( zInfo ) );
60 zInfo.total_in= zInfo.avail_in = nLenSrc;
61 zInfo.total_out= zInfo.avail_out= nLenDst;
62 zInfo.next_in= (unsigned char *)abSrc;
63 zInfo.next_out= abDst;
64
65 int nErr, nRet= -1;
66 nErr= deflateInit( &zInfo, Z_DEFAULT_COMPRESSION ); // zlib function
67 switch( nErr )
68 {
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 -1 ;
75 }
76 nErr= deflate( &zInfo, Z_FINISH ); // zlib function
77 if ( nErr == Z_STREAM_END )
78 {
79 nRet= zInfo.total_out;
80 }
81 else
82 {
83 n_log( LOG_ERR, "%s on string %p size %d", zError( nErr ), abSrc, nLenSrc );
84 }
85 deflateEnd( &zInfo ); // zlib function
86 return( nRet );
87} /* CompressData */
88
89
90
99int UncompressData( unsigned char *abSrc, unsigned int nLenSrc, unsigned char *abDst, unsigned int nLenDst )
100{
101 __n_assert( abSrc, return -1 );
102 __n_assert( abDst, return -1 );
103
104 if( nLenSrc == 0 )
105 {
106 n_log( LOG_ERR, "nLenSrc (%d) <= 0", nLenSrc );
107 return 0 ;
108 }
109 if( nLenDst == 0 )
110 {
111 n_log( LOG_ERR, "nLenDst (%d) <= 0", nLenDst );
112 return 0 ;
113 }
114
115 z_stream zInfo ;
116 memset( &zInfo, 0, sizeof( zInfo ) );
117 zInfo.total_in= zInfo.avail_in= nLenSrc;
118 zInfo.total_out= zInfo.avail_out= nLenDst;
119 zInfo.next_in= (unsigned char *)abSrc;
120 zInfo.next_out= abDst;
121
122 int nErr, nRet= 0 ;
123 nErr= inflateInit( &zInfo ); // zlib function
124 switch( nErr )
125 {
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 {
136 nRet= zInfo.total_out;
137 }
138 else
139 {
140 n_log( LOG_ERR, "%s on string %p size %d", zError( nErr ), abSrc, nLenSrc );
141 }
142 inflateEnd( &zInfo ); // zlib function
143 return( nRet ); // -1 or len of output
144} /* UncompressData */
145
146
147
154{
155 __n_assert( src, return NULL );
156 __n_assert( src -> data, return NULL );
157
158 if( src -> length <= 0 )
159 {
160 n_log( LOG_ERR, "length of src (%d) <= 0", src -> length );
161 return NULL ;
162 }
163 if( src -> written <= 0 )
164 {
165 n_log( LOG_ERR, "written of src (%d) <= 0", src -> written );
166 return NULL ;
167 }
168
169 /* storage for original string size + zipped string + padding */
170 unsigned int 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 int32_t src_length = htonl( src -> length );
179 memcpy( zipped -> data, &src_length, sizeof( int32_t ) );
180 char *dataptr = zipped -> data + 4 ;
181
182 int compressed_size = 0 ;
183 compressed_size = CompressData( (unsigned char *)src -> data, src -> written, (unsigned char *)dataptr, zip_max_size );
184 if( compressed_size == -1 )
185 {
186 free_nstr( &zipped );
187 n_log( LOG_ERR, "unable to zip string %p %d/%d bytes", src -> data, src -> written, src -> length );
188 return NULL ;
189 }
190 zipped -> written = 4 + compressed_size ;
191 n_log( LOG_DEBUG, "zip :%d original: %d", zipped -> written, src -> length );
192
193 return zipped ;
194} /* zip_nstr */
195
196
197
204{
205 __n_assert( src, return NULL );
206 __n_assert( src -> data, return NULL );
207
208 if( src -> length <= 0 )
209 {
210 n_log( LOG_ERR, "length of src (%d) <= 0", src -> length );
211 return NULL ;
212 }
213 if( src -> written <= 0 )
214 {
215 n_log( LOG_ERR, "written of src (%d) <= 0", src -> written );
216 return NULL ;
217 }
218
219 int32_t original_size = 0 ;
220 memcpy( &original_size, src -> data, sizeof( int32_t ) );
221 original_size = ntohl( original_size );
222 if( original_size <= 0 )
223 {
224 n_log( LOG_ERR, "original size (%d) <= 0", original_size );
225 return NULL ;
226 }
227 /* storage for original string size + zipped string + padding */
228 N_STR *unzipped = new_nstr( original_size );
229 __n_assert( unzipped, return NULL );
230 __n_assert( unzipped -> data, return NULL );
231
232 /* copying size */
233 unzipped -> written = UncompressData( ((unsigned char *)src -> data) + 4, src -> written, (unsigned char *)unzipped -> data, original_size );
234 if( unzipped -> written == 0 )
235 {
236 n_log( LOG_ERR, "unable to unzip string %p %d/%d bytes", unzipped -> data, unzipped -> written, unzipped -> length );
237 free_nstr( &unzipped );
238 return NULL ;
239 }
240 n_log( LOG_DEBUG, "Size: zip: %d => unzip :%d original:%d", src -> written, unzipped -> written, original_size );
241
242 return unzipped ;
243} /* unzip_nstr */
#define __n_assert(__ptr, __ret)
macro to assert things
Definition: n_common.h:276
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition: n_log.h:74
#define LOG_DEBUG
debug-level messages
Definition: n_log.h:66
#define LOG_ERR
error conditions
Definition: n_log.h:58
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
Definition: n_str.h:222
N_STR * new_nstr(NSTRBYTE size)
create a new N_STR string
Definition: n_str.c:215
A box including a string and his lenght.
Definition: n_str.h:173
int GetMaxCompressedLen(unsigned int nLenSrc)
Return the maximum compressed size.
Definition: n_zlib.c:26
int CompressData(unsigned char *abSrc, unsigned int nLenSrc, unsigned char *abDst, unsigned int nLenDst)
Compress a string to another.
Definition: n_zlib.c:42
int UncompressData(unsigned char *abSrc, unsigned int nLenSrc, unsigned char *abDst, unsigned int nLenDst)
Uncompress a string to another.
Definition: n_zlib.c:99
N_STR * unzip_nstr(N_STR *src)
return an uncompressed version of src
Definition: n_zlib.c:203
N_STR * zip_nstr(N_STR *src)
return a compressed version of src
Definition: n_zlib.c:153
Generic log system.
ZLIB compression handler.