pollita Mon Sep 13 23:48:17 2004 EDT Modified files: /php-src/ext/standard basic_functions.c streamsfuncs.c streamsfuncs.h /php-src/main php_streams.h /php-src/main/streams filter.c php_stream_filter_api.h streams.c /php-src NEWS Log: Added stream_filter_remove() to cancel a stream filter. Register filters as resources when instantiated by stream_filter_(ap|pre)pend(). Export php_stream_filter_flush() internal function to wind buffered data out of a particular filter until consumed by a later filter or sent to stream->readbuffer or stream->ops->write()
http://cvs.php.net/diff.php/php-src/ext/standard/basic_functions.c?r1=1.686&r2=1.687&ty=u Index: php-src/ext/standard/basic_functions.c diff -u php-src/ext/standard/basic_functions.c:1.686 php-src/ext/standard/basic_functions.c:1.687 --- php-src/ext/standard/basic_functions.c:1.686 Fri Sep 10 16:45:33 2004 +++ php-src/ext/standard/basic_functions.c Mon Sep 13 23:48:16 2004 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.c,v 1.686 2004/09/10 20:45:33 pollita Exp $ */ +/* $Id: basic_functions.c,v 1.687 2004/09/14 03:48:16 pollita Exp $ */ #include "php.h" #include "php_streams.h" @@ -600,6 +600,7 @@ PHP_FE(stream_context_get_default, NULL) PHP_FE(stream_filter_prepend, NULL) PHP_FE(stream_filter_append, NULL) + PHP_FE(stream_filter_remove, NULL) PHP_FE(stream_socket_client, second_and_third_args_force_ref) PHP_FE(stream_socket_server, second_and_third_args_force_ref) PHP_FE(stream_socket_accept, third_arg_force_ref) http://cvs.php.net/diff.php/php-src/ext/standard/streamsfuncs.c?r1=1.40&r2=1.41&ty=u Index: php-src/ext/standard/streamsfuncs.c diff -u php-src/ext/standard/streamsfuncs.c:1.40 php-src/ext/standard/streamsfuncs.c:1.41 --- php-src/ext/standard/streamsfuncs.c:1.40 Fri Aug 6 10:08:17 2004 +++ php-src/ext/standard/streamsfuncs.c Mon Sep 13 23:48:16 2004 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: streamsfuncs.c,v 1.40 2004/08/06 14:08:17 wez Exp $ */ +/* $Id: streamsfuncs.c,v 1.41 2004/09/14 03:48:16 pollita Exp $ */ #include "php.h" #include "php_globals.h" @@ -987,7 +987,7 @@ int filternamelen; long read_write = 0; zval *filterparams = NULL; - php_stream_filter *filter; + php_stream_filter *filter = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|lz", &zstream, &filtername, &filternamelen, &read_write, &filterparams) == FAILURE) { @@ -1036,10 +1036,14 @@ } } - RETURN_TRUE; + if (filter) { + RETURN_RESOURCE(ZEND_REGISTER_RESOURCE(NULL, filter, php_file_le_stream_filter())); + } else { + RETURN_FALSE; + } } -/* {{{ proto bool stream_filter_prepend(resource stream, string filtername[, int read_write[, string filterparams]]) +/* {{{ proto resource stream_filter_prepend(resource stream, string filtername[, int read_write[, string filterparams]]) Prepend a filter to a stream */ PHP_FUNCTION(stream_filter_prepend) { @@ -1047,7 +1051,7 @@ } /* }}} */ -/* {{{ proto bool stream_filter_append(resource stream, string filtername[, int read_write[, string filterparams]]) +/* {{{ proto resource stream_filter_append(resource stream, string filtername[, int read_write[, string filterparams]]) Append a filter to a stream */ PHP_FUNCTION(stream_filter_append) { @@ -1055,6 +1059,36 @@ } /* }}} */ +/* {{{ proto bool stream_filter_remove(resource stream_filter) + Flushes any data in the filter's internal buffer, removes it from the chain, and frees the resource */ +PHP_FUNCTION(stream_filter_remove) +{ + zval *zfilter; + php_stream_filter *filter; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zfilter) == FAILURE) { + RETURN_FALSE; + } + + filter = zend_fetch_resource(&zfilter TSRMLS_CC, -1, NULL, NULL, 1, php_file_le_stream_filter()); + if (!filter) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid resource given, not a stream filter"); + RETURN_FALSE; + } + + if (php_stream_filter_flush(filter, 1) == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to flush filter, not removing"); + RETURN_FALSE; + } + + if (zend_list_delete(Z_LVAL_P(zfilter)) == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not invalidate filter, not removing"); + RETURN_FALSE; + } else { + php_stream_filter_remove(filter, 1 TSRMLS_CC); + RETURN_TRUE; + } +} /* }}} */ /* {{{ proto string stream_get_line(resource stream, int maxlen, string ending) http://cvs.php.net/diff.php/php-src/ext/standard/streamsfuncs.h?r1=1.10&r2=1.11&ty=u Index: php-src/ext/standard/streamsfuncs.h diff -u php-src/ext/standard/streamsfuncs.h:1.10 php-src/ext/standard/streamsfuncs.h:1.11 --- php-src/ext/standard/streamsfuncs.h:1.10 Fri Sep 10 16:45:35 2004 +++ php-src/ext/standard/streamsfuncs.h Mon Sep 13 23:48:16 2004 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: streamsfuncs.h,v 1.10 2004/09/10 20:45:35 pollita Exp $ */ +/* $Id: streamsfuncs.h,v 1.11 2004/09/14 03:48:16 pollita Exp $ */ /* Flags for stream_socket_client */ #define PHP_STREAM_CLIENT_PERSISTENT 1 @@ -52,6 +52,7 @@ PHP_FUNCTION(stream_context_get_default); PHP_FUNCTION(stream_filter_prepend); PHP_FUNCTION(stream_filter_append); +PHP_FUNCTION(stream_filter_remove); PHP_FUNCTION(stream_socket_enable_crypto); /* http://cvs.php.net/diff.php/php-src/main/php_streams.h?r1=1.96&r2=1.97&ty=u Index: php-src/main/php_streams.h diff -u php-src/main/php_streams.h:1.96 php-src/main/php_streams.h:1.97 --- php-src/main/php_streams.h:1.96 Fri Sep 10 16:45:35 2004 +++ php-src/main/php_streams.h Mon Sep 13 23:48:16 2004 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_streams.h,v 1.96 2004/09/10 20:45:35 pollita Exp $ */ +/* $Id: php_streams.h,v 1.97 2004/09/14 03:48:16 pollita Exp $ */ #ifndef PHP_STREAMS_H #define PHP_STREAMS_H @@ -30,6 +30,7 @@ BEGIN_EXTERN_C() PHPAPI int php_file_le_stream(void); PHPAPI int php_file_le_pstream(void); +PHPAPI int php_file_le_stream_filter(void); END_EXTERN_C() /* {{{ Streams memory debugging stuff */ http://cvs.php.net/diff.php/php-src/main/streams/filter.c?r1=1.14&r2=1.15&ty=u Index: php-src/main/streams/filter.c diff -u php-src/main/streams/filter.c:1.14 php-src/main/streams/filter.c:1.15 --- php-src/main/streams/filter.c:1.14 Mon Sep 13 17:07:22 2004 +++ php-src/main/streams/filter.c Mon Sep 13 23:48:16 2004 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: filter.c,v 1.14 2004/09/13 21:07:22 pollita Exp $ */ +/* $Id: filter.c,v 1.15 2004/09/14 03:48:16 pollita Exp $ */ #include "php.h" #include "php_globals.h" @@ -403,6 +403,88 @@ } } +} + +PHPAPI int _php_stream_filter_flush(php_stream_filter *filter, int finish TSRMLS_DC) +{ + php_stream_bucket_brigade brig_a = { NULL, NULL }, brig_b = { NULL, NULL }, *inp = &brig_a, *outp = &brig_b, *brig_temp; + php_stream_bucket *bucket; + php_stream_filter_chain *chain; + php_stream_filter *current; + php_stream *stream; + size_t flushed_size = 0; + long flags = (finish ? PSFS_FLAG_FLUSH_CLOSE : PSFS_FLAG_FLUSH_INC); + + if (!filter->chain || !filter->chain->stream) { + /* Filter is not attached to a chain, or chain is somehow not part of a stream */ + return FAILURE; + } + + chain = filter->chain; + stream = chain->stream; + + for(current = filter; current; current = current->next) { + php_stream_filter_status_t status; + + status = filter->fops->filter(stream, filter, inp, outp, NULL, flags TSRMLS_CC); + if (status == PSFS_FEED_ME) { + /* We've flushed the data far enough */ + return SUCCESS; + } + if (status == PSFS_ERR_FATAL) { + return FAILURE; + } + /* Otherwise we have data available to PASS_ON + Swap the brigades and continue */ + brig_temp = inp; + inp = outp; + outp = brig_temp; + outp->head = NULL; + outp->tail = NULL; + + flags = PSFS_FLAG_NORMAL; + } + + /* Last filter returned data via PSFS_PASS_ON + Do something with it */ + + for(bucket = inp->head; bucket; bucket = bucket->next) { + flushed_size += bucket->buflen; + } + + if (flushed_size == 0) { + /* Unlikely, but possible */ + return SUCCESS; + } + + if (chain == &(stream->readfilters)) { + /* Dump any newly flushed data to the read buffer */ + if (stream->readpos > 0) { + /* Back the buffer up */ + memcpy(stream->readbuf, stream->readbuf + stream->readpos, stream->writepos - stream->readpos); + stream->readpos = 0; + stream->writepos -= stream->readpos; + } + if (flushed_size > (stream->readbuflen - stream->writepos)) { + /* Grow the buffer */ + stream->readbuf = perealloc(stream->readbuf, stream->writepos + flushed_size + stream->chunk_size, stream->is_persistent); + } + while ((bucket = inp->head)) { + memcpy(stream->readbuf + stream->writepos, bucket->buf, bucket->buflen); + stream->writepos += bucket->buflen; + php_stream_bucket_unlink(bucket TSRMLS_CC); + php_stream_bucket_delref(bucket TSRMLS_CC); + } + } else if (chain == &(stream->writefilters)) { + /* Send flushed data to the stream */ + while ((bucket = inp->head)) { + stream->ops->write(stream, bucket->buf, bucket->buflen TSRMLS_CC); + php_stream_bucket_unlink(bucket TSRMLS_CC); + php_stream_bucket_delref(bucket TSRMLS_CC); + } + } + + return SUCCESS; } PHPAPI php_stream_filter *php_stream_filter_remove(php_stream_filter *filter, int call_dtor TSRMLS_DC) http://cvs.php.net/diff.php/php-src/main/streams/php_stream_filter_api.h?r1=1.10&r2=1.11&ty=u Index: php-src/main/streams/php_stream_filter_api.h diff -u php-src/main/streams/php_stream_filter_api.h:1.10 php-src/main/streams/php_stream_filter_api.h:1.11 --- php-src/main/streams/php_stream_filter_api.h:1.10 Mon Jun 21 17:08:05 2004 +++ php-src/main/streams/php_stream_filter_api.h Mon Sep 13 23:48:16 2004 @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_stream_filter_api.h,v 1.10 2004/06/21 21:08:05 pollita Exp $ */ +/* $Id: php_stream_filter_api.h,v 1.11 2004/09/14 03:48:16 pollita Exp $ */ /* The filter API works on the principle of "Bucket-Brigades". This is * partially inspired by the Apache 2 method of doing things, although @@ -123,6 +123,7 @@ BEGIN_EXTERN_C() PHPAPI void _php_stream_filter_prepend(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC); PHPAPI void _php_stream_filter_append(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC); +PHPAPI int _php_stream_filter_flush(php_stream_filter *filter, int finish TSRMLS_DC); PHPAPI php_stream_filter *php_stream_filter_remove(php_stream_filter *filter, int call_dtor TSRMLS_DC); PHPAPI void php_stream_filter_free(php_stream_filter *filter TSRMLS_DC); PHPAPI php_stream_filter *_php_stream_filter_alloc(php_stream_filter_ops *fops, void *abstract, int persistent STREAMS_DC TSRMLS_DC); @@ -131,6 +132,7 @@ #define php_stream_filter_alloc_rel(fops, thisptr, persistent) _php_stream_filter_alloc((fops), (thisptr), (persistent) STREAMS_REL_CC TSRMLS_CC) #define php_stream_filter_prepend(chain, filter) _php_stream_filter_prepend((chain), (filter) TSRMLS_CC) #define php_stream_filter_append(chain, filter) _php_stream_filter_append((chain), (filter) TSRMLS_CC) +#define php_stream_filter_flush(filter, finish) _php_stream_filter_flush((filter), (finish) TSRMLS_CC) #define php_stream_is_filtered(stream) ((stream)->readfilters.head || (stream)->writefilters.head) http://cvs.php.net/diff.php/php-src/main/streams/streams.c?r1=1.66&r2=1.67&ty=u Index: php-src/main/streams/streams.c diff -u php-src/main/streams/streams.c:1.66 php-src/main/streams/streams.c:1.67 --- php-src/main/streams/streams.c:1.66 Mon Sep 13 17:07:22 2004 +++ php-src/main/streams/streams.c Mon Sep 13 23:48:16 2004 @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: streams.c,v 1.66 2004/09/13 21:07:22 pollita Exp $ */ +/* $Id: streams.c,v 1.67 2004/09/14 03:48:16 pollita Exp $ */ #define _GNU_SOURCE #include "php.h" @@ -38,6 +38,7 @@ static HashTable url_stream_wrappers_hash; static int le_stream = FAILURE; /* true global */ static int le_pstream = FAILURE; /* true global */ +static int le_stream_filter = FAILURE; /* true global */ PHPAPI int php_file_le_stream(void) { @@ -49,6 +50,11 @@ return le_pstream; } +PHPAPI int php_file_le_stream_filter(void) +{ + return le_stream_filter; +} + PHPAPI HashTable *_php_stream_get_url_stream_wrappers_hash(TSRMLS_D) { return (FG(stream_wrappers) ? FG(stream_wrappers) : &url_stream_wrappers_hash); @@ -1369,6 +1375,9 @@ { le_stream = zend_register_list_destructors_ex(stream_resource_regular_dtor, NULL, "stream", module_number); le_pstream = zend_register_list_destructors_ex(NULL, stream_resource_persistent_dtor, "persistent stream", module_number); + + /* Filters are cleaned up by the streams they're attached to */ + le_stream_filter = zend_register_list_destructors_ex(NULL, NULL, "stream filter", module_number); return ( zend_hash_init(&url_stream_wrappers_hash, 0, NULL, NULL, 1) == SUCCESS http://cvs.php.net/diff.php/php-src/NEWS?r1=1.1808&r2=1.1809&ty=u Index: php-src/NEWS diff -u php-src/NEWS:1.1808 php-src/NEWS:1.1809 --- php-src/NEWS:1.1808 Fri Sep 10 16:45:26 2004 +++ php-src/NEWS Mon Sep 13 23:48:17 2004 @@ -16,6 +16,7 @@ . stream_socket_enable_crypto() (Wez) . stream_wrapper_unregister() (Sara) . stream_wrapper_restore() (Sara) + . stream_filter_remove() (Sara) . DomDocumentFragment->appendXML() (Christian) . SimpleXMLElement->registerXPathNamespace() (Christian) . mysqli->client_info property (Georg) @@ -31,6 +32,7 @@ - Added HTTP/1.1 and chunked encoding support to http:// wrapper. (Sara) - Added support of parameter->value arrays to xsl_xsltprocessor_set_parameter() (Tony) +- Changed stream_filter_(ap|pre)pend() to return resource. (Sara) - Fixed bug with raw_post_data not getting set. (Brian) - Fixed bug in mysql->client_version. (Georg) - Fixed ZTS destruction. (Marcus)
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php