3 python-bz2 - python bz2 library interface
5 Copyright (c) 2002 Gustavo Niemeyer <niemeyer@conectiva.com>
6 Copyright (c) 2002 Python Software Foundation; All Rights Reserved
13 #include "structmember.h"
19 static char __author__
[] =
20 "The bz2 python module was written by:\n\
22 Gustavo Niemeyer <niemeyer@conectiva.com>\n\
25 /* Our very own off_t-like type, 64-bit if possible */
26 /* copied from Objects/fileobject.c */
27 #if !defined(HAVE_LARGEFILE_SUPPORT)
28 typedef off_t Py_off_t
;
29 #elif SIZEOF_OFF_T >= 8
30 typedef off_t Py_off_t
;
31 #elif SIZEOF_FPOS_T >= 8
32 typedef fpos_t Py_off_t
;
34 #error "Large file support, but neither off_t nor fpos_t is large enough."
37 #define BUF(v) PyBytes_AS_STRING(v)
41 #define MODE_READ_EOF 2
44 #define BZ2FileObject_Check(v) (Py_TYPE(v) == &BZ2File_Type)
47 #ifdef BZ_CONFIG_ERROR
50 #define BZS_TOTAL_OUT(bzs) \
51 (((long)bzs->total_out_hi32 << 32) + bzs->total_out_lo32)
52 #elif SIZEOF_LONG_LONG >= 8
53 #define BZS_TOTAL_OUT(bzs) \
54 (((PY_LONG_LONG)bzs->total_out_hi32 << 32) + bzs->total_out_lo32)
56 #define BZS_TOTAL_OUT(bzs) \
60 #else /* ! BZ_CONFIG_ERROR */
62 #define BZ2_bzRead bzRead
63 #define BZ2_bzReadOpen bzReadOpen
64 #define BZ2_bzReadClose bzReadClose
65 #define BZ2_bzWrite bzWrite
66 #define BZ2_bzWriteOpen bzWriteOpen
67 #define BZ2_bzWriteClose bzWriteClose
68 #define BZ2_bzCompress bzCompress
69 #define BZ2_bzCompressInit bzCompressInit
70 #define BZ2_bzCompressEnd bzCompressEnd
71 #define BZ2_bzDecompress bzDecompress
72 #define BZ2_bzDecompressInit bzDecompressInit
73 #define BZ2_bzDecompressEnd bzDecompressEnd
75 #define BZS_TOTAL_OUT(bzs) bzs->total_out
77 #endif /* ! BZ_CONFIG_ERROR */
81 #define ACQUIRE_LOCK(obj) do { \
82 if (!PyThread_acquire_lock(obj->lock, 0)) { \
83 Py_BEGIN_ALLOW_THREADS \
84 PyThread_acquire_lock(obj->lock, 1); \
85 Py_END_ALLOW_THREADS \
87 #define RELEASE_LOCK(obj) PyThread_release_lock(obj->lock)
89 #define ACQUIRE_LOCK(obj)
90 #define RELEASE_LOCK(obj)
93 /* Bits in f_newlinetypes */
94 #define NEWLINE_UNKNOWN 0 /* No newline seen, yet */
95 #define NEWLINE_CR 1 /* \r newline seen */
96 #define NEWLINE_LF 2 /* \n newline seen */
97 #define NEWLINE_CRLF 4 /* \r\n newline seen */
99 /* ===================================================================== */
100 /* Structure definitions. */
106 char* f_buf
; /* Allocated readahead buffer */
107 char* f_bufend
; /* Points after last occupied position */
108 char* f_bufptr
; /* Current buffer position */
115 PyThread_type_lock lock
;
124 PyThread_type_lock lock
;
132 PyObject
*unused_data
;
134 PyThread_type_lock lock
;
138 /* ===================================================================== */
139 /* Utility functions. */
142 Util_CatchBZ2Error(int bzerror
)
150 #ifdef BZ_CONFIG_ERROR
151 case BZ_CONFIG_ERROR
:
152 PyErr_SetString(PyExc_SystemError
,
153 "the bz2 library was not compiled "
160 PyErr_SetString(PyExc_ValueError
,
161 "the bz2 library has received wrong "
172 case BZ_DATA_ERROR_MAGIC
:
173 PyErr_SetString(PyExc_IOError
, "invalid data stream");
178 PyErr_SetString(PyExc_IOError
, "unknown IO error");
182 case BZ_UNEXPECTED_EOF
:
183 PyErr_SetString(PyExc_EOFError
,
184 "compressed file ended before the "
185 "logical end-of-stream was detected");
189 case BZ_SEQUENCE_ERROR
:
190 PyErr_SetString(PyExc_RuntimeError
,
191 "wrong sequence of bz2 library "
200 #define SMALLCHUNK 8192
202 #define SMALLCHUNK BUFSIZ
206 #define BIGCHUNK (512 * 32)
208 #define BIGCHUNK (512 * 1024)
211 /* This is a hacked version of Python's fileobject.c:new_buffersize(). */
213 Util_NewBufferSize(size_t currentsize
)
215 if (currentsize
> SMALLCHUNK
) {
216 /* Keep doubling until we reach BIGCHUNK;
217 then keep adding BIGCHUNK. */
218 if (currentsize
<= BIGCHUNK
)
219 return currentsize
+ currentsize
;
221 return currentsize
+ BIGCHUNK
;
223 return currentsize
+ SMALLCHUNK
;
226 /* This is a hacked version of Python's fileobject.c:get_line(). */
228 Util_GetLine(BZ2FileObject
*f
, int n
)
232 size_t total_v_size
; /* total # of slots in buffer */
233 size_t used_v_size
; /* # used slots in buffer */
234 size_t increment
; /* amount to increment the buffer */
239 total_v_size
= n
> 0 ? n
: 100;
240 v
= PyBytes_FromStringAndSize((char *)NULL
, total_v_size
);
245 end
= buf
+ total_v_size
;
248 Py_BEGIN_ALLOW_THREADS
250 bytes_read
= BZ2_bzRead(&bzerror
, f
->fp
, &c
, 1);
255 } while (bzerror
== BZ_OK
&& c
!= '\n' && buf
!= end
);
257 if (bzerror
== BZ_STREAM_END
) {
259 f
->mode
= MODE_READ_EOF
;
261 } else if (bzerror
!= BZ_OK
) {
262 Util_CatchBZ2Error(bzerror
);
268 /* Must be because buf == end */
271 used_v_size
= total_v_size
;
272 increment
= total_v_size
>> 2; /* mild exponential growth */
273 total_v_size
+= increment
;
274 if (total_v_size
> INT_MAX
) {
275 PyErr_SetString(PyExc_OverflowError
,
276 "line is longer than a Python string can hold");
280 if (_PyBytes_Resize(&v
, total_v_size
) < 0) {
283 buf
= BUF(v
) + used_v_size
;
284 end
= BUF(v
) + total_v_size
;
287 used_v_size
= buf
- BUF(v
);
288 if (used_v_size
!= total_v_size
) {
289 if (_PyBytes_Resize(&v
, used_v_size
) < 0) {
296 /* This is a hacked version of Python's fileobject.c:drop_readahead(). */
298 Util_DropReadAhead(BZ2FileObject
*f
)
300 if (f
->f_buf
!= NULL
) {
301 PyMem_Free(f
->f_buf
);
306 /* This is a hacked version of Python's fileobject.c:readahead(). */
308 Util_ReadAhead(BZ2FileObject
*f
, int bufsize
)
313 if (f
->f_buf
!= NULL
) {
314 if((f
->f_bufend
- f
->f_bufptr
) >= 1)
317 Util_DropReadAhead(f
);
319 if (f
->mode
== MODE_READ_EOF
) {
320 f
->f_bufptr
= f
->f_buf
;
321 f
->f_bufend
= f
->f_buf
;
324 if ((f
->f_buf
= PyMem_Malloc(bufsize
)) == NULL
) {
328 Py_BEGIN_ALLOW_THREADS
329 chunksize
= BZ2_bzRead(&bzerror
, f
->fp
, f
->f_buf
, bufsize
);
332 if (bzerror
== BZ_STREAM_END
) {
334 f
->mode
= MODE_READ_EOF
;
335 } else if (bzerror
!= BZ_OK
) {
336 Util_CatchBZ2Error(bzerror
);
337 Util_DropReadAhead(f
);
340 f
->f_bufptr
= f
->f_buf
;
341 f
->f_bufend
= f
->f_buf
+ chunksize
;
345 /* This is a hacked version of Python's
346 * fileobject.c:readahead_get_line_skip(). */
347 static PyBytesObject
*
348 Util_ReadAheadGetLineSkip(BZ2FileObject
*f
, int skip
, int bufsize
)
355 if (f
->f_buf
== NULL
)
356 if (Util_ReadAhead(f
, bufsize
) < 0)
359 len
= f
->f_bufend
- f
->f_bufptr
;
361 return (PyBytesObject
*)
362 PyBytes_FromStringAndSize(NULL
, skip
);
363 bufptr
= memchr(f
->f_bufptr
, '\n', len
);
364 if (bufptr
!= NULL
) {
365 bufptr
++; /* Count the '\n' */
366 len
= bufptr
- f
->f_bufptr
;
367 s
= (PyBytesObject
*)
368 PyBytes_FromStringAndSize(NULL
, skip
+len
);
371 memcpy(PyBytes_AS_STRING(s
)+skip
, f
->f_bufptr
, len
);
372 f
->f_bufptr
= bufptr
;
373 if (bufptr
== f
->f_bufend
)
374 Util_DropReadAhead(f
);
376 bufptr
= f
->f_bufptr
;
378 f
->f_buf
= NULL
; /* Force new readahead buffer */
379 s
= Util_ReadAheadGetLineSkip(f
, skip
+len
,
380 bufsize
+ (bufsize
>>2));
385 memcpy(PyBytes_AS_STRING(s
)+skip
, bufptr
, len
);
391 /* ===================================================================== */
392 /* Methods of BZ2File. */
394 PyDoc_STRVAR(BZ2File_read__doc__
,
395 "read([size]) -> string\n\
397 Read at most size uncompressed bytes, returned as a string. If the size\n\
398 argument is negative or omitted, read until EOF is reached.\n\
401 /* This is a hacked version of Python's fileobject.c:file_read(). */
403 BZ2File_read(BZ2FileObject
*self
, PyObject
*args
)
405 long bytesrequested
= -1;
406 size_t bytesread
, buffersize
, chunksize
;
408 PyObject
*ret
= NULL
;
410 if (!PyArg_ParseTuple(args
, "|l:read", &bytesrequested
))
414 switch (self
->mode
) {
418 ret
= PyBytes_FromStringAndSize("", 0);
421 PyErr_SetString(PyExc_ValueError
,
422 "I/O operation on closed file");
425 PyErr_SetString(PyExc_IOError
,
426 "file is not ready for reading");
430 if (bytesrequested
< 0)
431 buffersize
= Util_NewBufferSize((size_t)0);
433 buffersize
= bytesrequested
;
434 if (buffersize
> INT_MAX
) {
435 PyErr_SetString(PyExc_OverflowError
,
436 "requested number of bytes is "
437 "more than a Python string can hold");
440 ret
= PyBytes_FromStringAndSize((char *)NULL
, buffersize
);
441 if (ret
== NULL
|| buffersize
== 0)
446 Py_BEGIN_ALLOW_THREADS
447 chunksize
= BZ2_bzRead(&bzerror
, self
->fp
,
449 buffersize
-bytesread
);
450 self
->pos
+= chunksize
;
452 bytesread
+= chunksize
;
453 if (bzerror
== BZ_STREAM_END
) {
454 self
->size
= self
->pos
;
455 self
->mode
= MODE_READ_EOF
;
457 } else if (bzerror
!= BZ_OK
) {
458 Util_CatchBZ2Error(bzerror
);
463 if (bytesrequested
< 0) {
464 buffersize
= Util_NewBufferSize(buffersize
);
465 if (_PyBytes_Resize(&ret
, buffersize
) < 0) {
473 if (bytesread
!= buffersize
) {
474 if (_PyBytes_Resize(&ret
, bytesread
) < 0) {
484 PyDoc_STRVAR(BZ2File_readline__doc__
,
485 "readline([size]) -> string\n\
487 Return the next line from the file, as a string, retaining newline.\n\
488 A non-negative size argument will limit the maximum number of bytes to\n\
489 return (an incomplete line may be returned then). Return an empty\n\
494 BZ2File_readline(BZ2FileObject
*self
, PyObject
*args
)
496 PyObject
*ret
= NULL
;
499 if (!PyArg_ParseTuple(args
, "|i:readline", &sizehint
))
503 switch (self
->mode
) {
507 ret
= PyBytes_FromStringAndSize("", 0);
510 PyErr_SetString(PyExc_ValueError
,
511 "I/O operation on closed file");
514 PyErr_SetString(PyExc_IOError
,
515 "file is not ready for reading");
520 ret
= PyBytes_FromStringAndSize("", 0);
522 ret
= Util_GetLine(self
, (sizehint
< 0) ? 0 : sizehint
);
529 PyDoc_STRVAR(BZ2File_readlines__doc__
,
530 "readlines([size]) -> list\n\
532 Call readline() repeatedly and return a list of lines read.\n\
533 The optional size argument, if given, is an approximate bound on the\n\
534 total number of bytes in the lines returned.\n\
537 /* This is a hacked version of Python's fileobject.c:file_readlines(). */
539 BZ2File_readlines(BZ2FileObject
*self
, PyObject
*args
)
542 PyObject
*list
= NULL
;
544 char small_buffer
[SMALLCHUNK
];
545 char *buffer
= small_buffer
;
546 size_t buffersize
= SMALLCHUNK
;
547 PyObject
*big_buffer
= NULL
;
550 size_t totalread
= 0;
556 if (!PyArg_ParseTuple(args
, "|l:readlines", &sizehint
))
560 switch (self
->mode
) {
564 list
= PyList_New(0);
567 PyErr_SetString(PyExc_ValueError
,
568 "I/O operation on closed file");
571 PyErr_SetString(PyExc_IOError
,
572 "file is not ready for reading");
576 if ((list
= PyList_New(0)) == NULL
)
580 Py_BEGIN_ALLOW_THREADS
581 nread
= BZ2_bzRead(&bzerror
, self
->fp
,
582 buffer
+nfilled
, buffersize
-nfilled
);
585 if (bzerror
== BZ_STREAM_END
) {
586 self
->size
= self
->pos
;
587 self
->mode
= MODE_READ_EOF
;
593 } else if (bzerror
!= BZ_OK
) {
594 Util_CatchBZ2Error(bzerror
);
601 p
= memchr(buffer
+nfilled
, '\n', nread
);
602 if (!shortread
&& p
== NULL
) {
603 /* Need a larger buffer to fit this line */
606 if (buffersize
> INT_MAX
) {
607 PyErr_SetString(PyExc_OverflowError
,
608 "line is longer than a Python string can hold");
611 if (big_buffer
== NULL
) {
612 /* Create the big buffer */
613 big_buffer
= PyBytes_FromStringAndSize(
615 if (big_buffer
== NULL
)
617 buffer
= PyBytes_AS_STRING(big_buffer
);
618 memcpy(buffer
, small_buffer
, nfilled
);
621 /* Grow the big buffer */
622 if (_PyBytes_Resize(&big_buffer
, buffersize
) < 0){
626 buffer
= PyBytes_AS_STRING(big_buffer
);
630 end
= buffer
+nfilled
+nread
;
633 /* Process complete lines */
635 line
= PyBytes_FromStringAndSize(q
, p
-q
);
638 err
= PyList_Append(list
, line
);
643 p
= memchr(q
, '\n', end
-q
);
645 /* Move the remaining incomplete line to the start */
647 memmove(buffer
, q
, nfilled
);
649 if (totalread
>= (size_t)sizehint
)
657 /* Partial last line */
658 line
= PyBytes_FromStringAndSize(buffer
, nfilled
);
662 /* Need to complete the last line */
663 PyObject
*rest
= Util_GetLine(self
, 0);
668 PyBytes_Concat(&line
, rest
);
673 err
= PyList_Append(list
, line
);
682 Py_DECREF(big_buffer
);
687 PyDoc_STRVAR(BZ2File_write__doc__
,
688 "write(data) -> None\n\
690 Write the 'data' string to file. Note that due to buffering, close() may\n\
691 be needed before the file on disk reflects the data written.\n\
694 /* This is a hacked version of Python's fileobject.c:file_write(). */
696 BZ2File_write(BZ2FileObject
*self
, PyObject
*args
)
698 PyObject
*ret
= NULL
;
704 if (!PyArg_ParseTuple(args
, "y*:write", &pbuf
))
710 switch (self
->mode
) {
715 PyErr_SetString(PyExc_ValueError
,
716 "I/O operation on closed file");
720 PyErr_SetString(PyExc_IOError
,
721 "file is not ready for writing");
725 Py_BEGIN_ALLOW_THREADS
726 BZ2_bzWrite (&bzerror
, self
->fp
, buf
, len
);
730 if (bzerror
!= BZ_OK
) {
731 Util_CatchBZ2Error(bzerror
);
739 PyBuffer_Release(&pbuf
);
744 PyDoc_STRVAR(BZ2File_writelines__doc__
,
745 "writelines(sequence_of_strings) -> None\n\
747 Write the sequence of strings to the file. Note that newlines are not\n\
748 added. The sequence can be any iterable object producing strings. This is\n\
749 equivalent to calling write() for each string.\n\
752 /* This is a hacked version of Python's fileobject.c:file_writelines(). */
754 BZ2File_writelines(BZ2FileObject
*self
, PyObject
*seq
)
756 #define CHUNKSIZE 1000
757 PyObject
*list
= NULL
;
758 PyObject
*iter
= NULL
;
759 PyObject
*ret
= NULL
;
761 int i
, j
, index
, len
, islist
;
765 switch (self
->mode
) {
770 PyErr_SetString(PyExc_ValueError
,
771 "I/O operation on closed file");
775 PyErr_SetString(PyExc_IOError
,
776 "file is not ready for writing");
780 islist
= PyList_Check(seq
);
782 iter
= PyObject_GetIter(seq
);
784 PyErr_SetString(PyExc_TypeError
,
785 "writelines() requires an iterable argument");
788 list
= PyList_New(CHUNKSIZE
);
793 /* Strategy: slurp CHUNKSIZE lines into a private list,
794 checking that they are all strings, then write that list
795 without holding the interpreter lock, then come back for more. */
796 for (index
= 0; ; index
+= CHUNKSIZE
) {
799 list
= PyList_GetSlice(seq
, index
, index
+CHUNKSIZE
);
802 j
= PyList_GET_SIZE(list
);
805 for (j
= 0; j
< CHUNKSIZE
; j
++) {
806 line
= PyIter_Next(iter
);
808 if (PyErr_Occurred())
812 PyList_SetItem(list
, j
, line
);
818 /* Check that all entries are indeed byte strings. If not,
819 apply the same rules as for file.write() and
820 convert the rets to strings. This is slow, but
821 seems to be the only way since all conversion APIs
822 could potentially execute Python code. */
823 for (i
= 0; i
< j
; i
++) {
824 PyObject
*v
= PyList_GET_ITEM(list
, i
);
825 if (!PyBytes_Check(v
)) {
828 if (PyObject_AsCharBuffer(v
, &buffer
, &len
)) {
829 PyErr_SetString(PyExc_TypeError
,
836 line
= PyBytes_FromStringAndSize(buffer
,
841 PyList_SET_ITEM(list
, i
, line
);
845 /* Since we are releasing the global lock, the
846 following code may *not* execute Python code. */
847 Py_BEGIN_ALLOW_THREADS
848 for (i
= 0; i
< j
; i
++) {
849 line
= PyList_GET_ITEM(list
, i
);
850 len
= PyBytes_GET_SIZE(line
);
851 BZ2_bzWrite (&bzerror
, self
->fp
,
852 PyBytes_AS_STRING(line
), len
);
853 if (bzerror
!= BZ_OK
) {
855 Util_CatchBZ2Error(bzerror
);
876 PyDoc_STRVAR(BZ2File_seek__doc__
,
877 "seek(offset [, whence]) -> None\n\
879 Move to new file position. Argument offset is a byte count. Optional\n\
880 argument whence defaults to 0 (offset from start of file, offset\n\
881 should be >= 0); other values are 1 (move relative to current position,\n\
882 positive or negative), and 2 (move relative to end of file, usually\n\
883 negative, although many platforms allow seeking beyond the end of a file).\n\
885 Note that seeking of bz2 files is emulated, and depending on the parameters\n\
886 the operation may be extremely slow.\n\
890 BZ2File_seek(BZ2FileObject
*self
, PyObject
*args
)
895 char small_buffer
[SMALLCHUNK
];
896 char *buffer
= small_buffer
;
897 size_t buffersize
= SMALLCHUNK
;
898 Py_off_t bytesread
= 0;
902 PyObject
*ret
= NULL
;
904 if (!PyArg_ParseTuple(args
, "O|i:seek", &offobj
, &where
))
906 #if !defined(HAVE_LARGEFILE_SUPPORT)
907 offset
= PyLong_AsLong(offobj
);
909 offset
= PyLong_Check(offobj
) ?
910 PyLong_AsLongLong(offobj
) : PyLong_AsLong(offobj
);
912 if (PyErr_Occurred())
916 Util_DropReadAhead(self
);
917 switch (self
->mode
) {
923 PyErr_SetString(PyExc_ValueError
,
924 "I/O operation on closed file");
928 PyErr_SetString(PyExc_IOError
,
929 "seek works only while reading");
934 if (self
->size
== -1) {
935 assert(self
->mode
!= MODE_READ_EOF
);
937 Py_BEGIN_ALLOW_THREADS
938 chunksize
= BZ2_bzRead(&bzerror
, self
->fp
,
940 self
->pos
+= chunksize
;
943 bytesread
+= chunksize
;
944 if (bzerror
== BZ_STREAM_END
) {
946 } else if (bzerror
!= BZ_OK
) {
947 Util_CatchBZ2Error(bzerror
);
951 self
->mode
= MODE_READ_EOF
;
952 self
->size
= self
->pos
;
955 offset
= self
->size
+ offset
;
956 } else if (where
== 1) {
957 offset
= self
->pos
+ offset
;
960 /* Before getting here, offset must be the absolute position the file
961 * pointer should be set to. */
963 if (offset
>= self
->pos
) {
964 /* we can move forward */
967 /* we cannot move back, so rewind the stream */
968 BZ2_bzReadClose(&bzerror
, self
->fp
);
969 if (bzerror
!= BZ_OK
) {
970 Util_CatchBZ2Error(bzerror
);
975 self
->fp
= BZ2_bzReadOpen(&bzerror
, self
->rawfp
,
977 if (bzerror
!= BZ_OK
) {
978 Util_CatchBZ2Error(bzerror
);
981 self
->mode
= MODE_READ
;
984 if (offset
<= 0 || self
->mode
== MODE_READ_EOF
)
987 /* Before getting here, offset must be set to the number of bytes
988 * to walk forward. */
990 if (offset
-bytesread
> buffersize
)
991 readsize
= buffersize
;
993 /* offset might be wider that readsize, but the result
994 * of the subtraction is bound by buffersize (see the
995 * condition above). buffersize is 8192. */
996 readsize
= (size_t)(offset
-bytesread
);
997 Py_BEGIN_ALLOW_THREADS
998 chunksize
= BZ2_bzRead(&bzerror
, self
->fp
, buffer
, readsize
);
999 self
->pos
+= chunksize
;
1000 Py_END_ALLOW_THREADS
1001 bytesread
+= chunksize
;
1002 if (bzerror
== BZ_STREAM_END
) {
1003 self
->size
= self
->pos
;
1004 self
->mode
= MODE_READ_EOF
;
1006 } else if (bzerror
!= BZ_OK
) {
1007 Util_CatchBZ2Error(bzerror
);
1010 if (bytesread
== offset
)
1023 PyDoc_STRVAR(BZ2File_tell__doc__
,
1026 Return the current file position, an integer (may be a long integer).\n\
1030 BZ2File_tell(BZ2FileObject
*self
, PyObject
*args
)
1032 PyObject
*ret
= NULL
;
1034 if (self
->mode
== MODE_CLOSED
) {
1035 PyErr_SetString(PyExc_ValueError
,
1036 "I/O operation on closed file");
1040 #if !defined(HAVE_LARGEFILE_SUPPORT)
1041 ret
= PyLong_FromLong(self
->pos
);
1043 ret
= PyLong_FromLongLong(self
->pos
);
1050 PyDoc_STRVAR(BZ2File_close__doc__
,
1051 "close() -> None or (perhaps) an integer\n\
1053 Close the file. Sets data attribute .closed to true. A closed file\n\
1054 cannot be used for further I/O operations. close() may be called more\n\
1055 than once without error.\n\
1059 BZ2File_close(BZ2FileObject
*self
)
1061 PyObject
*ret
= NULL
;
1062 int bzerror
= BZ_OK
;
1064 if (self
->mode
== MODE_CLOSED
) {
1069 switch (self
->mode
) {
1072 BZ2_bzReadClose(&bzerror
, self
->fp
);
1075 BZ2_bzWriteClose(&bzerror
, self
->fp
,
1079 self
->mode
= MODE_CLOSED
;
1080 fclose(self
->rawfp
);
1082 if (bzerror
== BZ_OK
) {
1087 Util_CatchBZ2Error(bzerror
);
1094 PyDoc_STRVAR(BZ2File_enter_doc
,
1095 "__enter__() -> self.");
1098 BZ2File_enter(BZ2FileObject
*self
)
1100 if (self
->mode
== MODE_CLOSED
) {
1101 PyErr_SetString(PyExc_ValueError
,
1102 "I/O operation on closed file");
1106 return (PyObject
*) self
;
1109 PyDoc_STRVAR(BZ2File_exit_doc
,
1110 "__exit__(*excinfo) -> None. Closes the file.");
1113 BZ2File_exit(BZ2FileObject
*self
, PyObject
*args
)
1115 PyObject
*ret
= PyObject_CallMethod((PyObject
*) self
, "close", NULL
);
1117 /* If error occurred, pass through */
1124 static PyObject
*BZ2File_getiter(BZ2FileObject
*self
);
1126 static PyMethodDef BZ2File_methods
[] = {
1127 {"read", (PyCFunction
)BZ2File_read
, METH_VARARGS
, BZ2File_read__doc__
},
1128 {"readline", (PyCFunction
)BZ2File_readline
, METH_VARARGS
, BZ2File_readline__doc__
},
1129 {"readlines", (PyCFunction
)BZ2File_readlines
, METH_VARARGS
, BZ2File_readlines__doc__
},
1130 {"write", (PyCFunction
)BZ2File_write
, METH_VARARGS
, BZ2File_write__doc__
},
1131 {"writelines", (PyCFunction
)BZ2File_writelines
, METH_O
, BZ2File_writelines__doc__
},
1132 {"seek", (PyCFunction
)BZ2File_seek
, METH_VARARGS
, BZ2File_seek__doc__
},
1133 {"tell", (PyCFunction
)BZ2File_tell
, METH_NOARGS
, BZ2File_tell__doc__
},
1134 {"close", (PyCFunction
)BZ2File_close
, METH_NOARGS
, BZ2File_close__doc__
},
1135 {"__enter__", (PyCFunction
)BZ2File_enter
, METH_NOARGS
, BZ2File_enter_doc
},
1136 {"__exit__", (PyCFunction
)BZ2File_exit
, METH_VARARGS
, BZ2File_exit_doc
},
1137 {NULL
, NULL
} /* sentinel */
1141 /* ===================================================================== */
1142 /* Getters and setters of BZ2File. */
1145 BZ2File_get_closed(BZ2FileObject
*self
, void *closure
)
1147 return PyLong_FromLong(self
->mode
== MODE_CLOSED
);
1150 static PyGetSetDef BZ2File_getset
[] = {
1151 {"closed", (getter
)BZ2File_get_closed
, NULL
,
1152 "True if the file is closed"},
1153 {NULL
} /* Sentinel */
1157 /* ===================================================================== */
1158 /* Slot definitions for BZ2File_Type. */
1161 BZ2File_init(BZ2FileObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1163 static char *kwlist
[] = {"filename", "mode", "buffering",
1164 "compresslevel", 0};
1165 PyObject
*name_obj
= NULL
;
1169 int compresslevel
= 9;
1175 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O&|sii:BZ2File",
1176 kwlist
, PyUnicode_FSConverter
, &name_obj
,
1181 if (PyBytes_Check(name_obj
))
1182 name
= PyBytes_AsString(name_obj
);
1184 name
= PyByteArray_AsString(name_obj
);
1185 if (compresslevel
< 1 || compresslevel
> 9) {
1186 PyErr_SetString(PyExc_ValueError
,
1187 "compresslevel must be between 1 and 9");
1188 Py_DECREF(name_obj
);
1210 PyErr_Format(PyExc_ValueError
,
1211 "invalid mode char %c", *mode
);
1212 Py_DECREF(name_obj
);
1220 if (mode_char
== 0) {
1224 mode
= (mode_char
== 'r') ? "rb" : "wb";
1226 self
->rawfp
= fopen(name
, mode
);
1227 Py_DECREF(name_obj
);
1228 if (self
->rawfp
== NULL
) {
1229 PyErr_SetFromErrno(PyExc_IOError
);
1232 /* XXX Ignore buffering */
1234 /* From now on, we have stuff to dealloc, so jump to error label
1235 * instead of returning */
1238 self
->lock
= PyThread_allocate_lock();
1240 PyErr_SetString(PyExc_MemoryError
, "unable to allocate lock");
1245 if (mode_char
== 'r')
1246 self
->fp
= BZ2_bzReadOpen(&bzerror
, self
->rawfp
,
1249 self
->fp
= BZ2_bzWriteOpen(&bzerror
, self
->rawfp
,
1250 compresslevel
, 0, 0);
1252 if (bzerror
!= BZ_OK
) {
1253 Util_CatchBZ2Error(bzerror
);
1257 self
->mode
= (mode_char
== 'r') ? MODE_READ
: MODE_WRITE
;
1262 fclose(self
->rawfp
);
1266 PyThread_free_lock(self
->lock
);
1274 BZ2File_dealloc(BZ2FileObject
*self
)
1279 PyThread_free_lock(self
->lock
);
1281 switch (self
->mode
) {
1284 BZ2_bzReadClose(&bzerror
, self
->fp
);
1287 BZ2_bzWriteClose(&bzerror
, self
->fp
,
1291 Util_DropReadAhead(self
);
1292 if (self
->rawfp
!= NULL
)
1293 fclose(self
->rawfp
);
1294 Py_TYPE(self
)->tp_free((PyObject
*)self
);
1297 /* This is a hacked version of Python's fileobject.c:file_getiter(). */
1299 BZ2File_getiter(BZ2FileObject
*self
)
1301 if (self
->mode
== MODE_CLOSED
) {
1302 PyErr_SetString(PyExc_ValueError
,
1303 "I/O operation on closed file");
1306 Py_INCREF((PyObject
*)self
);
1307 return (PyObject
*)self
;
1310 /* This is a hacked version of Python's fileobject.c:file_iternext(). */
1311 #define READAHEAD_BUFSIZE 8192
1313 BZ2File_iternext(BZ2FileObject
*self
)
1317 if (self
->mode
== MODE_CLOSED
) {
1319 PyErr_SetString(PyExc_ValueError
,
1320 "I/O operation on closed file");
1323 ret
= Util_ReadAheadGetLineSkip(self
, 0, READAHEAD_BUFSIZE
);
1325 if (ret
== NULL
|| PyBytes_GET_SIZE(ret
) == 0) {
1329 return (PyObject
*)ret
;
1332 /* ===================================================================== */
1333 /* BZ2File_Type definition. */
1335 PyDoc_VAR(BZ2File__doc__
) =
1337 "BZ2File(name [, mode='r', buffering=0, compresslevel=9]) -> file object\n\
1339 Open a bz2 file. The mode can be 'r' or 'w', for reading (default) or\n\
1340 writing. When opened for writing, the file will be created if it doesn't\n\
1341 exist, and truncated otherwise. If the buffering argument is given, 0 means\n\
1342 unbuffered, and larger numbers specify the buffer size. If compresslevel\n\
1343 is given, must be a number between 1 and 9.\n\
1344 Data read is always returned in bytes; data written ought to be bytes.\n\
1347 static PyTypeObject BZ2File_Type
= {
1348 PyVarObject_HEAD_INIT(NULL
, 0)
1349 "bz2.BZ2File", /*tp_name*/
1350 sizeof(BZ2FileObject
), /*tp_basicsize*/
1352 (destructor
)BZ2File_dealloc
, /*tp_dealloc*/
1359 0, /*tp_as_sequence*/
1360 0, /*tp_as_mapping*/
1364 PyObject_GenericGetAttr
,/*tp_getattro*/
1365 PyObject_GenericSetAttr
,/*tp_setattro*/
1367 Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
, /*tp_flags*/
1368 BZ2File__doc__
, /*tp_doc*/
1371 0, /*tp_richcompare*/
1372 0, /*tp_weaklistoffset*/
1373 (getiterfunc
)BZ2File_getiter
, /*tp_iter*/
1374 (iternextfunc
)BZ2File_iternext
, /*tp_iternext*/
1375 BZ2File_methods
, /*tp_methods*/
1377 BZ2File_getset
, /*tp_getset*/
1382 0, /*tp_dictoffset*/
1383 (initproc
)BZ2File_init
, /*tp_init*/
1384 PyType_GenericAlloc
, /*tp_alloc*/
1385 PyType_GenericNew
, /*tp_new*/
1386 PyObject_Free
, /*tp_free*/
1391 /* ===================================================================== */
1392 /* Methods of BZ2Comp. */
1394 PyDoc_STRVAR(BZ2Comp_compress__doc__
,
1395 "compress(data) -> string\n\
1397 Provide more data to the compressor object. It will return chunks of\n\
1398 compressed data whenever possible. When you've finished providing data\n\
1399 to compress, call the flush() method to finish the compression process,\n\
1400 and return what is left in the internal buffers.\n\
1404 BZ2Comp_compress(BZ2CompObject
*self
, PyObject
*args
)
1409 int bufsize
= SMALLCHUNK
;
1410 PY_LONG_LONG totalout
;
1411 PyObject
*ret
= NULL
;
1412 bz_stream
*bzs
= &self
->bzs
;
1415 if (!PyArg_ParseTuple(args
, "y*:compress", &pdata
))
1418 datasize
= pdata
.len
;
1420 if (datasize
== 0) {
1421 PyBuffer_Release(&pdata
);
1422 return PyBytes_FromStringAndSize("", 0);
1426 if (!self
->running
) {
1427 PyErr_SetString(PyExc_ValueError
,
1428 "this object was already flushed");
1432 ret
= PyBytes_FromStringAndSize(NULL
, bufsize
);
1436 bzs
->next_in
= data
;
1437 bzs
->avail_in
= datasize
;
1438 bzs
->next_out
= BUF(ret
);
1439 bzs
->avail_out
= bufsize
;
1441 totalout
= BZS_TOTAL_OUT(bzs
);
1444 Py_BEGIN_ALLOW_THREADS
1445 bzerror
= BZ2_bzCompress(bzs
, BZ_RUN
);
1446 Py_END_ALLOW_THREADS
1447 if (bzerror
!= BZ_RUN_OK
) {
1448 Util_CatchBZ2Error(bzerror
);
1451 if (bzs
->avail_in
== 0)
1452 break; /* no more input data */
1453 if (bzs
->avail_out
== 0) {
1454 bufsize
= Util_NewBufferSize(bufsize
);
1455 if (_PyBytes_Resize(&ret
, bufsize
) < 0) {
1456 BZ2_bzCompressEnd(bzs
);
1459 bzs
->next_out
= BUF(ret
) + (BZS_TOTAL_OUT(bzs
)
1461 bzs
->avail_out
= bufsize
- (bzs
->next_out
- BUF(ret
));
1465 if (_PyBytes_Resize(&ret
,
1466 (Py_ssize_t
)(BZS_TOTAL_OUT(bzs
) - totalout
)) < 0)
1470 PyBuffer_Release(&pdata
);
1475 PyBuffer_Release(&pdata
);
1480 PyDoc_STRVAR(BZ2Comp_flush__doc__
,
1481 "flush() -> string\n\
1483 Finish the compression process and return what is left in internal buffers.\n\
1484 You must not use the compressor object after calling this method.\n\
1488 BZ2Comp_flush(BZ2CompObject
*self
)
1490 int bufsize
= SMALLCHUNK
;
1491 PyObject
*ret
= NULL
;
1492 bz_stream
*bzs
= &self
->bzs
;
1493 PY_LONG_LONG totalout
;
1497 if (!self
->running
) {
1498 PyErr_SetString(PyExc_ValueError
, "object was already "
1504 ret
= PyBytes_FromStringAndSize(NULL
, bufsize
);
1508 bzs
->next_out
= BUF(ret
);
1509 bzs
->avail_out
= bufsize
;
1511 totalout
= BZS_TOTAL_OUT(bzs
);
1514 Py_BEGIN_ALLOW_THREADS
1515 bzerror
= BZ2_bzCompress(bzs
, BZ_FINISH
);
1516 Py_END_ALLOW_THREADS
1517 if (bzerror
== BZ_STREAM_END
) {
1519 } else if (bzerror
!= BZ_FINISH_OK
) {
1520 Util_CatchBZ2Error(bzerror
);
1523 if (bzs
->avail_out
== 0) {
1524 bufsize
= Util_NewBufferSize(bufsize
);
1525 if (_PyBytes_Resize(&ret
, bufsize
) < 0)
1527 bzs
->next_out
= BUF(ret
);
1528 bzs
->next_out
= BUF(ret
) + (BZS_TOTAL_OUT(bzs
)
1530 bzs
->avail_out
= bufsize
- (bzs
->next_out
- BUF(ret
));
1534 if (bzs
->avail_out
!= 0) {
1535 if (_PyBytes_Resize(&ret
,
1536 (Py_ssize_t
)(BZS_TOTAL_OUT(bzs
) - totalout
)) < 0)
1549 static PyMethodDef BZ2Comp_methods
[] = {
1550 {"compress", (PyCFunction
)BZ2Comp_compress
, METH_VARARGS
,
1551 BZ2Comp_compress__doc__
},
1552 {"flush", (PyCFunction
)BZ2Comp_flush
, METH_NOARGS
,
1553 BZ2Comp_flush__doc__
},
1554 {NULL
, NULL
} /* sentinel */
1558 /* ===================================================================== */
1559 /* Slot definitions for BZ2Comp_Type. */
1562 BZ2Comp_init(BZ2CompObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1564 int compresslevel
= 9;
1566 static char *kwlist
[] = {"compresslevel", 0};
1568 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:BZ2Compressor",
1569 kwlist
, &compresslevel
))
1572 if (compresslevel
< 1 || compresslevel
> 9) {
1573 PyErr_SetString(PyExc_ValueError
,
1574 "compresslevel must be between 1 and 9");
1579 self
->lock
= PyThread_allocate_lock();
1581 PyErr_SetString(PyExc_MemoryError
, "unable to allocate lock");
1586 memset(&self
->bzs
, 0, sizeof(bz_stream
));
1587 bzerror
= BZ2_bzCompressInit(&self
->bzs
, compresslevel
, 0, 0);
1588 if (bzerror
!= BZ_OK
) {
1589 Util_CatchBZ2Error(bzerror
);
1599 PyThread_free_lock(self
->lock
);
1607 BZ2Comp_dealloc(BZ2CompObject
*self
)
1611 PyThread_free_lock(self
->lock
);
1613 BZ2_bzCompressEnd(&self
->bzs
);
1614 Py_TYPE(self
)->tp_free((PyObject
*)self
);
1618 /* ===================================================================== */
1619 /* BZ2Comp_Type definition. */
1621 PyDoc_STRVAR(BZ2Comp__doc__
,
1622 "BZ2Compressor([compresslevel=9]) -> compressor object\n\
1624 Create a new compressor object. This object may be used to compress\n\
1625 data sequentially. If you want to compress data in one shot, use the\n\
1626 compress() function instead. The compresslevel parameter, if given,\n\
1627 must be a number between 1 and 9.\n\
1630 static PyTypeObject BZ2Comp_Type
= {
1631 PyVarObject_HEAD_INIT(NULL
, 0)
1632 "bz2.BZ2Compressor", /*tp_name*/
1633 sizeof(BZ2CompObject
), /*tp_basicsize*/
1635 (destructor
)BZ2Comp_dealloc
, /*tp_dealloc*/
1642 0, /*tp_as_sequence*/
1643 0, /*tp_as_mapping*/
1647 PyObject_GenericGetAttr
,/*tp_getattro*/
1648 PyObject_GenericSetAttr
,/*tp_setattro*/
1650 Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
, /*tp_flags*/
1651 BZ2Comp__doc__
, /*tp_doc*/
1654 0, /*tp_richcompare*/
1655 0, /*tp_weaklistoffset*/
1658 BZ2Comp_methods
, /*tp_methods*/
1665 0, /*tp_dictoffset*/
1666 (initproc
)BZ2Comp_init
, /*tp_init*/
1667 PyType_GenericAlloc
, /*tp_alloc*/
1668 PyType_GenericNew
, /*tp_new*/
1669 PyObject_Free
, /*tp_free*/
1674 /* ===================================================================== */
1675 /* Members of BZ2Decomp. */
1678 #define OFF(x) offsetof(BZ2DecompObject, x)
1680 static PyMemberDef BZ2Decomp_members
[] = {
1681 {"unused_data", T_OBJECT
, OFF(unused_data
), READONLY
},
1682 {NULL
} /* Sentinel */
1686 /* ===================================================================== */
1687 /* Methods of BZ2Decomp. */
1689 PyDoc_STRVAR(BZ2Decomp_decompress__doc__
,
1690 "decompress(data) -> string\n\
1692 Provide more data to the decompressor object. It will return chunks\n\
1693 of decompressed data whenever possible. If you try to decompress data\n\
1694 after the end of stream is found, EOFError will be raised. If any data\n\
1695 was found after the end of stream, it'll be ignored and saved in\n\
1696 unused_data attribute.\n\
1700 BZ2Decomp_decompress(BZ2DecompObject
*self
, PyObject
*args
)
1705 int bufsize
= SMALLCHUNK
;
1706 PY_LONG_LONG totalout
;
1707 PyObject
*ret
= NULL
;
1708 bz_stream
*bzs
= &self
->bzs
;
1711 if (!PyArg_ParseTuple(args
, "y*:decompress", &pdata
))
1714 datasize
= pdata
.len
;
1717 if (!self
->running
) {
1718 PyErr_SetString(PyExc_EOFError
, "end of stream was "
1723 ret
= PyBytes_FromStringAndSize(NULL
, bufsize
);
1727 bzs
->next_in
= data
;
1728 bzs
->avail_in
= datasize
;
1729 bzs
->next_out
= BUF(ret
);
1730 bzs
->avail_out
= bufsize
;
1732 totalout
= BZS_TOTAL_OUT(bzs
);
1735 Py_BEGIN_ALLOW_THREADS
1736 bzerror
= BZ2_bzDecompress(bzs
);
1737 Py_END_ALLOW_THREADS
1738 if (bzerror
== BZ_STREAM_END
) {
1739 if (bzs
->avail_in
!= 0) {
1740 Py_DECREF(self
->unused_data
);
1742 PyBytes_FromStringAndSize(bzs
->next_in
,
1748 if (bzerror
!= BZ_OK
) {
1749 Util_CatchBZ2Error(bzerror
);
1752 if (bzs
->avail_in
== 0)
1753 break; /* no more input data */
1754 if (bzs
->avail_out
== 0) {
1755 bufsize
= Util_NewBufferSize(bufsize
);
1756 if (_PyBytes_Resize(&ret
, bufsize
) < 0) {
1757 BZ2_bzDecompressEnd(bzs
);
1760 bzs
->next_out
= BUF(ret
);
1761 bzs
->next_out
= BUF(ret
) + (BZS_TOTAL_OUT(bzs
)
1763 bzs
->avail_out
= bufsize
- (bzs
->next_out
- BUF(ret
));
1767 if (bzs
->avail_out
!= 0) {
1768 if (_PyBytes_Resize(&ret
,
1769 (Py_ssize_t
)(BZS_TOTAL_OUT(bzs
) - totalout
)) < 0)
1774 PyBuffer_Release(&pdata
);
1779 PyBuffer_Release(&pdata
);
1784 static PyMethodDef BZ2Decomp_methods
[] = {
1785 {"decompress", (PyCFunction
)BZ2Decomp_decompress
, METH_VARARGS
, BZ2Decomp_decompress__doc__
},
1786 {NULL
, NULL
} /* sentinel */
1790 /* ===================================================================== */
1791 /* Slot definitions for BZ2Decomp_Type. */
1794 BZ2Decomp_init(BZ2DecompObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1798 if (!PyArg_ParseTuple(args
, ":BZ2Decompressor"))
1802 self
->lock
= PyThread_allocate_lock();
1804 PyErr_SetString(PyExc_MemoryError
, "unable to allocate lock");
1809 self
->unused_data
= PyBytes_FromStringAndSize("", 0);
1810 if (!self
->unused_data
)
1813 memset(&self
->bzs
, 0, sizeof(bz_stream
));
1814 bzerror
= BZ2_bzDecompressInit(&self
->bzs
, 0, 0);
1815 if (bzerror
!= BZ_OK
) {
1816 Util_CatchBZ2Error(bzerror
);
1827 PyThread_free_lock(self
->lock
);
1831 Py_CLEAR(self
->unused_data
);
1836 BZ2Decomp_dealloc(BZ2DecompObject
*self
)
1840 PyThread_free_lock(self
->lock
);
1842 Py_XDECREF(self
->unused_data
);
1843 BZ2_bzDecompressEnd(&self
->bzs
);
1844 Py_TYPE(self
)->tp_free((PyObject
*)self
);
1848 /* ===================================================================== */
1849 /* BZ2Decomp_Type definition. */
1851 PyDoc_STRVAR(BZ2Decomp__doc__
,
1852 "BZ2Decompressor() -> decompressor object\n\
1854 Create a new decompressor object. This object may be used to decompress\n\
1855 data sequentially. If you want to decompress data in one shot, use the\n\
1856 decompress() function instead.\n\
1859 static PyTypeObject BZ2Decomp_Type
= {
1860 PyVarObject_HEAD_INIT(NULL
, 0)
1861 "bz2.BZ2Decompressor", /*tp_name*/
1862 sizeof(BZ2DecompObject
), /*tp_basicsize*/
1864 (destructor
)BZ2Decomp_dealloc
, /*tp_dealloc*/
1871 0, /*tp_as_sequence*/
1872 0, /*tp_as_mapping*/
1876 PyObject_GenericGetAttr
,/*tp_getattro*/
1877 PyObject_GenericSetAttr
,/*tp_setattro*/
1879 Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
, /*tp_flags*/
1880 BZ2Decomp__doc__
, /*tp_doc*/
1883 0, /*tp_richcompare*/
1884 0, /*tp_weaklistoffset*/
1887 BZ2Decomp_methods
, /*tp_methods*/
1888 BZ2Decomp_members
, /*tp_members*/
1894 0, /*tp_dictoffset*/
1895 (initproc
)BZ2Decomp_init
, /*tp_init*/
1896 PyType_GenericAlloc
, /*tp_alloc*/
1897 PyType_GenericNew
, /*tp_new*/
1898 PyObject_Free
, /*tp_free*/
1903 /* ===================================================================== */
1904 /* Module functions. */
1906 PyDoc_STRVAR(bz2_compress__doc__
,
1907 "compress(data [, compresslevel=9]) -> string\n\
1909 Compress data in one shot. If you want to compress data sequentially,\n\
1910 use an instance of BZ2Compressor instead. The compresslevel parameter, if\n\
1911 given, must be a number between 1 and 9.\n\
1915 bz2_compress(PyObject
*self
, PyObject
*args
, PyObject
*kwargs
)
1917 int compresslevel
=9;
1922 PyObject
*ret
= NULL
;
1924 bz_stream
*bzs
= &_bzs
;
1926 static char *kwlist
[] = {"data", "compresslevel", 0};
1928 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "y*|i",
1933 datasize
= pdata
.len
;
1935 if (compresslevel
< 1 || compresslevel
> 9) {
1936 PyErr_SetString(PyExc_ValueError
,
1937 "compresslevel must be between 1 and 9");
1938 PyBuffer_Release(&pdata
);
1942 /* Conforming to bz2 manual, this is large enough to fit compressed
1943 * data in one shot. We will check it later anyway. */
1944 bufsize
= datasize
+ (datasize
/100+1) + 600;
1946 ret
= PyBytes_FromStringAndSize(NULL
, bufsize
);
1948 PyBuffer_Release(&pdata
);
1952 memset(bzs
, 0, sizeof(bz_stream
));
1954 bzs
->next_in
= data
;
1955 bzs
->avail_in
= datasize
;
1956 bzs
->next_out
= BUF(ret
);
1957 bzs
->avail_out
= bufsize
;
1959 bzerror
= BZ2_bzCompressInit(bzs
, compresslevel
, 0, 0);
1960 if (bzerror
!= BZ_OK
) {
1961 Util_CatchBZ2Error(bzerror
);
1962 PyBuffer_Release(&pdata
);
1968 Py_BEGIN_ALLOW_THREADS
1969 bzerror
= BZ2_bzCompress(bzs
, BZ_FINISH
);
1970 Py_END_ALLOW_THREADS
1971 if (bzerror
== BZ_STREAM_END
) {
1973 } else if (bzerror
!= BZ_FINISH_OK
) {
1974 BZ2_bzCompressEnd(bzs
);
1975 Util_CatchBZ2Error(bzerror
);
1976 PyBuffer_Release(&pdata
);
1980 if (bzs
->avail_out
== 0) {
1981 bufsize
= Util_NewBufferSize(bufsize
);
1982 if (_PyBytes_Resize(&ret
, bufsize
) < 0) {
1983 BZ2_bzCompressEnd(bzs
);
1984 PyBuffer_Release(&pdata
);
1987 bzs
->next_out
= BUF(ret
) + BZS_TOTAL_OUT(bzs
);
1988 bzs
->avail_out
= bufsize
- (bzs
->next_out
- BUF(ret
));
1992 if (bzs
->avail_out
!= 0) {
1993 if (_PyBytes_Resize(&ret
, (Py_ssize_t
)BZS_TOTAL_OUT(bzs
)) < 0) {
1997 BZ2_bzCompressEnd(bzs
);
1999 PyBuffer_Release(&pdata
);
2003 PyDoc_STRVAR(bz2_decompress__doc__
,
2004 "decompress(data) -> decompressed data\n\
2006 Decompress data in one shot. If you want to decompress data sequentially,\n\
2007 use an instance of BZ2Decompressor instead.\n\
2011 bz2_decompress(PyObject
*self
, PyObject
*args
)
2016 int bufsize
= SMALLCHUNK
;
2019 bz_stream
*bzs
= &_bzs
;
2022 if (!PyArg_ParseTuple(args
, "y*:decompress", &pdata
))
2025 datasize
= pdata
.len
;
2027 if (datasize
== 0) {
2028 PyBuffer_Release(&pdata
);
2029 return PyBytes_FromStringAndSize("", 0);
2032 ret
= PyBytes_FromStringAndSize(NULL
, bufsize
);
2034 PyBuffer_Release(&pdata
);
2038 memset(bzs
, 0, sizeof(bz_stream
));
2040 bzs
->next_in
= data
;
2041 bzs
->avail_in
= datasize
;
2042 bzs
->next_out
= BUF(ret
);
2043 bzs
->avail_out
= bufsize
;
2045 bzerror
= BZ2_bzDecompressInit(bzs
, 0, 0);
2046 if (bzerror
!= BZ_OK
) {
2047 Util_CatchBZ2Error(bzerror
);
2049 PyBuffer_Release(&pdata
);
2054 Py_BEGIN_ALLOW_THREADS
2055 bzerror
= BZ2_bzDecompress(bzs
);
2056 Py_END_ALLOW_THREADS
2057 if (bzerror
== BZ_STREAM_END
) {
2059 } else if (bzerror
!= BZ_OK
) {
2060 BZ2_bzDecompressEnd(bzs
);
2061 Util_CatchBZ2Error(bzerror
);
2062 PyBuffer_Release(&pdata
);
2066 if (bzs
->avail_in
== 0) {
2067 BZ2_bzDecompressEnd(bzs
);
2068 PyErr_SetString(PyExc_ValueError
,
2069 "couldn't find end of stream");
2070 PyBuffer_Release(&pdata
);
2074 if (bzs
->avail_out
== 0) {
2075 bufsize
= Util_NewBufferSize(bufsize
);
2076 if (_PyBytes_Resize(&ret
, bufsize
) < 0) {
2077 BZ2_bzDecompressEnd(bzs
);
2078 PyBuffer_Release(&pdata
);
2081 bzs
->next_out
= BUF(ret
) + BZS_TOTAL_OUT(bzs
);
2082 bzs
->avail_out
= bufsize
- (bzs
->next_out
- BUF(ret
));
2086 if (bzs
->avail_out
!= 0) {
2087 if (_PyBytes_Resize(&ret
, (Py_ssize_t
)BZS_TOTAL_OUT(bzs
)) < 0) {
2091 BZ2_bzDecompressEnd(bzs
);
2092 PyBuffer_Release(&pdata
);
2097 static PyMethodDef bz2_methods
[] = {
2098 {"compress", (PyCFunction
) bz2_compress
, METH_VARARGS
|METH_KEYWORDS
,
2099 bz2_compress__doc__
},
2100 {"decompress", (PyCFunction
) bz2_decompress
, METH_VARARGS
,
2101 bz2_decompress__doc__
},
2102 {NULL
, NULL
} /* sentinel */
2105 /* ===================================================================== */
2106 /* Initialization function. */
2108 PyDoc_STRVAR(bz2__doc__
,
2109 "The python bz2 module provides a comprehensive interface for\n\
2110 the bz2 compression library. It implements a complete file\n\
2111 interface, one shot (de)compression functions, and types for\n\
2112 sequential (de)compression.\n\
2116 static struct PyModuleDef bz2module
= {
2117 PyModuleDef_HEAD_INIT
,
2133 Py_TYPE(&BZ2File_Type
) = &PyType_Type
;
2134 Py_TYPE(&BZ2Comp_Type
) = &PyType_Type
;
2135 Py_TYPE(&BZ2Decomp_Type
) = &PyType_Type
;
2137 m
= PyModule_Create(&bz2module
);
2141 PyModule_AddObject(m
, "__author__", PyUnicode_FromString(__author__
));
2143 Py_INCREF(&BZ2File_Type
);
2144 PyModule_AddObject(m
, "BZ2File", (PyObject
*)&BZ2File_Type
);
2146 Py_INCREF(&BZ2Comp_Type
);
2147 PyModule_AddObject(m
, "BZ2Compressor", (PyObject
*)&BZ2Comp_Type
);
2149 Py_INCREF(&BZ2Decomp_Type
);
2150 PyModule_AddObject(m
, "BZ2Decompressor", (PyObject
*)&BZ2Decomp_Type
);