Ignore:
Timestamp:
Mar 19, 2014, 11:11:30 AM (11 years ago)
Author:
dmik
Message:

python: Update vendor to 2.7.6.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • python/vendor/current/Modules/bz2module.c

    r2 r388  
    4242#define MODE_WRITE    3
    4343
    44 #define BZ2FileObject_Check(v)  (Py_TYPE(v) == &BZ2File_Type)
    45 
    46 
    47 #ifdef BZ_CONFIG_ERROR
    48 
    49 #if SIZEOF_LONG >= 8
    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)
    55 #else
    56 #define BZS_TOTAL_OUT(bzs) \
    57         bzs->total_out_lo32
    58 #endif
    59 
    60 #else /* ! BZ_CONFIG_ERROR */
     44
     45#ifndef BZ_CONFIG_ERROR
    6146
    6247#define BZ2_bzRead bzRead
     
    7358#define BZ2_bzDecompressEnd bzDecompressEnd
    7459
    75 #define BZS_TOTAL_OUT(bzs) bzs->total_out
    76 
    7760#endif /* ! BZ_CONFIG_ERROR */
    7861
     
    8063#ifdef WITH_THREAD
    8164#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 \
    86         } } while(0)
     65    if (!PyThread_acquire_lock(obj->lock, 0)) { \
     66        Py_BEGIN_ALLOW_THREADS \
     67        PyThread_acquire_lock(obj->lock, 1); \
     68        Py_END_ALLOW_THREADS \
     69    } } while(0)
    8770#define RELEASE_LOCK(obj) PyThread_release_lock(obj->lock)
    8871#else
     
    9174#endif
    9275
     76#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
     77
    9378/* 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 */
     79#define NEWLINE_UNKNOWN 0       /* No newline seen, yet */
     80#define NEWLINE_CR 1            /* \r newline seen */
     81#define NEWLINE_LF 2            /* \n newline seen */
     82#define NEWLINE_CRLF 4          /* \r\n newline seen */
    9883
    9984/* ===================================================================== */
     
    10186
    10287typedef struct {
    103         PyObject_HEAD
    104         PyObject *file;
    105 
    106         char* f_buf;            /* Allocated readahead buffer */
    107         char* f_bufend;         /* Points after last occupied position */
    108         char* f_bufptr;         /* Current buffer position */
    109 
    110         int f_softspace;        /* Flag used by 'print' command */
    111 
    112         int f_univ_newline;     /* Handle any newline convention */
    113         int f_newlinetypes;     /* Types of newlines seen */
    114         int f_skipnextlf;       /* Skip next \n */
    115 
    116         BZFILE *fp;
    117         int mode;
    118         Py_off_t pos;
    119         Py_off_t size;
     88    PyObject_HEAD
     89    PyObject *file;
     90
     91    char* f_buf;                /* Allocated readahead buffer */
     92    char* f_bufend;             /* Points after last occupied position */
     93    char* f_bufptr;             /* Current buffer position */
     94
     95    int f_softspace;            /* Flag used by 'print' command */
     96
     97    int f_univ_newline;         /* Handle any newline convention */
     98    int f_newlinetypes;         /* Types of newlines seen */
     99    int f_skipnextlf;           /* Skip next \n */
     100
     101    BZFILE *fp;
     102    int mode;
     103    Py_off_t pos;
     104    Py_off_t size;
    120105#ifdef WITH_THREAD
    121         PyThread_type_lock lock;
     106    PyThread_type_lock lock;
    122107#endif
    123108} BZ2FileObject;
    124109
    125110typedef struct {
    126         PyObject_HEAD
    127         bz_stream bzs;
    128         int running;
     111    PyObject_HEAD
     112    bz_stream bzs;
     113    int running;
    129114#ifdef WITH_THREAD
    130         PyThread_type_lock lock;
     115    PyThread_type_lock lock;
    131116#endif
    132117} BZ2CompObject;
    133118
    134119typedef struct {
    135         PyObject_HEAD
    136         bz_stream bzs;
    137         int running;
    138         PyObject *unused_data;
     120    PyObject_HEAD
     121    bz_stream bzs;
     122    int running;
     123    PyObject *unused_data;
    139124#ifdef WITH_THREAD
    140         PyThread_type_lock lock;
     125    PyThread_type_lock lock;
    141126#endif
    142127} BZ2DecompObject;
     
    145130/* Utility functions. */
    146131
     132/* Refuse regular I/O if there's data in the iteration-buffer.
     133 * Mixing them would cause data to arrive out of order, as the read*
     134 * methods don't use the iteration buffer. */
     135static int
     136check_iterbuffered(BZ2FileObject *f)
     137{
     138    if (f->f_buf != NULL &&
     139        (f->f_bufend - f->f_bufptr) > 0 &&
     140        f->f_buf[0] != '\0') {
     141        PyErr_SetString(PyExc_ValueError,
     142            "Mixing iteration and read methods would lose data");
     143        return -1;
     144    }
     145    return 0;
     146}
     147
    147148static int
    148149Util_CatchBZ2Error(int bzerror)
    149150{
    150         int ret = 0;
    151         switch(bzerror) {
    152                 case BZ_OK:
    153                 case BZ_STREAM_END:
    154                         break;
     151    int ret = 0;
     152    switch(bzerror) {
     153        case BZ_OK:
     154        case BZ_STREAM_END:
     155            break;
    155156
    156157#ifdef BZ_CONFIG_ERROR
    157                 case BZ_CONFIG_ERROR:
    158                         PyErr_SetString(PyExc_SystemError,
    159                                         "the bz2 library was not compiled "
    160                                         "correctly");
    161                         ret = 1;
    162                         break;
     158        case BZ_CONFIG_ERROR:
     159            PyErr_SetString(PyExc_SystemError,
     160                            "the bz2 library was not compiled "
     161                            "correctly");
     162            ret = 1;
     163            break;
    163164#endif
    164165
    165                 case BZ_PARAM_ERROR:
    166                         PyErr_SetString(PyExc_ValueError,
    167                                         "the bz2 library has received wrong "
    168                                         "parameters");
    169                         ret = 1;
    170                         break;
    171 
    172                 case BZ_MEM_ERROR:
    173                         PyErr_NoMemory();
    174                         ret = 1;
    175                         break;
    176 
    177                 case BZ_DATA_ERROR:
    178                 case BZ_DATA_ERROR_MAGIC:
    179                         PyErr_SetString(PyExc_IOError, "invalid data stream");
    180                         ret = 1;
    181                         break;
    182 
    183                 case BZ_IO_ERROR:
    184                         PyErr_SetString(PyExc_IOError, "unknown IO error");
    185                         ret = 1;
    186                         break;
    187 
    188                 case BZ_UNEXPECTED_EOF:
    189                         PyErr_SetString(PyExc_EOFError,
    190                                         "compressed file ended before the "
    191                                         "logical end-of-stream was detected");
    192                         ret = 1;
    193                         break;
    194 
    195                 case BZ_SEQUENCE_ERROR:
    196                         PyErr_SetString(PyExc_RuntimeError,
    197                                         "wrong sequence of bz2 library "
    198                                         "commands used");
    199                         ret = 1;
    200                         break;
    201         }
    202         return ret;
     166        case BZ_PARAM_ERROR:
     167            PyErr_SetString(PyExc_ValueError,
     168                            "the bz2 library has received wrong "
     169                            "parameters");
     170            ret = 1;
     171            break;
     172
     173        case BZ_MEM_ERROR:
     174            PyErr_NoMemory();
     175            ret = 1;
     176            break;
     177
     178        case BZ_DATA_ERROR:
     179        case BZ_DATA_ERROR_MAGIC:
     180            PyErr_SetString(PyExc_IOError, "invalid data stream");
     181            ret = 1;
     182            break;
     183
     184        case BZ_IO_ERROR:
     185            PyErr_SetString(PyExc_IOError, "unknown IO error");
     186            ret = 1;
     187            break;
     188
     189        case BZ_UNEXPECTED_EOF:
     190            PyErr_SetString(PyExc_EOFError,
     191                            "compressed file ended before the "
     192                            "logical end-of-stream was detected");
     193            ret = 1;
     194            break;
     195
     196        case BZ_SEQUENCE_ERROR:
     197            PyErr_SetString(PyExc_RuntimeError,
     198                            "wrong sequence of bz2 library "
     199                            "commands used");
     200            ret = 1;
     201            break;
     202    }
     203    return ret;
    203204}
    204205
     
    209210#endif
    210211
    211 #if SIZEOF_INT < 4
    212 #define BIGCHUNK  (512 * 32)
    213 #else
    214 #define BIGCHUNK  (512 * 1024)
    215 #endif
    216 
    217212/* This is a hacked version of Python's fileobject.c:new_buffersize(). */
    218213static size_t
    219214Util_NewBufferSize(size_t currentsize)
    220215{
    221         if (currentsize > SMALLCHUNK) {
    222                 /* Keep doubling until we reach BIGCHUNK;
    223                    then keep adding BIGCHUNK. */
    224                 if (currentsize <= BIGCHUNK)
    225                         return currentsize + currentsize;
    226                 else
    227                         return currentsize + BIGCHUNK;
    228         }
    229         return currentsize + SMALLCHUNK;
     216    /* Expand the buffer by an amount proportional to the current size,
     217       giving us amortized linear-time behavior. Use a less-than-double
     218       growth factor to avoid excessive allocation. */
     219    return currentsize + (currentsize >> 3) + 6;
     220}
     221
     222static int
     223Util_GrowBuffer(PyObject **buf)
     224{
     225    size_t size = PyString_GET_SIZE(*buf);
     226    size_t new_size = Util_NewBufferSize(size);
     227    if (new_size > size) {
     228        return _PyString_Resize(buf, new_size);
     229    } else {  /* overflow */
     230        PyErr_SetString(PyExc_OverflowError,
     231                        "Unable to allocate buffer - output too large");
     232        return -1;
     233    }
    230234}
    231235
     
    234238Util_GetLine(BZ2FileObject *f, int n)
    235239{
    236         char c;
    237         char *buf, *end;
    238         size_t total_v_size;    /* total # of slots in buffer */
    239         size_t used_v_size;     /* # used slots in buffer */
    240         size_t increment;       /* amount to increment the buffer */
    241         PyObject *v;
    242         int bzerror;
    243         int bytes_read;
    244         int newlinetypes = f->f_newlinetypes;
    245         int skipnextlf = f->f_skipnextlf;
    246         int univ_newline = f->f_univ_newline;
    247 
    248         total_v_size = n > 0 ? n : 100;
    249         v = PyString_FromStringAndSize((char *)NULL, total_v_size);
    250         if (v == NULL)
    251                 return NULL;
    252 
    253         buf = BUF(v);
    254         end = buf + total_v_size;
    255 
    256         for (;;) {
    257                 Py_BEGIN_ALLOW_THREADS
    258                 while (buf != end) {
    259                         bytes_read = BZ2_bzRead(&bzerror, f->fp, &c, 1);
    260                         f->pos++;
    261                         if (bytes_read == 0) break;
    262                         if (univ_newline) {
    263                                 if (skipnextlf) {
    264                                         skipnextlf = 0;
    265                                         if (c == '\n') {
    266                                                 /* Seeing a \n here with skipnextlf true means we
    267                                                 * saw a \r before.
    268                                                 */
    269                                                 newlinetypes |= NEWLINE_CRLF;
    270                                                 if (bzerror != BZ_OK) break;
    271                                                 bytes_read = BZ2_bzRead(&bzerror, f->fp, &c, 1);
    272                                                 f->pos++;
    273                                                 if (bytes_read == 0) break;
    274                                         } else {
    275                                                 newlinetypes |= NEWLINE_CR;
    276                                         }
    277                                 }
    278                                 if (c == '\r') {
    279                                         skipnextlf = 1;
    280                                         c = '\n';
    281                                 } else if (c == '\n')
    282                                         newlinetypes |= NEWLINE_LF;
    283                         }
    284                         *buf++ = c;
    285                         if (bzerror != BZ_OK || c == '\n') break;
    286                 }
    287                 if (univ_newline && bzerror == BZ_STREAM_END && skipnextlf)
    288                         newlinetypes |= NEWLINE_CR;
    289                 Py_END_ALLOW_THREADS
    290                 f->f_newlinetypes = newlinetypes;
    291                 f->f_skipnextlf = skipnextlf;
    292                 if (bzerror == BZ_STREAM_END) {
    293                         f->size = f->pos;
    294                         f->mode = MODE_READ_EOF;
    295                         break;
    296                 } else if (bzerror != BZ_OK) {
    297                         Util_CatchBZ2Error(bzerror);
    298                         Py_DECREF(v);
    299                         return NULL;
    300                 }
    301                 if (c == '\n')
    302                         break;
    303                 /* Must be because buf == end */
    304                 if (n > 0)
    305                         break;
    306                 used_v_size = total_v_size;
    307                 increment = total_v_size >> 2; /* mild exponential growth */
    308                 total_v_size += increment;
    309                 if (total_v_size > INT_MAX) {
    310                         PyErr_SetString(PyExc_OverflowError,
    311                             "line is longer than a Python string can hold");
    312                         Py_DECREF(v);
    313                         return NULL;
    314                 }
    315                 if (_PyString_Resize(&v, total_v_size) < 0)
    316                         return NULL;
    317                 buf = BUF(v) + used_v_size;
    318                 end = BUF(v) + total_v_size;
    319         }
    320 
    321         used_v_size = buf - BUF(v);
    322         if (used_v_size != total_v_size)
    323                 _PyString_Resize(&v, used_v_size);
    324         return v;
     240    char c;
     241    char *buf, *end;
     242    size_t total_v_size;        /* total # of slots in buffer */
     243    size_t used_v_size;         /* # used slots in buffer */
     244    size_t increment;       /* amount to increment the buffer */
     245    PyObject *v;
     246    int bzerror;
     247    int bytes_read;
     248    int newlinetypes = f->f_newlinetypes;
     249    int skipnextlf = f->f_skipnextlf;
     250    int univ_newline = f->f_univ_newline;
     251
     252    total_v_size = n > 0 ? n : 100;
     253    v = PyString_FromStringAndSize((char *)NULL, total_v_size);
     254    if (v == NULL)
     255        return NULL;
     256
     257    buf = BUF(v);
     258    end = buf + total_v_size;
     259
     260    for (;;) {
     261        Py_BEGIN_ALLOW_THREADS
     262        while (buf != end) {
     263            bytes_read = BZ2_bzRead(&bzerror, f->fp, &c, 1);
     264            f->pos++;
     265            if (bytes_read == 0) break;
     266            if (univ_newline) {
     267                if (skipnextlf) {
     268                    skipnextlf = 0;
     269                    if (c == '\n') {
     270                        /* Seeing a \n here with skipnextlf true means we
     271                        * saw a \r before.
     272                        */
     273                        newlinetypes |= NEWLINE_CRLF;
     274                        if (bzerror != BZ_OK) break;
     275                        bytes_read = BZ2_bzRead(&bzerror, f->fp, &c, 1);
     276                        f->pos++;
     277                        if (bytes_read == 0) break;
     278                    } else {
     279                        newlinetypes |= NEWLINE_CR;
     280                    }
     281                }
     282                if (c == '\r') {
     283                    skipnextlf = 1;
     284                    c = '\n';
     285                } else if (c == '\n')
     286                    newlinetypes |= NEWLINE_LF;
     287            }
     288            *buf++ = c;
     289            if (bzerror != BZ_OK || c == '\n') break;
     290        }
     291        if (univ_newline && bzerror == BZ_STREAM_END && skipnextlf)
     292            newlinetypes |= NEWLINE_CR;
     293        Py_END_ALLOW_THREADS
     294        f->f_newlinetypes = newlinetypes;
     295        f->f_skipnextlf = skipnextlf;
     296        if (bzerror == BZ_STREAM_END) {
     297            f->size = f->pos;
     298            f->mode = MODE_READ_EOF;
     299            break;
     300        } else if (bzerror != BZ_OK) {
     301            Util_CatchBZ2Error(bzerror);
     302            Py_DECREF(v);
     303            return NULL;
     304        }
     305        if (c == '\n')
     306            break;
     307        /* Must be because buf == end */
     308        if (n > 0)
     309            break;
     310        used_v_size = total_v_size;
     311        increment = total_v_size >> 2; /* mild exponential growth */
     312        total_v_size += increment;
     313        if (total_v_size > INT_MAX) {
     314            PyErr_SetString(PyExc_OverflowError,
     315                "line is longer than a Python string can hold");
     316            Py_DECREF(v);
     317            return NULL;
     318        }
     319        if (_PyString_Resize(&v, total_v_size) < 0)
     320            return NULL;
     321        buf = BUF(v) + used_v_size;
     322        end = BUF(v) + total_v_size;
     323    }
     324
     325    used_v_size = buf - BUF(v);
     326    if (used_v_size != total_v_size)
     327        _PyString_Resize(&v, used_v_size);
     328    return v;
    325329}
    326330
     
    329333size_t
    330334Util_UnivNewlineRead(int *bzerror, BZFILE *stream,
    331                      char* buf, size_t n, BZ2FileObject *f)
    332 {
    333         char *dst = buf;
    334         int newlinetypes, skipnextlf;
    335 
    336         assert(buf != NULL);
    337         assert(stream != NULL);
    338 
    339         if (!f->f_univ_newline)
    340                 return BZ2_bzRead(bzerror, stream, buf, n);
    341 
    342         newlinetypes = f->f_newlinetypes;
    343         skipnextlf = f->f_skipnextlf;
    344 
    345         /* Invariant:  n is the number of bytes remaining to be filled
    346         * in the buffer.
    347         */
    348         while (n) {
    349                 size_t nread;
    350                 int shortread;
    351                 char *src = dst;
    352 
    353                 nread = BZ2_bzRead(bzerror, stream, dst, n);
    354                 assert(nread <= n);
    355                 n -= nread; /* assuming 1 byte out for each in; will adjust */
    356                 shortread = n != 0;     /* true iff EOF or error */
    357                 while (nread--) {
    358                         char c = *src++;
    359                         if (c == '\r') {
    360                                 /* Save as LF and set flag to skip next LF. */
    361                                 *dst++ = '\n';
    362                                 skipnextlf = 1;
    363                         }
    364                         else if (skipnextlf && c == '\n') {
    365                                 /* Skip LF, and remember we saw CR LF. */
    366                                 skipnextlf = 0;
    367                                 newlinetypes |= NEWLINE_CRLF;
    368                                 ++n;
    369                         }
    370                         else {
    371                                 /* Normal char to be stored in buffer.  Also
    372                                 * update the newlinetypes flag if either this
    373                                 * is an LF or the previous char was a CR.
    374                                 */
    375                                 if (c == '\n')
    376                                         newlinetypes |= NEWLINE_LF;
    377                                 else if (skipnextlf)
    378                                         newlinetypes |= NEWLINE_CR;
    379                                 *dst++ = c;
    380                                 skipnextlf = 0;
    381                         }
    382                 }
    383                 if (shortread) {
    384                         /* If this is EOF, update type flags. */
    385                         if (skipnextlf && *bzerror == BZ_STREAM_END)
    386                                 newlinetypes |= NEWLINE_CR;
    387                         break;
    388                 }
    389         }
    390         f->f_newlinetypes = newlinetypes;
    391         f->f_skipnextlf = skipnextlf;
    392         return dst - buf;
     335                     char* buf, size_t n, BZ2FileObject *f)
     336{
     337    char *dst = buf;
     338    int newlinetypes, skipnextlf;
     339
     340    assert(buf != NULL);
     341    assert(stream != NULL);
     342
     343    if (!f->f_univ_newline)
     344        return BZ2_bzRead(bzerror, stream, buf, n);
     345
     346    newlinetypes = f->f_newlinetypes;
     347    skipnextlf = f->f_skipnextlf;
     348
     349    /* Invariant:  n is the number of bytes remaining to be filled
     350    * in the buffer.
     351    */
     352    while (n) {
     353        size_t nread;
     354        int shortread;
     355        char *src = dst;
     356
     357        nread = BZ2_bzRead(bzerror, stream, dst, n);
     358        assert(nread <= n);
     359        n -= nread; /* assuming 1 byte out for each in; will adjust */
     360        shortread = n != 0;             /* true iff EOF or error */
     361        while (nread--) {
     362            char c = *src++;
     363            if (c == '\r') {
     364                /* Save as LF and set flag to skip next LF. */
     365                *dst++ = '\n';
     366                skipnextlf = 1;
     367            }
     368            else if (skipnextlf && c == '\n') {
     369                /* Skip LF, and remember we saw CR LF. */
     370                skipnextlf = 0;
     371                newlinetypes |= NEWLINE_CRLF;
     372                ++n;
     373            }
     374            else {
     375                /* Normal char to be stored in buffer.  Also
     376                * update the newlinetypes flag if either this
     377                * is an LF or the previous char was a CR.
     378                */
     379                if (c == '\n')
     380                    newlinetypes |= NEWLINE_LF;
     381                else if (skipnextlf)
     382                    newlinetypes |= NEWLINE_CR;
     383                *dst++ = c;
     384                skipnextlf = 0;
     385            }
     386        }
     387        if (shortread) {
     388            /* If this is EOF, update type flags. */
     389            if (skipnextlf && *bzerror == BZ_STREAM_END)
     390                newlinetypes |= NEWLINE_CR;
     391            break;
     392        }
     393    }
     394    f->f_newlinetypes = newlinetypes;
     395    f->f_skipnextlf = skipnextlf;
     396    return dst - buf;
    393397}
    394398
     
    397401Util_DropReadAhead(BZ2FileObject *f)
    398402{
    399         if (f->f_buf != NULL) {
    400                 PyMem_Free(f->f_buf);
    401                 f->f_buf = NULL;
    402         }
     403    if (f->f_buf != NULL) {
     404        PyMem_Free(f->f_buf);
     405        f->f_buf = NULL;
     406    }
    403407}
    404408
     
    407411Util_ReadAhead(BZ2FileObject *f, int bufsize)
    408412{
    409         int chunksize;
    410         int bzerror;
    411 
    412         if (f->f_buf != NULL) {
    413                 if((f->f_bufend - f->f_bufptr) >= 1)
    414                         return 0;
    415                 else
    416                         Util_DropReadAhead(f);
    417         }
    418         if (f->mode == MODE_READ_EOF) {
    419                 f->f_bufptr = f->f_buf;
    420                 f->f_bufend = f->f_buf;
    421                 return 0;
    422         }
    423         if ((f->f_buf = PyMem_Malloc(bufsize)) == NULL) {
    424                 PyErr_NoMemory();
    425                 return -1;
    426         }
    427         Py_BEGIN_ALLOW_THREADS
    428         chunksize = Util_UnivNewlineRead(&bzerror, f->fp, f->f_buf,
    429                                         bufsize, f);
    430         Py_END_ALLOW_THREADS
    431         f->pos += chunksize;
    432         if (bzerror == BZ_STREAM_END) {
    433                 f->size = f->pos;
    434                 f->mode = MODE_READ_EOF;
    435         } else if (bzerror != BZ_OK) {
    436                 Util_CatchBZ2Error(bzerror);
    437                 Util_DropReadAhead(f);
    438                 return -1;
    439         }
    440         f->f_bufptr = f->f_buf;
    441         f->f_bufend = f->f_buf + chunksize;
    442         return 0;
     413    int chunksize;
     414    int bzerror;
     415
     416    if (f->f_buf != NULL) {
     417        if((f->f_bufend - f->f_bufptr) >= 1)
     418            return 0;
     419        else
     420            Util_DropReadAhead(f);
     421    }
     422    if (f->mode == MODE_READ_EOF) {
     423        f->f_bufptr = f->f_buf;
     424        f->f_bufend = f->f_buf;
     425        return 0;
     426    }
     427    if ((f->f_buf = PyMem_Malloc(bufsize)) == NULL) {
     428        PyErr_NoMemory();
     429        return -1;
     430    }
     431    Py_BEGIN_ALLOW_THREADS
     432    chunksize = Util_UnivNewlineRead(&bzerror, f->fp, f->f_buf,
     433                                    bufsize, f);
     434    Py_END_ALLOW_THREADS
     435    f->pos += chunksize;
     436    if (bzerror == BZ_STREAM_END) {
     437        f->size = f->pos;
     438        f->mode = MODE_READ_EOF;
     439    } else if (bzerror != BZ_OK) {
     440        Util_CatchBZ2Error(bzerror);
     441        Util_DropReadAhead(f);
     442        return -1;
     443    }
     444    f->f_bufptr = f->f_buf;
     445    f->f_bufend = f->f_buf + chunksize;
     446    return 0;
    443447}
    444448
     
    448452Util_ReadAheadGetLineSkip(BZ2FileObject *f, int skip, int bufsize)
    449453{
    450         PyStringObject* s;
    451         char *bufptr;
    452         char *buf;
    453         int len;
    454 
    455         if (f->f_buf == NULL)
    456                 if (Util_ReadAhead(f, bufsize) < 0)
    457                         return NULL;
    458 
    459         len = f->f_bufend - f->f_bufptr;
    460         if (len == 0)
    461                 return (PyStringObject *)
    462                         PyString_FromStringAndSize(NULL, skip);
    463         bufptr = memchr(f->f_bufptr, '\n', len);
    464         if (bufptr != NULL) {
    465                 bufptr++;                       /* Count the '\n' */
    466                 len = bufptr - f->f_bufptr;
    467                 s = (PyStringObject *)
    468                         PyString_FromStringAndSize(NULL, skip+len);
    469                 if (s == NULL)
    470                         return NULL;
    471                 memcpy(PyString_AS_STRING(s)+skip, f->f_bufptr, len);
    472                 f->f_bufptr = bufptr;
    473                 if (bufptr == f->f_bufend)
    474                         Util_DropReadAhead(f);
    475         } else {
    476                 bufptr = f->f_bufptr;
    477                 buf = f->f_buf;
    478                 f->f_buf = NULL;        /* Force new readahead buffer */
    479                 s = Util_ReadAheadGetLineSkip(f, skip+len,
    480                                               bufsize + (bufsize>>2));
    481                 if (s == NULL) {
    482                         PyMem_Free(buf);
    483                         return NULL;
    484                 }
    485                 memcpy(PyString_AS_STRING(s)+skip, bufptr, len);
    486                 PyMem_Free(buf);
    487         }
    488         return s;
     454    PyStringObject* s;
     455    char *bufptr;
     456    char *buf;
     457    int len;
     458
     459    if (f->f_buf == NULL)
     460        if (Util_ReadAhead(f, bufsize) < 0)
     461            return NULL;
     462
     463    len = f->f_bufend - f->f_bufptr;
     464    if (len == 0)
     465        return (PyStringObject *)
     466            PyString_FromStringAndSize(NULL, skip);
     467    bufptr = memchr(f->f_bufptr, '\n', len);
     468    if (bufptr != NULL) {
     469        bufptr++;                               /* Count the '\n' */
     470        len = bufptr - f->f_bufptr;
     471        s = (PyStringObject *)
     472            PyString_FromStringAndSize(NULL, skip+len);
     473        if (s == NULL)
     474            return NULL;
     475        memcpy(PyString_AS_STRING(s)+skip, f->f_bufptr, len);
     476        f->f_bufptr = bufptr;
     477        if (bufptr == f->f_bufend)
     478            Util_DropReadAhead(f);
     479    } else {
     480        bufptr = f->f_bufptr;
     481        buf = f->f_buf;
     482        f->f_buf = NULL;                /* Force new readahead buffer */
     483        s = Util_ReadAheadGetLineSkip(f, skip+len,
     484                                      bufsize + (bufsize>>2));
     485        if (s == NULL) {
     486            PyMem_Free(buf);
     487            return NULL;
     488        }
     489        memcpy(PyString_AS_STRING(s)+skip, bufptr, len);
     490        PyMem_Free(buf);
     491    }
     492    return s;
    489493}
    490494
     
    503507BZ2File_read(BZ2FileObject *self, PyObject *args)
    504508{
    505         long bytesrequested = -1;
    506         size_t bytesread, buffersize, chunksize;
    507         int bzerror;
    508         PyObject *ret = NULL;
    509 
    510         if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
    511                 return NULL;
    512 
    513         ACQUIRE_LOCK(self);
    514         switch (self->mode) {
    515                 case MODE_READ:
    516                         break;
    517                 case MODE_READ_EOF:
    518                         ret = PyString_FromString("");
    519                         goto cleanup;
    520                 case MODE_CLOSED:
    521                         PyErr_SetString(PyExc_ValueError,
    522                                         "I/O operation on closed file");
    523                         goto cleanup;
    524                 default:
    525                         PyErr_SetString(PyExc_IOError,
    526                                         "file is not ready for reading");
    527                         goto cleanup;
    528         }
    529 
    530         if (bytesrequested < 0)
    531                 buffersize = Util_NewBufferSize((size_t)0);
    532         else
    533                 buffersize = bytesrequested;
    534         if (buffersize > INT_MAX) {
    535                 PyErr_SetString(PyExc_OverflowError,
    536                                 "requested number of bytes is "
    537                                 "more than a Python string can hold");
    538                 goto cleanup;
    539         }
    540         ret = PyString_FromStringAndSize((char *)NULL, buffersize);
    541         if (ret == NULL)
    542                 goto cleanup;
    543         bytesread = 0;
    544 
    545         for (;;) {
    546                 Py_BEGIN_ALLOW_THREADS
    547                 chunksize = Util_UnivNewlineRead(&bzerror, self->fp,
    548                                                  BUF(ret)+bytesread,
    549                                                  buffersize-bytesread,
    550                                                  self);
    551                 self->pos += chunksize;
    552                 Py_END_ALLOW_THREADS
    553                 bytesread += chunksize;
    554                 if (bzerror == BZ_STREAM_END) {
    555                         self->size = self->pos;
    556                         self->mode = MODE_READ_EOF;
    557                         break;
    558                 } else if (bzerror != BZ_OK) {
    559                         Util_CatchBZ2Error(bzerror);
    560                         Py_DECREF(ret);
    561                         ret = NULL;
    562                         goto cleanup;
    563                 }
    564                 if (bytesrequested < 0) {
    565                         buffersize = Util_NewBufferSize(buffersize);
    566                         if (_PyString_Resize(&ret, buffersize) < 0)
    567                                 goto cleanup;
    568                 } else {
    569                         break;
    570                 }
    571         }
    572         if (bytesread != buffersize)
    573                 _PyString_Resize(&ret, bytesread);
     509    long bytesrequested = -1;
     510    size_t bytesread, buffersize, chunksize;
     511    int bzerror;
     512    PyObject *ret = NULL;
     513
     514    if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
     515        return NULL;
     516
     517    ACQUIRE_LOCK(self);
     518    switch (self->mode) {
     519        case MODE_READ:
     520            break;
     521        case MODE_READ_EOF:
     522            ret = PyString_FromString("");
     523            goto cleanup;
     524        case MODE_CLOSED:
     525            PyErr_SetString(PyExc_ValueError,
     526                            "I/O operation on closed file");
     527            goto cleanup;
     528        default:
     529            PyErr_SetString(PyExc_IOError,
     530                            "file is not ready for reading");
     531            goto cleanup;
     532    }
     533
     534    /* refuse to mix with f.next() */
     535    if (check_iterbuffered(self))
     536        goto cleanup;
     537
     538    if (bytesrequested < 0)
     539        buffersize = Util_NewBufferSize((size_t)0);
     540    else
     541        buffersize = bytesrequested;
     542    if (buffersize > INT_MAX) {
     543        PyErr_SetString(PyExc_OverflowError,
     544                        "requested number of bytes is "
     545                        "more than a Python string can hold");
     546        goto cleanup;
     547    }
     548    ret = PyString_FromStringAndSize((char *)NULL, buffersize);
     549    if (ret == NULL)
     550        goto cleanup;
     551    bytesread = 0;
     552
     553    for (;;) {
     554        Py_BEGIN_ALLOW_THREADS
     555        chunksize = Util_UnivNewlineRead(&bzerror, self->fp,
     556                                         BUF(ret)+bytesread,
     557                                         buffersize-bytesread,
     558                                         self);
     559        self->pos += chunksize;
     560        Py_END_ALLOW_THREADS
     561        bytesread += chunksize;
     562        if (bzerror == BZ_STREAM_END) {
     563            self->size = self->pos;
     564            self->mode = MODE_READ_EOF;
     565            break;
     566        } else if (bzerror != BZ_OK) {
     567            Util_CatchBZ2Error(bzerror);
     568            Py_DECREF(ret);
     569            ret = NULL;
     570            goto cleanup;
     571        }
     572        if (bytesrequested < 0) {
     573            buffersize = Util_NewBufferSize(buffersize);
     574            if (_PyString_Resize(&ret, buffersize) < 0)
     575                goto cleanup;
     576        } else {
     577            break;
     578        }
     579    }
     580    if (bytesread != buffersize)
     581        _PyString_Resize(&ret, bytesread);
    574582
    575583cleanup:
    576         RELEASE_LOCK(self);
    577         return ret;
     584    RELEASE_LOCK(self);
     585    return ret;
    578586}
    579587
     
    590598BZ2File_readline(BZ2FileObject *self, PyObject *args)
    591599{
    592         PyObject *ret = NULL;
    593         int sizehint = -1;
    594 
    595         if (!PyArg_ParseTuple(args, "|i:readline", &sizehint))
    596                 return NULL;
    597 
    598         ACQUIRE_LOCK(self);
    599         switch (self->mode) {
    600                 case MODE_READ:
    601                         break;
    602                 case MODE_READ_EOF:
    603                         ret = PyString_FromString("");
    604                         goto cleanup;
    605                 case MODE_CLOSED:
    606                         PyErr_SetString(PyExc_ValueError,
    607                                         "I/O operation on closed file");
    608                         goto cleanup;
    609                 default:
    610                         PyErr_SetString(PyExc_IOError,
    611                                         "file is not ready for reading");
    612                         goto cleanup;
    613         }
    614 
    615         if (sizehint == 0)
    616                 ret = PyString_FromString("");
    617         else
    618                 ret = Util_GetLine(self, (sizehint < 0) ? 0 : sizehint);
     600    PyObject *ret = NULL;
     601    int sizehint = -1;
     602
     603    if (!PyArg_ParseTuple(args, "|i:readline", &sizehint))
     604        return NULL;
     605
     606    ACQUIRE_LOCK(self);
     607    switch (self->mode) {
     608        case MODE_READ:
     609            break;
     610        case MODE_READ_EOF:
     611            ret = PyString_FromString("");
     612            goto cleanup;
     613        case MODE_CLOSED:
     614            PyErr_SetString(PyExc_ValueError,
     615                            "I/O operation on closed file");
     616            goto cleanup;
     617        default:
     618            PyErr_SetString(PyExc_IOError,
     619                            "file is not ready for reading");
     620            goto cleanup;
     621    }
     622
     623    /* refuse to mix with f.next() */
     624    if (check_iterbuffered(self))
     625        goto cleanup;
     626
     627    if (sizehint == 0)
     628        ret = PyString_FromString("");
     629    else
     630        ret = Util_GetLine(self, (sizehint < 0) ? 0 : sizehint);
    619631
    620632cleanup:
    621         RELEASE_LOCK(self);
    622         return ret;
     633    RELEASE_LOCK(self);
     634    return ret;
    623635}
    624636
     
    635647BZ2File_readlines(BZ2FileObject *self, PyObject *args)
    636648{
    637         long sizehint = 0;
    638         PyObject *list = NULL;
    639         PyObject *line;
    640         char small_buffer[SMALLCHUNK];
    641         char *buffer = small_buffer;
    642         size_t buffersize = SMALLCHUNK;
    643         PyObject *big_buffer = NULL;
    644         size_t nfilled = 0;
    645         size_t nread;
    646         size_t totalread = 0;
    647         char *p, *q, *end;
    648         int err;
    649         int shortread = 0;
    650         int bzerror;
    651 
    652         if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
    653                 return NULL;
    654 
    655         ACQUIRE_LOCK(self);
    656         switch (self->mode) {
    657                 case MODE_READ:
    658                         break;
    659                 case MODE_READ_EOF:
    660                         list = PyList_New(0);
    661                         goto cleanup;
    662                 case MODE_CLOSED:
    663                         PyErr_SetString(PyExc_ValueError,
    664                                         "I/O operation on closed file");
    665                         goto cleanup;
    666                 default:
    667                         PyErr_SetString(PyExc_IOError,
    668                                         "file is not ready for reading");
    669                         goto cleanup;
    670         }
    671 
    672         if ((list = PyList_New(0)) == NULL)
    673                 goto cleanup;
    674 
    675         for (;;) {
    676                 Py_BEGIN_ALLOW_THREADS
    677                 nread = Util_UnivNewlineRead(&bzerror, self->fp,
    678                                              buffer+nfilled,
    679                                              buffersize-nfilled, self);
    680                 self->pos += nread;
    681                 Py_END_ALLOW_THREADS
    682                 if (bzerror == BZ_STREAM_END) {
    683                         self->size = self->pos;
    684                         self->mode = MODE_READ_EOF;
    685                         if (nread == 0) {
    686                                 sizehint = 0;
    687                                 break;
    688                         }
    689                         shortread = 1;
    690                 } else if (bzerror != BZ_OK) {
    691                         Util_CatchBZ2Error(bzerror);
    692                   error:
    693                         Py_DECREF(list);
    694                         list = NULL;
    695                         goto cleanup;
    696                 }
    697                 totalread += nread;
    698                 p = memchr(buffer+nfilled, '\n', nread);
    699                 if (!shortread && p == NULL) {
    700                         /* Need a larger buffer to fit this line */
    701                         nfilled += nread;
    702                         buffersize *= 2;
    703                         if (buffersize > INT_MAX) {
    704                                 PyErr_SetString(PyExc_OverflowError,
    705                                 "line is longer than a Python string can hold");
    706                                 goto error;
    707                         }
    708                         if (big_buffer == NULL) {
    709                                 /* Create the big buffer */
    710                                 big_buffer = PyString_FromStringAndSize(
    711                                         NULL, buffersize);
    712                                 if (big_buffer == NULL)
    713                                         goto error;
    714                                 buffer = PyString_AS_STRING(big_buffer);
    715                                 memcpy(buffer, small_buffer, nfilled);
    716                         }
    717                         else {
    718                                 /* Grow the big buffer */
    719                                 _PyString_Resize(&big_buffer, buffersize);
    720                                 buffer = PyString_AS_STRING(big_buffer);
    721                         }
    722                         continue;                       
    723                 }
    724                 end = buffer+nfilled+nread;
    725                 q = buffer;
    726                 while (p != NULL) {
    727                         /* Process complete lines */
    728                         p++;
    729                         line = PyString_FromStringAndSize(q, p-q);
    730                         if (line == NULL)
    731                                 goto error;
    732                         err = PyList_Append(list, line);
    733                         Py_DECREF(line);
    734                         if (err != 0)
    735                                 goto error;
    736                         q = p;
    737                         p = memchr(q, '\n', end-q);
    738                 }
    739                 /* Move the remaining incomplete line to the start */
    740                 nfilled = end-q;
    741                 memmove(buffer, q, nfilled);
    742                 if (sizehint > 0)
    743                         if (totalread >= (size_t)sizehint)
    744                                 break;
    745                 if (shortread) {
    746                         sizehint = 0;
    747                         break;
    748                 }
    749         }
    750         if (nfilled != 0) {
    751                 /* Partial last line */
    752                 line = PyString_FromStringAndSize(buffer, nfilled);
    753                 if (line == NULL)
    754                         goto error;
    755                 if (sizehint > 0) {
    756                         /* Need to complete the last line */
    757                         PyObject *rest = Util_GetLine(self, 0);
    758                         if (rest == NULL) {
    759                                 Py_DECREF(line);
    760                                 goto error;
    761                         }
    762                         PyString_Concat(&line, rest);
    763                         Py_DECREF(rest);
    764                         if (line == NULL)
    765                                 goto error;
    766                 }
    767                 err = PyList_Append(list, line);
    768                 Py_DECREF(line);
    769                 if (err != 0)
    770                         goto error;
    771         }
     649    long sizehint = 0;
     650    PyObject *list = NULL;
     651    PyObject *line;
     652    char small_buffer[SMALLCHUNK];
     653    char *buffer = small_buffer;
     654    size_t buffersize = SMALLCHUNK;
     655    PyObject *big_buffer = NULL;
     656    size_t nfilled = 0;
     657    size_t nread;
     658    size_t totalread = 0;
     659    char *p, *q, *end;
     660    int err;
     661    int shortread = 0;
     662    int bzerror;
     663
     664    if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
     665        return NULL;
     666
     667    ACQUIRE_LOCK(self);
     668    switch (self->mode) {
     669        case MODE_READ:
     670            break;
     671        case MODE_READ_EOF:
     672            list = PyList_New(0);
     673            goto cleanup;
     674        case MODE_CLOSED:
     675            PyErr_SetString(PyExc_ValueError,
     676                            "I/O operation on closed file");
     677            goto cleanup;
     678        default:
     679            PyErr_SetString(PyExc_IOError,
     680                            "file is not ready for reading");
     681            goto cleanup;
     682    }
     683
     684    /* refuse to mix with f.next() */
     685    if (check_iterbuffered(self))
     686        goto cleanup;
     687
     688    if ((list = PyList_New(0)) == NULL)
     689        goto cleanup;
     690
     691    for (;;) {
     692        Py_BEGIN_ALLOW_THREADS
     693        nread = Util_UnivNewlineRead(&bzerror, self->fp,
     694                                     buffer+nfilled,
     695                                     buffersize-nfilled, self);
     696        self->pos += nread;
     697        Py_END_ALLOW_THREADS
     698        if (bzerror == BZ_STREAM_END) {
     699            self->size = self->pos;
     700            self->mode = MODE_READ_EOF;
     701            if (nread == 0) {
     702                sizehint = 0;
     703                break;
     704            }
     705            shortread = 1;
     706        } else if (bzerror != BZ_OK) {
     707            Util_CatchBZ2Error(bzerror);
     708          error:
     709            Py_DECREF(list);
     710            list = NULL;
     711            goto cleanup;
     712        }
     713        totalread += nread;
     714        p = memchr(buffer+nfilled, '\n', nread);
     715        if (!shortread && p == NULL) {
     716            /* Need a larger buffer to fit this line */
     717            nfilled += nread;
     718            buffersize *= 2;
     719            if (buffersize > INT_MAX) {
     720                PyErr_SetString(PyExc_OverflowError,
     721                "line is longer than a Python string can hold");
     722                goto error;
     723            }
     724            if (big_buffer == NULL) {
     725                /* Create the big buffer */
     726                big_buffer = PyString_FromStringAndSize(
     727                    NULL, buffersize);
     728                if (big_buffer == NULL)
     729                    goto error;
     730                buffer = PyString_AS_STRING(big_buffer);
     731                memcpy(buffer, small_buffer, nfilled);
     732            }
     733            else {
     734                /* Grow the big buffer */
     735                _PyString_Resize(&big_buffer, buffersize);
     736                buffer = PyString_AS_STRING(big_buffer);
     737            }
     738            continue;
     739        }
     740        end = buffer+nfilled+nread;
     741        q = buffer;
     742        while (p != NULL) {
     743            /* Process complete lines */
     744            p++;
     745            line = PyString_FromStringAndSize(q, p-q);
     746            if (line == NULL)
     747                goto error;
     748            err = PyList_Append(list, line);
     749            Py_DECREF(line);
     750            if (err != 0)
     751                goto error;
     752            q = p;
     753            p = memchr(q, '\n', end-q);
     754        }
     755        /* Move the remaining incomplete line to the start */
     756        nfilled = end-q;
     757        memmove(buffer, q, nfilled);
     758        if (sizehint > 0)
     759            if (totalread >= (size_t)sizehint)
     760                break;
     761        if (shortread) {
     762            sizehint = 0;
     763            break;
     764        }
     765    }
     766    if (nfilled != 0) {
     767        /* Partial last line */
     768        line = PyString_FromStringAndSize(buffer, nfilled);
     769        if (line == NULL)
     770            goto error;
     771        if (sizehint > 0) {
     772            /* Need to complete the last line */
     773            PyObject *rest = Util_GetLine(self, 0);
     774            if (rest == NULL) {
     775                Py_DECREF(line);
     776                goto error;
     777            }
     778            PyString_Concat(&line, rest);
     779            Py_DECREF(rest);
     780            if (line == NULL)
     781                goto error;
     782        }
     783        err = PyList_Append(list, line);
     784        Py_DECREF(line);
     785        if (err != 0)
     786            goto error;
     787    }
    772788
    773789  cleanup:
    774         RELEASE_LOCK(self);
    775         if (big_buffer) {
    776                 Py_DECREF(big_buffer);
    777         }
    778         return list;
     790    RELEASE_LOCK(self);
     791    if (big_buffer) {
     792        Py_DECREF(big_buffer);
     793    }
     794    return list;
    779795}
    780796
     
    797813BZ2File_write(BZ2FileObject *self, PyObject *args)
    798814{
    799         PyObject *ret = NULL;
    800         Py_buffer pbuf;
    801         char *buf;
    802         int len;
    803         int bzerror;
    804 
    805         if (!PyArg_ParseTuple(args, "s*:write", &pbuf))
    806                 return NULL;
    807         buf = pbuf.buf;
    808         len = pbuf.len;
    809 
    810         ACQUIRE_LOCK(self);
    811         switch (self->mode) {
    812                 case MODE_WRITE:
    813                         break;
    814 
    815                 case MODE_CLOSED:
    816                         PyErr_SetString(PyExc_ValueError,
    817                                         "I/O operation on closed file");
    818                         goto cleanup;
    819 
    820                 default:
    821                         PyErr_SetString(PyExc_IOError,
    822                                         "file is not ready for writing");
    823                         goto cleanup;
    824         }
    825 
    826         self->f_softspace = 0;
    827 
    828         Py_BEGIN_ALLOW_THREADS
    829         BZ2_bzWrite (&bzerror, self->fp, buf, len);
    830         self->pos += len;
    831         Py_END_ALLOW_THREADS
    832 
    833         if (bzerror != BZ_OK) {
    834                 Util_CatchBZ2Error(bzerror);
    835                 goto cleanup;
    836         }
    837 
    838         Py_INCREF(Py_None);
    839         ret = Py_None;
     815    PyObject *ret = NULL;
     816    Py_buffer pbuf;
     817    char *buf;
     818    int len;
     819    int bzerror;
     820
     821    if (!PyArg_ParseTuple(args, "s*:write", &pbuf))
     822        return NULL;
     823    buf = pbuf.buf;
     824    len = pbuf.len;
     825
     826    ACQUIRE_LOCK(self);
     827    switch (self->mode) {
     828        case MODE_WRITE:
     829            break;
     830
     831        case MODE_CLOSED:
     832            PyErr_SetString(PyExc_ValueError,
     833                            "I/O operation on closed file");
     834            goto cleanup;
     835
     836        default:
     837            PyErr_SetString(PyExc_IOError,
     838                            "file is not ready for writing");
     839            goto cleanup;
     840    }
     841
     842    self->f_softspace = 0;
     843
     844    Py_BEGIN_ALLOW_THREADS
     845    BZ2_bzWrite (&bzerror, self->fp, buf, len);
     846    self->pos += len;
     847    Py_END_ALLOW_THREADS
     848
     849    if (bzerror != BZ_OK) {
     850        Util_CatchBZ2Error(bzerror);
     851        goto cleanup;
     852    }
     853
     854    Py_INCREF(Py_None);
     855    ret = Py_None;
    840856
    841857cleanup:
    842         PyBuffer_Release(&pbuf);
    843         RELEASE_LOCK(self);
    844         return ret;
     858    PyBuffer_Release(&pbuf);
     859    RELEASE_LOCK(self);
     860    return ret;
    845861}
    846862
     
    858874{
    859875#define CHUNKSIZE 1000
    860         PyObject *list = NULL;
    861         PyObject *iter = NULL;
    862         PyObject *ret = NULL;
    863         PyObject *line;
    864         int i, j, index, len, islist;
    865         int bzerror;
    866 
    867         ACQUIRE_LOCK(self);
    868         switch (self->mode) {
    869                 case MODE_WRITE:
    870                         break;
    871 
    872                 case MODE_CLOSED:
    873                         PyErr_SetString(PyExc_ValueError,
    874                                         "I/O operation on closed file");
    875                         goto error;
    876 
    877                 default:
    878                         PyErr_SetString(PyExc_IOError,
    879                                         "file is not ready for writing");
    880                         goto error;
    881         }
    882 
    883         islist = PyList_Check(seq);
    884         if  (!islist) {
    885                 iter = PyObject_GetIter(seq);
    886                 if (iter == NULL) {
    887                         PyErr_SetString(PyExc_TypeError,
    888                                 "writelines() requires an iterable argument");
    889                         goto error;
    890                 }
    891                 list = PyList_New(CHUNKSIZE);
    892                 if (list == NULL)
    893                         goto error;
    894         }
    895 
    896         /* Strategy: slurp CHUNKSIZE lines into a private list,
    897            checking that they are all strings, then write that list
    898            without holding the interpreter lock, then come back for more. */
    899         for (index = 0; ; index += CHUNKSIZE) {
    900                 if (islist) {
    901                         Py_XDECREF(list);
    902                         list = PyList_GetSlice(seq, index, index+CHUNKSIZE);
    903                         if (list == NULL)
    904                                 goto error;
    905                         j = PyList_GET_SIZE(list);
    906                 }
    907                 else {
    908                         for (j = 0; j < CHUNKSIZE; j++) {
    909                                 line = PyIter_Next(iter);
    910                                 if (line == NULL) {
    911                                         if (PyErr_Occurred())
    912                                                 goto error;
    913                                         break;
    914                                 }
    915                                 PyList_SetItem(list, j, line);
    916                         }
    917                 }
    918                 if (j == 0)
    919                         break;
    920 
    921                 /* Check that all entries are indeed strings. If not,
    922                    apply the same rules as for file.write() and
    923                    convert the rets to strings. This is slow, but
    924                    seems to be the only way since all conversion APIs
    925                    could potentially execute Python code. */
    926                 for (i = 0; i < j; i++) {
    927                         PyObject *v = PyList_GET_ITEM(list, i);
    928                         if (!PyString_Check(v)) {
    929                                 const char *buffer;
    930                                 Py_ssize_t len;
    931                                 if (PyObject_AsCharBuffer(v, &buffer, &len)) {
    932                                         PyErr_SetString(PyExc_TypeError,
    933                                                         "writelines() "
    934                                                         "argument must be "
    935                                                         "a sequence of "
    936                                                         "strings");
    937                                         goto error;
    938                                 }
    939                                 line = PyString_FromStringAndSize(buffer,
    940                                                                   len);
    941                                 if (line == NULL)
    942                                         goto error;
    943                                 Py_DECREF(v);
    944                                 PyList_SET_ITEM(list, i, line);
    945                         }
    946                 }
    947 
    948                 self->f_softspace = 0;
    949 
    950                 /* Since we are releasing the global lock, the
    951                    following code may *not* execute Python code. */
    952                 Py_BEGIN_ALLOW_THREADS
    953                 for (i = 0; i < j; i++) {
    954                         line = PyList_GET_ITEM(list, i);
    955                         len = PyString_GET_SIZE(line);
    956                         BZ2_bzWrite (&bzerror, self->fp,
    957                                      PyString_AS_STRING(line), len);
    958                         if (bzerror != BZ_OK) {
    959                                 Py_BLOCK_THREADS
    960                                 Util_CatchBZ2Error(bzerror);
    961                                 goto error;
    962                         }
    963                 }
    964                 Py_END_ALLOW_THREADS
    965 
    966                 if (j < CHUNKSIZE)
    967                         break;
    968         }
    969 
    970         Py_INCREF(Py_None);
    971         ret = Py_None;
     876    PyObject *list = NULL;
     877    PyObject *iter = NULL;
     878    PyObject *ret = NULL;
     879    PyObject *line;
     880    int i, j, index, len, islist;
     881    int bzerror;
     882
     883    ACQUIRE_LOCK(self);
     884    switch (self->mode) {
     885        case MODE_WRITE:
     886            break;
     887
     888        case MODE_CLOSED:
     889            PyErr_SetString(PyExc_ValueError,
     890                            "I/O operation on closed file");
     891            goto error;
     892
     893        default:
     894            PyErr_SetString(PyExc_IOError,
     895                            "file is not ready for writing");
     896            goto error;
     897    }
     898
     899    islist = PyList_Check(seq);
     900    if  (!islist) {
     901        iter = PyObject_GetIter(seq);
     902        if (iter == NULL) {
     903            PyErr_SetString(PyExc_TypeError,
     904                "writelines() requires an iterable argument");
     905            goto error;
     906        }
     907        list = PyList_New(CHUNKSIZE);
     908        if (list == NULL)
     909            goto error;
     910    }
     911
     912    /* Strategy: slurp CHUNKSIZE lines into a private list,
     913       checking that they are all strings, then write that list
     914       without holding the interpreter lock, then come back for more. */
     915    for (index = 0; ; index += CHUNKSIZE) {
     916        if (islist) {
     917            Py_XDECREF(list);
     918            list = PyList_GetSlice(seq, index, index+CHUNKSIZE);
     919            if (list == NULL)
     920                goto error;
     921            j = PyList_GET_SIZE(list);
     922        }
     923        else {
     924            for (j = 0; j < CHUNKSIZE; j++) {
     925                line = PyIter_Next(iter);
     926                if (line == NULL) {
     927                    if (PyErr_Occurred())
     928                        goto error;
     929                    break;
     930                }
     931                PyList_SetItem(list, j, line);
     932            }
     933        }
     934        if (j == 0)
     935            break;
     936
     937        /* Check that all entries are indeed strings. If not,
     938           apply the same rules as for file.write() and
     939           convert the rets to strings. This is slow, but
     940           seems to be the only way since all conversion APIs
     941           could potentially execute Python code. */
     942        for (i = 0; i < j; i++) {
     943            PyObject *v = PyList_GET_ITEM(list, i);
     944            if (!PyString_Check(v)) {
     945                const char *buffer;
     946                Py_ssize_t len;
     947                if (PyObject_AsCharBuffer(v, &buffer, &len)) {
     948                    PyErr_SetString(PyExc_TypeError,
     949                                    "writelines() "
     950                                    "argument must be "
     951                                    "a sequence of "
     952                                    "strings");
     953                    goto error;
     954                }
     955                line = PyString_FromStringAndSize(buffer,
     956                                                  len);
     957                if (line == NULL)
     958                    goto error;
     959                Py_DECREF(v);
     960                PyList_SET_ITEM(list, i, line);
     961            }
     962        }
     963
     964        self->f_softspace = 0;
     965
     966        /* Since we are releasing the global lock, the
     967           following code may *not* execute Python code. */
     968        Py_BEGIN_ALLOW_THREADS
     969        for (i = 0; i < j; i++) {
     970            line = PyList_GET_ITEM(list, i);
     971            len = PyString_GET_SIZE(line);
     972            BZ2_bzWrite (&bzerror, self->fp,
     973                         PyString_AS_STRING(line), len);
     974            if (bzerror != BZ_OK) {
     975                Py_BLOCK_THREADS
     976                Util_CatchBZ2Error(bzerror);
     977                goto error;
     978            }
     979        }
     980        Py_END_ALLOW_THREADS
     981
     982        if (j < CHUNKSIZE)
     983            break;
     984    }
     985
     986    Py_INCREF(Py_None);
     987    ret = Py_None;
    972988
    973989  error:
    974         RELEASE_LOCK(self);
    975         Py_XDECREF(list);
    976         Py_XDECREF(iter);
    977         return ret;
     990    RELEASE_LOCK(self);
     991    Py_XDECREF(list);
     992    Py_XDECREF(iter);
     993    return ret;
    978994#undef CHUNKSIZE
    979995}
     
    9951011BZ2File_seek(BZ2FileObject *self, PyObject *args)
    9961012{
    997         int where = 0;
    998         PyObject *offobj;
    999         Py_off_t offset;
    1000         char small_buffer[SMALLCHUNK];
    1001         char *buffer = small_buffer;
    1002         size_t buffersize = SMALLCHUNK;
    1003         Py_off_t bytesread = 0;
    1004         size_t readsize;
    1005         int chunksize;
    1006         int bzerror;
    1007         PyObject *ret = NULL;
    1008 
    1009         if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &where))
    1010                 return NULL;
     1013    int where = 0;
     1014    PyObject *offobj;
     1015    Py_off_t offset;
     1016    char small_buffer[SMALLCHUNK];
     1017    char *buffer = small_buffer;
     1018    size_t buffersize = SMALLCHUNK;
     1019    Py_off_t bytesread = 0;
     1020    size_t readsize;
     1021    int chunksize;
     1022    int bzerror;
     1023    PyObject *ret = NULL;
     1024
     1025    if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &where))
     1026        return NULL;
    10111027#if !defined(HAVE_LARGEFILE_SUPPORT)
    1012         offset = PyInt_AsLong(offobj);
     1028    offset = PyInt_AsLong(offobj);
    10131029#else
    1014         offset = PyLong_Check(offobj) ?
    1015                 PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
     1030    offset = PyLong_Check(offobj) ?
     1031        PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
    10161032#endif
    1017         if (PyErr_Occurred())
    1018                 return NULL;
    1019 
    1020         ACQUIRE_LOCK(self);
    1021         Util_DropReadAhead(self);
    1022         switch (self->mode) {
    1023                 case MODE_READ:
    1024                 case MODE_READ_EOF:
    1025                         break;
    1026 
    1027                 case MODE_CLOSED:
    1028                         PyErr_SetString(PyExc_ValueError,
    1029                                         "I/O operation on closed file");
    1030                         goto cleanup;
    1031 
    1032                 default:
    1033                         PyErr_SetString(PyExc_IOError,
    1034                                         "seek works only while reading");
    1035                         goto cleanup;
    1036         }
    1037 
    1038         if (where == 2) {
    1039                 if (self->size == -1) {
    1040                         assert(self->mode != MODE_READ_EOF);
    1041                         for (;;) {
    1042                                 Py_BEGIN_ALLOW_THREADS
    1043                                 chunksize = Util_UnivNewlineRead(
    1044                                                 &bzerror, self->fp,
    1045                                                 buffer, buffersize,
    1046                                                 self);
    1047                                 self->pos += chunksize;
    1048                                 Py_END_ALLOW_THREADS
    1049 
    1050                                 bytesread += chunksize;
    1051                                 if (bzerror == BZ_STREAM_END) {
    1052                                         break;
    1053                                 } else if (bzerror != BZ_OK) {
    1054                                         Util_CatchBZ2Error(bzerror);
    1055                                         goto cleanup;
    1056                                 }
    1057                         }
    1058                         self->mode = MODE_READ_EOF;
    1059                         self->size = self->pos;
    1060                         bytesread = 0;
    1061                 }
    1062                 offset = self->size + offset;
    1063         } else if (where == 1) {
    1064                 offset = self->pos + offset;
    1065         }
    1066 
    1067         /* Before getting here, offset must be the absolute position the file
    1068         * pointer should be set to. */
    1069 
    1070         if (offset >= self->pos) {
    1071                 /* we can move forward */
    1072                 offset -= self->pos;
    1073         } else {
    1074                 /* we cannot move back, so rewind the stream */
    1075                 BZ2_bzReadClose(&bzerror, self->fp);
    1076                 if (self->fp) {
    1077                         PyFile_DecUseCount((PyFileObject *)self->file);
    1078                         self->fp = NULL;
    1079                 }
    1080                 if (bzerror != BZ_OK) {
    1081                         Util_CatchBZ2Error(bzerror);
    1082                         goto cleanup;
    1083                 }
    1084                 ret = PyObject_CallMethod(self->file, "seek", "(i)", 0);
    1085                 if (!ret)
    1086                         goto cleanup;
    1087                 Py_DECREF(ret);
    1088                 ret = NULL;
    1089                 self->pos = 0;
    1090                 self->fp = BZ2_bzReadOpen(&bzerror, PyFile_AsFile(self->file),
    1091                                           0, 0, NULL, 0);
    1092                 if (self->fp)
    1093                         PyFile_IncUseCount((PyFileObject *)self->file);
    1094                 if (bzerror != BZ_OK) {
    1095                         Util_CatchBZ2Error(bzerror);
    1096                         goto cleanup;
    1097                 }
    1098                 self->mode = MODE_READ;
    1099         }
    1100 
    1101         if (offset <= 0 || self->mode == MODE_READ_EOF)
    1102                 goto exit;
    1103 
    1104         /* Before getting here, offset must be set to the number of bytes
    1105         * to walk forward. */
    1106         for (;;) {
    1107                 if (offset-bytesread > buffersize)
    1108                         readsize = buffersize;
    1109                 else
    1110                         /* offset might be wider that readsize, but the result
    1111                         * of the subtraction is bound by buffersize (see the
    1112                         * condition above). buffersize is 8192. */
    1113                         readsize = (size_t)(offset-bytesread);
    1114                 Py_BEGIN_ALLOW_THREADS
    1115                 chunksize = Util_UnivNewlineRead(&bzerror, self->fp,
    1116                                                 buffer, readsize, self);
    1117                 self->pos += chunksize;
    1118                 Py_END_ALLOW_THREADS
    1119                 bytesread += chunksize;
    1120                 if (bzerror == BZ_STREAM_END) {
    1121                         self->size = self->pos;
    1122                         self->mode = MODE_READ_EOF;
    1123                         break;
    1124                 } else if (bzerror != BZ_OK) {
    1125                         Util_CatchBZ2Error(bzerror);
    1126                         goto cleanup;
    1127                 }
    1128                 if (bytesread == offset)
    1129                         break;
    1130         }
     1033    if (PyErr_Occurred())
     1034        return NULL;
     1035
     1036    ACQUIRE_LOCK(self);
     1037    Util_DropReadAhead(self);
     1038    switch (self->mode) {
     1039        case MODE_READ:
     1040        case MODE_READ_EOF:
     1041            break;
     1042
     1043        case MODE_CLOSED:
     1044            PyErr_SetString(PyExc_ValueError,
     1045                            "I/O operation on closed file");
     1046            goto cleanup;
     1047
     1048        default:
     1049            PyErr_SetString(PyExc_IOError,
     1050                            "seek works only while reading");
     1051            goto cleanup;
     1052    }
     1053
     1054    if (where == 2) {
     1055        if (self->size == -1) {
     1056            assert(self->mode != MODE_READ_EOF);
     1057            for (;;) {
     1058                Py_BEGIN_ALLOW_THREADS
     1059                chunksize = Util_UnivNewlineRead(
     1060                                &bzerror, self->fp,
     1061                                buffer, buffersize,
     1062                                self);
     1063                self->pos += chunksize;
     1064                Py_END_ALLOW_THREADS
     1065
     1066                bytesread += chunksize;
     1067                if (bzerror == BZ_STREAM_END) {
     1068                    break;
     1069                } else if (bzerror != BZ_OK) {
     1070                    Util_CatchBZ2Error(bzerror);
     1071                    goto cleanup;
     1072                }
     1073            }
     1074            self->mode = MODE_READ_EOF;
     1075            self->size = self->pos;
     1076            bytesread = 0;
     1077        }
     1078        offset = self->size + offset;
     1079    } else if (where == 1) {
     1080        offset = self->pos + offset;
     1081    }
     1082
     1083    /* Before getting here, offset must be the absolute position the file
     1084    * pointer should be set to. */
     1085
     1086    if (offset >= self->pos) {
     1087        /* we can move forward */
     1088        offset -= self->pos;
     1089    } else {
     1090        /* we cannot move back, so rewind the stream */
     1091        BZ2_bzReadClose(&bzerror, self->fp);
     1092        if (self->fp) {
     1093            PyFile_DecUseCount((PyFileObject *)self->file);
     1094            self->fp = NULL;
     1095        }
     1096        if (bzerror != BZ_OK) {
     1097            Util_CatchBZ2Error(bzerror);
     1098            goto cleanup;
     1099        }
     1100        ret = PyObject_CallMethod(self->file, "seek", "(i)", 0);
     1101        if (!ret)
     1102            goto cleanup;
     1103        Py_DECREF(ret);
     1104        ret = NULL;
     1105        self->pos = 0;
     1106        self->fp = BZ2_bzReadOpen(&bzerror, PyFile_AsFile(self->file),
     1107                                  0, 0, NULL, 0);
     1108        if (self->fp)
     1109            PyFile_IncUseCount((PyFileObject *)self->file);
     1110        if (bzerror != BZ_OK) {
     1111            Util_CatchBZ2Error(bzerror);
     1112            goto cleanup;
     1113        }
     1114        self->mode = MODE_READ;
     1115    }
     1116
     1117    if (offset <= 0 || self->mode == MODE_READ_EOF)
     1118        goto exit;
     1119
     1120    /* Before getting here, offset must be set to the number of bytes
     1121    * to walk forward. */
     1122    for (;;) {
     1123        if (offset-bytesread > buffersize)
     1124            readsize = buffersize;
     1125        else
     1126            /* offset might be wider that readsize, but the result
     1127            * of the subtraction is bound by buffersize (see the
     1128            * condition above). buffersize is 8192. */
     1129            readsize = (size_t)(offset-bytesread);
     1130        Py_BEGIN_ALLOW_THREADS
     1131        chunksize = Util_UnivNewlineRead(&bzerror, self->fp,
     1132                                        buffer, readsize, self);
     1133        self->pos += chunksize;
     1134        Py_END_ALLOW_THREADS
     1135        bytesread += chunksize;
     1136        if (bzerror == BZ_STREAM_END) {
     1137            self->size = self->pos;
     1138            self->mode = MODE_READ_EOF;
     1139            break;
     1140        } else if (bzerror != BZ_OK) {
     1141            Util_CatchBZ2Error(bzerror);
     1142            goto cleanup;
     1143        }
     1144        if (bytesread == offset)
     1145            break;
     1146    }
    11311147
    11321148exit:
    1133         Py_INCREF(Py_None);
    1134         ret = Py_None;
     1149    Py_INCREF(Py_None);
     1150    ret = Py_None;
    11351151
    11361152cleanup:
    1137         RELEASE_LOCK(self);
    1138         return ret;
     1153    RELEASE_LOCK(self);
     1154    return ret;
    11391155}
    11401156
     
    11481164BZ2File_tell(BZ2FileObject *self, PyObject *args)
    11491165{
    1150         PyObject *ret = NULL;
    1151 
    1152         if (self->mode == MODE_CLOSED) {
    1153                 PyErr_SetString(PyExc_ValueError,
    1154                                 "I/O operation on closed file");
    1155                 goto cleanup;
    1156         }
     1166    PyObject *ret = NULL;
     1167
     1168    if (self->mode == MODE_CLOSED) {
     1169        PyErr_SetString(PyExc_ValueError,
     1170                        "I/O operation on closed file");
     1171        goto cleanup;
     1172    }
    11571173
    11581174#if !defined(HAVE_LARGEFILE_SUPPORT)
    1159         ret = PyInt_FromLong(self->pos);
     1175    ret = PyInt_FromLong(self->pos);
    11601176#else
    1161         ret = PyLong_FromLongLong(self->pos);
     1177    ret = PyLong_FromLongLong(self->pos);
    11621178#endif
    11631179
    11641180cleanup:
    1165         return ret;
     1181    return ret;
    11661182}
    11671183
     
    11771193BZ2File_close(BZ2FileObject *self)
    11781194{
    1179         PyObject *ret = NULL;
    1180         int bzerror = BZ_OK;
    1181 
    1182         ACQUIRE_LOCK(self);
    1183         switch (self->mode) {
    1184                 case MODE_READ:
    1185                 case MODE_READ_EOF:
    1186                         BZ2_bzReadClose(&bzerror, self->fp);
    1187                         break;
    1188                 case MODE_WRITE:
    1189                         BZ2_bzWriteClose(&bzerror, self->fp,
    1190                                          0, NULL, NULL);
    1191                         break;
    1192         }
    1193         if (self->fp) {
    1194                 PyFile_DecUseCount((PyFileObject *)self->file);
    1195                 self->fp = NULL;
    1196         }
    1197         self->mode = MODE_CLOSED;
    1198         ret = PyObject_CallMethod(self->file, "close", NULL);
    1199         if (bzerror != BZ_OK) {
    1200                 Util_CatchBZ2Error(bzerror);
    1201                 Py_XDECREF(ret);
    1202                 ret = NULL;
    1203         }
    1204 
    1205         RELEASE_LOCK(self);
    1206         return ret;
    1207 }
     1195    PyObject *ret = NULL;
     1196    int bzerror = BZ_OK;
     1197
     1198    ACQUIRE_LOCK(self);
     1199    switch (self->mode) {
     1200        case MODE_READ:
     1201        case MODE_READ_EOF:
     1202            BZ2_bzReadClose(&bzerror, self->fp);
     1203            break;
     1204        case MODE_WRITE:
     1205            BZ2_bzWriteClose(&bzerror, self->fp,
     1206                             0, NULL, NULL);
     1207            break;
     1208    }
     1209    if (self->fp) {
     1210        PyFile_DecUseCount((PyFileObject *)self->file);
     1211        self->fp = NULL;
     1212    }
     1213    self->mode = MODE_CLOSED;
     1214    ret = PyObject_CallMethod(self->file, "close", NULL);
     1215    if (bzerror != BZ_OK) {
     1216        Util_CatchBZ2Error(bzerror);
     1217        Py_XDECREF(ret);
     1218        ret = NULL;
     1219    }
     1220
     1221    RELEASE_LOCK(self);
     1222    return ret;
     1223}
     1224
     1225PyDoc_STRVAR(BZ2File_enter_doc,
     1226"__enter__() -> self.");
     1227
     1228static PyObject *
     1229BZ2File_enter(BZ2FileObject *self)
     1230{
     1231    if (self->mode == MODE_CLOSED) {
     1232        PyErr_SetString(PyExc_ValueError,
     1233            "I/O operation on closed file");
     1234        return NULL;
     1235    }
     1236    Py_INCREF(self);
     1237    return (PyObject *) self;
     1238}
     1239
     1240PyDoc_STRVAR(BZ2File_exit_doc,
     1241"__exit__(*excinfo) -> None.  Closes the file.");
     1242
     1243static PyObject *
     1244BZ2File_exit(BZ2FileObject *self, PyObject *args)
     1245{
     1246    PyObject *ret = PyObject_CallMethod((PyObject *) self, "close", NULL);
     1247    if (!ret)
     1248        /* If error occurred, pass through */
     1249        return NULL;
     1250    Py_DECREF(ret);
     1251    Py_RETURN_NONE;
     1252}
     1253
    12081254
    12091255static PyObject *BZ2File_getiter(BZ2FileObject *self);
    12101256
    12111257static PyMethodDef BZ2File_methods[] = {
    1212         {"read", (PyCFunction)BZ2File_read, METH_VARARGS, BZ2File_read__doc__},
    1213         {"readline", (PyCFunction)BZ2File_readline, METH_VARARGS, BZ2File_readline__doc__},
    1214         {"readlines", (PyCFunction)BZ2File_readlines, METH_VARARGS, BZ2File_readlines__doc__},
    1215         {"xreadlines", (PyCFunction)BZ2File_getiter, METH_VARARGS, BZ2File_xreadlines__doc__},
    1216         {"write", (PyCFunction)BZ2File_write, METH_VARARGS, BZ2File_write__doc__},
    1217         {"writelines", (PyCFunction)BZ2File_writelines, METH_O, BZ2File_writelines__doc__},
    1218         {"seek", (PyCFunction)BZ2File_seek, METH_VARARGS, BZ2File_seek__doc__},
    1219         {"tell", (PyCFunction)BZ2File_tell, METH_NOARGS, BZ2File_tell__doc__},
    1220         {"close", (PyCFunction)BZ2File_close, METH_NOARGS, BZ2File_close__doc__},
    1221         {NULL,          NULL}           /* sentinel */
     1258    {"read", (PyCFunction)BZ2File_read, METH_VARARGS, BZ2File_read__doc__},
     1259    {"readline", (PyCFunction)BZ2File_readline, METH_VARARGS, BZ2File_readline__doc__},
     1260    {"readlines", (PyCFunction)BZ2File_readlines, METH_VARARGS, BZ2File_readlines__doc__},
     1261    {"xreadlines", (PyCFunction)BZ2File_getiter, METH_VARARGS, BZ2File_xreadlines__doc__},
     1262    {"write", (PyCFunction)BZ2File_write, METH_VARARGS, BZ2File_write__doc__},
     1263    {"writelines", (PyCFunction)BZ2File_writelines, METH_O, BZ2File_writelines__doc__},
     1264    {"seek", (PyCFunction)BZ2File_seek, METH_VARARGS, BZ2File_seek__doc__},
     1265    {"tell", (PyCFunction)BZ2File_tell, METH_NOARGS, BZ2File_tell__doc__},
     1266    {"close", (PyCFunction)BZ2File_close, METH_NOARGS, BZ2File_close__doc__},
     1267    {"__enter__", (PyCFunction)BZ2File_enter, METH_NOARGS, BZ2File_enter_doc},
     1268    {"__exit__", (PyCFunction)BZ2File_exit, METH_VARARGS, BZ2File_exit_doc},
     1269    {NULL,              NULL}           /* sentinel */
    12221270};
    12231271
     
    12301278BZ2File_get_newlines(BZ2FileObject *self, void *closure)
    12311279{
    1232         switch (self->f_newlinetypes) {
    1233         case NEWLINE_UNKNOWN:
    1234                 Py_INCREF(Py_None);
    1235                 return Py_None;
    1236         case NEWLINE_CR:
    1237                 return PyString_FromString("\r");
    1238         case NEWLINE_LF:
    1239                 return PyString_FromString("\n");
    1240         case NEWLINE_CR|NEWLINE_LF:
    1241                 return Py_BuildValue("(ss)", "\r", "\n");
    1242         case NEWLINE_CRLF:
    1243                 return PyString_FromString("\r\n");
    1244         case NEWLINE_CR|NEWLINE_CRLF:
    1245                 return Py_BuildValue("(ss)", "\r", "\r\n");
    1246         case NEWLINE_LF|NEWLINE_CRLF:
    1247                 return Py_BuildValue("(ss)", "\n", "\r\n");
    1248         case NEWLINE_CR|NEWLINE_LF|NEWLINE_CRLF:
    1249                 return Py_BuildValue("(sss)", "\r", "\n", "\r\n");
    1250         default:
    1251                 PyErr_Format(PyExc_SystemError,
    1252                              "Unknown newlines value 0x%x\n",
    1253                              self->f_newlinetypes);
    1254                 return NULL;
    1255         }
     1280    switch (self->f_newlinetypes) {
     1281    case NEWLINE_UNKNOWN:
     1282        Py_INCREF(Py_None);
     1283        return Py_None;
     1284    case NEWLINE_CR:
     1285        return PyString_FromString("\r");
     1286    case NEWLINE_LF:
     1287        return PyString_FromString("\n");
     1288    case NEWLINE_CR|NEWLINE_LF:
     1289        return Py_BuildValue("(ss)", "\r", "\n");
     1290    case NEWLINE_CRLF:
     1291        return PyString_FromString("\r\n");
     1292    case NEWLINE_CR|NEWLINE_CRLF:
     1293        return Py_BuildValue("(ss)", "\r", "\r\n");
     1294    case NEWLINE_LF|NEWLINE_CRLF:
     1295        return Py_BuildValue("(ss)", "\n", "\r\n");
     1296    case NEWLINE_CR|NEWLINE_LF|NEWLINE_CRLF:
     1297        return Py_BuildValue("(sss)", "\r", "\n", "\r\n");
     1298    default:
     1299        PyErr_Format(PyExc_SystemError,
     1300                     "Unknown newlines value 0x%x\n",
     1301                     self->f_newlinetypes);
     1302        return NULL;
     1303    }
    12561304}
    12571305
     
    12591307BZ2File_get_closed(BZ2FileObject *self, void *closure)
    12601308{
    1261         return PyInt_FromLong(self->mode == MODE_CLOSED);
     1309    return PyInt_FromLong(self->mode == MODE_CLOSED);
    12621310}
    12631311
     
    12651313BZ2File_get_mode(BZ2FileObject *self, void *closure)
    12661314{
    1267         return PyObject_GetAttrString(self->file, "mode");
     1315    return PyObject_GetAttrString(self->file, "mode");
    12681316}
    12691317
     
    12711319BZ2File_get_name(BZ2FileObject *self, void *closure)
    12721320{
    1273         return PyObject_GetAttrString(self->file, "name");
     1321    return PyObject_GetAttrString(self->file, "name");
    12741322}
    12751323
    12761324static PyGetSetDef BZ2File_getset[] = {
    1277         {"closed", (getter)BZ2File_get_closed, NULL,
    1278                         "True if the file is closed"},
    1279         {"newlines", (getter)BZ2File_get_newlines, NULL,
    1280                         "end-of-line convention used in this file"},
    1281         {"mode", (getter)BZ2File_get_mode, NULL,
    1282                         "file mode ('r', 'w', or 'U')"},
    1283         {"name", (getter)BZ2File_get_name, NULL,
    1284                         "file name"},
    1285         {NULL}  /* Sentinel */
     1325    {"closed", (getter)BZ2File_get_closed, NULL,
     1326                    "True if the file is closed"},
     1327    {"newlines", (getter)BZ2File_get_newlines, NULL,
     1328                    "end-of-line convention used in this file"},
     1329    {"mode", (getter)BZ2File_get_mode, NULL,
     1330                    "file mode ('r', 'w', or 'U')"},
     1331    {"name", (getter)BZ2File_get_name, NULL,
     1332                    "file name"},
     1333    {NULL}      /* Sentinel */
    12861334};
    12871335
     
    12941342
    12951343static PyMemberDef BZ2File_members[] = {
    1296         {"softspace",   T_INT,          OFF(f_softspace), 0,
    1297         "flag indicating that a space needs to be printed; used by print"},
    1298         {NULL}  /* Sentinel */
     1344    {"softspace",       T_INT,          OFF(f_softspace), 0,
     1345    "flag indicating that a space needs to be printed; used by print"},
     1346    {NULL}      /* Sentinel */
    12991347};
    13001348
     
    13051353BZ2File_init(BZ2FileObject *self, PyObject *args, PyObject *kwargs)
    13061354{
    1307         static char *kwlist[] = {"filename", "mode", "buffering",
    1308                                        "compresslevel", 0};
    1309         PyObject *name;
    1310         char *mode = "r";
    1311         int buffering = -1;
    1312         int compresslevel = 9;
    1313         int bzerror;
    1314         int mode_char = 0;
    1315 
    1316         self->size = -1;
    1317 
    1318         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|sii:BZ2File",
    1319                                         kwlist, &name, &mode, &buffering,
    1320                                         &compresslevel))
    1321                 return -1;
    1322 
    1323         if (compresslevel < 1 || compresslevel > 9) {
    1324                 PyErr_SetString(PyExc_ValueError,
    1325                                 "compresslevel must be between 1 and 9");
    1326                 return -1;
    1327         }
    1328 
    1329         for (;;) {
    1330                 int error = 0;
    1331                 switch (*mode) {
    1332                         case 'r':
    1333                         case 'w':
    1334                                 if (mode_char)
    1335                                         error = 1;
    1336                                 mode_char = *mode;
    1337                                 break;
    1338 
    1339                         case 'b':
    1340                                 break;
    1341 
    1342                         case 'U':
     1355    static char *kwlist[] = {"filename", "mode", "buffering",
     1356                                   "compresslevel", 0};
     1357    PyObject *name;
     1358    char *mode = "r";
     1359    int buffering = -1;
     1360    int compresslevel = 9;
     1361    int bzerror;
     1362    int mode_char = 0;
     1363
     1364    self->size = -1;
     1365
     1366    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|sii:BZ2File",
     1367                                    kwlist, &name, &mode, &buffering,
     1368                                    &compresslevel))
     1369        return -1;
     1370
     1371    if (compresslevel < 1 || compresslevel > 9) {
     1372        PyErr_SetString(PyExc_ValueError,
     1373                        "compresslevel must be between 1 and 9");
     1374        return -1;
     1375    }
     1376
     1377    for (;;) {
     1378        int error = 0;
     1379        switch (*mode) {
     1380            case 'r':
     1381            case 'w':
     1382                if (mode_char)
     1383                    error = 1;
     1384                mode_char = *mode;
     1385                break;
     1386
     1387            case 'b':
     1388                break;
     1389
     1390            case 'U':
    13431391#ifdef __VMS
    1344                                 self->f_univ_newline = 0;
     1392                self->f_univ_newline = 0;
    13451393#else
    1346                                 self->f_univ_newline = 1;
     1394                self->f_univ_newline = 1;
    13471395#endif
    1348                                 break;
    1349 
    1350                         default:
    1351                                 error = 1;
    1352                                 break;
    1353                 }
    1354                 if (error) {
    1355                         PyErr_Format(PyExc_ValueError,
    1356                                      "invalid mode char %c", *mode);
    1357                         return -1;
    1358                 }
    1359                 mode++;
    1360                 if (*mode == '\0')
    1361                         break;
    1362         }
    1363 
    1364         if (mode_char == 0) {
    1365                 mode_char = 'r';
    1366         }
    1367 
    1368         mode = (mode_char == 'r') ? "rb" : "wb";
    1369 
    1370         self->file = PyObject_CallFunction((PyObject*)&PyFile_Type, "(Osi)",
    1371                                            name, mode, buffering);
    1372         if (self->file == NULL)
    1373                 return -1;
    1374 
    1375         /* From now on, we have stuff to dealloc, so jump to error label
    1376         * instead of returning */
     1396                break;
     1397
     1398            default:
     1399                error = 1;
     1400                break;
     1401        }
     1402        if (error) {
     1403            PyErr_Format(PyExc_ValueError,
     1404                         "invalid mode char %c", *mode);
     1405            return -1;
     1406        }
     1407        mode++;
     1408        if (*mode == '\0')
     1409            break;
     1410    }
     1411
     1412    if (mode_char == 0) {
     1413        mode_char = 'r';
     1414    }
     1415
     1416    mode = (mode_char == 'r') ? "rb" : "wb";
     1417
     1418    self->file = PyObject_CallFunction((PyObject*)&PyFile_Type, "(Osi)",
     1419                                       name, mode, buffering);
     1420    if (self->file == NULL)
     1421        return -1;
     1422
     1423    /* From now on, we have stuff to dealloc, so jump to error label
     1424    * instead of returning */
    13771425
    13781426#ifdef WITH_THREAD
    1379         self->lock = PyThread_allocate_lock();
    1380         if (!self->lock) {
    1381                 PyErr_SetString(PyExc_MemoryError, "unable to allocate lock");
    1382                 goto error;
    1383         }
     1427    self->lock = PyThread_allocate_lock();
     1428    if (!self->lock) {
     1429        PyErr_SetString(PyExc_MemoryError, "unable to allocate lock");
     1430        goto error;
     1431    }
    13841432#endif
    13851433
    1386         if (mode_char == 'r')
    1387                 self->fp = BZ2_bzReadOpen(&bzerror,
    1388                                           PyFile_AsFile(self->file),
    1389                                           0, 0, NULL, 0);
    1390         else
    1391                 self->fp = BZ2_bzWriteOpen(&bzerror,
    1392                                            PyFile_AsFile(self->file),
    1393                                            compresslevel, 0, 0);
    1394 
    1395         if (bzerror != BZ_OK) {
    1396                 Util_CatchBZ2Error(bzerror);
    1397                 goto error;
    1398         }
    1399         PyFile_IncUseCount((PyFileObject *)self->file);
    1400 
    1401         self->mode = (mode_char == 'r') ? MODE_READ : MODE_WRITE;
    1402 
    1403         return 0;
     1434    if (mode_char == 'r')
     1435        self->fp = BZ2_bzReadOpen(&bzerror,
     1436                                  PyFile_AsFile(self->file),
     1437                                  0, 0, NULL, 0);
     1438    else
     1439        self->fp = BZ2_bzWriteOpen(&bzerror,
     1440                                   PyFile_AsFile(self->file),
     1441                                   compresslevel, 0, 0);
     1442
     1443    if (bzerror != BZ_OK) {
     1444        Util_CatchBZ2Error(bzerror);
     1445        goto error;
     1446    }
     1447    PyFile_IncUseCount((PyFileObject *)self->file);
     1448
     1449    self->mode = (mode_char == 'r') ? MODE_READ : MODE_WRITE;
     1450
     1451    return 0;
    14041452
    14051453error:
    1406         Py_CLEAR(self->file);
     1454    Py_CLEAR(self->file);
    14071455#ifdef WITH_THREAD
    1408         if (self->lock) {
    1409                 PyThread_free_lock(self->lock);
    1410                 self->lock = NULL;
    1411         }
     1456    if (self->lock) {
     1457        PyThread_free_lock(self->lock);
     1458        self->lock = NULL;
     1459    }
    14121460#endif
    1413         return -1;
     1461    return -1;
    14141462}
    14151463
     
    14171465BZ2File_dealloc(BZ2FileObject *self)
    14181466{
    1419         int bzerror;
     1467    int bzerror;
    14201468#ifdef WITH_THREAD
    1421         if (self->lock)
    1422                 PyThread_free_lock(self->lock);
     1469    if (self->lock)
     1470        PyThread_free_lock(self->lock);
    14231471#endif
    1424         switch (self->mode) {
    1425                 case MODE_READ:
    1426                 case MODE_READ_EOF:
    1427                         BZ2_bzReadClose(&bzerror, self->fp);
    1428                         break;
    1429                 case MODE_WRITE:
    1430                         BZ2_bzWriteClose(&bzerror, self->fp,
    1431                                         0, NULL, NULL);
    1432                         break;
    1433         }
    1434         if (self->fp) {
    1435                 PyFile_DecUseCount((PyFileObject *)self->file);
    1436                 self->fp = NULL;
    1437         }
    1438         Util_DropReadAhead(self);
    1439         Py_XDECREF(self->file);
    1440         Py_TYPE(self)->tp_free((PyObject *)self);
     1472    switch (self->mode) {
     1473        case MODE_READ:
     1474        case MODE_READ_EOF:
     1475            BZ2_bzReadClose(&bzerror, self->fp);
     1476            break;
     1477        case MODE_WRITE:
     1478            BZ2_bzWriteClose(&bzerror, self->fp,
     1479                            0, NULL, NULL);
     1480            break;
     1481    }
     1482    if (self->fp) {
     1483        PyFile_DecUseCount((PyFileObject *)self->file);
     1484        self->fp = NULL;
     1485    }
     1486    Util_DropReadAhead(self);
     1487    Py_XDECREF(self->file);
     1488    Py_TYPE(self)->tp_free((PyObject *)self);
    14411489}
    14421490
     
    14451493BZ2File_getiter(BZ2FileObject *self)
    14461494{
    1447         if (self->mode == MODE_CLOSED) {
    1448                 PyErr_SetString(PyExc_ValueError,
    1449                                 "I/O operation on closed file");
    1450                 return NULL;
    1451         }
    1452         Py_INCREF((PyObject*)self);
    1453         return (PyObject *)self;
     1495    if (self->mode == MODE_CLOSED) {
     1496        PyErr_SetString(PyExc_ValueError,
     1497                        "I/O operation on closed file");
     1498        return NULL;
     1499    }
     1500    Py_INCREF((PyObject*)self);
     1501    return (PyObject *)self;
    14541502}
    14551503
     
    14591507BZ2File_iternext(BZ2FileObject *self)
    14601508{
    1461         PyStringObject* ret;
    1462         ACQUIRE_LOCK(self);
    1463         if (self->mode == MODE_CLOSED) {
    1464                 RELEASE_LOCK(self);
    1465                 PyErr_SetString(PyExc_ValueError,
    1466                                 "I/O operation on closed file");
    1467                 return NULL;
    1468         }
    1469         ret = Util_ReadAheadGetLineSkip(self, 0, READAHEAD_BUFSIZE);
    1470         RELEASE_LOCK(self);
    1471         if (ret == NULL || PyString_GET_SIZE(ret) == 0) {
    1472                 Py_XDECREF(ret);
    1473                 return NULL;
    1474         }
    1475         return (PyObject *)ret;
     1509    PyStringObject* ret;
     1510    ACQUIRE_LOCK(self);
     1511    if (self->mode == MODE_CLOSED) {
     1512        RELEASE_LOCK(self);
     1513        PyErr_SetString(PyExc_ValueError,
     1514                        "I/O operation on closed file");
     1515        return NULL;
     1516    }
     1517    ret = Util_ReadAheadGetLineSkip(self, 0, READAHEAD_BUFSIZE);
     1518    RELEASE_LOCK(self);
     1519    if (ret == NULL || PyString_GET_SIZE(ret) == 0) {
     1520        Py_XDECREF(ret);
     1521        return NULL;
     1522    }
     1523    return (PyObject *)ret;
    14761524}
    14771525
     
    15011549
    15021550static PyTypeObject BZ2File_Type = {
    1503         PyVarObject_HEAD_INIT(NULL, 0)
    1504         "bz2.BZ2File",          /*tp_name*/
    1505         sizeof(BZ2FileObject),  /*tp_basicsize*/
    1506         0,                      /*tp_itemsize*/
    1507         (destructor)BZ2File_dealloc, /*tp_dealloc*/
    1508         0,                      /*tp_print*/
    1509         0,                      /*tp_getattr*/
    1510         0,                      /*tp_setattr*/
    1511         0,                      /*tp_compare*/
    1512         0,                      /*tp_repr*/
    1513         0,                      /*tp_as_number*/
    1514         0,                      /*tp_as_sequence*/
    1515         0,                      /*tp_as_mapping*/
    1516         0,                      /*tp_hash*/
    1517         0,                      /*tp_call*/
    1518         0,                      /*tp_str*/
    1519         PyObject_GenericGetAttr,/*tp_getattro*/
    1520         PyObject_GenericSetAttr,/*tp_setattro*/
    1521         0,                      /*tp_as_buffer*/
    1522         Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
    1523         BZ2File__doc__,         /*tp_doc*/
    1524         0,                      /*tp_traverse*/
    1525         0,                      /*tp_clear*/
    1526         0,                      /*tp_richcompare*/
    1527         0,                      /*tp_weaklistoffset*/
    1528         (getiterfunc)BZ2File_getiter, /*tp_iter*/
    1529         (iternextfunc)BZ2File_iternext, /*tp_iternext*/
    1530         BZ2File_methods,        /*tp_methods*/
    1531         BZ2File_members,        /*tp_members*/
    1532         BZ2File_getset,         /*tp_getset*/
    1533         0,                      /*tp_base*/
    1534         0,                      /*tp_dict*/
    1535         0,                      /*tp_descr_get*/
    1536         0,                      /*tp_descr_set*/
    1537         0,                      /*tp_dictoffset*/
    1538         (initproc)BZ2File_init, /*tp_init*/
    1539         PyType_GenericAlloc,    /*tp_alloc*/
    1540         PyType_GenericNew,      /*tp_new*/
    1541         _PyObject_Del,          /*tp_free*/
    1542         0,                      /*tp_is_gc*/
     1551    PyVarObject_HEAD_INIT(NULL, 0)
     1552    "bz2.BZ2File",              /*tp_name*/
     1553    sizeof(BZ2FileObject),      /*tp_basicsize*/
     1554    0,                          /*tp_itemsize*/
     1555    (destructor)BZ2File_dealloc, /*tp_dealloc*/
     1556    0,                          /*tp_print*/
     1557    0,                          /*tp_getattr*/
     1558    0,                          /*tp_setattr*/
     1559    0,                          /*tp_compare*/
     1560    0,                          /*tp_repr*/
     1561    0,                          /*tp_as_number*/
     1562    0,                          /*tp_as_sequence*/
     1563    0,                          /*tp_as_mapping*/
     1564    0,                          /*tp_hash*/
     1565    0,                      /*tp_call*/
     1566    0,                      /*tp_str*/
     1567    PyObject_GenericGetAttr,/*tp_getattro*/
     1568    PyObject_GenericSetAttr,/*tp_setattro*/
     1569    0,                      /*tp_as_buffer*/
     1570    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
     1571    BZ2File__doc__,         /*tp_doc*/
     1572    0,                      /*tp_traverse*/
     1573    0,                      /*tp_clear*/
     1574    0,                      /*tp_richcompare*/
     1575    0,                      /*tp_weaklistoffset*/
     1576    (getiterfunc)BZ2File_getiter, /*tp_iter*/
     1577    (iternextfunc)BZ2File_iternext, /*tp_iternext*/
     1578    BZ2File_methods,        /*tp_methods*/
     1579    BZ2File_members,        /*tp_members*/
     1580    BZ2File_getset,         /*tp_getset*/
     1581    0,                      /*tp_base*/
     1582    0,                      /*tp_dict*/
     1583    0,                      /*tp_descr_get*/
     1584    0,                      /*tp_descr_set*/
     1585    0,                      /*tp_dictoffset*/
     1586    (initproc)BZ2File_init, /*tp_init*/
     1587    PyType_GenericAlloc,    /*tp_alloc*/
     1588    PyType_GenericNew,      /*tp_new*/
     1589    _PyObject_Del,          /*tp_free*/
     1590    0,                      /*tp_is_gc*/
    15431591};
    15441592
     
    15591607BZ2Comp_compress(BZ2CompObject *self, PyObject *args)
    15601608{
    1561         Py_buffer pdata;
    1562         char *data;
    1563         int datasize;
    1564         int bufsize = SMALLCHUNK;
    1565         PY_LONG_LONG totalout;
    1566         PyObject *ret = NULL;
    1567         bz_stream *bzs = &self->bzs;
    1568         int bzerror;
    1569 
    1570         if (!PyArg_ParseTuple(args, "s*:compress", &pdata))
    1571                 return NULL;
    1572         data = pdata.buf;
    1573         datasize = pdata.len;
    1574 
    1575         if (datasize == 0) {
    1576                 PyBuffer_Release(&pdata);
    1577                 return PyString_FromString("");
    1578         }
    1579 
    1580         ACQUIRE_LOCK(self);
    1581         if (!self->running) {
    1582                 PyErr_SetString(PyExc_ValueError,
    1583                                 "this object was already flushed");
    1584                 goto error;
    1585         }
    1586 
    1587         ret = PyString_FromStringAndSize(NULL, bufsize);
    1588         if (!ret)
    1589                 goto error;
    1590 
    1591         bzs->next_in = data;
    1592         bzs->avail_in = datasize;
    1593         bzs->next_out = BUF(ret);
    1594         bzs->avail_out = bufsize;
    1595 
    1596         totalout = BZS_TOTAL_OUT(bzs);
    1597 
    1598         for (;;) {
    1599                 Py_BEGIN_ALLOW_THREADS
    1600                 bzerror = BZ2_bzCompress(bzs, BZ_RUN);
    1601                 Py_END_ALLOW_THREADS
    1602                 if (bzerror != BZ_RUN_OK) {
    1603                         Util_CatchBZ2Error(bzerror);
    1604                         goto error;
    1605                 }
    1606                 if (bzs->avail_in == 0)
    1607                         break; /* no more input data */
    1608                 if (bzs->avail_out == 0) {
    1609                         bufsize = Util_NewBufferSize(bufsize);
    1610                         if (_PyString_Resize(&ret, bufsize) < 0) {
    1611                                 BZ2_bzCompressEnd(bzs);
    1612                                 goto error;
    1613                         }
    1614                         bzs->next_out = BUF(ret) + (BZS_TOTAL_OUT(bzs)
    1615                                                     - totalout);
    1616                         bzs->avail_out = bufsize - (bzs->next_out - BUF(ret));
    1617                 }
    1618         }
    1619 
    1620         _PyString_Resize(&ret, (Py_ssize_t)(BZS_TOTAL_OUT(bzs) - totalout));
    1621 
    1622         RELEASE_LOCK(self);
    1623         PyBuffer_Release(&pdata);
    1624         return ret;
     1609    Py_buffer pdata;
     1610    size_t input_left;
     1611    size_t output_size = 0;
     1612    PyObject *ret = NULL;
     1613    bz_stream *bzs = &self->bzs;
     1614    int bzerror;
     1615
     1616    if (!PyArg_ParseTuple(args, "s*:compress", &pdata))
     1617        return NULL;
     1618
     1619    if (pdata.len == 0) {
     1620        PyBuffer_Release(&pdata);
     1621        return PyString_FromString("");
     1622    }
     1623
     1624    ACQUIRE_LOCK(self);
     1625    if (!self->running) {
     1626        PyErr_SetString(PyExc_ValueError,
     1627                        "this object was already flushed");
     1628        goto error;
     1629    }
     1630
     1631    ret = PyString_FromStringAndSize(NULL, SMALLCHUNK);
     1632    if (!ret)
     1633        goto error;
     1634
     1635    bzs->next_in = pdata.buf;
     1636    bzs->avail_in = MIN(pdata.len, UINT_MAX);
     1637    input_left = pdata.len - bzs->avail_in;
     1638
     1639    bzs->next_out = BUF(ret);
     1640    bzs->avail_out = PyString_GET_SIZE(ret);
     1641
     1642    for (;;) {
     1643        char *saved_next_out;
     1644
     1645        Py_BEGIN_ALLOW_THREADS
     1646        saved_next_out = bzs->next_out;
     1647        bzerror = BZ2_bzCompress(bzs, BZ_RUN);
     1648        output_size += bzs->next_out - saved_next_out;
     1649        Py_END_ALLOW_THREADS
     1650
     1651        if (bzerror != BZ_RUN_OK) {
     1652            Util_CatchBZ2Error(bzerror);
     1653            goto error;
     1654        }
     1655        if (bzs->avail_in == 0) {
     1656            if (input_left == 0)
     1657                break; /* no more input data */
     1658            bzs->avail_in = MIN(input_left, UINT_MAX);
     1659            input_left -= bzs->avail_in;
     1660        }
     1661        if (bzs->avail_out == 0) {
     1662            size_t buffer_left = PyString_GET_SIZE(ret) - output_size;
     1663            if (buffer_left == 0) {
     1664                if (Util_GrowBuffer(&ret) < 0) {
     1665                    BZ2_bzCompressEnd(bzs);
     1666                    goto error;
     1667                }
     1668                bzs->next_out = BUF(ret) + output_size;
     1669                buffer_left = PyString_GET_SIZE(ret) - output_size;
     1670            }
     1671            bzs->avail_out = MIN(buffer_left, UINT_MAX);
     1672        }
     1673    }
     1674
     1675    if (_PyString_Resize(&ret, output_size) < 0)
     1676        goto error;
     1677
     1678    RELEASE_LOCK(self);
     1679    PyBuffer_Release(&pdata);
     1680    return ret;
    16251681
    16261682error:
    1627         RELEASE_LOCK(self);
    1628         PyBuffer_Release(&pdata);
    1629         Py_XDECREF(ret);
    1630         return NULL;
     1683    RELEASE_LOCK(self);
     1684    PyBuffer_Release(&pdata);
     1685    Py_XDECREF(ret);
     1686    return NULL;
    16311687}
    16321688
     
    16411697BZ2Comp_flush(BZ2CompObject *self)
    16421698{
    1643         int bufsize = SMALLCHUNK;
    1644         PyObject *ret = NULL;
    1645         bz_stream *bzs = &self->bzs;
    1646         PY_LONG_LONG totalout;
    1647         int bzerror;
    1648 
    1649         ACQUIRE_LOCK(self);
    1650         if (!self->running) {
    1651                 PyErr_SetString(PyExc_ValueError, "object was already "
    1652                                                   "flushed");
    1653                 goto error;
    1654         }
    1655         self->running = 0;
    1656 
    1657         ret = PyString_FromStringAndSize(NULL, bufsize);
    1658         if (!ret)
    1659                 goto error;
    1660 
    1661         bzs->next_out = BUF(ret);
    1662         bzs->avail_out = bufsize;
    1663 
    1664         totalout = BZS_TOTAL_OUT(bzs);
    1665 
    1666         for (;;) {
    1667                 Py_BEGIN_ALLOW_THREADS
    1668                 bzerror = BZ2_bzCompress(bzs, BZ_FINISH);
    1669                 Py_END_ALLOW_THREADS
    1670                 if (bzerror == BZ_STREAM_END) {
    1671                         break;
    1672                 } else if (bzerror != BZ_FINISH_OK) {
    1673                         Util_CatchBZ2Error(bzerror);
    1674                         goto error;
    1675                 }
    1676                 if (bzs->avail_out == 0) {
    1677                         bufsize = Util_NewBufferSize(bufsize);
    1678                         if (_PyString_Resize(&ret, bufsize) < 0)
    1679                                 goto error;
    1680                         bzs->next_out = BUF(ret);
    1681                         bzs->next_out = BUF(ret) + (BZS_TOTAL_OUT(bzs)
    1682                                                     - totalout);
    1683                         bzs->avail_out = bufsize - (bzs->next_out - BUF(ret));
    1684                 }
    1685         }
    1686 
    1687         if (bzs->avail_out != 0)
    1688                 _PyString_Resize(&ret, (Py_ssize_t)(BZS_TOTAL_OUT(bzs) - totalout));
    1689 
    1690         RELEASE_LOCK(self);
    1691         return ret;
     1699    size_t output_size = 0;
     1700    PyObject *ret = NULL;
     1701    bz_stream *bzs = &self->bzs;
     1702    int bzerror;
     1703
     1704    ACQUIRE_LOCK(self);
     1705    if (!self->running) {
     1706        PyErr_SetString(PyExc_ValueError, "object was already flushed");
     1707        goto error;
     1708    }
     1709    self->running = 0;
     1710
     1711    ret = PyString_FromStringAndSize(NULL, SMALLCHUNK);
     1712    if (!ret)
     1713        goto error;
     1714
     1715    bzs->next_out = BUF(ret);
     1716    bzs->avail_out = PyString_GET_SIZE(ret);
     1717
     1718    for (;;) {
     1719        char *saved_next_out;
     1720
     1721        Py_BEGIN_ALLOW_THREADS
     1722        saved_next_out = bzs->next_out;
     1723        bzerror = BZ2_bzCompress(bzs, BZ_FINISH);
     1724        output_size += bzs->next_out - saved_next_out;
     1725        Py_END_ALLOW_THREADS
     1726
     1727        if (bzerror == BZ_STREAM_END) {
     1728            break;
     1729        } else if (bzerror != BZ_FINISH_OK) {
     1730            Util_CatchBZ2Error(bzerror);
     1731            goto error;
     1732        }
     1733        if (bzs->avail_out == 0) {
     1734            size_t buffer_left = PyString_GET_SIZE(ret) - output_size;
     1735            if (buffer_left == 0) {
     1736                if (Util_GrowBuffer(&ret) < 0)
     1737                    goto error;
     1738                bzs->next_out = BUF(ret) + output_size;
     1739                buffer_left = PyString_GET_SIZE(ret) - output_size;
     1740            }
     1741            bzs->avail_out = MIN(buffer_left, UINT_MAX);
     1742        }
     1743    }
     1744
     1745    if (output_size != PyString_GET_SIZE(ret))
     1746        if (_PyString_Resize(&ret, output_size) < 0)
     1747            goto error;
     1748
     1749    RELEASE_LOCK(self);
     1750    return ret;
    16921751
    16931752error:
    1694         RELEASE_LOCK(self);
    1695         Py_XDECREF(ret);
    1696         return NULL;
     1753    RELEASE_LOCK(self);
     1754    Py_XDECREF(ret);
     1755    return NULL;
    16971756}
    16981757
    16991758static PyMethodDef BZ2Comp_methods[] = {
    1700         {"compress", (PyCFunction)BZ2Comp_compress, METH_VARARGS,
    1701         BZ2Comp_compress__doc__},
    1702         {"flush", (PyCFunction)BZ2Comp_flush, METH_NOARGS,
    1703         BZ2Comp_flush__doc__},
    1704         {NULL,          NULL}           /* sentinel */
     1759    {"compress", (PyCFunction)BZ2Comp_compress, METH_VARARGS,
     1760    BZ2Comp_compress__doc__},
     1761    {"flush", (PyCFunction)BZ2Comp_flush, METH_NOARGS,
     1762    BZ2Comp_flush__doc__},
     1763    {NULL,              NULL}           /* sentinel */
    17051764};
    17061765
     
    17121771BZ2Comp_init(BZ2CompObject *self, PyObject *args, PyObject *kwargs)
    17131772{
    1714         int compresslevel = 9;
    1715         int bzerror;
    1716         static char *kwlist[] = {"compresslevel", 0};
    1717 
    1718         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:BZ2Compressor",
    1719                                         kwlist, &compresslevel))
    1720                 return -1;
    1721 
    1722         if (compresslevel < 1 || compresslevel > 9) {
    1723                 PyErr_SetString(PyExc_ValueError,
    1724                                 "compresslevel must be between 1 and 9");
    1725                 goto error;
    1726         }
     1773    int compresslevel = 9;
     1774    int bzerror;
     1775    static char *kwlist[] = {"compresslevel", 0};
     1776
     1777    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:BZ2Compressor",
     1778                                    kwlist, &compresslevel))
     1779        return -1;
     1780
     1781    if (compresslevel < 1 || compresslevel > 9) {
     1782        PyErr_SetString(PyExc_ValueError,
     1783                        "compresslevel must be between 1 and 9");
     1784        goto error;
     1785    }
    17271786
    17281787#ifdef WITH_THREAD
    1729         self->lock = PyThread_allocate_lock();
    1730         if (!self->lock) {
    1731                 PyErr_SetString(PyExc_MemoryError, "unable to allocate lock");
    1732                 goto error;
    1733         }
     1788    self->lock = PyThread_allocate_lock();
     1789    if (!self->lock) {
     1790        PyErr_SetString(PyExc_MemoryError, "unable to allocate lock");
     1791        goto error;
     1792    }
    17341793#endif
    17351794
    1736         memset(&self->bzs, 0, sizeof(bz_stream));
    1737         bzerror = BZ2_bzCompressInit(&self->bzs, compresslevel, 0, 0);
    1738         if (bzerror != BZ_OK) {
    1739                 Util_CatchBZ2Error(bzerror);
    1740                 goto error;
    1741         }
    1742 
    1743         self->running = 1;
    1744 
    1745         return 0;
     1795    memset(&self->bzs, 0, sizeof(bz_stream));
     1796    bzerror = BZ2_bzCompressInit(&self->bzs, compresslevel, 0, 0);
     1797    if (bzerror != BZ_OK) {
     1798        Util_CatchBZ2Error(bzerror);
     1799        goto error;
     1800    }
     1801
     1802    self->running = 1;
     1803
     1804    return 0;
    17461805error:
    17471806#ifdef WITH_THREAD
    1748         if (self->lock) {
    1749                 PyThread_free_lock(self->lock);
    1750                 self->lock = NULL;
    1751         }
     1807    if (self->lock) {
     1808        PyThread_free_lock(self->lock);
     1809        self->lock = NULL;
     1810    }
    17521811#endif
    1753         return -1;
     1812    return -1;
    17541813}
    17551814
     
    17581817{
    17591818#ifdef WITH_THREAD
    1760         if (self->lock)
    1761                 PyThread_free_lock(self->lock);
     1819    if (self->lock)
     1820        PyThread_free_lock(self->lock);
    17621821#endif
    1763         BZ2_bzCompressEnd(&self->bzs);
    1764         Py_TYPE(self)->tp_free((PyObject *)self);
     1822    BZ2_bzCompressEnd(&self->bzs);
     1823    Py_TYPE(self)->tp_free((PyObject *)self);
    17651824}
    17661825
     
    17791838
    17801839static PyTypeObject BZ2Comp_Type = {
    1781         PyVarObject_HEAD_INIT(NULL, 0)
    1782         "bz2.BZ2Compressor",    /*tp_name*/
    1783         sizeof(BZ2CompObject),  /*tp_basicsize*/
    1784         0,                      /*tp_itemsize*/
    1785         (destructor)BZ2Comp_dealloc, /*tp_dealloc*/
    1786         0,                      /*tp_print*/
    1787         0,                      /*tp_getattr*/
    1788         0,                      /*tp_setattr*/
    1789         0,                      /*tp_compare*/
    1790         0,                      /*tp_repr*/
    1791         0,                      /*tp_as_number*/
    1792         0,                      /*tp_as_sequence*/
    1793         0,                      /*tp_as_mapping*/
    1794         0,                      /*tp_hash*/
    1795         0,                      /*tp_call*/
    1796         0,                      /*tp_str*/
    1797         PyObject_GenericGetAttr,/*tp_getattro*/
    1798         PyObject_GenericSetAttr,/*tp_setattro*/
    1799         0,                      /*tp_as_buffer*/
    1800         Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
    1801         BZ2Comp__doc__,         /*tp_doc*/
    1802         0,                      /*tp_traverse*/
    1803         0,                      /*tp_clear*/
    1804         0,                      /*tp_richcompare*/
    1805         0,                      /*tp_weaklistoffset*/
    1806         0,                      /*tp_iter*/
    1807         0,                      /*tp_iternext*/
    1808         BZ2Comp_methods,        /*tp_methods*/
    1809         0,                      /*tp_members*/
    1810         0,                      /*tp_getset*/
    1811         0,                      /*tp_base*/
    1812         0,                      /*tp_dict*/
    1813         0,                      /*tp_descr_get*/
    1814         0,                      /*tp_descr_set*/
    1815         0,                      /*tp_dictoffset*/
    1816         (initproc)BZ2Comp_init, /*tp_init*/
    1817         PyType_GenericAlloc,    /*tp_alloc*/
    1818         PyType_GenericNew,      /*tp_new*/
    1819         _PyObject_Del,          /*tp_free*/
    1820         0,                      /*tp_is_gc*/
     1840    PyVarObject_HEAD_INIT(NULL, 0)
     1841    "bz2.BZ2Compressor",        /*tp_name*/
     1842    sizeof(BZ2CompObject),      /*tp_basicsize*/
     1843    0,                          /*tp_itemsize*/
     1844    (destructor)BZ2Comp_dealloc, /*tp_dealloc*/
     1845    0,                          /*tp_print*/
     1846    0,                          /*tp_getattr*/
     1847    0,                          /*tp_setattr*/
     1848    0,                          /*tp_compare*/
     1849    0,                          /*tp_repr*/
     1850    0,                          /*tp_as_number*/
     1851    0,                          /*tp_as_sequence*/
     1852    0,                          /*tp_as_mapping*/
     1853    0,                          /*tp_hash*/
     1854    0,                      /*tp_call*/
     1855    0,                      /*tp_str*/
     1856    PyObject_GenericGetAttr,/*tp_getattro*/
     1857    PyObject_GenericSetAttr,/*tp_setattro*/
     1858    0,                      /*tp_as_buffer*/
     1859    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
     1860    BZ2Comp__doc__,         /*tp_doc*/
     1861    0,                      /*tp_traverse*/
     1862    0,                      /*tp_clear*/
     1863    0,                      /*tp_richcompare*/
     1864    0,                      /*tp_weaklistoffset*/
     1865    0,                      /*tp_iter*/
     1866    0,                      /*tp_iternext*/
     1867    BZ2Comp_methods,        /*tp_methods*/
     1868    0,                      /*tp_members*/
     1869    0,                      /*tp_getset*/
     1870    0,                      /*tp_base*/
     1871    0,                      /*tp_dict*/
     1872    0,                      /*tp_descr_get*/
     1873    0,                      /*tp_descr_set*/
     1874    0,                      /*tp_dictoffset*/
     1875    (initproc)BZ2Comp_init, /*tp_init*/
     1876    PyType_GenericAlloc,    /*tp_alloc*/
     1877    PyType_GenericNew,      /*tp_new*/
     1878    _PyObject_Del,          /*tp_free*/
     1879    0,                      /*tp_is_gc*/
    18211880};
    18221881
     
    18291888
    18301889static PyMemberDef BZ2Decomp_members[] = {
    1831         {"unused_data", T_OBJECT, OFF(unused_data), RO},
    1832         {NULL}  /* Sentinel */
     1890    {"unused_data", T_OBJECT, OFF(unused_data), RO},
     1891    {NULL}      /* Sentinel */
    18331892};
    18341893
     
    18501909BZ2Decomp_decompress(BZ2DecompObject *self, PyObject *args)
    18511910{
    1852         Py_buffer pdata;
    1853         char *data;
    1854         int datasize;
    1855         int bufsize = SMALLCHUNK;
    1856         PY_LONG_LONG totalout;
    1857         PyObject *ret = NULL;
    1858         bz_stream *bzs = &self->bzs;
    1859         int bzerror;
    1860 
    1861         if (!PyArg_ParseTuple(args, "s*:decompress", &pdata))
    1862                 return NULL;
    1863         data = pdata.buf;
    1864         datasize = pdata.len;
    1865 
    1866         ACQUIRE_LOCK(self);
    1867         if (!self->running) {
    1868                 PyErr_SetString(PyExc_EOFError, "end of stream was "
    1869                                                 "already found");
    1870                 goto error;
    1871         }
    1872 
    1873         ret = PyString_FromStringAndSize(NULL, bufsize);
    1874         if (!ret)
    1875                 goto error;
    1876 
    1877         bzs->next_in = data;
    1878         bzs->avail_in = datasize;
    1879         bzs->next_out = BUF(ret);
    1880         bzs->avail_out = bufsize;
    1881 
    1882         totalout = BZS_TOTAL_OUT(bzs);
    1883 
    1884         for (;;) {
    1885                 Py_BEGIN_ALLOW_THREADS
    1886                 bzerror = BZ2_bzDecompress(bzs);
    1887                 Py_END_ALLOW_THREADS
    1888                 if (bzerror == BZ_STREAM_END) {
    1889                         if (bzs->avail_in != 0) {
    1890                                 Py_DECREF(self->unused_data);
    1891                                 self->unused_data =
    1892                                     PyString_FromStringAndSize(bzs->next_in,
    1893                                                                bzs->avail_in);
    1894                         }
    1895                         self->running = 0;
    1896                         break;
    1897                 }
    1898                 if (bzerror != BZ_OK) {
    1899                         Util_CatchBZ2Error(bzerror);
    1900                         goto error;
    1901                 }
    1902                 if (bzs->avail_in == 0)
    1903                         break; /* no more input data */
    1904                 if (bzs->avail_out == 0) {
    1905                         bufsize = Util_NewBufferSize(bufsize);
    1906                         if (_PyString_Resize(&ret, bufsize) < 0) {
    1907                                 BZ2_bzDecompressEnd(bzs);
    1908                                 goto error;
    1909                         }
    1910                         bzs->next_out = BUF(ret);
    1911                         bzs->next_out = BUF(ret) + (BZS_TOTAL_OUT(bzs)
    1912                                                     - totalout);
    1913                         bzs->avail_out = bufsize - (bzs->next_out - BUF(ret));
    1914                 }
    1915         }
    1916 
    1917         if (bzs->avail_out != 0)
    1918                 _PyString_Resize(&ret, (Py_ssize_t)(BZS_TOTAL_OUT(bzs) - totalout));
    1919 
    1920         RELEASE_LOCK(self);
    1921         PyBuffer_Release(&pdata);
    1922         return ret;
     1911    Py_buffer pdata;
     1912    size_t input_left;
     1913    size_t output_size = 0;
     1914    PyObject *ret = NULL;
     1915    bz_stream *bzs = &self->bzs;
     1916    int bzerror;
     1917
     1918    if (!PyArg_ParseTuple(args, "s*:decompress", &pdata))
     1919        return NULL;
     1920
     1921    ACQUIRE_LOCK(self);
     1922    if (!self->running) {
     1923        PyErr_SetString(PyExc_EOFError, "end of stream was "
     1924                                        "already found");
     1925        goto error;
     1926    }
     1927
     1928    ret = PyString_FromStringAndSize(NULL, SMALLCHUNK);
     1929    if (!ret)
     1930        goto error;
     1931
     1932    bzs->next_in = pdata.buf;
     1933    bzs->avail_in = MIN(pdata.len, UINT_MAX);
     1934    input_left = pdata.len - bzs->avail_in;
     1935
     1936    bzs->next_out = BUF(ret);
     1937    bzs->avail_out = PyString_GET_SIZE(ret);
     1938
     1939    for (;;) {
     1940        char *saved_next_out;
     1941
     1942        Py_BEGIN_ALLOW_THREADS
     1943        saved_next_out = bzs->next_out;
     1944        bzerror = BZ2_bzDecompress(bzs);
     1945        output_size += bzs->next_out - saved_next_out;
     1946        Py_END_ALLOW_THREADS
     1947
     1948        if (bzerror == BZ_STREAM_END) {
     1949            self->running = 0;
     1950            input_left += bzs->avail_in;
     1951            if (input_left != 0) {
     1952                Py_DECREF(self->unused_data);
     1953                self->unused_data =
     1954                    PyString_FromStringAndSize(bzs->next_in, input_left);
     1955                if (self->unused_data == NULL)
     1956                    goto error;
     1957            }
     1958            break;
     1959        }
     1960        if (bzerror != BZ_OK) {
     1961            Util_CatchBZ2Error(bzerror);
     1962            goto error;
     1963        }
     1964        if (bzs->avail_in == 0) {
     1965            if (input_left == 0)
     1966                break; /* no more input data */
     1967            bzs->avail_in = MIN(input_left, UINT_MAX);
     1968            input_left -= bzs->avail_in;
     1969        }
     1970        if (bzs->avail_out == 0) {
     1971            size_t buffer_left = PyString_GET_SIZE(ret) - output_size;
     1972            if (buffer_left == 0) {
     1973                if (Util_GrowBuffer(&ret) < 0) {
     1974                    BZ2_bzDecompressEnd(bzs);
     1975                    goto error;
     1976                }
     1977                bzs->next_out = BUF(ret) + output_size;
     1978                buffer_left = PyString_GET_SIZE(ret) - output_size;
     1979            }
     1980            bzs->avail_out = MIN(buffer_left, UINT_MAX);
     1981        }
     1982    }
     1983
     1984    if (output_size != PyString_GET_SIZE(ret))
     1985        if (_PyString_Resize(&ret, output_size) < 0)
     1986            goto error;
     1987
     1988    RELEASE_LOCK(self);
     1989    PyBuffer_Release(&pdata);
     1990    return ret;
    19231991
    19241992error:
    1925         RELEASE_LOCK(self);
    1926         PyBuffer_Release(&pdata);
    1927         Py_XDECREF(ret);
    1928         return NULL;
     1993    RELEASE_LOCK(self);
     1994    PyBuffer_Release(&pdata);
     1995    Py_XDECREF(ret);
     1996    return NULL;
    19291997}
    19301998
    19311999static PyMethodDef BZ2Decomp_methods[] = {
    1932         {"decompress", (PyCFunction)BZ2Decomp_decompress, METH_VARARGS, BZ2Decomp_decompress__doc__},
    1933         {NULL,          NULL}           /* sentinel */
     2000    {"decompress", (PyCFunction)BZ2Decomp_decompress, METH_VARARGS, BZ2Decomp_decompress__doc__},
     2001    {NULL,              NULL}           /* sentinel */
    19342002};
    19352003
     
    19412009BZ2Decomp_init(BZ2DecompObject *self, PyObject *args, PyObject *kwargs)
    19422010{
    1943         int bzerror;
    1944 
    1945         if (!PyArg_ParseTuple(args, ":BZ2Decompressor"))
    1946                 return -1;
     2011    int bzerror;
     2012
     2013    if (!PyArg_ParseTuple(args, ":BZ2Decompressor"))
     2014        return -1;
    19472015
    19482016#ifdef WITH_THREAD
    1949         self->lock = PyThread_allocate_lock();
    1950         if (!self->lock) {
    1951                 PyErr_SetString(PyExc_MemoryError, "unable to allocate lock");
    1952                 goto error;
    1953         }
     2017    self->lock = PyThread_allocate_lock();
     2018    if (!self->lock) {
     2019        PyErr_SetString(PyExc_MemoryError, "unable to allocate lock");
     2020        goto error;
     2021    }
    19542022#endif
    19552023
    1956         self->unused_data = PyString_FromString("");
    1957         if (!self->unused_data)
    1958                 goto error;
    1959 
    1960         memset(&self->bzs, 0, sizeof(bz_stream));
    1961         bzerror = BZ2_bzDecompressInit(&self->bzs, 0, 0);
    1962         if (bzerror != BZ_OK) {
    1963                 Util_CatchBZ2Error(bzerror);
    1964                 goto error;
    1965         }
    1966 
    1967         self->running = 1;
    1968 
    1969         return 0;
     2024    self->unused_data = PyString_FromString("");
     2025    if (!self->unused_data)
     2026        goto error;
     2027
     2028    memset(&self->bzs, 0, sizeof(bz_stream));
     2029    bzerror = BZ2_bzDecompressInit(&self->bzs, 0, 0);
     2030    if (bzerror != BZ_OK) {
     2031        Util_CatchBZ2Error(bzerror);
     2032        goto error;
     2033    }
     2034
     2035    self->running = 1;
     2036
     2037    return 0;
    19702038
    19712039error:
    19722040#ifdef WITH_THREAD
    1973         if (self->lock) {
    1974                 PyThread_free_lock(self->lock);
    1975                 self->lock = NULL;
    1976         }
     2041    if (self->lock) {
     2042        PyThread_free_lock(self->lock);
     2043        self->lock = NULL;
     2044    }
    19772045#endif
    1978         Py_CLEAR(self->unused_data);
    1979         return -1;
     2046    Py_CLEAR(self->unused_data);
     2047    return -1;
    19802048}
    19812049
     
    19842052{
    19852053#ifdef WITH_THREAD
    1986         if (self->lock)
    1987                 PyThread_free_lock(self->lock);
     2054    if (self->lock)
     2055        PyThread_free_lock(self->lock);
    19882056#endif
    1989         Py_XDECREF(self->unused_data);
    1990         BZ2_bzDecompressEnd(&self->bzs);
    1991         Py_TYPE(self)->tp_free((PyObject *)self);
     2057    Py_XDECREF(self->unused_data);
     2058    BZ2_bzDecompressEnd(&self->bzs);
     2059    Py_TYPE(self)->tp_free((PyObject *)self);
    19922060}
    19932061
     
    20052073
    20062074static PyTypeObject BZ2Decomp_Type = {
    2007         PyVarObject_HEAD_INIT(NULL, 0)
    2008         "bz2.BZ2Decompressor",  /*tp_name*/
    2009         sizeof(BZ2DecompObject), /*tp_basicsize*/
    2010         0,                      /*tp_itemsize*/
    2011         (destructor)BZ2Decomp_dealloc, /*tp_dealloc*/
    2012         0,                      /*tp_print*/
    2013         0,                      /*tp_getattr*/
    2014         0,                      /*tp_setattr*/
    2015         0,                      /*tp_compare*/
    2016         0,                      /*tp_repr*/
    2017         0,                      /*tp_as_number*/
    2018         0,                      /*tp_as_sequence*/
    2019         0,                      /*tp_as_mapping*/
    2020         0,                      /*tp_hash*/
    2021         0,                      /*tp_call*/
    2022         0,                      /*tp_str*/
    2023         PyObject_GenericGetAttr,/*tp_getattro*/
    2024         PyObject_GenericSetAttr,/*tp_setattro*/
    2025         0,                      /*tp_as_buffer*/
    2026         Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
    2027         BZ2Decomp__doc__,       /*tp_doc*/
    2028         0,                      /*tp_traverse*/
    2029         0,                      /*tp_clear*/
    2030         0,                      /*tp_richcompare*/
    2031         0,                      /*tp_weaklistoffset*/
    2032         0,                      /*tp_iter*/
    2033         0,                      /*tp_iternext*/
    2034         BZ2Decomp_methods,      /*tp_methods*/
    2035         BZ2Decomp_members,      /*tp_members*/
    2036         0,                      /*tp_getset*/
    2037         0,                      /*tp_base*/
    2038         0,                      /*tp_dict*/
    2039         0,                      /*tp_descr_get*/
    2040         0,                      /*tp_descr_set*/
    2041         0,                      /*tp_dictoffset*/
    2042         (initproc)BZ2Decomp_init, /*tp_init*/
    2043         PyType_GenericAlloc,    /*tp_alloc*/
    2044         PyType_GenericNew,      /*tp_new*/
    2045         _PyObject_Del,          /*tp_free*/
    2046         0,                      /*tp_is_gc*/
     2075    PyVarObject_HEAD_INIT(NULL, 0)
     2076    "bz2.BZ2Decompressor",      /*tp_name*/
     2077    sizeof(BZ2DecompObject), /*tp_basicsize*/
     2078    0,                          /*tp_itemsize*/
     2079    (destructor)BZ2Decomp_dealloc, /*tp_dealloc*/
     2080    0,                          /*tp_print*/
     2081    0,                          /*tp_getattr*/
     2082    0,                          /*tp_setattr*/
     2083    0,                          /*tp_compare*/
     2084    0,                          /*tp_repr*/
     2085    0,                          /*tp_as_number*/
     2086    0,                          /*tp_as_sequence*/
     2087    0,                          /*tp_as_mapping*/
     2088    0,                          /*tp_hash*/
     2089    0,                      /*tp_call*/
     2090    0,                      /*tp_str*/
     2091    PyObject_GenericGetAttr,/*tp_getattro*/
     2092    PyObject_GenericSetAttr,/*tp_setattro*/
     2093    0,                      /*tp_as_buffer*/
     2094    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
     2095    BZ2Decomp__doc__,       /*tp_doc*/
     2096    0,                      /*tp_traverse*/
     2097    0,                      /*tp_clear*/
     2098    0,                      /*tp_richcompare*/
     2099    0,                      /*tp_weaklistoffset*/
     2100    0,                      /*tp_iter*/
     2101    0,                      /*tp_iternext*/
     2102    BZ2Decomp_methods,      /*tp_methods*/
     2103    BZ2Decomp_members,      /*tp_members*/
     2104    0,                      /*tp_getset*/
     2105    0,                      /*tp_base*/
     2106    0,                      /*tp_dict*/
     2107    0,                      /*tp_descr_get*/
     2108    0,                      /*tp_descr_set*/
     2109    0,                      /*tp_dictoffset*/
     2110    (initproc)BZ2Decomp_init, /*tp_init*/
     2111    PyType_GenericAlloc,    /*tp_alloc*/
     2112    PyType_GenericNew,      /*tp_new*/
     2113    _PyObject_Del,          /*tp_free*/
     2114    0,                      /*tp_is_gc*/
    20472115};
    20482116
     
    20622130bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
    20632131{
    2064         int compresslevel=9;
    2065         Py_buffer pdata;
    2066         char *data;
    2067         int datasize;
    2068         int bufsize;
    2069         PyObject *ret = NULL;
    2070         bz_stream _bzs;
    2071         bz_stream *bzs = &_bzs;
    2072         int bzerror;
    2073         static char *kwlist[] = {"data", "compresslevel", 0};
    2074 
    2075         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s*|i",
    2076                                          kwlist, &pdata,
    2077                                          &compresslevel))
    2078                 return NULL;
    2079         data = pdata.buf;
    2080         datasize = pdata.len;
    2081 
    2082         if (compresslevel < 1 || compresslevel > 9) {
    2083                 PyErr_SetString(PyExc_ValueError,
    2084                                 "compresslevel must be between 1 and 9");
    2085                 PyBuffer_Release(&pdata);
    2086                 return NULL;
    2087         }
    2088 
    2089         /* Conforming to bz2 manual, this is large enough to fit compressed
    2090          * data in one shot. We will check it later anyway. */
    2091         bufsize = datasize + (datasize/100+1) + 600;
    2092 
    2093         ret = PyString_FromStringAndSize(NULL, bufsize);
    2094         if (!ret) {
    2095                 PyBuffer_Release(&pdata);
    2096                 return NULL;
    2097         }
    2098 
    2099         memset(bzs, 0, sizeof(bz_stream));
    2100 
    2101         bzs->next_in = data;
    2102         bzs->avail_in = datasize;
    2103         bzs->next_out = BUF(ret);
    2104         bzs->avail_out = bufsize;
    2105 
    2106         bzerror = BZ2_bzCompressInit(bzs, compresslevel, 0, 0);
    2107         if (bzerror != BZ_OK) {
    2108                 Util_CatchBZ2Error(bzerror);
    2109                 PyBuffer_Release(&pdata);
    2110                 Py_DECREF(ret);
    2111                 return NULL;
    2112         }
    2113 
    2114         for (;;) {
    2115                 Py_BEGIN_ALLOW_THREADS
    2116                 bzerror = BZ2_bzCompress(bzs, BZ_FINISH);
    2117                 Py_END_ALLOW_THREADS
    2118                 if (bzerror == BZ_STREAM_END) {
    2119                         break;
    2120                 } else if (bzerror != BZ_FINISH_OK) {
    2121                         BZ2_bzCompressEnd(bzs);
    2122                         Util_CatchBZ2Error(bzerror);
    2123                         PyBuffer_Release(&pdata);
    2124                         Py_DECREF(ret);
    2125                         return NULL;
    2126                 }
    2127                 if (bzs->avail_out == 0) {
    2128                         bufsize = Util_NewBufferSize(bufsize);
    2129                         if (_PyString_Resize(&ret, bufsize) < 0) {
    2130                                 BZ2_bzCompressEnd(bzs);
    2131                                 PyBuffer_Release(&pdata);
    2132                                 Py_DECREF(ret);
    2133                                 return NULL;
    2134                         }
    2135                         bzs->next_out = BUF(ret) + BZS_TOTAL_OUT(bzs);
    2136                         bzs->avail_out = bufsize - (bzs->next_out - BUF(ret));
    2137                 }
    2138         }
    2139 
    2140         if (bzs->avail_out != 0)
    2141                 _PyString_Resize(&ret, (Py_ssize_t)BZS_TOTAL_OUT(bzs));
    2142         BZ2_bzCompressEnd(bzs);
    2143 
    2144         PyBuffer_Release(&pdata);
    2145         return ret;
     2132    int compresslevel=9;
     2133    int action;
     2134    Py_buffer pdata;
     2135    size_t input_left;
     2136    size_t output_size = 0;
     2137    PyObject *ret = NULL;
     2138    bz_stream _bzs;
     2139    bz_stream *bzs = &_bzs;
     2140    int bzerror;
     2141    static char *kwlist[] = {"data", "compresslevel", 0};
     2142
     2143    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s*|i",
     2144                                     kwlist, &pdata,
     2145                                     &compresslevel))
     2146        return NULL;
     2147
     2148    if (compresslevel < 1 || compresslevel > 9) {
     2149        PyErr_SetString(PyExc_ValueError,
     2150                        "compresslevel must be between 1 and 9");
     2151        PyBuffer_Release(&pdata);
     2152        return NULL;
     2153    }
     2154
     2155    ret = PyString_FromStringAndSize(NULL, SMALLCHUNK);
     2156    if (!ret) {
     2157        PyBuffer_Release(&pdata);
     2158        return NULL;
     2159    }
     2160
     2161    memset(bzs, 0, sizeof(bz_stream));
     2162
     2163    bzs->next_in = pdata.buf;
     2164    bzs->avail_in = MIN(pdata.len, UINT_MAX);
     2165    input_left = pdata.len - bzs->avail_in;
     2166
     2167    bzs->next_out = BUF(ret);
     2168    bzs->avail_out = PyString_GET_SIZE(ret);
     2169
     2170    bzerror = BZ2_bzCompressInit(bzs, compresslevel, 0, 0);
     2171    if (bzerror != BZ_OK) {
     2172        Util_CatchBZ2Error(bzerror);
     2173        PyBuffer_Release(&pdata);
     2174        Py_DECREF(ret);
     2175        return NULL;
     2176    }
     2177
     2178    action = input_left > 0 ? BZ_RUN : BZ_FINISH;
     2179
     2180    for (;;) {
     2181        char *saved_next_out;
     2182
     2183        Py_BEGIN_ALLOW_THREADS
     2184        saved_next_out = bzs->next_out;
     2185        bzerror = BZ2_bzCompress(bzs, action);
     2186        output_size += bzs->next_out - saved_next_out;
     2187        Py_END_ALLOW_THREADS
     2188
     2189        if (bzerror == BZ_STREAM_END) {
     2190            break;
     2191        } else if (bzerror != BZ_RUN_OK && bzerror != BZ_FINISH_OK) {
     2192            BZ2_bzCompressEnd(bzs);
     2193            Util_CatchBZ2Error(bzerror);
     2194            PyBuffer_Release(&pdata);
     2195            Py_DECREF(ret);
     2196            return NULL;
     2197        }
     2198        if (action == BZ_RUN && bzs->avail_in == 0) {
     2199            if (input_left == 0) {
     2200                action = BZ_FINISH;
     2201            } else {
     2202                bzs->avail_in = MIN(input_left, UINT_MAX);
     2203                input_left -= bzs->avail_in;
     2204            }
     2205        }
     2206        if (bzs->avail_out == 0) {
     2207            size_t buffer_left = PyString_GET_SIZE(ret) - output_size;
     2208            if (buffer_left == 0) {
     2209                if (Util_GrowBuffer(&ret) < 0) {
     2210                    BZ2_bzCompressEnd(bzs);
     2211                    PyBuffer_Release(&pdata);
     2212                    return NULL;
     2213                }
     2214                bzs->next_out = BUF(ret) + output_size;
     2215                buffer_left = PyString_GET_SIZE(ret) - output_size;
     2216            }
     2217            bzs->avail_out = MIN(buffer_left, UINT_MAX);
     2218        }
     2219    }
     2220
     2221    if (output_size != PyString_GET_SIZE(ret))
     2222        _PyString_Resize(&ret, output_size);  /* Sets ret to NULL on failure. */
     2223
     2224    BZ2_bzCompressEnd(bzs);
     2225    PyBuffer_Release(&pdata);
     2226    return ret;
    21462227}
    21472228
     
    21562237bz2_decompress(PyObject *self, PyObject *args)
    21572238{
    2158         Py_buffer pdata;
    2159         char *data;
    2160         int datasize;
    2161         int bufsize = SMALLCHUNK;
    2162         PyObject *ret;
    2163         bz_stream _bzs;
    2164         bz_stream *bzs = &_bzs;
    2165         int bzerror;
    2166 
    2167         if (!PyArg_ParseTuple(args, "s*:decompress", &pdata))
    2168                 return NULL;
    2169         data = pdata.buf;
    2170         datasize = pdata.len;
    2171 
    2172         if (datasize == 0) {
    2173                 PyBuffer_Release(&pdata);
    2174                 return PyString_FromString("");
    2175         }
    2176 
    2177         ret = PyString_FromStringAndSize(NULL, bufsize);
    2178         if (!ret) {
    2179                 PyBuffer_Release(&pdata);
    2180                 return NULL;
    2181         }
    2182 
    2183         memset(bzs, 0, sizeof(bz_stream));
    2184 
    2185         bzs->next_in = data;
    2186         bzs->avail_in = datasize;
    2187         bzs->next_out = BUF(ret);
    2188         bzs->avail_out = bufsize;
    2189 
    2190         bzerror = BZ2_bzDecompressInit(bzs, 0, 0);
    2191         if (bzerror != BZ_OK) {
    2192                 Util_CatchBZ2Error(bzerror);
    2193                 Py_DECREF(ret);
    2194                 PyBuffer_Release(&pdata);
    2195                 return NULL;
    2196         }
    2197 
    2198         for (;;) {
    2199                 Py_BEGIN_ALLOW_THREADS
    2200                 bzerror = BZ2_bzDecompress(bzs);
    2201                 Py_END_ALLOW_THREADS
    2202                 if (bzerror == BZ_STREAM_END) {
    2203                         break;
    2204                 } else if (bzerror != BZ_OK) {
    2205                         BZ2_bzDecompressEnd(bzs);
    2206                         Util_CatchBZ2Error(bzerror);
    2207                         PyBuffer_Release(&pdata);
    2208                         Py_DECREF(ret);
    2209                         return NULL;
    2210                 }
    2211                 if (bzs->avail_in == 0) {
    2212                         BZ2_bzDecompressEnd(bzs);
    2213                         PyErr_SetString(PyExc_ValueError,
    2214                                         "couldn't find end of stream");
    2215                         PyBuffer_Release(&pdata);
    2216                         Py_DECREF(ret);
    2217                         return NULL;
    2218                 }
    2219                 if (bzs->avail_out == 0) {
    2220                         bufsize = Util_NewBufferSize(bufsize);
    2221                         if (_PyString_Resize(&ret, bufsize) < 0) {
    2222                                 BZ2_bzDecompressEnd(bzs);
    2223                                 PyBuffer_Release(&pdata);
    2224                                 Py_DECREF(ret);
    2225                                 return NULL;
    2226                         }
    2227                         bzs->next_out = BUF(ret) + BZS_TOTAL_OUT(bzs);
    2228                         bzs->avail_out = bufsize - (bzs->next_out - BUF(ret));
    2229                 }
    2230         }
    2231 
    2232         if (bzs->avail_out != 0)
    2233                 _PyString_Resize(&ret, (Py_ssize_t)BZS_TOTAL_OUT(bzs));
    2234         BZ2_bzDecompressEnd(bzs);
    2235         PyBuffer_Release(&pdata);
    2236 
    2237         return ret;
     2239    Py_buffer pdata;
     2240    size_t input_left;
     2241    size_t output_size = 0;
     2242    PyObject *ret;
     2243    bz_stream _bzs;
     2244    bz_stream *bzs = &_bzs;
     2245    int bzerror;
     2246
     2247    if (!PyArg_ParseTuple(args, "s*:decompress", &pdata))
     2248        return NULL;
     2249
     2250    if (pdata.len == 0) {
     2251        PyBuffer_Release(&pdata);
     2252        return PyString_FromString("");
     2253    }
     2254
     2255    ret = PyString_FromStringAndSize(NULL, SMALLCHUNK);
     2256    if (!ret) {
     2257        PyBuffer_Release(&pdata);
     2258        return NULL;
     2259    }
     2260
     2261    memset(bzs, 0, sizeof(bz_stream));
     2262
     2263    bzs->next_in = pdata.buf;
     2264    bzs->avail_in = MIN(pdata.len, UINT_MAX);
     2265    input_left = pdata.len - bzs->avail_in;
     2266
     2267    bzs->next_out = BUF(ret);
     2268    bzs->avail_out = PyString_GET_SIZE(ret);
     2269
     2270    bzerror = BZ2_bzDecompressInit(bzs, 0, 0);
     2271    if (bzerror != BZ_OK) {
     2272        Util_CatchBZ2Error(bzerror);
     2273        Py_DECREF(ret);
     2274        PyBuffer_Release(&pdata);
     2275        return NULL;
     2276    }
     2277
     2278    for (;;) {
     2279        char *saved_next_out;
     2280
     2281        Py_BEGIN_ALLOW_THREADS
     2282        saved_next_out = bzs->next_out;
     2283        bzerror = BZ2_bzDecompress(bzs);
     2284        output_size += bzs->next_out - saved_next_out;
     2285        Py_END_ALLOW_THREADS
     2286
     2287        if (bzerror == BZ_STREAM_END) {
     2288            break;
     2289        } else if (bzerror != BZ_OK) {
     2290            BZ2_bzDecompressEnd(bzs);
     2291            Util_CatchBZ2Error(bzerror);
     2292            PyBuffer_Release(&pdata);
     2293            Py_DECREF(ret);
     2294            return NULL;
     2295        }
     2296        if (bzs->avail_in == 0) {
     2297            if (input_left == 0) {
     2298                BZ2_bzDecompressEnd(bzs);
     2299                PyErr_SetString(PyExc_ValueError,
     2300                                "couldn't find end of stream");
     2301                PyBuffer_Release(&pdata);
     2302                Py_DECREF(ret);
     2303                return NULL;
     2304            }
     2305            bzs->avail_in = MIN(input_left, UINT_MAX);
     2306            input_left -= bzs->avail_in;
     2307        }
     2308        if (bzs->avail_out == 0) {
     2309            size_t buffer_left = PyString_GET_SIZE(ret) - output_size;
     2310            if (buffer_left == 0) {
     2311                if (Util_GrowBuffer(&ret) < 0) {
     2312                    BZ2_bzDecompressEnd(bzs);
     2313                    PyBuffer_Release(&pdata);
     2314                    return NULL;
     2315                }
     2316                bzs->next_out = BUF(ret) + output_size;
     2317                buffer_left = PyString_GET_SIZE(ret) - output_size;
     2318            }
     2319            bzs->avail_out = MIN(buffer_left, UINT_MAX);
     2320        }
     2321    }
     2322
     2323    if (output_size != PyString_GET_SIZE(ret))
     2324        _PyString_Resize(&ret, output_size);  /* Sets ret to NULL on failure. */
     2325
     2326    BZ2_bzDecompressEnd(bzs);
     2327    PyBuffer_Release(&pdata);
     2328    return ret;
    22382329}
    22392330
    22402331static PyMethodDef bz2_methods[] = {
    2241         {"compress", (PyCFunction) bz2_compress, METH_VARARGS|METH_KEYWORDS,
    2242                 bz2_compress__doc__},
    2243         {"decompress", (PyCFunction) bz2_decompress, METH_VARARGS,
    2244                 bz2_decompress__doc__},
    2245         {NULL,          NULL}           /* sentinel */
     2332    {"compress", (PyCFunction) bz2_compress, METH_VARARGS|METH_KEYWORDS,
     2333        bz2_compress__doc__},
     2334    {"decompress", (PyCFunction) bz2_decompress, METH_VARARGS,
     2335        bz2_decompress__doc__},
     2336    {NULL,              NULL}           /* sentinel */
    22462337};
    22472338
     
    22592350initbz2(void)
    22602351{
    2261         PyObject *m;
    2262 
    2263         Py_TYPE(&BZ2File_Type) = &PyType_Type;
    2264         Py_TYPE(&BZ2Comp_Type) = &PyType_Type;
    2265         Py_TYPE(&BZ2Decomp_Type) = &PyType_Type;
    2266 
    2267         m = Py_InitModule3("bz2", bz2_methods, bz2__doc__);
    2268         if (m == NULL)
    2269                 return;
    2270 
    2271         PyModule_AddObject(m, "__author__", PyString_FromString(__author__));
    2272 
    2273         Py_INCREF(&BZ2File_Type);
    2274         PyModule_AddObject(m, "BZ2File", (PyObject *)&BZ2File_Type);
    2275 
    2276         Py_INCREF(&BZ2Comp_Type);
    2277         PyModule_AddObject(m, "BZ2Compressor", (PyObject *)&BZ2Comp_Type);
    2278 
    2279         Py_INCREF(&BZ2Decomp_Type);
    2280         PyModule_AddObject(m, "BZ2Decompressor", (PyObject *)&BZ2Decomp_Type);
    2281 }
     2352    PyObject *m;
     2353
     2354    if (PyType_Ready(&BZ2File_Type) < 0)
     2355        return;
     2356    if (PyType_Ready(&BZ2Comp_Type) < 0)
     2357        return;
     2358    if (PyType_Ready(&BZ2Decomp_Type) < 0)
     2359        return;
     2360
     2361    m = Py_InitModule3("bz2", bz2_methods, bz2__doc__);
     2362    if (m == NULL)
     2363        return;
     2364
     2365    PyModule_AddObject(m, "__author__", PyString_FromString(__author__));
     2366
     2367    Py_INCREF(&BZ2File_Type);
     2368    PyModule_AddObject(m, "BZ2File", (PyObject *)&BZ2File_Type);
     2369
     2370    Py_INCREF(&BZ2Comp_Type);
     2371    PyModule_AddObject(m, "BZ2Compressor", (PyObject *)&BZ2Comp_Type);
     2372
     2373    Py_INCREF(&BZ2Decomp_Type);
     2374    PyModule_AddObject(m, "BZ2Decompressor", (PyObject *)&BZ2Decomp_Type);
     2375}
Note: See TracChangeset for help on using the changeset viewer.