pollita Fri Jul 16 20:05:31 2004 EDT Added files: /php-src/ext/zlib zlib_filter.c /php-src/ext/zlib/tests zlib_filter_inflate.phpt zlib_filter_deflate.phpt
Modified files: /php-src/ext/zlib config0.m4 php_zlib.h zlib.c /php-src NEWS Log: Add zlib stream filter support
http://cvs.php.net/diff.php/php-src/ext/zlib/config0.m4?r1=1.14&r2=1.15&ty=u Index: php-src/ext/zlib/config0.m4 diff -u php-src/ext/zlib/config0.m4:1.14 php-src/ext/zlib/config0.m4:1.15 --- php-src/ext/zlib/config0.m4:1.14 Thu Jun 26 20:37:21 2003 +++ php-src/ext/zlib/config0.m4 Fri Jul 16 20:05:30 2004 @@ -1,5 +1,5 @@ dnl -dnl $Id: config0.m4,v 1.14 2003/06/27 00:37:21 sas Exp $ +dnl $Id: config0.m4,v 1.15 2004/07/17 00:05:30 pollita Exp $ dnl PHP_ARG_WITH(zlib,for ZLIB support, @@ -9,7 +9,7 @@ [ --with-zlib-dir=<DIR> Define the location of zlib install directory], no, no) if test "$PHP_ZLIB" != "no" -o "$PHP_ZLIB_DIR" != "no"; then - PHP_NEW_EXTENSION(zlib, zlib.c zlib_fopen_wrapper.c, $ext_shared) + PHP_NEW_EXTENSION(zlib, zlib.c zlib_fopen_wrapper.c zlib_filter.c, $ext_shared) PHP_SUBST(ZLIB_SHARED_LIBADD) if test "$PHP_ZLIB" != "yes" -a "$PHP_ZLIB" != "no"; then http://cvs.php.net/diff.php/php-src/ext/zlib/php_zlib.h?r1=1.40&r2=1.41&ty=u Index: php-src/ext/zlib/php_zlib.h diff -u php-src/ext/zlib/php_zlib.h:1.40 php-src/ext/zlib/php_zlib.h:1.41 --- php-src/ext/zlib/php_zlib.h:1.40 Thu Jan 8 12:33:03 2004 +++ php-src/ext/zlib/php_zlib.h Fri Jul 16 20:05:30 2004 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_zlib.h,v 1.40 2004/01/08 17:33:03 sniper Exp $ */ +/* $Id: php_zlib.h,v 1.41 2004/07/17 00:05:30 pollita Exp $ */ #ifndef PHP_ZLIB_H #define PHP_ZLIB_H @@ -35,6 +35,7 @@ char *output_handler; ZEND_END_MODULE_GLOBALS(zlib) +extern php_stream_filter_factory php_zlib_filter_factory; extern zend_module_entry php_zlib_module_entry; #define zlib_module_ptr &php_zlib_module_entry http://cvs.php.net/diff.php/php-src/ext/zlib/zlib.c?r1=1.181&r2=1.182&ty=u Index: php-src/ext/zlib/zlib.c diff -u php-src/ext/zlib/zlib.c:1.181 php-src/ext/zlib/zlib.c:1.182 --- php-src/ext/zlib/zlib.c:1.181 Thu Jan 8 03:17:52 2004 +++ php-src/ext/zlib/zlib.c Fri Jul 16 20:05:30 2004 @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zlib.c,v 1.181 2004/01/08 08:17:52 andi Exp $ */ +/* $Id: zlib.c,v 1.182 2004/07/17 00:05:30 pollita Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -209,6 +209,7 @@ ts_allocate_id(&zlib_globals_id, sizeof(zend_zlib_globals), (ts_allocate_ctor) php_zlib_init_globals, NULL); #endif php_register_url_stream_wrapper("compress.zlib", &php_stream_gzip_wrapper TSRMLS_CC); + php_stream_filter_register_factory("zlib.*", &php_zlib_filter_factory TSRMLS_CC); REGISTER_LONG_CONSTANT("FORCE_GZIP", CODING_GZIP, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FORCE_DEFLATE", CODING_DEFLATE, CONST_CS | CONST_PERSISTENT); @@ -243,6 +244,7 @@ PHP_MSHUTDOWN_FUNCTION(zlib) { php_unregister_url_stream_wrapper("zlib" TSRMLS_CC); + php_stream_filter_unregister_factory("zlib.*" TSRMLS_CC); UNREGISTER_INI_ENTRIES(); @@ -256,6 +258,8 @@ { php_info_print_table_start(); php_info_print_table_row(2, "ZLib Support", "enabled"); + php_info_print_table_row(2, "Stream Wrapper support", "compress.zlib://"); + php_info_print_table_row(2, "Stream Filter support", "zlib.inflate, zlib.deflate"); php_info_print_table_row(2, "Compiled Version", ZLIB_VERSION); php_info_print_table_row(2, "Linked Version", (char *) zlibVersion()); php_info_print_table_end(); http://cvs.php.net/diff.php/php-src/NEWS?r1=1.1763&r2=1.1764&ty=u Index: php-src/NEWS diff -u php-src/NEWS:1.1763 php-src/NEWS:1.1764 --- php-src/NEWS:1.1763 Fri Jul 16 03:31:34 2004 +++ php-src/NEWS Fri Jul 16 20:05:31 2004 @@ -1,6 +1,7 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2004, PHP 5.1.0 +- Added zlib stream filter suport. (Sara) - Changed the implementation of TRUE, FALSE, and NULL from constants to keywords. (Marcus) - Fixed ZTS destruction. (Marcus) http://cvs.php.net/co.php/php-src/ext/zlib/zlib_filter.c?r=1.1&p=1 Index: php-src/ext/zlib/zlib_filter.c +++ php-src/ext/zlib/zlib_filter.c /* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2004 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.0 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_0.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | [EMAIL PROTECTED] so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Sara Golemon ([EMAIL PROTECTED]) | +----------------------------------------------------------------------+ */ /* $Id: zlib_filter.c,v 1.1 2004/07/17 00:05:30 pollita Exp $ */ #include "php.h" #include "php_zlib.h" /* {{{ data structure */ typedef struct _php_zlib_filter_data { z_stream strm; char *inbuf; size_t inbuf_len; char *outbuf; size_t outbuf_len; } php_zlib_filter_data; /* }}} */ /* {{{ Memory management wrappers */ static voidpf php_zlib_alloc(voidpf opaque, uInt items, uInt size) { return (voidpf)safe_emalloc(items, size, 0); } static void php_zlib_free(voidpf opaque, voidpf address) { efree((void*)address); } /* }}} */ /* {{{ zlib.inflate filter implementation */ static php_stream_filter_status_t php_zlib_inflate_filter( php_stream *stream, php_stream_filter *thisfilter, php_stream_bucket_brigade *buckets_in, php_stream_bucket_brigade *buckets_out, size_t *bytes_consumed, int flags TSRMLS_DC) { php_zlib_filter_data *data; php_stream_bucket *bucket; size_t consumed = 0, original_out, original_in; int status; php_stream_filter_status_t exit_status = PSFS_FEED_ME; z_stream *streamp; if (!thisfilter || !thisfilter->abstract) { /* Should never happen */ return PSFS_ERR_FATAL; } data = (php_zlib_filter_data *)(thisfilter->abstract); streamp = &(data->strm); original_in = data->strm.total_in; original_out = data->strm.total_out; while (buckets_in->head) { size_t bin = 0, desired; bucket = php_stream_bucket_make_writeable(buckets_in->head TSRMLS_CC); while (bin < bucket->buflen) { desired = bucket->buflen - bin; if (desired > data->inbuf_len) { desired = data->inbuf_len; } memcpy(data->strm.next_in, bucket->buf + bin, desired); data->strm.avail_in = desired; status = inflate(&(data->strm), flags & PSFS_FLAG_FLUSH_CLOSE ? Z_FINISH : Z_SYNC_FLUSH); if (status != Z_OK && status != Z_STREAM_END) { /* Something bad happened */ php_stream_bucket_delref(bucket TSRMLS_CC); return PSFS_ERR_FATAL; } desired -= data->strm.avail_in; /* desired becomes what we consumed this round through */ data->strm.next_in = data->inbuf; data->strm.avail_in = 0; consumed += desired; bin += desired; if (data->strm.avail_out < data->outbuf_len) { php_stream_bucket *out_bucket; size_t bucketlen = data->outbuf_len - data->strm.avail_out; out_bucket = php_stream_bucket_new(stream, estrndup(data->outbuf, bucketlen), bucketlen, 1, 0 TSRMLS_CC); php_stream_bucket_append(buckets_out, out_bucket TSRMLS_CC); data->strm.avail_out = data->outbuf_len; data->strm.next_out = data->outbuf; exit_status = PSFS_PASS_ON; } } php_stream_bucket_delref(bucket TSRMLS_CC); } if (flags & PSFS_FLAG_FLUSH_CLOSE) { /* Spit it out! */ status = Z_OK; while (status == Z_OK) { status = inflate(&(data->strm), Z_FINISH); if (data->strm.avail_out < data->outbuf_len) { size_t bucketlen = data->outbuf_len - data->strm.avail_out; bucket = php_stream_bucket_new(stream, estrndup(data->outbuf, bucketlen), bucketlen, 1, 0 TSRMLS_CC); php_stream_bucket_append(buckets_out, bucket TSRMLS_CC); data->strm.avail_out = data->outbuf_len; data->strm.next_out = data->outbuf; exit_status = PSFS_PASS_ON; } } } if (bytes_consumed) { *bytes_consumed = consumed; } return exit_status; } static void php_zlib_inflate_dtor(php_stream_filter *thisfilter TSRMLS_DC) { if (thisfilter && thisfilter->abstract) { php_zlib_filter_data *data = thisfilter->abstract; inflateEnd(&(data->strm)); efree(data->inbuf); efree(data->outbuf); efree(data); } } static php_stream_filter_ops php_zlib_inflate_ops = { php_zlib_inflate_filter, php_zlib_inflate_dtor, "zlib.inflate" }; /* }}} */ /* {{{ zlib.inflate filter implementation */ static php_stream_filter_status_t php_zlib_deflate_filter( php_stream *stream, php_stream_filter *thisfilter, php_stream_bucket_brigade *buckets_in, php_stream_bucket_brigade *buckets_out, size_t *bytes_consumed, int flags TSRMLS_DC) { php_zlib_filter_data *data; php_stream_bucket *bucket; size_t consumed = 0, original_out, original_in; int status; php_stream_filter_status_t exit_status = PSFS_FEED_ME; z_stream *streamp; if (!thisfilter || !thisfilter->abstract) { /* Should never happen */ return PSFS_ERR_FATAL; } data = (php_zlib_filter_data *)(thisfilter->abstract); streamp = &(data->strm); original_in = data->strm.total_in; original_out = data->strm.total_out; while (buckets_in->head) { size_t bin = 0, desired; bucket = php_stream_bucket_make_writeable(buckets_in->head TSRMLS_CC); while (bin < bucket->buflen) { desired = bucket->buflen - bin; if (desired > data->inbuf_len) { desired = data->inbuf_len; } memcpy(data->strm.next_in, bucket->buf + bin, desired); data->strm.avail_in = desired; status = deflate(&(data->strm), flags & PSFS_FLAG_FLUSH_CLOSE ? Z_FULL_FLUSH : (flags & PSFS_FLAG_FLUSH_INC ? Z_SYNC_FLUSH : Z_NO_FLUSH)); if (status != Z_OK) { /* Something bad happened */ php_stream_bucket_delref(bucket TSRMLS_CC); return PSFS_ERR_FATAL; } desired -= data->strm.avail_in; /* desired becomes what we consumed this round through */ data->strm.next_in = data->inbuf; data->strm.avail_in = 0; consumed += desired; bin += desired; if (data->strm.avail_out < data->outbuf_len) { php_stream_bucket *out_bucket; size_t bucketlen = data->outbuf_len - data->strm.avail_out; out_bucket = php_stream_bucket_new(stream, estrndup(data->outbuf, bucketlen), bucketlen, 1, 0 TSRMLS_CC); php_stream_bucket_append(buckets_out, out_bucket TSRMLS_CC); data->strm.avail_out = data->outbuf_len; data->strm.next_out = data->outbuf; exit_status = PSFS_PASS_ON; } } php_stream_bucket_delref(bucket TSRMLS_CC); } if (flags & PSFS_FLAG_FLUSH_CLOSE) { /* Spit it out! */ status = Z_OK; while (status == Z_OK) { status = deflate(&(data->strm), Z_FINISH); if (data->strm.avail_out < data->outbuf_len) { size_t bucketlen = data->outbuf_len - data->strm.avail_out; bucket = php_stream_bucket_new(stream, estrndup(data->outbuf, bucketlen), bucketlen, 1, 0 TSRMLS_CC); php_stream_bucket_append(buckets_out, bucket TSRMLS_CC); data->strm.avail_out = data->outbuf_len; data->strm.next_out = data->outbuf; exit_status = PSFS_PASS_ON; } } } if (bytes_consumed) { *bytes_consumed = consumed; } return exit_status; } static void php_zlib_deflate_dtor(php_stream_filter *thisfilter TSRMLS_DC) { if (thisfilter && thisfilter->abstract) { php_zlib_filter_data *data = thisfilter->abstract; deflateEnd(&(data->strm)); efree(data->inbuf); efree(data->outbuf); efree(data); } } static php_stream_filter_ops php_zlib_deflate_ops = { php_zlib_deflate_filter, php_zlib_deflate_dtor, "zlib.deflate" }; /* }}} */ /* {{{ zlib.* common factory */ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *filterparams, int persistent TSRMLS_DC) { php_stream_filter_ops *fops = NULL; php_zlib_filter_data *data; int status; /* Create this filter */ data = ecalloc(1, sizeof(php_zlib_filter_data)); /* Circular reference */ data->strm.opaque = (voidpf) data; data->strm.zalloc = (alloc_func) php_zlib_alloc; data->strm.zfree = (free_func) php_zlib_free; data->strm.avail_out = data->outbuf_len = data->inbuf_len = 2048; data->strm.next_in = data->inbuf = (Bytef *) emalloc(data->inbuf_len); data->strm.avail_in = 0; data->strm.next_out = data->outbuf = (Bytef *) emalloc(data->outbuf_len); data->strm.data_type = Z_ASCII; if (strcasecmp(filtername, "zlib.inflate") == 0) { int windowBits = MAX_WBITS; if (filterparams) { zval **tmpzval; if ((Z_TYPE_P(filterparams) == IS_ARRAY || Z_TYPE_P(filterparams) == IS_OBJECT) && zend_hash_find(HASH_OF(filterparams), "window", sizeof("window"), (void **) &tmpzval) == SUCCESS) { /* log-2 base of history window (9 - 15) */ SEPARATE_ZVAL(tmpzval); convert_to_long_ex(tmpzval); if (Z_LVAL_PP(tmpzval) < 9 || Z_LVAL_PP(tmpzval) > MAX_WBITS) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter give for window size. (%ld)", Z_LVAL_PP(tmpzval)); } else { windowBits = Z_LVAL_PP(tmpzval); } zval_ptr_dtor(tmpzval); } } /* RFC 1951 Inflate */ status = inflateInit2(&(data->strm), windowBits); fops = &php_zlib_inflate_ops; } else if (strcasecmp(filtername, "zlib.deflate") == 0) { /* RFC 1951 Deflate */ int level = Z_DEFAULT_COMPRESSION; int windowBits = MAX_WBITS; int memLevel = MAX_MEM_LEVEL; if (filterparams) { zval **tmpzval; /* filterparams can either be a scalar value to indicate compression level (shortcut method) Or can be a hash containing one or more of 'window', 'memory', and/or 'level' members. */ switch (Z_TYPE_P(filterparams)) { case IS_ARRAY: case IS_OBJECT: if (zend_hash_find(HASH_OF(filterparams), "memory", sizeof("memory"), (void**) &tmpzval) == SUCCESS) { /* Memory Level (1 - 9) */ SEPARATE_ZVAL(tmpzval); convert_to_long_ex(tmpzval); if (Z_LVAL_PP(tmpzval) < 1 || Z_LVAL_PP(tmpzval) > MAX_MEM_LEVEL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter give for memory level. (%ld)", Z_LVAL_PP(tmpzval)); } else { memLevel = Z_LVAL_PP(tmpzval); } zval_ptr_dtor(tmpzval); } if (zend_hash_find(HASH_OF(filterparams), "window", sizeof("window"), (void**) &tmpzval) == SUCCESS) { /* log-2 base of history window (9 - 15) */ SEPARATE_ZVAL(tmpzval); convert_to_long_ex(tmpzval); if (Z_LVAL_PP(tmpzval) < 9 || Z_LVAL_PP(tmpzval) > MAX_WBITS) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter give for window size. (%ld)", Z_LVAL_PP(tmpzval)); } else { windowBits = Z_LVAL_PP(tmpzval); } zval_ptr_dtor(tmpzval); } if (zend_hash_find(HASH_OF(filterparams), "level", sizeof("level"), (void**) &tmpzval) == SUCCESS) { /* Psuedo pass through to catch level validating code */ goto factory_setlevel; } break; case IS_STRING: case IS_DOUBLE: case IS_LONG: tmpzval = &filterparams; factory_setlevel: /* Set compression level within reason (-1 == default, 0 == none, 1-9 == least to most compression */ SEPARATE_ZVAL(tmpzval); convert_to_long_ex(tmpzval); if (Z_LVAL_PP(tmpzval) < -1 || Z_LVAL_PP(tmpzval) > 9) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid compression level specified. (%ld)", Z_LVAL_PP(tmpzval)); } else { level = Z_LVAL_PP(tmpzval); } zval_ptr_dtor(tmpzval); break; default: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid filter parameter, ignored."); } } status = deflateInit2(&(data->strm), level, Z_DEFLATED, windowBits, memLevel, 0); fops = &php_zlib_deflate_ops; } else { status = Z_DATA_ERROR; } if (status != Z_OK) { /* Unspecified (probably strm) error, let stream-filter error do its own whining */ efree(data->strm.next_in); efree(data->strm.next_out); efree(data); return NULL; } return php_stream_filter_alloc(fops, data, persistent); } php_stream_filter_factory php_zlib_filter_factory = { php_zlib_filter_create }; /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */ http://cvs.php.net/co.php/php-src/ext/zlib/tests/zlib_filter_inflate.phpt?r=1.1&p=1 Index: php-src/ext/zlib/tests/zlib_filter_inflate.phpt +++ php-src/ext/zlib/tests/zlib_filter_inflate.phpt --TEST-- zlib.inflate (with convert.base64-decode) --SKIPIF-- <?php if (!extension_loaded("zlib")) print "skip"; ?> --FILE-- <?php /* $Id: zlib_filter_inflate.phpt,v 1.1 2004/07/17 00:05:30 pollita Exp $ */ $text = 'eJwdy0EOgCAMRNGrzM6N8R4co4YBMbRNGkLi7VV2f/FfgijGRUzGA/XMDi+QlWFQuT1QaQzpO9I2iWbFQ2U0t49VDjk7d4g1/R+xDG0LHC8+diGh'; $fp = fopen('php://stdout', 'w'); stream_filter_append($fp, 'convert.base64-decode', STREAM_FILTER_WRITE); stream_filter_append($fp, 'zlib.inflate', STREAM_FILTER_WRITE); fwrite($fp, $text); fclose($fp); ?> --EXPECT-- I am the very model of a modern major general, I've information vegetable, animal, and mineral. http://cvs.php.net/co.php/php-src/ext/zlib/tests/zlib_filter_deflate.phpt?r=1.1&p=1 Index: php-src/ext/zlib/tests/zlib_filter_deflate.phpt +++ php-src/ext/zlib/tests/zlib_filter_deflate.phpt --TEST-- zlib.deflate (with convert.base64-encode) --SKIPIF-- <?php if (!extension_loaded("zlib")) print "skip"; ?> --FILE-- <?php /* $Id: zlib_filter_deflate.phpt,v 1.1 2004/07/17 00:05:30 pollita Exp $ */ $text = 'I am the very model of a modern major general, I\'ve information vegetable, animal, and mineral.'; $fp = fopen('php://stdout', 'w'); stream_filter_append($fp, 'zlib.deflate', STREAM_FILTER_WRITE); stream_filter_append($fp, 'convert.base64-encode', STREAM_FILTER_WRITE); fwrite($fp, $text); fclose($fp); ?> --EXPECT-- eJwdy0EOgCAMRNGrzM6N8R4co4YBMbRNGkLi7VV2f/FfgijGRUzGA/XMDi+QlWFQuT1QaQzpO9I2iWbFQ2U0t49VDjk7d4g1/R+xDG0LHC8+diGh
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php