blob: 6fe97292fe43172a769e9e4d49d4ee30d4f8d82d [file] [log] [blame]
Guido van Rossumfb221561997-04-29 15:38:09 +00001/* zlibmodule.c -- gzip-compatible data compression */
2
3#include <Python.h>
4#include <zlib.h>
5
6/* The following parameters are copied from zutil.h, version 0.95 */
7#define DEFLATED 8
8#if MAX_MEM_LEVEL >= 8
9# define DEF_MEM_LEVEL 8
10#else
11# define DEF_MEM_LEVEL MAX_MEM_LEVEL
12#endif
13#define DEF_WBITS MAX_WBITS
14
15/* The output buffer will be increased in chunks of ADDCHUNK bytes. */
16#define ADDCHUNK 2048
17#define PyInit_zlib initzlib
18
19staticforward PyTypeObject Comptype;
20staticforward PyTypeObject Decomptype;
21
22static PyObject *ZlibError;
23
24typedef struct
25{
26 PyObject_HEAD
27 z_stream zst;
28} compobject;
29
30static compobject *
31newcompobject(type)
32 PyTypeObject *type;
33{
34 compobject *self;
35 self = PyObject_NEW(compobject, type);
36 if (self == NULL)
37 return NULL;
38 return self;
39}
40
41static PyObject *
42PyZlib_compress(self, args)
43 PyObject *self;
44 PyObject *args;
45{
46 PyObject *ReturnVal;
47 Byte *input, *output;
48 int length, level=Z_DEFAULT_COMPRESSION, err;
49 z_stream zst;
50
51 if (!PyArg_ParseTuple(args, "s#|i", &input, &length, &level))
52 return NULL;
53 zst.avail_out=length+length/1000+12+1;
54 output=(Byte*)malloc(zst.avail_out);
55 if (output==NULL)
56 {
57 PyErr_SetString(PyExc_MemoryError,
58 "Can't allocate memory to compress data");
59 return NULL;
60 }
61 zst.zalloc=(alloc_func)zst.zfree=(free_func)Z_NULL;
62 zst.next_out=(Byte *)output;
63 zst.next_in =(Byte *)input;
64 zst.avail_in=length;
65 err=deflateInit(&zst, level);
66 switch(err)
67 {
68 case(Z_OK):
69 break;
70 case(Z_MEM_ERROR):
71 PyErr_SetString(PyExc_MemoryError,
72 "Out of memory while compressing data");
73 free(output);
74 return NULL;
75 break;
76 case(Z_STREAM_ERROR):
77 PyErr_SetString(ZlibError,
78 "Bad compression level");
79 free(output);
80 return NULL;
81 break;
82 default:
83 {
84 char temp[500];
85 if (zst.msg==Z_NULL) zst.msg="";
86 sprintf(temp, "Error %i while compressing data [%s]", err, zst.msg);
87 PyErr_SetString(ZlibError, temp);
88 deflateEnd(&zst);
89 free(output);
90 return NULL;
91 }
92 break;
93 }
94
95 err=deflate(&zst, Z_FINISH);
96 switch(err)
97 {
98 case(Z_STREAM_END):
99 break;
100 /* Are there other errors to be trapped here? */
101 default:
102 {
103 char temp[500];
104 if (zst.msg==Z_NULL) zst.msg="";
105 sprintf(temp, "Error %i while compressing data [%s]", err, zst.msg);
106 PyErr_SetString(ZlibError, temp);
107 deflateEnd(&zst);
108 free(output);
109 return NULL;
110 }
111 }
112 err=deflateEnd(&zst);
113 if (err!=Z_OK)
114 {
115 char temp[500];
116 if (zst.msg==Z_NULL) zst.msg="";
117 sprintf(temp, "Error %i while finishing data compression [%s]",
118 err, zst.msg);
119 PyErr_SetString(ZlibError, temp);
120 free(output);
121 return NULL;
122 }
123 ReturnVal=PyString_FromStringAndSize(output, zst.total_out);
124 free(output);
125 return ReturnVal;
126}
127
128static PyObject *
129PyZlib_decompress(self, args)
130 PyObject *self;
131 PyObject *args;
132{
133 PyObject *ReturnVal;
134 Byte *input, *output;
135 int length, err;
136 z_stream zst;
137 if (!PyArg_ParseTuple(args, "s#", &input, &length))
138 return NULL;
139
140 zst.avail_in=length;
141 zst.avail_out=length=length*2;
142 output=(Byte*)malloc(zst.avail_out);
143 if (output==NULL)
144 {
145 PyErr_SetString(PyExc_MemoryError,
146 "Can't allocate memory to decompress data");
147 return NULL;
148 }
149 zst.zalloc=(alloc_func)zst.zfree=(free_func)Z_NULL;
150 zst.next_out=(Byte *)output;
151 zst.next_in =(Byte *)input;
152 err=inflateInit(&zst);
153 switch(err)
154 {
155 case(Z_OK):
156 break;
157 case(Z_MEM_ERROR):
158 PyErr_SetString(PyExc_MemoryError,
159 "Out of memory while decompressing data");
160 free(output);
161 return NULL;
162 default:
163 {
164 char temp[500];
165 if (zst.msg==Z_NULL) zst.msg="";
166 sprintf(temp, "Error %i while preparing to decompress data [%s]",
167 err, zst.msg);
168 PyErr_SetString(ZlibError, temp);
169 inflateEnd(&zst);
170 free(output);
171 return NULL;
172 }
173 }
174 do
175 {
176 err=inflate(&zst, Z_FINISH);
177 switch(err)
178 {
179 case(Z_OK):
180 case(Z_STREAM_END):
181 output=(Byte *)realloc(output, length+ADDCHUNK);
182 if (output==NULL)
183 {
184 PyErr_SetString(PyExc_MemoryError,
185 "Out of memory while decompressing data");
186 inflateEnd(&zst);
187 return NULL;
188 }
189 zst.next_out=output+length;
190 zst.avail_out=ADDCHUNK;
191 length += ADDCHUNK;
192 break;
193 default:
194 {
195 char temp[500];
196 if (zst.msg==Z_NULL) zst.msg="";
197 sprintf(temp, "Error %i while decompressing data: [%s]",
198 err, zst.msg);
199 PyErr_SetString(ZlibError, temp);
200 inflateEnd(&zst);
201 return NULL;
202 }
203 }
204 } while(err!=Z_STREAM_END);
205
206 err=inflateEnd(&zst);
207 if (err!=Z_OK)
208 {
209 char temp[500];
210 if (zst.msg==Z_NULL) zst.msg="";
211 sprintf(temp, "Error %i while finishing data decompression [%s]",
212 err, zst.msg);
213 PyErr_SetString(ZlibError, temp);
214 free(output);
215 return NULL;
216 }
217 ReturnVal=PyString_FromStringAndSize(output, zst.total_out);
218 free(output);
219 return ReturnVal;
220}
221
222static PyObject *
223PyZlib_compressobj(selfptr, args)
224 PyObject *selfptr;
225 PyObject *args;
226{
227 compobject *self;
228 int level=Z_DEFAULT_COMPRESSION, method=DEFLATED;
229 int wbits=MAX_WBITS, memLevel=DEF_MEM_LEVEL, strategy=0, err;
230 /* XXX Argh! Is there a better way to have multiple levels of */
231 /* optional arguments? */
232 if (!PyArg_ParseTuple(args, "iiiii", &level, &method, &wbits, &memLevel, &strategy))
233 {
234 PyErr_Clear();
235 if (!PyArg_ParseTuple(args, "iiii", &level, &method, &wbits,
236 &memLevel))
237 {
238 PyErr_Clear();
239 if (!PyArg_ParseTuple(args, "iii", &level, &method, &wbits))
240 {
241 PyErr_Clear();
242 if (!PyArg_ParseTuple(args, "ii", &level, &method))
243 {
244 PyErr_Clear();
245 if (!PyArg_ParseTuple(args, "i", &level))
246 {
247 PyErr_Clear();
248 if (!PyArg_ParseTuple(args, ""))
249 return (NULL);
250 }
251 }
252 }
253 }
254 }
255 self=newcompobject(&Comptype);
256 if (self==NULL) return(NULL);
257 self->zst.zalloc=(alloc_func)self->zst.zfree=(free_func)Z_NULL;
258 err=deflateInit2(&self->zst, level, method, wbits, memLevel, strategy);
259 switch(err)
260 {
261 case (Z_OK):
262 return (PyObject*)self;
263 break;
264 case (Z_MEM_ERROR):
265 PyErr_SetString(PyExc_MemoryError,
266 "Can't allocate memory for compression object");
267 return NULL;
268 break;
269 case(Z_STREAM_ERROR):
270 PyErr_SetString(PyExc_ValueError,
271 "Invalid compression level");
272 return NULL;
273 break;
274 default:
275 {
276 char temp[500];
277 if (self->zst.msg==Z_NULL) self->zst.msg="";
278 sprintf(temp, "Error %i while creating compression object [%s]",
279 err, self->zst.msg);
280 PyErr_SetString(ZlibError, temp);
281 return NULL;
282 break;
283 }
284 }
285}
286
287static PyObject *
288PyZlib_decompressobj(selfptr, args)
289 PyObject *selfptr;
290 PyObject *args;
291{
292 int wbits=DEF_WBITS, err;
293 compobject *self;
294 if (!PyArg_ParseTuple(args, "|i", &wbits))
295 {
296 return NULL;
297 }
298 self=newcompobject(&Decomptype);
299 if (self==NULL) return(NULL);
300 self->zst.zalloc=(alloc_func)self->zst.zfree=(free_func)Z_NULL;
301 /* XXX If illegal values of wbits are allowed to get here, Python
302 coredumps, instead of raising an exception as it should.
303 This is a bug in zlib 0.95; I have reported it. */
304 err=inflateInit2(&self->zst, wbits);
305 switch(err)
306 {
307 case (Z_OK):
308 return (PyObject*)self;
309 break;
310 case (Z_MEM_ERROR):
311 PyErr_SetString(PyExc_MemoryError,
312 "Can't allocate memory for decompression object");
313 return NULL;
314 break;
315 default:
316 {
317 char temp[500];
318 if (self->zst.msg==Z_NULL) self->zst.msg="";
319 sprintf(temp, "Error %i while creating decompression object [%s]",
320 err, self->zst.msg);
321 PyErr_SetString(ZlibError, temp);
322 return NULL;
323 break;
324 }
325 }
326}
327
328static void
329Comp_dealloc(self)
330 compobject *self;
331{
332 int err;
333 err=deflateEnd(&self->zst); /* Deallocate zstream structure */
334}
335
336static void
337Decomp_dealloc(self)
338 compobject *self;
339{
340 int err;
341 err=inflateEnd(&self->zst); /* Deallocate zstream structure */
342}
343
344static PyObject *
345PyZlib_objcompress(self, args)
346 compobject *self;
347 PyObject *args;
348{
349 int length=0, err, inplen;
350 Byte *buf=NULL;
351 PyObject *RetVal;
352 Byte *input;
353
354 if (!PyArg_ParseTuple(args, "s#", &input, &inplen))
355 return NULL;
356 self->zst.avail_in=inplen;
357 self->zst.next_in=input;
358 do
359 {
360 buf=(Byte *)realloc(buf, length+ADDCHUNK);
361 if (buf==NULL)
362 {
363 PyErr_SetString(PyExc_MemoryError,
364 "Can't allocate memory to compress data");
365 return NULL;
366 }
367 self->zst.next_out=buf+length;
368 self->zst.avail_out=ADDCHUNK;
369 length += ADDCHUNK;
370 err=deflate(&(self->zst), Z_NO_FLUSH);
371 } while (self->zst.avail_in!=0 && err==Z_OK);
372 if (err!=Z_OK)
373 {
374 char temp[500];
375 if (self->zst.msg==Z_NULL) self->zst.msg="";
376 sprintf(temp, "Error %i while compressing [%s]",
377 err, self->zst.msg);
378 PyErr_SetString(ZlibError, temp);
379 return NULL;
380 }
381 RetVal=PyString_FromStringAndSize(buf, self->zst.next_out-buf);
382 free(buf);
383 return RetVal;
384}
385
386static PyObject *
387PyZlib_objdecompress(self, args)
388 compobject *self;
389 PyObject *args;
390{
391 int length=0, err, inplen;
392 Byte *buf=NULL;
393 PyObject *RetVal;
394 Byte *input;
395 if (!PyArg_ParseTuple(args, "s#", &input, &inplen))
396 return NULL;
397 self->zst.avail_in=inplen;
398 self->zst.next_in=input;
399 do
400 {
401 buf=(Byte *)realloc(buf, length+ADDCHUNK);
402 if (buf==NULL)
403 {
404 PyErr_SetString(PyExc_MemoryError,
405 "Can't allocate memory to decompress data");
406 return NULL;
407 }
408 self->zst.next_out=buf+length;
409 self->zst.avail_out=ADDCHUNK;
410 length += ADDCHUNK;
411 err=inflate(&(self->zst), Z_NO_FLUSH);
412 } while (self->zst.avail_in!=0 && err==Z_OK);
413 if (err!=Z_OK && err!=Z_STREAM_END)
414 {
415 char temp[500];
416 if (self->zst.msg==Z_NULL) self->zst.msg="";
417 sprintf(temp, "Error %i while decompressing [%s]",
418 err, self->zst.msg);
419 PyErr_SetString(ZlibError, temp);
420 return NULL;
421 }
422 RetVal=PyString_FromStringAndSize(buf, self->zst.next_out-buf);
423 free(buf);
424 return RetVal;
425}
426
427static PyObject *
428PyZlib_flush(self, args)
429 compobject *self;
430 PyObject *args;
431{
432 int length=0, err;
433 Byte *buf=NULL;
434 PyObject *RetVal;
435
436 if (!PyArg_NoArgs(args))
437 return NULL;
438 self->zst.avail_in=0;
439 do
440 {
441 buf=(Byte *)realloc(buf, length+ADDCHUNK);
442 if (buf==NULL)
443 {
444 PyErr_SetString(PyExc_MemoryError,
445 "Can't allocate memory to compress data");
446 return NULL;
447 }
448 self->zst.next_out=buf+length;
449 self->zst.avail_out=ADDCHUNK;
450 length += ADDCHUNK;
451 err=deflate(&(self->zst), Z_FINISH);
452 } while (err==Z_OK);
453 if (err!=Z_STREAM_END)
454 {
455 char temp[500];
456 if (self->zst.msg==Z_NULL) self->zst.msg="";
457 sprintf(temp, "Error %i while compressing [%s]",
458 err, self->zst.msg);
459 PyErr_SetString(ZlibError, temp);
460 return NULL;
461 }
462 RetVal=PyString_FromStringAndSize(buf, self->zst.next_out-buf);
463 free(buf);
464 err=deflateEnd(&(self->zst));
465 if (err!=Z_OK)
466 {
467 char temp[500];
468 if (self->zst.msg==Z_NULL) self->zst.msg="";
469 sprintf(temp, "Error %i while flushing compression object [%s]",
470 err, self->zst.msg);
471 PyErr_SetString(ZlibError, temp);
472 return NULL;
473 }
474 return RetVal;
475}
476
477static PyObject *
478PyZlib_unflush(self, args)
479 compobject *self;
480 PyObject *args;
481{
482 int length=0, err;
483 Byte *buf=NULL;
484 PyObject *RetVal;
485
486 if (!PyArg_NoArgs(args))
487 return NULL;
488 self->zst.avail_in=0;
489 do
490 {
491 buf=(Byte *)realloc(buf, length+ADDCHUNK);
492 if (buf==NULL)
493 {
494 PyErr_SetString(PyExc_MemoryError,
495 "Can't allocate memory to decompress data");
496 return NULL;
497 }
498 self->zst.next_out=buf+length;
499 length += ADDCHUNK;
500 err=inflate(&(self->zst), Z_FINISH);
501 } while (err==Z_OK);
502 if (err!=Z_STREAM_END)
503 {
504 char temp[500];
505 if (self->zst.msg==Z_NULL) self->zst.msg="";
506 sprintf(temp, "Error %i while decompressing [%s]",
507 err, self->zst.msg);
508 PyErr_SetString(ZlibError, temp);
509 return NULL;
510 }
511 RetVal=PyString_FromStringAndSize(buf, self->zst.next_out - buf);
512 free(buf);
513 err=inflateEnd(&(self->zst));
514 if (err!=Z_OK)
515 {
516 char temp[500];
517 if (self->zst.msg==Z_NULL) self->zst.msg="";
518 sprintf(temp, "Error %i while flushing decompression object [%s]",
519 err, self->zst.msg);
520 PyErr_SetString(ZlibError, temp);
521 return NULL;
522 }
523 return RetVal;
524}
525
526static PyMethodDef comp_methods[] =
527{
528 {"compress", PyZlib_objcompress, 1},
529 {"flush", PyZlib_flush, 0},
530 {NULL, NULL}
531};
532
533static PyMethodDef Decomp_methods[] =
534{
535 {"decompress", PyZlib_objdecompress, 1},
536 {"flush", PyZlib_unflush, 0},
537 {NULL, NULL}
538};
539
540static PyObject *
541Comp_getattr(self, name)
542 compobject *self;
543 char *name;
544{
545 return Py_FindMethod(comp_methods, (PyObject *)self, name);
546}
547
548static PyObject *
549Decomp_getattr(self, name)
550 compobject *self;
551 char *name;
552{
553 return Py_FindMethod(Decomp_methods, (PyObject *)self, name);
554}
555
556static PyObject *
557PyZlib_adler32(self, args)
558 PyObject *self, *args;
559{
560 uLong adler32val=adler32(0L, Z_NULL, 0);
561 Byte *buf;
562 int len;
563
564 if (!PyArg_ParseTuple(args, "s#|l", &buf, &len, &adler32val))
565 {
566 return NULL;
567 }
568 adler32val=adler32(adler32val, buf, len);
569 return Py_BuildValue("l", adler32val);
570}
571
572
573static PyObject *
574PyZlib_crc32(self, args)
575 PyObject *self, *args;
576{
577 uLong crc32val=crc32(0L, Z_NULL, 0);
578 Byte *buf;
579 int len;
580 if (!PyArg_ParseTuple(args, "s#|l", &buf, &len, &crc32val))
581 {
582 return NULL;
583 }
584 crc32val=crc32(crc32val, buf, len);
585 return Py_BuildValue("l", crc32val);
586}
587
588
589static PyMethodDef zlib_methods[] =
590{
591 {"adler32", PyZlib_adler32, 1},
592 {"compress", PyZlib_compress, 1},
593 {"compressobj", PyZlib_compressobj, 1},
594 {"crc32", PyZlib_crc32, 1},
595 {"decompress", PyZlib_decompress, 1},
596 {"decompressobj", PyZlib_decompressobj, 1},
597 {NULL, NULL}
598};
599
600statichere PyTypeObject Comptype = {
601 PyObject_HEAD_INIT(&PyType_Type)
602 0,
603 "Compress",
604 sizeof(compobject),
605 0,
606 (destructor)Comp_dealloc, /*tp_dealloc*/
607 0, /*tp_print*/
608 (getattrfunc)Comp_getattr, /*tp_getattr*/
609 0, /*tp_setattr*/
610 0, /*tp_compare*/
611 0, /*tp_repr*/
612 0, /*tp_as_number*/
613 0, /*tp_as_sequence*/
614 0, /*tp_as_mapping*/
615};
616
617statichere PyTypeObject Decomptype = {
618 PyObject_HEAD_INIT(&PyType_Type)
619 0,
620 "Decompress",
621 sizeof(compobject),
622 0,
623 (destructor)Decomp_dealloc, /*tp_dealloc*/
624 0, /*tp_print*/
625 (getattrfunc)Decomp_getattr, /*tp_getattr*/
626 0, /*tp_setattr*/
627 0, /*tp_compare*/
628 0, /*tp_repr*/
629 0, /*tp_as_number*/
630 0, /*tp_as_sequence*/
631 0, /*tp_as_mapping*/
632};
633
634/* The following insint() routine was blatantly ripped off from
635 socketmodule.c */
636
637/* Convenience routine to export an integer value.
638 For simplicity, errors (which are unlikely anyway) are ignored. */
639static void
640insint(d, name, value)
641 PyObject *d;
642 char *name;
643 int value;
644{
645 PyObject *v = PyInt_FromLong((long) value);
646 if (v == NULL) {
647 /* Don't bother reporting this error */
648 PyErr_Clear();
649 }
650 else {
651 PyDict_SetItemString(d, name, v);
652 Py_DECREF(v);
653 }
654}
655
656void
657PyInit_zlib()
658{
659 PyObject *m, *d;
660 m = Py_InitModule("zlib", zlib_methods);
661 d = PyModule_GetDict(m);
662 ZlibError = Py_BuildValue("s", "zlib.error");
663 PyDict_SetItemString(d, "error", ZlibError);
664 insint(d, "MAX_WBITS", MAX_WBITS);
665 insint(d, "DEFLATED", DEFLATED);
666 insint(d, "DEF_MEM_LEVEL", DEF_MEM_LEVEL);
667
668 if (PyErr_Occurred())
669 Py_FatalError("can't initialize module zlib");
670}