cvs: php4 /ext/bz2 bz2.c
| From: | Sterling Hughes | Date: | Sun, 27 Jan 2002 05:32:13 +0000 |
| Subject: | cvs: php4 /ext/bz2 bz2.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-9187@lists.php.net to get a copy of this message | ||
sterling Sun Jan 27 00:32:13 2002 EDT
Modified files:
/php4/ext/bz2 bz2.c
Log:
Update code to last working version to avoid recent breaks.
# Uncensored: Update code to pre-jeroen state.
Index: php4/ext/bz2/bz2.c diff -u php4/ext/bz2/bz2.c:1.31 php4/ext/bz2/bz2.c:1.32 --- php4/ext/bz2/bz2.c:1.31 Tue Dec 11 10:28:54 2001 +++ php4/ext/bz2/bz2.c Sun Jan 27 00:32:12 2002 @@ -1,8 +1,8 @@ /* +----------------------------------------------------------------------+ - | PHP Version 4 | + | PHP version 4.0 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2002 The PHP Group | + | Copyright (c) 1997-2001 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -13,11 +13,10 @@ | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Sterling Hughes <sterling@php.net> | - | Jeroen van Wolffelaar <jeroen@php.net> | +----------------------------------------------------------------------+ */ -/* $Id: bz2.c,v 1.31 2001/12/11 15:28:54 sebastian Exp $ */ +/* $Id: bz2.c,v 1.32 2002/01/27 05:32:12 sterling Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -43,10 +42,8 @@ #define PHP_BZ_ERRSTR 1 #define PHP_BZ_ERRBOTH 2 -/* Incrementation of the buffer on each try. Uncompressedsize * - * (1-DECOMPRESS_INCREMENT) is the maximum amount of temporarily wasted - * memory. Higher numbers will increase speed. */ -#define PHP_BZ_DECOMPRESS_INCREMENT 1.50 +/* Blocksize of the decompression buffer */ +#define PHP_BZ_DECOMPRESS_SIZE 4096 function_entry bz2_functions[] = { PHP_FE(bzopen, NULL) @@ -101,7 +98,7 @@ php_info_print_table_end(); } -/* {{{ proto resource bzopen(string fn|resource fp, string mode) +/* {{{ proto int bzopen(string|int file|fp, string mode) Opens a new BZip2 stream */ PHP_FUNCTION(bzopen) { @@ -109,14 +106,14 @@ **mode; /* The mode to open the stream with */ BZFILE *bz; /* The compressed file stream */ FILE *fp; /* If filepointer is given, its placed in here */ - char *path; + char *path; if (ZEND_NUM_ARGS() != 2 || - zend_get_parameters_ex(2, &file, &mode) == FAILURE) { + zend_get_parameters_ex(2, &file, &mode) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(mode); - + /* If it's not a resource its a string containing the filename to open */ if (Z_TYPE_PP(file) != IS_RESOURCE) { convert_to_string_ex(file); @@ -139,24 +136,24 @@ php_error(E_WARNING, "bzopen(): Unable to open file"); RETURN_FALSE; } - + ZEND_REGISTER_RESOURCE(return_value, bz, le_bz2); } /* }}} */ -/* {{{ proto string bzread(resouce bzp [, int len]) +/* {{{ proto string bzread(int bz [, int len]) Reads len bytes from the BZip2 stream given by bz */ PHP_FUNCTION(bzread) { - zval **bzp, /* BZip2 Resource Pointer */ - **zlen; /* The (optional) length to read */ - BZFILE *bz; /* BZip2 File pointer */ - void *buf; /* Buffer to read data into */ - int len = 1024, /* Length to read, passed to the BZ2_bzread function */ - argc = ZEND_NUM_ARGS(); /* Argument count */ + zval **bzp, /* BZip2 Resource Pointer */ + **zlen; /* The (optional) length to read */ + BZFILE *bz; /* BZip2 File pointer */ + void *buf; /* Buffer to read data into */ + int len = 1024, /* Length to read, passed to the BZ2_bzread function */ + argc = ZEND_NUM_ARGS(); /* Argument count */ if (argc < 1 || argc > 2 || - zend_get_parameters_ex(argc, &bzp, &zlen) == FAILURE) { + zend_get_parameters_ex(argc, &bzp, &zlen) == FAILURE) { WRONG_PARAM_COUNT; } @@ -174,26 +171,26 @@ BZ2_bzread(bz, buf, len); RETVAL_STRINGL(buf, len, 1); - + /* We copied the buffer, so now we can free it */ efree(buf); } /* }}} */ -/* {{{ proto int bzwrite(resouce bzp, string data [, int len]) +/* {{{ proto int bzwrite(int bz, string data [, int len]) Writes data to the BZip2 stream given by bz */ PHP_FUNCTION(bzwrite) { - zval **bzp, /* Bzip2 Resource Pointer */ - **data, /* The data to write */ - **zlen; /* The (optional) length of the data to write */ - BZFILE *bz; /* BZip2 File pointer */ - int error, /* Error container */ - len, /* Length to read, passed to the BZ2_bzwrite function */ - argc = ZEND_NUM_ARGS(); /* Argument count */ - + zval **bzp, /* Bzip2 Resource Pointer */ + **data, /* The data to write */ + **zlen; /* The (optional) length of the data to write */ + BZFILE *bz; /* BZip2 File pointer */ + int error, /* Error container */ + len, /* Length to read, passed to the BZ2_bzwrite function */ + argc = ZEND_NUM_ARGS(); /* Argument count */ + if (argc < 2 || argc > 3 || - zend_get_parameters_ex(argc, &bzp, &data, &zlen) == FAILURE) { + zend_get_parameters_ex(argc, &bzp, &data, &zlen) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(data); @@ -209,14 +206,14 @@ else { len = Z_STRLEN_PP(data); } - + /* Write the data and return the error */ error = BZ2_bzwrite(bz, (void *) Z_STRVAL_PP(data), len); RETURN_LONG(error); } /* }}} */ -/* {{{ proto int bzflush(resouce bzp) +/* {{{ proto int bzflush(int bz) Flushes a BZip2 stream */ PHP_FUNCTION(bzflush) { @@ -225,25 +222,25 @@ int error; /* Error container */ if (ZEND_NUM_ARGS() != 1 || - zend_get_parameters_ex(1, &bzp) == FAILURE) { + zend_get_parameters_ex(1, &bzp) == FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(bz, BZFILE *, bzp, -1, "BZip2 File Handle", le_bz2); - + error = BZ2_bzflush(bz); RETURN_LONG(error); } /* }}} */ -/* {{{ proto int bzclose(resouce bzp) +/* {{{ proto int bzclose(int bz) Closes a BZip2 stream */ PHP_FUNCTION(bzclose) { zval **bzp=NULL; /* BZip2 Resource Pointer */ BZFILE *bz; /* BZip2 File pointer */ - + if (ZEND_NUM_ARGS() != 1 || - zend_get_parameters_ex(1, &bzp) == FAILURE) { + zend_get_parameters_ex(1, &bzp) == FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(bz, BZFILE *, bzp, -1, "BZip2 File Handle", le_bz2); @@ -251,7 +248,7 @@ } /* }}} */ -/* {{{ proto int bzerrno(resouce bzp) +/* {{{ proto int bzerrno(int bz) Returns the error number */ PHP_FUNCTION(bzerrno) { @@ -259,7 +256,7 @@ } /* }}} */ -/* {{{ proto string bzerrstr(resouce bzp) +/* {{{ proto string bzerrstr(int bz) Returns the error string */ PHP_FUNCTION(bzerrstr) { @@ -267,7 +264,7 @@ } /* }}} */ -/* {{{ proto array bzerror(resouce bzp) +/* {{{ proto array bzerror(int bz) Returns the error number and error string in an associative array */ PHP_FUNCTION(bzerror) { @@ -279,46 +276,56 @@ Compresses a string into BZip2 encoded data */ PHP_FUNCTION(bzcompress) { - zval **source, /* Source data to compress */ - **zblock_size, /* Optional block size to use */ - **zwork_factor; /* Optional work factor to use */ - char *dest = NULL; /* Destination to place the compressed data into */ - int error, /* Error Container */ - block_size = 4, /* Block size for compression algorithm */ - work_factor = 0; /* Work factor for compression algorithm */ - unsigned int size; /* The size to "realloc" if the initial buffer wasn't big enough */ - - if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 3 || - zend_get_parameters_ex(ZEND_NUM_ARGS(), &source, &zblock_size, &zwork_factor) == FAILURE) { + zval **source, /* Source data to compress */ + **zblock_size, /* Optional block size to use */ + **zwork_factor; /* Optional work factor to use */ + char *dest = NULL; /* Destination to place the compressed data into */ + int error, /* Error Container */ + block_size = 4, /* Block size for compression algorithm */ + work_factor = 0, /* Work factor for compression algorithm */ + argc = ZEND_NUM_ARGS(); /* Argument count */ + unsigned int size, /* The size to "realloc" if the initial buffer wasn't big enough */ + source_len, /* Length of the source data */ + dest_len; /* Length of the destination buffer */ + + if (argc < 1 || argc > 3 || + zend_get_parameters_ex(argc, &source, &zblock_size, &zwork_factor) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(source); - - /* Allocate the destination buffer. The length of the data + .01 x length - * of data + 600 which is the largest size the results of the compression - * could possibly be, at least that's what the libbz2 docs say (thanks to - * jeremy@nirvani.net for pointing this out). */ - dest = emalloc(Z_STRLEN_PP(source) + (0.01 * Z_STRLEN_PP(source)) + 601); - + + /* Assign them to easy to use variables, dest_len is initially the length of the data + + .01 x length of data + 600 which is the largest size the results of the compression + could possibly be, at least that's what the libbz2 docs say (thanks to jeremy@nirvani.net + for pointing this out). */ + source_len = Z_STRLEN_PP(source); + dest_len = Z_STRLEN_PP(source) + (0.01 * Z_STRLEN_PP(source)) + 600; + + /* Allocate the destination buffer */ + dest = emalloc(dest_len + 1); + /* Handle the optional arguments */ - if (ZEND_NUM_ARGS() > 1) { + if (argc > 1) { convert_to_long_ex(zblock_size); block_size = Z_LVAL_PP(zblock_size); } - - if (ZEND_NUM_ARGS() > 2) { + + if (argc > 2) { convert_to_long_ex(zwork_factor); work_factor = Z_LVAL_PP(zwork_factor); } - error = BZ2_bzBuffToBuffCompress(dest, &size, Z_STRVAL_PP(source), Z_STRLEN_PP(source), block_size, 0, work_factor); - + error = BZ2_bzBuffToBuffCompress(dest, &size, Z_STRVAL_PP(source), source_len, block_size, 0, work_factor); if (error != BZ_OK) { - php_error(E_WARNING, "bzcompress failed"); - RETVAL_FALSE; + RETVAL_LONG(error); } else { + /* Copy the buffer, we have perhaps allocate alot more than we need, + so we want to copy the correct amount and then free the in-exactly + allocated buffer */ RETVAL_STRINGL(dest, size, 1); } + + /* Free the buffer */ efree(dest); } /* }}} */ @@ -327,49 +334,49 @@ Decompresses BZip2 compressed data */ PHP_FUNCTION(bzdecompress) { - zval **source, /* Source data to decompress */ - **zsmall; /* (Optional) user specified small */ - char *dest = NULL; /* Destination buffer */ - int error, /* Error container */ - size, /* Current size to realloc the dest buffer to */ - small = 0; /* The actual small */ - - if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2 || - zend_get_parameters_ex(ZEND_NUM_ARGS(), &source, &zsmall) == FAILURE) { + zval **source, /* Source data to decompress */ + **zsmall; /* (Optional) user specified small */ + char *dest = emalloc(PHP_BZ_DECOMPRESS_SIZE); /* Destination buffer, initially allocated */ + int error, /* Error container */ + iter = 1, /* Iteration count for the compression loop */ + size, /* Current size to realloc the dest buffer to */ + dest_len = PHP_BZ_DECOMPRESS_SIZE, /* Size of the destination length */ + small = 0, /* The actual small */ + argc = ZEND_NUM_ARGS(); /* Argument count */ + + if (argc < 1 || argc > 2 || + zend_get_parameters_ex(argc, &source, &zsmall) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(source); - + /* optional small argument handling */ - if (ZEND_NUM_ARGS() > 1) { + if (argc > 1) { convert_to_long_ex(zsmall); small = Z_LVAL_PP(zsmall); } - - /* result will be at least the compressed size */ - size = Z_STRLEN_PP(source); - /* If size is too small, go to a minimum */ - if (size < 1024) - size = 1024; - - /* (de)Compression Loop */ + + /* (de)Compression Loop */ do { - /* exponentially increment size. */ - size = PHP_BZ_DECOMPRESS_INCREMENT * (float)size; - /* Handle the (re)allocation of the buffer */ - dest = dest? erealloc(dest, size) : emalloc(size); + size = dest_len * iter; + if (iter > 1) { + dest = erealloc(dest, size); + } + ++iter; /* Perform the decompression */ error = BZ2_bzBuffToBuffDecompress(dest, &size, Z_STRVAL_PP(source), Z_STRLEN_PP(source), small, 0); } while (error == BZ_OUTBUFF_FULL); - + if (error != BZ_OK) { - php_error(E_WARNING, "bzdecompress failed"); - RETVAL_FALSE; + RETVAL_LONG(error); } else { + /* we might have allocated a little to much, so copy the exact size and free the + in-exactly allocated buffer */ RETVAL_STRINGL(dest, size, 1); } + efree(dest); } /* }}} */ @@ -392,16 +399,16 @@ BZFILE *bz; /* BZip2 File pointer */ const char *errstr; /* Error string */ int errnum; /* Error number */ - + if (ZEND_NUM_ARGS() != 1 || - zend_get_parameters_ex(1, &bzp) == FAILURE) { + zend_get_parameters_ex(1, &bzp) == FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(bz, BZFILE *, bzp, -1, "BZip2 File pointer", le_bz2); - + /* Fetch the error information */ errstr = BZ2_bzerror(bz, &errnum); - + /* Determine what to return */ switch (opt) { case PHP_BZ_ERRNO: @@ -412,10 +419,10 @@ break; case PHP_BZ_ERRBOTH: array_init(return_value); - + add_assoc_long (return_value, "errno", errnum); add_assoc_string(return_value, "errstr", (char*)errstr, 1); - + break; } }
Index: php4/ext/bz2/bz2.c diff -u php4/ext/bz2/bz2.c:1.31 php4/ext/bz2/bz2.c:1.32 --- php4/ext/bz2/bz2.c:1.31 Tue Dec 11 10:28:54 2001 +++ php4/ext/bz2/bz2.c Sun Jan 27 00:32:12 2002 @@ -1,8 +1,8 @@ /* +----------------------------------------------------------------------+ - | PHP Version 4 | + | PHP version 4.0 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2002 The PHP Group | + | Copyright (c) 1997-2001 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -13,11 +13,10 @@ | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Sterling Hughes <sterling@php.net> | - | Jeroen van Wolffelaar <jeroen@php.net> | +----------------------------------------------------------------------+ */ -/* $Id: bz2.c,v 1.31 2001/12/11 15:28:54 sebastian Exp $ */ +/* $Id: bz2.c,v 1.32 2002/01/27 05:32:12 sterling Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -43,10 +42,8 @@ #define PHP_BZ_ERRSTR 1 #define PHP_BZ_ERRBOTH 2 -/* Incrementation of the buffer on each try. Uncompressedsize * - * (1-DECOMPRESS_INCREMENT) is the maximum amount of temporarily wasted - * memory. Higher numbers will increase speed. */ -#define PHP_BZ_DECOMPRESS_INCREMENT 1.50 +/* Blocksize of the decompression buffer */ +#define PHP_BZ_DECOMPRESS_SIZE 4096 function_entry bz2_functions[] = { PHP_FE(bzopen, NULL) @@ -101,7 +98,7 @@ php_info_print_table_end(); } -/* {{{ proto resource bzopen(string fn|resource fp, string mode) +/* {{{ proto int bzopen(string|int file|fp, string mode) Opens a new BZip2 stream */ PHP_FUNCTION(bzopen) { @@ -109,14 +106,14 @@ **mode; /* The mode to open the stream with */ BZFILE *bz; /* The compressed file stream */ FILE *fp; /* If filepointer is given, its placed in here */ - char *path; + char *path; if (ZEND_NUM_ARGS() != 2 || - zend_get_parameters_ex(2, &file, &mode) == FAILURE) { + zend_get_parameters_ex(2, &file, &mode) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(mode); - + /* If it's not a resource its a string containing the filename to open */ if (Z_TYPE_PP(file) != IS_RESOURCE) { convert_to_string_ex(file); @@ -139,24 +136,24 @@ php_error(E_WARNING, "bzopen(): Unable to open file"); RETURN_FALSE; } - + ZEND_REGISTER_RESOURCE(return_value, bz, le_bz2); } /* }}} */ -/* {{{ proto string bzread(resouce bzp [, int len]) +/* {{{ proto string bzread(int bz [, int len]) Reads len bytes from the BZip2 stream given by bz */ PHP_FUNCTION(bzread) { - zval **bzp, /* BZip2 Resource Pointer */ - **zlen; /* The (optional) length to read */ - BZFILE *bz; /* BZip2 File pointer */ - void *buf; /* Buffer to read data into */ - int len = 1024, /* Length to read, passed to the BZ2_bzread function */ - argc = ZEND_NUM_ARGS(); /* Argument count */ + zval **bzp, /* BZip2 Resource Pointer */ + **zlen; /* The (optional) length to read */ + BZFILE *bz; /* BZip2 File pointer */ + void *buf; /* Buffer to read data into */ + int len = 1024, /* Length to read, passed to the BZ2_bzread function */ + argc = ZEND_NUM_ARGS(); /* Argument count */ if (argc < 1 || argc > 2 || - zend_get_parameters_ex(argc, &bzp, &zlen) == FAILURE) { + zend_get_parameters_ex(argc, &bzp, &zlen) == FAILURE) { WRONG_PARAM_COUNT; } @@ -174,26 +171,26 @@ BZ2_bzread(bz, buf, len); RETVAL_STRINGL(buf, len, 1); - + /* We copied the buffer, so now we can free it */ efree(buf); } /* }}} */ -/* {{{ proto int bzwrite(resouce bzp, string data [, int len]) +/* {{{ proto int bzwrite(int bz, string data [, int len]) Writes data to the BZip2 stream given by bz */ PHP_FUNCTION(bzwrite) { - zval **bzp, /* Bzip2 Resource Pointer */ - **data, /* The data to write */ - **zlen; /* The (optional) length of the data to write */ - BZFILE *bz; /* BZip2 File pointer */ - int error, /* Error container */ - len, /* Length to read, passed to the BZ2_bzwrite function */ - argc = ZEND_NUM_ARGS(); /* Argument count */ - + zval **bzp, /* Bzip2 Resource Pointer */ + **data, /* The data to write */ + **zlen; /* The (optional) length of the data to write */ + BZFILE *bz; /* BZip2 File pointer */ + int error, /* Error container */ + len, /* Length to read, passed to the BZ2_bzwrite function */ + argc = ZEND_NUM_ARGS(); /* Argument count */ + if (argc < 2 || argc > 3 || - zend_get_parameters_ex(argc, &bzp, &data, &zlen) == FAILURE) { + zend_get_parameters_ex(argc, &bzp, &data, &zlen) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(data); @@ -209,14 +206,14 @@ else { len = Z_STRLEN_PP(data); } - + /* Write the data and return the error */ error = BZ2_bzwrite(bz, (void *) Z_STRVAL_PP(data), len); RETURN_LONG(error); } /* }}} */ -/* {{{ proto int bzflush(resouce bzp) +/* {{{ proto int bzflush(int bz) Flushes a BZip2 stream */ PHP_FUNCTION(bzflush) { @@ -225,25 +222,25 @@ int error; /* Error container */ if (ZEND_NUM_ARGS() != 1 || - zend_get_parameters_ex(1, &bzp) == FAILURE) { + zend_get_parameters_ex(1, &bzp) == FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(bz, BZFILE *, bzp, -1, "BZip2 File Handle", le_bz2); - + error = BZ2_bzflush(bz); RETURN_LONG(error); } /* }}} */ -/* {{{ proto int bzclose(resouce bzp) +/* {{{ proto int bzclose(int bz) Closes a BZip2 stream */ PHP_FUNCTION(bzclose) { zval **bzp=NULL; /* BZip2 Resource Pointer */ BZFILE *bz; /* BZip2 File pointer */ - + if (ZEND_NUM_ARGS() != 1 || - zend_get_parameters_ex(1, &bzp) == FAILURE) { + zend_get_parameters_ex(1, &bzp) == FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(bz, BZFILE *, bzp, -1, "BZip2 File Handle", le_bz2); @@ -251,7 +248,7 @@ } /* }}} */ -/* {{{ proto int bzerrno(resouce bzp) +/* {{{ proto int bzerrno(int bz) Returns the error number */ PHP_FUNCTION(bzerrno) { @@ -259,7 +256,7 @@ } /* }}} */ -/* {{{ proto string bzerrstr(resouce bzp) +/* {{{ proto string bzerrstr(int bz) Returns the error string */ PHP_FUNCTION(bzerrstr) { @@ -267,7 +264,7 @@ } /* }}} */ -/* {{{ proto array bzerror(resouce bzp) +/* {{{ proto array bzerror(int bz) Returns the error number and error string in an associative array */ PHP_FUNCTION(bzerror) { @@ -279,46 +276,56 @@ Compresses a string into BZip2 encoded data */ PHP_FUNCTION(bzcompress) { - zval **source, /* Source data to compress */ - **zblock_size, /* Optional block size to use */ - **zwork_factor; /* Optional work factor to use */ - char *dest = NULL; /* Destination to place the compressed data into */ - int error, /* Error Container */ - block_size = 4, /* Block size for compression algorithm */ - work_factor = 0; /* Work factor for compression algorithm */ - unsigned int size; /* The size to "realloc" if the initial buffer wasn't big enough */ - - if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 3 || - zend_get_parameters_ex(ZEND_NUM_ARGS(), &source, &zblock_size, &zwork_factor) == FAILURE) { + zval **source, /* Source data to compress */ + **zblock_size, /* Optional block size to use */ + **zwork_factor; /* Optional work factor to use */ + char *dest = NULL; /* Destination to place the compressed data into */ + int error, /* Error Container */ + block_size = 4, /* Block size for compression algorithm */ + work_factor = 0, /* Work factor for compression algorithm */ + argc = ZEND_NUM_ARGS(); /* Argument count */ + unsigned int size, /* The size to "realloc" if the initial buffer wasn't big enough */ + source_len, /* Length of the source data */ + dest_len; /* Length of the destination buffer */ + + if (argc < 1 || argc > 3 || + zend_get_parameters_ex(argc, &source, &zblock_size, &zwork_factor) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(source); - - /* Allocate the destination buffer. The length of the data + .01 x length - * of data + 600 which is the largest size the results of the compression - * could possibly be, at least that's what the libbz2 docs say (thanks to - * jeremy@nirvani.net for pointing this out). */ - dest = emalloc(Z_STRLEN_PP(source) + (0.01 * Z_STRLEN_PP(source)) + 601); - + + /* Assign them to easy to use variables, dest_len is initially the length of the data + + .01 x length of data + 600 which is the largest size the results of the compression + could possibly be, at least that's what the libbz2 docs say (thanks to jeremy@nirvani.net + for pointing this out). */ + source_len = Z_STRLEN_PP(source); + dest_len = Z_STRLEN_PP(source) + (0.01 * Z_STRLEN_PP(source)) + 600; + + /* Allocate the destination buffer */ + dest = emalloc(dest_len + 1); + /* Handle the optional arguments */ - if (ZEND_NUM_ARGS() > 1) { + if (argc > 1) { convert_to_long_ex(zblock_size); block_size = Z_LVAL_PP(zblock_size); } - - if (ZEND_NUM_ARGS() > 2) { + + if (argc > 2) { convert_to_long_ex(zwork_factor); work_factor = Z_LVAL_PP(zwork_factor); } - error = BZ2_bzBuffToBuffCompress(dest, &size, Z_STRVAL_PP(source), Z_STRLEN_PP(source), block_size, 0, work_factor); - + error = BZ2_bzBuffToBuffCompress(dest, &size, Z_STRVAL_PP(source), source_len, block_size, 0, work_factor); if (error != BZ_OK) { - php_error(E_WARNING, "bzcompress failed"); - RETVAL_FALSE; + RETVAL_LONG(error); } else { + /* Copy the buffer, we have perhaps allocate alot more than we need, + so we want to copy the correct amount and then free the in-exactly + allocated buffer */ RETVAL_STRINGL(dest, size, 1); } + + /* Free the buffer */ efree(dest); } /* }}} */ @@ -327,49 +334,49 @@ Decompresses BZip2 compressed data */ PHP_FUNCTION(bzdecompress) { - zval **source, /* Source data to decompress */ - **zsmall; /* (Optional) user specified small */ - char *dest = NULL; /* Destination buffer */ - int error, /* Error container */ - size, /* Current size to realloc the dest buffer to */ - small = 0; /* The actual small */ - - if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2 || - zend_get_parameters_ex(ZEND_NUM_ARGS(), &source, &zsmall) == FAILURE) { + zval **source, /* Source data to decompress */ + **zsmall; /* (Optional) user specified small */ + char *dest = emalloc(PHP_BZ_DECOMPRESS_SIZE); /* Destination buffer, initially allocated */ + int error, /* Error container */ + iter = 1, /* Iteration count for the compression loop */ + size, /* Current size to realloc the dest buffer to */ + dest_len = PHP_BZ_DECOMPRESS_SIZE, /* Size of the destination length */ + small = 0, /* The actual small */ + argc = ZEND_NUM_ARGS(); /* Argument count */ + + if (argc < 1 || argc > 2 || + zend_get_parameters_ex(argc, &source, &zsmall) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(source); - + /* optional small argument handling */ - if (ZEND_NUM_ARGS() > 1) { + if (argc > 1) { convert_to_long_ex(zsmall); small = Z_LVAL_PP(zsmall); } - - /* result will be at least the compressed size */ - size = Z_STRLEN_PP(source); - /* If size is too small, go to a minimum */ - if (size < 1024) - size = 1024; - - /* (de)Compression Loop */ + + /* (de)Compression Loop */ do { - /* exponentially increment size. */ - size = PHP_BZ_DECOMPRESS_INCREMENT * (float)size; - /* Handle the (re)allocation of the buffer */ - dest = dest? erealloc(dest, size) : emalloc(size); + size = dest_len * iter; + if (iter > 1) { + dest = erealloc(dest, size); + } + ++iter; /* Perform the decompression */ error = BZ2_bzBuffToBuffDecompress(dest, &size, Z_STRVAL_PP(source), Z_STRLEN_PP(source), small, 0); } while (error == BZ_OUTBUFF_FULL); - + if (error != BZ_OK) { - php_error(E_WARNING, "bzdecompress failed"); - RETVAL_FALSE; + RETVAL_LONG(error); } else { + /* we might have allocated a little to much, so copy the exact size and free the + in-exactly allocated buffer */ RETVAL_STRINGL(dest, size, 1); } + efree(dest); } /* }}} */ @@ -392,16 +399,16 @@ BZFILE *bz; /* BZip2 File pointer */ const char *errstr; /* Error string */ int errnum; /* Error number */ - + if (ZEND_NUM_ARGS() != 1 || - zend_get_parameters_ex(1, &bzp) == FAILURE) { + zend_get_parameters_ex(1, &bzp) == FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(bz, BZFILE *, bzp, -1, "BZip2 File pointer", le_bz2); - + /* Fetch the error information */ errstr = BZ2_bzerror(bz, &errnum); - + /* Determine what to return */ switch (opt) { case PHP_BZ_ERRNO: @@ -412,10 +419,10 @@ break; case PHP_BZ_ERRBOTH: array_init(return_value); - + add_assoc_long (return_value, "errno", errnum); add_assoc_string(return_value, "errstr", (char*)errstr, 1); - + break; } }