PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - main/streams - filter.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 186 265 70.2 %
Date: 2014-04-10 Functions: 18 21 85.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 5                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2014 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             :    | Authors: Wez Furlong <wez@thebrainroom.com>                          |
      16             :    +----------------------------------------------------------------------+
      17             :  */
      18             : 
      19             : /* $Id$ */
      20             : 
      21             : #include "php.h"
      22             : #include "php_globals.h"
      23             : #include "php_network.h"
      24             : #include "php_open_temporary_file.h"
      25             : #include "ext/standard/file.h"
      26             : #include <stddef.h>
      27             : #include <fcntl.h>
      28             : 
      29             : #include "php_streams_int.h"
      30             : 
      31             : /* Global filter hash, copied to FG(stream_filters) on registration of volatile filter */
      32             : static HashTable stream_filters_hash;
      33             : 
      34             : /* Should only be used during core initialization */
      35       40246 : PHPAPI HashTable *php_get_stream_filters_hash_global(void)
      36             : {
      37       40246 :         return &stream_filters_hash;
      38             : }
      39             : 
      40             : /* Normal hash selection/retrieval call */
      41         144 : PHPAPI HashTable *_php_get_stream_filters_hash(TSRMLS_D)
      42             : {
      43         144 :         return (FG(stream_filters) ? FG(stream_filters) : &stream_filters_hash);
      44             : }
      45             : 
      46             : /* API for registering GLOBAL filters */
      47      241260 : PHPAPI int php_stream_filter_register_factory(const char *filterpattern, php_stream_filter_factory *factory TSRMLS_DC)
      48             : {
      49      241260 :         return zend_hash_add(&stream_filters_hash, (char*)filterpattern, strlen(filterpattern) + 1, factory, sizeof(*factory), NULL);
      50             : }
      51             : 
      52      241692 : PHPAPI int php_stream_filter_unregister_factory(const char *filterpattern TSRMLS_DC)
      53             : {
      54      241692 :         return zend_hash_del(&stream_filters_hash, (char*)filterpattern, strlen(filterpattern) + 1);
      55             : }
      56             : 
      57             : /* API for registering VOLATILE wrappers */
      58          13 : PHPAPI int php_stream_filter_register_factory_volatile(const char *filterpattern, php_stream_filter_factory *factory TSRMLS_DC)
      59             : {
      60          13 :         if (!FG(stream_filters)) {
      61             :                 php_stream_filter_factory tmpfactory;
      62             : 
      63           9 :                 ALLOC_HASHTABLE(FG(stream_filters));
      64           9 :                 zend_hash_init(FG(stream_filters), zend_hash_num_elements(&stream_filters_hash), NULL, NULL, 1);
      65           9 :                 zend_hash_copy(FG(stream_filters), &stream_filters_hash, NULL, &tmpfactory, sizeof(php_stream_filter_factory));
      66             :         }
      67             : 
      68          13 :         return zend_hash_add(FG(stream_filters), (char*)filterpattern, strlen(filterpattern) + 1, factory, sizeof(*factory), NULL);
      69             : }
      70             : 
      71             : /* Buckets */
      72             : 
      73         587 : PHPAPI php_stream_bucket *php_stream_bucket_new(php_stream *stream, char *buf, size_t buflen, int own_buf, int buf_persistent TSRMLS_DC)
      74             : {
      75         587 :         int is_persistent = php_stream_is_persistent(stream);
      76             :         php_stream_bucket *bucket;
      77             : 
      78         587 :         bucket = (php_stream_bucket*)pemalloc(sizeof(php_stream_bucket), is_persistent);
      79             : 
      80         587 :         if (bucket == NULL) {
      81           0 :                 return NULL;
      82             :         }
      83             :         
      84         587 :         bucket->next = bucket->prev = NULL;
      85             : 
      86         587 :         if (is_persistent && !buf_persistent) {
      87             :                 /* all data in a persistent bucket must also be persistent */
      88           0 :                 bucket->buf = pemalloc(buflen, 1);
      89             :                 
      90           0 :                 if (bucket->buf == NULL) {
      91           0 :                         pefree(bucket, 1);
      92           0 :                         return NULL;
      93             :                 }
      94             :                 
      95           0 :                 memcpy(bucket->buf, buf, buflen);
      96           0 :                 bucket->buflen = buflen;
      97           0 :                 bucket->own_buf = 1;
      98             :         } else {
      99         587 :                 bucket->buf = buf;
     100         587 :                 bucket->buflen = buflen;
     101         587 :                 bucket->own_buf = own_buf;
     102             :         }
     103         587 :         bucket->is_persistent = is_persistent;
     104         587 :         bucket->refcount = 1;
     105         587 :         bucket->brigade = NULL;
     106             : 
     107         587 :         return bucket;
     108             : }
     109             : 
     110             : /* Given a bucket, returns a version of that bucket with a writeable buffer.
     111             :  * If the original bucket has a refcount of 1 and owns its buffer, then it
     112             :  * is returned unchanged.
     113             :  * Otherwise, a copy of the buffer is made.
     114             :  * In both cases, the original bucket is unlinked from its brigade.
     115             :  * If a copy is made, the original bucket is delref'd.
     116             :  * */
     117         200 : PHPAPI php_stream_bucket *php_stream_bucket_make_writeable(php_stream_bucket *bucket TSRMLS_DC)
     118             : {
     119             :         php_stream_bucket *retval;
     120             : 
     121         200 :         php_stream_bucket_unlink(bucket TSRMLS_CC);
     122             :         
     123         200 :         if (bucket->refcount == 1 && bucket->own_buf) {
     124           7 :                 return bucket;
     125             :         }
     126             : 
     127         193 :         retval = (php_stream_bucket*)pemalloc(sizeof(php_stream_bucket), bucket->is_persistent);
     128         193 :         memcpy(retval, bucket, sizeof(*retval));
     129             : 
     130         193 :         retval->buf = pemalloc(retval->buflen, retval->is_persistent);
     131         193 :         memcpy(retval->buf, bucket->buf, retval->buflen);
     132             : 
     133         193 :         retval->refcount = 1;
     134         193 :         retval->own_buf = 1;
     135             : 
     136         193 :         php_stream_bucket_delref(bucket TSRMLS_CC);
     137             :         
     138         193 :         return retval;
     139             : }
     140             : 
     141           0 : PHPAPI int php_stream_bucket_split(php_stream_bucket *in, php_stream_bucket **left, php_stream_bucket **right, size_t length TSRMLS_DC)
     142             : {
     143           0 :         *left = (php_stream_bucket*)pecalloc(1, sizeof(php_stream_bucket), in->is_persistent);
     144           0 :         *right = (php_stream_bucket*)pecalloc(1, sizeof(php_stream_bucket), in->is_persistent);
     145             : 
     146           0 :         if (*left == NULL || *right == NULL) {
     147             :                 goto exit_fail;
     148             :         }
     149             : 
     150           0 :         (*left)->buf = pemalloc(length, in->is_persistent);
     151           0 :         (*left)->buflen = length;
     152           0 :         memcpy((*left)->buf, in->buf, length);
     153           0 :         (*left)->refcount = 1;
     154           0 :         (*left)->own_buf = 1;
     155           0 :         (*left)->is_persistent = in->is_persistent;
     156             :         
     157           0 :         (*right)->buflen = in->buflen - length;
     158           0 :         (*right)->buf = pemalloc((*right)->buflen, in->is_persistent);
     159           0 :         memcpy((*right)->buf, in->buf + length, (*right)->buflen);
     160           0 :         (*right)->refcount = 1;
     161           0 :         (*right)->own_buf = 1;
     162           0 :         (*right)->is_persistent = in->is_persistent;
     163             :         
     164           0 :         return SUCCESS;
     165             :         
     166             : exit_fail:
     167           0 :         if (*right) {
     168           0 :                 if ((*right)->buf) {
     169           0 :                         pefree((*right)->buf, in->is_persistent);
     170             :                 }
     171           0 :                 pefree(*right, in->is_persistent);
     172             :         }
     173           0 :         if (*left) {
     174           0 :                 if ((*left)->buf) {
     175           0 :                         pefree((*left)->buf, in->is_persistent);
     176             :                 }
     177           0 :                 pefree(*left, in->is_persistent);
     178             :         }
     179           0 :         return FAILURE;
     180             : }
     181             : 
     182         796 : PHPAPI void php_stream_bucket_delref(php_stream_bucket *bucket TSRMLS_DC)
     183             : {
     184         796 :         if (--bucket->refcount == 0) {
     185         780 :                 if (bucket->own_buf) {
     186         551 :                         pefree(bucket->buf, bucket->is_persistent);
     187             :                 }
     188         780 :                 pefree(bucket, bucket->is_persistent);
     189             :         }
     190         796 : }
     191             : 
     192           0 : PHPAPI void php_stream_bucket_prepend(php_stream_bucket_brigade *brigade, php_stream_bucket *bucket TSRMLS_DC)
     193             : {
     194           0 :         bucket->next = brigade->head;
     195           0 :         bucket->prev = NULL;
     196             : 
     197           0 :         if (brigade->head) {
     198           0 :                 brigade->head->prev = bucket;
     199             :         } else {
     200           0 :                 brigade->tail = bucket;
     201             :         }
     202           0 :         brigade->head = bucket;
     203           0 :         bucket->brigade = brigade;
     204           0 : }
     205             : 
     206         632 : PHPAPI void php_stream_bucket_append(php_stream_bucket_brigade *brigade, php_stream_bucket *bucket TSRMLS_DC)
     207             : {
     208         632 :         if (brigade->tail == bucket) {
     209           1 :                 return;
     210             :         }
     211             : 
     212         631 :         bucket->prev = brigade->tail;
     213         631 :         bucket->next = NULL;
     214             : 
     215         631 :         if (brigade->tail) {
     216         166 :                 brigade->tail->next = bucket;
     217             :         } else {
     218         465 :                 brigade->head = bucket;
     219             :         }
     220         631 :         brigade->tail = bucket;
     221         631 :         bucket->brigade = brigade;
     222             : }
     223             : 
     224         631 : PHPAPI void php_stream_bucket_unlink(php_stream_bucket *bucket TSRMLS_DC)
     225             : {
     226         631 :         if (bucket->prev) {
     227           0 :                 bucket->prev->next = bucket->next;
     228         631 :         } else if (bucket->brigade) {
     229         631 :                 bucket->brigade->head = bucket->next;
     230             :         }
     231         631 :         if (bucket->next) {
     232         166 :                 bucket->next->prev = bucket->prev;
     233         465 :         } else if (bucket->brigade) {
     234         465 :                 bucket->brigade->tail = bucket->prev;
     235             :         }
     236         631 :         bucket->brigade = NULL;
     237         631 :         bucket->next = bucket->prev = NULL;
     238         631 : }
     239             :         
     240             : 
     241             : 
     242             : 
     243             : 
     244             : 
     245             : 
     246             : 
     247             : /* We allow very simple pattern matching for filter factories:
     248             :  * if "convert.charset.utf-8/sjis" is requested, we search first for an exact
     249             :  * match. If that fails, we try "convert.charset.*", then "convert.*"
     250             :  * This means that we don't need to clog up the hashtable with a zillion
     251             :  * charsets (for example) but still be able to provide them all as filters */
     252         270 : PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval *filterparams, int persistent TSRMLS_DC)
     253             : {
     254         270 :         HashTable *filter_hash = (FG(stream_filters) ? FG(stream_filters) : &stream_filters_hash);
     255         270 :         php_stream_filter_factory *factory = NULL;
     256         270 :         php_stream_filter *filter = NULL;
     257             :         int n;
     258             :         char *period;
     259             : 
     260         270 :         n = strlen(filtername);
     261             :         
     262         270 :         if (SUCCESS == zend_hash_find(filter_hash, (char*)filtername, n + 1, (void**)&factory)) {
     263          89 :                 filter = factory->create_filter(filtername, filterparams, persistent TSRMLS_CC);
     264         181 :         } else if ((period = strrchr(filtername, '.'))) {
     265             :                 /* try a wildcard */
     266             :                 char *wildname;
     267             : 
     268         181 :                 wildname = emalloc(n+3);
     269         181 :                 memcpy(wildname, filtername, n+1);
     270         181 :                 period = wildname + (period - filtername);
     271         545 :                 while (period && !filter) {
     272         183 :                         *period = '\0';
     273         183 :                         strncat(wildname, ".*", 2);
     274         183 :                         if (SUCCESS == zend_hash_find(filter_hash, wildname, strlen(wildname) + 1, (void**)&factory)) {
     275         182 :                                 filter = factory->create_filter(filtername, filterparams, persistent TSRMLS_CC);
     276             :                         }
     277             : 
     278         183 :                         *period = '\0';
     279         183 :                         period = strrchr(wildname, '.');
     280             :                 }
     281         181 :                 efree(wildname);
     282             :         }
     283             : 
     284         270 :         if (filter == NULL) {
     285             :                 /* TODO: these need correct docrefs */
     286           1 :                 if (factory == NULL)
     287           0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to locate filter \"%s\"", filtername);
     288             :                 else
     289           1 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to create or locate filter \"%s\"", filtername);
     290             :         }
     291             :         
     292         270 :         return filter;
     293             : }
     294             : 
     295         269 : PHPAPI php_stream_filter *_php_stream_filter_alloc(php_stream_filter_ops *fops, void *abstract, int persistent STREAMS_DC TSRMLS_DC)
     296             : {
     297             :         php_stream_filter *filter;
     298             : 
     299         269 :         filter = (php_stream_filter*) pemalloc_rel_orig(sizeof(php_stream_filter), persistent);
     300         269 :         memset(filter, 0, sizeof(php_stream_filter));
     301             : 
     302         269 :         filter->fops = fops;
     303         269 :         filter->abstract = abstract;
     304         269 :         filter->is_persistent = persistent;
     305             :         
     306         269 :         return filter;
     307             : }
     308             : 
     309         269 : PHPAPI void php_stream_filter_free(php_stream_filter *filter TSRMLS_DC)
     310             : {
     311         269 :         if (filter->fops->dtor)
     312         244 :                 filter->fops->dtor(filter TSRMLS_CC);
     313         269 :         pefree(filter, filter->is_persistent);
     314         269 : }
     315             : 
     316          10 : PHPAPI int php_stream_filter_prepend_ex(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC)
     317             : {
     318          10 :         filter->next = chain->head;
     319          10 :         filter->prev = NULL;
     320             : 
     321          10 :         if (chain->head) {
     322           2 :                 chain->head->prev = filter;
     323             :         } else {
     324           8 :                 chain->tail = filter;
     325             :         }
     326          10 :         chain->head = filter;
     327          10 :         filter->chain = chain;
     328             : 
     329          10 :         return SUCCESS;
     330             : }
     331             : 
     332           0 : PHPAPI void _php_stream_filter_prepend(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC)
     333             : {
     334           0 :         php_stream_filter_prepend_ex(chain, filter TSRMLS_CC);
     335           0 : }
     336             : 
     337         259 : PHPAPI int php_stream_filter_append_ex(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC)
     338             : {
     339         259 :         php_stream *stream = chain->stream;
     340             : 
     341         259 :         filter->prev = chain->tail;
     342         259 :         filter->next = NULL;
     343         259 :         if (chain->tail) {
     344          26 :                 chain->tail->next = filter;
     345             :         } else {
     346         233 :                 chain->head = filter;
     347             :         }
     348         259 :         chain->tail = filter;
     349         259 :         filter->chain = chain;
     350             : 
     351         259 :         if (&(stream->readfilters) == chain && (stream->writepos - stream->readpos) > 0) {
     352             :                 /* Let's going ahead and wind anything in the buffer through this filter */
     353           8 :                 php_stream_bucket_brigade brig_in = { NULL, NULL }, brig_out = { NULL, NULL };
     354           8 :                 php_stream_bucket_brigade *brig_inp = &brig_in, *brig_outp = &brig_out;
     355             :                 php_stream_filter_status_t status;
     356             :                 php_stream_bucket *bucket;
     357           8 :                 size_t consumed = 0;
     358             : 
     359           8 :                 bucket = php_stream_bucket_new(stream, (char*) stream->readbuf + stream->readpos, stream->writepos - stream->readpos, 0, 0 TSRMLS_CC);
     360           8 :                 php_stream_bucket_append(brig_inp, bucket TSRMLS_CC);
     361           8 :                 status = filter->fops->filter(stream, filter, brig_inp, brig_outp, &consumed, PSFS_FLAG_NORMAL TSRMLS_CC);
     362             : 
     363           8 :                 if (stream->readpos + consumed > (uint)stream->writepos) {
     364             :                         /* No behaving filter should cause this. */
     365           0 :                         status = PSFS_ERR_FATAL;
     366             :                 }
     367             : 
     368           8 :                 switch (status) {
     369             :                         case PSFS_ERR_FATAL:
     370          14 :                                 while (brig_in.head) {
     371           0 :                                         bucket = brig_in.head;
     372           0 :                                         php_stream_bucket_unlink(bucket TSRMLS_CC);
     373           0 :                                         php_stream_bucket_delref(bucket TSRMLS_CC);
     374             :                                 }
     375          14 :                                 while (brig_out.head) {
     376           0 :                                         bucket = brig_out.head;
     377           0 :                                         php_stream_bucket_unlink(bucket TSRMLS_CC);
     378           0 :                                         php_stream_bucket_delref(bucket TSRMLS_CC);
     379             :                                 }
     380           7 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Filter failed to process pre-buffered data");
     381           7 :                                 return FAILURE;
     382             :                         case PSFS_FEED_ME:
     383             :                                 /* We don't actually need data yet,
     384             :                                    leave this filter in a feed me state until data is needed. 
     385             :                                    Reset stream's internal read buffer since the filter is "holding" it. */
     386           0 :                                 stream->readpos = 0;
     387           0 :                                 stream->writepos = 0;
     388           0 :                                 break;
     389             :                         case PSFS_PASS_ON:
     390             :                                 /* If any data is consumed, we cannot rely upon the existing read buffer,
     391             :                                    as the filtered data must replace the existing data, so invalidate the cache */
     392             :                                 /* note that changes here should be reflected in
     393             :                                    main/streams/streams.c::php_stream_fill_read_buffer */
     394           1 :                                 stream->writepos = 0;
     395           1 :                                 stream->readpos = 0;
     396             : 
     397           3 :                                 while (brig_outp->head) {
     398           1 :                                         bucket = brig_outp->head;
     399             :                                         /* Grow buffer to hold this bucket if need be.
     400             :                                            TODO: See warning in main/stream/streams.c::php_stream_fill_read_buffer */
     401           1 :                                         if (stream->readbuflen - stream->writepos < bucket->buflen) {
     402           0 :                                                 stream->readbuflen += bucket->buflen;
     403           0 :                                                 stream->readbuf = perealloc(stream->readbuf, stream->readbuflen, stream->is_persistent);
     404             :                                         }
     405           1 :                                         memcpy(stream->readbuf + stream->writepos, bucket->buf, bucket->buflen);
     406           1 :                                         stream->writepos += bucket->buflen;
     407             : 
     408           1 :                                         php_stream_bucket_unlink(bucket TSRMLS_CC);
     409           1 :                                         php_stream_bucket_delref(bucket TSRMLS_CC);
     410             :                                 }
     411             :                                 break;
     412             :                 }
     413             :         }
     414             : 
     415         252 :         return SUCCESS;
     416             : }
     417             : 
     418         142 : PHPAPI void _php_stream_filter_append(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC)
     419             : {
     420         142 :         if (php_stream_filter_append_ex(chain, filter TSRMLS_CC) != SUCCESS) {
     421           0 :                 if (chain->head == filter) {
     422           0 :                         chain->head = NULL;
     423           0 :                         chain->tail = NULL;
     424             :                 } else {
     425           0 :                         filter->prev->next = NULL;
     426           0 :                         chain->tail = filter->prev;
     427             :                 }
     428             :         }
     429         142 : }
     430             : 
     431         157 : PHPAPI int _php_stream_filter_flush(php_stream_filter *filter, int finish TSRMLS_DC)
     432             : {
     433         157 :         php_stream_bucket_brigade brig_a = { NULL, NULL }, brig_b = { NULL, NULL }, *inp = &brig_a, *outp = &brig_b, *brig_temp;
     434             :         php_stream_bucket *bucket;
     435             :         php_stream_filter_chain *chain;
     436             :         php_stream_filter *current;
     437             :         php_stream *stream;
     438         157 :         size_t flushed_size = 0;
     439         157 :         long flags = (finish ? PSFS_FLAG_FLUSH_CLOSE : PSFS_FLAG_FLUSH_INC);
     440             : 
     441         157 :         if (!filter->chain || !filter->chain->stream) {
     442             :                 /* Filter is not attached to a chain, or chain is somehow not part of a stream */
     443           0 :                 return FAILURE;
     444             :         }
     445             : 
     446         157 :         chain = filter->chain;
     447         157 :         stream = chain->stream;
     448             : 
     449         235 :         for(current = filter; current; current = current->next) {
     450             :                 php_stream_filter_status_t status;
     451             : 
     452         157 :                 status = filter->fops->filter(stream, filter, inp, outp, NULL, flags TSRMLS_CC);
     453         157 :                 if (status == PSFS_FEED_ME) {
     454             :                         /* We've flushed the data far enough */
     455          69 :                         return SUCCESS;
     456             :                 }
     457          88 :                 if (status == PSFS_ERR_FATAL) {
     458          10 :                         return FAILURE;
     459             :                 }
     460             :                 /* Otherwise we have data available to PASS_ON
     461             :                         Swap the brigades and continue */
     462          78 :                 brig_temp = inp;
     463          78 :                 inp = outp;
     464          78 :                 outp = brig_temp;
     465          78 :                 outp->head = NULL;
     466          78 :                 outp->tail = NULL;
     467             : 
     468          78 :                 flags = PSFS_FLAG_NORMAL;
     469             :         }
     470             : 
     471             :         /* Last filter returned data via PSFS_PASS_ON
     472             :                 Do something with it */
     473             : 
     474         151 :         for(bucket = inp->head; bucket; bucket = bucket->next) {
     475          73 :                 flushed_size += bucket->buflen;
     476             :         }
     477             : 
     478          78 :         if (flushed_size == 0) {
     479             :                 /* Unlikely, but possible */
     480           9 :                 return SUCCESS;
     481             :         }
     482             : 
     483          69 :         if (chain == &(stream->readfilters)) {
     484             :                 /* Dump any newly flushed data to the read buffer */
     485           0 :                 if (stream->readpos > 0) {
     486             :                         /* Back the buffer up */
     487           0 :                         memcpy(stream->readbuf, stream->readbuf + stream->readpos, stream->writepos - stream->readpos);
     488           0 :                         stream->readpos = 0;
     489           0 :                         stream->writepos -= stream->readpos;
     490             :                 }
     491           0 :                 if (flushed_size > (stream->readbuflen - stream->writepos)) {
     492             :                         /* Grow the buffer */
     493           0 :                         stream->readbuf = perealloc(stream->readbuf, stream->writepos + flushed_size + stream->chunk_size, stream->is_persistent);
     494             :                 }
     495           0 :                 while ((bucket = inp->head)) {
     496           0 :                         memcpy(stream->readbuf + stream->writepos, bucket->buf, bucket->buflen);
     497           0 :                         stream->writepos += bucket->buflen;
     498           0 :                         php_stream_bucket_unlink(bucket TSRMLS_CC);
     499           0 :                         php_stream_bucket_delref(bucket TSRMLS_CC);
     500             :                 }
     501          69 :         } else if (chain == &(stream->writefilters)) {
     502             :                 /* Send flushed data to the stream */
     503         211 :                 while ((bucket = inp->head)) {
     504          73 :                         stream->ops->write(stream, bucket->buf, bucket->buflen TSRMLS_CC);
     505          73 :                         php_stream_bucket_unlink(bucket TSRMLS_CC);
     506          73 :                         php_stream_bucket_delref(bucket TSRMLS_CC);
     507             :                 }
     508             :         }
     509             : 
     510          69 :         return SUCCESS;
     511             : }
     512             : 
     513         269 : PHPAPI php_stream_filter *php_stream_filter_remove(php_stream_filter *filter, int call_dtor TSRMLS_DC)
     514             : {
     515         269 :         if (filter->prev) {
     516           0 :                 filter->prev->next = filter->next;
     517             :         } else {
     518         269 :                 filter->chain->head = filter->next;
     519             :         }
     520         269 :         if (filter->next) {
     521          28 :                 filter->next->prev = filter->prev;
     522             :         } else {
     523         241 :                 filter->chain->tail = filter->prev;
     524             :         }
     525             : 
     526         269 :         if (filter->rsrc_id > 0) {
     527          88 :                 zend_list_delete(filter->rsrc_id);
     528             :         }
     529             : 
     530         269 :         if (call_dtor) {
     531         269 :                 php_stream_filter_free(filter TSRMLS_CC);
     532         269 :                 return NULL;
     533             :         }
     534           0 :         return filter;
     535             : }
     536             : 
     537             : /*
     538             :  * Local variables:
     539             :  * tab-width: 4
     540             :  * c-basic-offset: 4
     541             :  * End:
     542             :  * vim600: noet sw=4 ts=4 fdm=marker
     543             :  * vim<600: noet sw=4 ts=4
     544             :  */

Generated by: LCOV version 1.10

Generated at Thu, 10 Apr 2014 08:54:03 +0000 (6 days ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.