1 /* 2 +----------------------------------------------------------------------+ 3 | PHP Version 7 | 4 +----------------------------------------------------------------------+ 5 | Copyright (c) 1997-2017 The PHP Group | 6 +----------------------------------------------------------------------+ 7 | This source file is subject to version 3.01 of the PHP license, | 8 | that is bundled with this package in the file LICENSE, and is | 9 | available through the world-wide-web at the following url: | 10 | http://www.php.net/license/3_01.txt | 11 | If you did not receive a copy of the PHP license and are unable to | 12 | obtain it through the world-wide-web, please send a note to | 13 | license@php.net so we can mail you a copy immediately. | 14 +----------------------------------------------------------------------+ 15 | Author: Wez Furlong <wez@thebrainroom.com> | 16 | With suggestions from: | 17 | Moriyoshi Koizumi <moriyoshi@at.wakwak.com> | 18 | Sara Golemon <pollita@php.net> | 19 +----------------------------------------------------------------------+ 20 */ 21 22 /* $Id$ */ 23 24 /* The filter API works on the principle of "Bucket-Brigades". This is 25 * partially inspired by the Apache 2 method of doing things, although 26 * it is intentially a light-weight implementation. 27 * 28 * Each stream can have a chain of filters for reading and another for writing. 29 * 30 * When data is written to the stream, it is placed into a bucket and placed at 31 * the start of the input brigade. 32 * 33 * The first filter in the chain is invoked on the brigade and (depending on 34 * it's return value), the next filter is invoked and so on. 35 * */ 36 37 #define PHP_STREAM_FILTER_READ 0x0001 38 #define PHP_STREAM_FILTER_WRITE 0x0002 39 #define PHP_STREAM_FILTER_ALL (PHP_STREAM_FILTER_READ | PHP_STREAM_FILTER_WRITE) 40 41 typedef struct _php_stream_bucket php_stream_bucket; 42 typedef struct _php_stream_bucket_brigade php_stream_bucket_brigade; 43 44 struct _php_stream_bucket { 45 php_stream_bucket *next, *prev; 46 php_stream_bucket_brigade *brigade; 47 48 char *buf; 49 size_t buflen; 50 /* if non-zero, buf should be pefreed when the bucket is destroyed */ 51 int own_buf; 52 int is_persistent; 53 54 /* destroy this struct when refcount falls to zero */ 55 int refcount; 56 }; 57 58 struct _php_stream_bucket_brigade { 59 php_stream_bucket *head, *tail; 60 }; 61 62 typedef enum { 63 PSFS_ERR_FATAL, /* error in data stream */ 64 PSFS_FEED_ME, /* filter needs more data; stop processing chain until more is available */ 65 PSFS_PASS_ON /* filter generated output buckets; pass them on to next in chain */ 66 } php_stream_filter_status_t; 67 68 /* Buckets API. */ 69 BEGIN_EXTERN_C() 70 PHPAPI php_stream_bucket *php_stream_bucket_new(php_stream *stream, char *buf, size_t buflen, int own_buf, int buf_persistent); 71 PHPAPI int php_stream_bucket_split(php_stream_bucket *in, php_stream_bucket **left, php_stream_bucket **right, size_t length); 72 PHPAPI void php_stream_bucket_delref(php_stream_bucket *bucket); 73 #define php_stream_bucket_addref(bucket) (bucket)->refcount++ 74 PHPAPI void php_stream_bucket_prepend(php_stream_bucket_brigade *brigade, php_stream_bucket *bucket); 75 PHPAPI void php_stream_bucket_append(php_stream_bucket_brigade *brigade, php_stream_bucket *bucket); 76 PHPAPI void php_stream_bucket_unlink(php_stream_bucket *bucket); 77 PHPAPI php_stream_bucket *php_stream_bucket_make_writeable(php_stream_bucket *bucket); 78 END_EXTERN_C() 79 80 #define PSFS_FLAG_NORMAL 0 /* regular read/write */ 81 #define PSFS_FLAG_FLUSH_INC 1 /* an incremental flush */ 82 #define PSFS_FLAG_FLUSH_CLOSE 2 /* final flush prior to closing */ 83 84 typedef struct _php_stream_filter_ops { 85 86 php_stream_filter_status_t (*filter)( 87 php_stream *stream, 88 php_stream_filter *thisfilter, 89 php_stream_bucket_brigade *buckets_in, 90 php_stream_bucket_brigade *buckets_out, 91 size_t *bytes_consumed, 92 int flags 93 ); 94 95 void (*dtor)(php_stream_filter *thisfilter); 96 97 const char *label; 98 99 } php_stream_filter_ops; 100 101 typedef struct _php_stream_filter_chain { 102 php_stream_filter *head, *tail; 103 104 /* Owning stream */ 105 php_stream *stream; 106 } php_stream_filter_chain; 107 108 struct _php_stream_filter { 109 php_stream_filter_ops *fops; 110 zval abstract; /* for use by filter implementation */ 111 php_stream_filter *next; 112 php_stream_filter *prev; 113 int is_persistent; 114 115 /* link into stream and chain */ 116 php_stream_filter_chain *chain; 117 118 /* buffered buckets */ 119 php_stream_bucket_brigade buffer; 120 121 /* filters are auto_registered when they're applied */ 122 zend_resource *res; 123 }; 124 125 /* stack filter onto a stream */ 126 BEGIN_EXTERN_C() 127 PHPAPI void _php_stream_filter_prepend(php_stream_filter_chain *chain, php_stream_filter *filter); 128 PHPAPI int php_stream_filter_prepend_ex(php_stream_filter_chain *chain, php_stream_filter *filter); 129 PHPAPI void _php_stream_filter_append(php_stream_filter_chain *chain, php_stream_filter *filter); 130 PHPAPI int php_stream_filter_append_ex(php_stream_filter_chain *chain, php_stream_filter *filter); 131 PHPAPI int _php_stream_filter_flush(php_stream_filter *filter, int finish); 132 PHPAPI php_stream_filter *php_stream_filter_remove(php_stream_filter *filter, int call_dtor); 133 PHPAPI void php_stream_filter_free(php_stream_filter *filter); 134 PHPAPI php_stream_filter *_php_stream_filter_alloc(php_stream_filter_ops *fops, void *abstract, int persistent STREAMS_DC); 135 END_EXTERN_C() 136 #define php_stream_filter_alloc(fops, thisptr, persistent) _php_stream_filter_alloc((fops), (thisptr), (persistent) STREAMS_CC) 137 #define php_stream_filter_alloc_rel(fops, thisptr, persistent) _php_stream_filter_alloc((fops), (thisptr), (persistent) STREAMS_REL_CC) 138 #define php_stream_filter_prepend(chain, filter) _php_stream_filter_prepend((chain), (filter)) 139 #define php_stream_filter_append(chain, filter) _php_stream_filter_append((chain), (filter)) 140 #define php_stream_filter_flush(filter, finish) _php_stream_filter_flush((filter), (finish)) 141 142 #define php_stream_is_filtered(stream) ((stream)->readfilters.head || (stream)->writefilters.head) 143 144 typedef struct _php_stream_filter_factory { 145 php_stream_filter *(*create_filter)(const char *filtername, zval *filterparams, int persistent); 146 } php_stream_filter_factory; 147 148 BEGIN_EXTERN_C() 149 PHPAPI int php_stream_filter_register_factory(const char *filterpattern, php_stream_filter_factory *factory); 150 PHPAPI int php_stream_filter_unregister_factory(const char *filterpattern); 151 PHPAPI int php_stream_filter_register_factory_volatile(const char *filterpattern, php_stream_filter_factory *factory); 152 PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval *filterparams, int persistent); 153 END_EXTERN_C() 154 155 /* 156 * Local variables: 157 * tab-width: 4 158 * c-basic-offset: 4 159 * End: 160 * vim600: sw=4 ts=4 fdm=marker 161 * vim<600: sw=4 ts=4 162 */ 163