This source file includes following definitions.
- zip_source_deflate
- compress_read
- decompress_read
- deflate_compress
- deflate_decompress
- deflate_free
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 #include <stdlib.h>
35 #include <string.h>
36 #include <limits.h>
37
38 #include "zipint.h"
39
40 struct deflate {
41 zip_error_t error;
42
43 bool eof;
44 bool can_store;
45 bool is_stored;
46 int mem_level;
47 zip_uint64_t size;
48 zip_uint8_t buffer[BUFSIZE];
49 z_stream zstr;
50 };
51
52 static zip_int64_t compress_read(zip_source_t *, struct deflate *, void *, zip_uint64_t);
53 static zip_int64_t decompress_read(zip_source_t *, struct deflate *, void *, zip_uint64_t);
54 static zip_int64_t deflate_compress(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
55 static zip_int64_t deflate_decompress(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
56 static void deflate_free(struct deflate *);
57
58
59 zip_source_t *
60 zip_source_deflate(zip_t *za, zip_source_t *src, zip_int32_t cm, int flags)
61 {
62 struct deflate *ctx;
63 zip_source_t *s2;
64
65 if (src == NULL || (cm != ZIP_CM_DEFLATE && !ZIP_CM_IS_DEFAULT(cm))) {
66 zip_error_set(&za->error, ZIP_ER_INVAL, 0);
67 return NULL;
68 }
69
70 if ((ctx=(struct deflate *)malloc(sizeof(*ctx))) == NULL) {
71 zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
72 return NULL;
73 }
74
75 zip_error_init(&ctx->error);
76 ctx->eof = false;
77 ctx->is_stored = false;
78 ctx->can_store = ZIP_CM_IS_DEFAULT(cm);
79 if (flags & ZIP_CODEC_ENCODE) {
80 ctx->mem_level = MAX_MEM_LEVEL;
81 }
82
83 if ((s2=zip_source_layered(za, src,
84 ((flags & ZIP_CODEC_ENCODE)
85 ? deflate_compress : deflate_decompress),
86 ctx)) == NULL) {
87 deflate_free(ctx);
88 return NULL;
89 }
90
91 return s2;
92 }
93
94
95 static zip_int64_t
96 compress_read(zip_source_t *src, struct deflate *ctx, void *data, zip_uint64_t len)
97 {
98 int end, ret;
99 zip_int64_t n;
100 zip_uint64_t out_offset;
101 uInt out_len;
102
103 if (zip_error_code_zip(&ctx->error) != ZIP_ER_OK)
104 return -1;
105
106 if (len == 0 || ctx->is_stored) {
107 return 0;
108 }
109
110 out_offset = 0;
111 out_len = (uInt)ZIP_MIN(UINT_MAX, len);
112 ctx->zstr.next_out = (Bytef *)data;
113 ctx->zstr.avail_out = out_len;
114
115 end = 0;
116 while (!end) {
117 ret = deflate(&ctx->zstr, ctx->eof ? Z_FINISH : 0);
118
119 switch (ret) {
120 case Z_STREAM_END:
121 if (ctx->can_store && ctx->zstr.total_in <= ctx->zstr.total_out) {
122 ctx->is_stored = true;
123 ctx->size = ctx->zstr.total_in;
124 memcpy(data, ctx->buffer, ctx->size);
125 return (zip_int64_t)ctx->size;
126 }
127
128 case Z_OK:
129
130
131 if (ctx->zstr.avail_out == 0) {
132 out_offset += out_len;
133 if (out_offset < len) {
134 out_len = (uInt)ZIP_MIN(UINT_MAX, len-out_offset);
135 ctx->zstr.next_out = (Bytef *)data+out_offset;
136 ctx->zstr.avail_out = out_len;
137 }
138 else {
139 ctx->can_store = false;
140 end = 1;
141 }
142 }
143 else if (ctx->eof && ctx->zstr.avail_in == 0)
144 end = 1;
145 break;
146
147 case Z_BUF_ERROR:
148 if (ctx->zstr.avail_in == 0) {
149 if (ctx->eof) {
150 end = 1;
151 break;
152 }
153
154 if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
155 _zip_error_set_from_source(&ctx->error, src);
156 end = 1;
157 break;
158 }
159 else if (n == 0) {
160 ctx->eof = true;
161
162 ctx->size = ctx->zstr.total_in;
163 }
164 else {
165 if (ctx->zstr.total_in > 0) {
166
167 ctx->can_store = false;
168 }
169 ctx->zstr.next_in = (Bytef *)ctx->buffer;
170 ctx->zstr.avail_in = (uInt)n;
171 }
172 continue;
173 }
174
175 case Z_NEED_DICT:
176 case Z_DATA_ERROR:
177 case Z_STREAM_ERROR:
178 case Z_MEM_ERROR:
179 zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
180
181 end = 1;
182 break;
183 }
184 }
185
186 if (ctx->zstr.avail_out < len) {
187 ctx->can_store = false;
188 return (zip_int64_t)(len - ctx->zstr.avail_out);
189 }
190
191 return (zip_error_code_zip(&ctx->error) == ZIP_ER_OK) ? 0 : -1;
192 }
193
194
195 static zip_int64_t
196 decompress_read(zip_source_t *src, struct deflate *ctx, void *data, zip_uint64_t len)
197 {
198 int end, ret;
199 zip_int64_t n;
200 zip_uint64_t out_offset;
201 uInt out_len;
202
203 if (zip_error_code_zip(&ctx->error) != ZIP_ER_OK)
204 return -1;
205
206 if (len == 0)
207 return 0;
208
209 out_offset = 0;
210 out_len = (uInt)ZIP_MIN(UINT_MAX, len);
211 ctx->zstr.next_out = (Bytef *)data;
212 ctx->zstr.avail_out = out_len;
213
214 end = 0;
215 while (!end) {
216 ret = inflate(&ctx->zstr, Z_SYNC_FLUSH);
217
218 switch (ret) {
219 case Z_OK:
220 if (ctx->zstr.avail_out == 0) {
221 out_offset += out_len;
222 if (out_offset < len) {
223 out_len = (uInt)ZIP_MIN(UINT_MAX, len-out_offset);
224 ctx->zstr.next_out = (Bytef *)data+out_offset;
225 ctx->zstr.avail_out = out_len;
226 }
227 else {
228 end = 1;
229 }
230 }
231 break;
232
233 case Z_STREAM_END:
234 ctx->eof = 1;
235 end = 1;
236 break;
237
238 case Z_BUF_ERROR:
239 if (ctx->zstr.avail_in == 0) {
240 if (ctx->eof) {
241 end = 1;
242 break;
243 }
244
245 if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
246 _zip_error_set_from_source(&ctx->error, src);
247 end = 1;
248 break;
249 }
250 else if (n == 0) {
251 ctx->eof = 1;
252 }
253 else {
254 ctx->zstr.next_in = (Bytef *)ctx->buffer;
255 ctx->zstr.avail_in = (uInt)n;
256 }
257 continue;
258 }
259
260 case Z_NEED_DICT:
261 case Z_DATA_ERROR:
262 case Z_STREAM_ERROR:
263 case Z_MEM_ERROR:
264 zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
265 end = 1;
266 break;
267 }
268 }
269
270 if (ctx->zstr.avail_out < len)
271 return (zip_int64_t)(len - ctx->zstr.avail_out);
272
273 return (zip_error_code_zip(&ctx->error) == ZIP_ER_OK) ? 0 : -1;
274 }
275
276
277 static zip_int64_t
278 deflate_compress(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
279 {
280 struct deflate *ctx;
281 int ret;
282
283 ctx = (struct deflate *)ud;
284
285 switch (cmd) {
286 case ZIP_SOURCE_OPEN:
287 ctx->zstr.zalloc = Z_NULL;
288 ctx->zstr.zfree = Z_NULL;
289 ctx->zstr.opaque = NULL;
290 ctx->zstr.avail_in = 0;
291 ctx->zstr.next_in = NULL;
292 ctx->zstr.avail_out = 0;
293 ctx->zstr.next_out = NULL;
294
295
296 if ((ret=deflateInit2(&ctx->zstr, Z_BEST_COMPRESSION, Z_DEFLATED, -MAX_WBITS, ctx->mem_level, Z_DEFAULT_STRATEGY)) != Z_OK) {
297 zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
298 return -1;
299 }
300
301 return 0;
302
303 case ZIP_SOURCE_READ:
304 return compress_read(src, ctx, data, len);
305
306 case ZIP_SOURCE_CLOSE:
307 deflateEnd(&ctx->zstr);
308 return 0;
309
310 case ZIP_SOURCE_STAT:
311 {
312 zip_stat_t *st;
313
314 st = (zip_stat_t *)data;
315
316 st->comp_method = ctx->is_stored ? ZIP_CM_STORE : ZIP_CM_DEFLATE;
317 st->valid |= ZIP_STAT_COMP_METHOD;
318 if (ctx->eof) {
319 st->comp_size = ctx->size;
320 st->valid |= ZIP_STAT_COMP_SIZE;
321 }
322 else
323 st->valid &= ~ZIP_STAT_COMP_SIZE;
324 }
325 return 0;
326
327 case ZIP_SOURCE_ERROR:
328 return zip_error_to_data(&ctx->error, data, len);
329
330 case ZIP_SOURCE_FREE:
331 deflate_free(ctx);
332 return 0;
333
334 case ZIP_SOURCE_SUPPORTS:
335 return ZIP_SOURCE_SUPPORTS_READABLE;
336
337 default:
338 zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0);
339 return -1;
340 }
341 }
342
343
344 static zip_int64_t
345 deflate_decompress(zip_source_t *src, void *ud, void *data,
346 zip_uint64_t len, zip_source_cmd_t cmd)
347 {
348 struct deflate *ctx;
349 zip_int64_t n;
350 int ret;
351
352 ctx = (struct deflate *)ud;
353
354 switch (cmd) {
355 case ZIP_SOURCE_OPEN:
356 if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
357 _zip_error_set_from_source(&ctx->error, src);
358 return -1;
359 }
360
361 ctx->zstr.zalloc = Z_NULL;
362 ctx->zstr.zfree = Z_NULL;
363 ctx->zstr.opaque = NULL;
364 ctx->zstr.next_in = (Bytef *)ctx->buffer;
365 ctx->zstr.avail_in = (uInt)n;
366
367
368 if ((ret=inflateInit2(&ctx->zstr, -MAX_WBITS)) != Z_OK) {
369 zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
370 return -1;
371 }
372 return 0;
373
374 case ZIP_SOURCE_READ:
375 return decompress_read(src, ctx, data, len);
376
377 case ZIP_SOURCE_CLOSE:
378 inflateEnd(&ctx->zstr);
379 return 0;
380
381 case ZIP_SOURCE_STAT:
382 {
383 zip_stat_t *st;
384
385 st = (zip_stat_t *)data;
386
387 st->comp_method = ZIP_CM_STORE;
388 if (st->comp_size > 0 && st->size > 0)
389 st->comp_size = st->size;
390
391 return 0;
392 }
393
394 case ZIP_SOURCE_ERROR:
395 return zip_error_to_data(&ctx->error, data, len);
396
397 case ZIP_SOURCE_FREE:
398 free(ctx);
399 return 0;
400
401 case ZIP_SOURCE_SUPPORTS:
402 return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, -1);
403
404 default:
405 zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
406 return -1;
407 }
408 }
409
410
411 static void
412 deflate_free(struct deflate *ctx)
413 {
414 free(ctx);
415 }