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: 187 265 70.6 %
Date: 2014-11-22 Functions: 18 21 85.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Sat, 22 Nov 2014 23:01:30 +0000 (18 hours ago)

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