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

LTP GCOV extension - code coverage report
Current view: directory - bz2 - bz2_filter.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 215
Code covered: 64.2 % Executed lines: 138
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 6                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2009 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: Sara Golemon (pollita@php.net)                              |
      16                 :    +----------------------------------------------------------------------+
      17                 : */
      18                 : 
      19                 : /* $Id: bz2_filter.c 280599 2009-05-15 17:27:56Z kalle $ */
      20                 : 
      21                 : #ifdef HAVE_CONFIG_H
      22                 : #include "config.h"
      23                 : #endif
      24                 : 
      25                 : #include "php.h"
      26                 : #include "php_bz2.h"
      27                 : 
      28                 : /* {{{ data structure */
      29                 : 
      30                 : enum strm_status {
      31                 :     PHP_BZ2_UNITIALIZED,
      32                 :     PHP_BZ2_RUNNING,
      33                 :     PHP_BZ2_FINISHED
      34                 : };
      35                 : 
      36                 : typedef struct _php_bz2_filter_data {
      37                 :         int persistent;
      38                 :         bz_stream strm;
      39                 :         char *inbuf;
      40                 :         size_t inbuf_len;
      41                 :         char *outbuf;
      42                 :         size_t outbuf_len;
      43                 :         
      44                 :         /* Decompress options */
      45                 :         enum strm_status status;
      46                 :         unsigned int small_footprint : 1;
      47                 :         unsigned int expect_concatenated : 1;
      48                 : } php_bz2_filter_data;
      49                 : 
      50                 : /* }}} */
      51                 : 
      52                 : /* {{{ Memory management wrappers */
      53                 : 
      54                 : static void *php_bz2_alloc(void *opaque, int items, int size)
      55             142 : {
      56             142 :         return (void *)safe_pemalloc(items, size, 0, ((php_bz2_filter_data*)opaque)->persistent);
      57                 : }
      58                 : 
      59                 : static void php_bz2_free(void *opaque, void *address)
      60             142 : {
      61             142 :         pefree((void *)address, ((php_bz2_filter_data*)opaque)->persistent);
      62             142 : }
      63                 : /* }}} */
      64                 : 
      65                 : /* {{{ bzip2.decompress filter implementation */
      66                 : 
      67                 : static php_stream_filter_status_t php_bz2_decompress_filter(
      68                 :         php_stream *stream,
      69                 :         php_stream_filter *thisfilter,
      70                 :         php_stream_bucket_brigade *buckets_in,
      71                 :         php_stream_bucket_brigade *buckets_out,
      72                 :         size_t *bytes_consumed,
      73                 :         int flags
      74                 :         TSRMLS_DC)
      75              59 : {
      76                 :         php_bz2_filter_data *data;
      77                 :         php_stream_bucket *bucket;
      78              59 :         size_t consumed = 0;
      79                 :         int status;
      80              59 :         php_stream_filter_status_t exit_status = PSFS_FEED_ME;
      81                 :         bz_stream *streamp;
      82                 : 
      83              59 :         if (!thisfilter || !thisfilter->abstract) {
      84                 :                 /* Should never happen */
      85               0 :                 return PSFS_ERR_FATAL;
      86                 :         }
      87                 : 
      88              59 :         data = (php_bz2_filter_data *)(thisfilter->abstract);
      89              59 :         streamp = &(data->strm);
      90                 : 
      91             141 :         while (buckets_in->head) {
      92              23 :                 int bin = 0;
      93                 :                 size_t desired;
      94                 : 
      95              23 :                 bucket = buckets_in->head;
      96                 : 
      97              23 :                 if (bucket->buf_type == IS_UNICODE) {
      98                 :                         /* decompression not allowed for unicode data */
      99               0 :                         return PSFS_ERR_FATAL;
     100                 :                 }
     101                 : 
     102              23 :                 bucket = php_stream_bucket_make_writeable(bucket TSRMLS_CC);
     103              83 :                 while (bin < bucket->buflen) {
     104              38 :                         if (data->status == PHP_BZ2_UNITIALIZED) {
     105              23 :                                 status = BZ2_bzDecompressInit(streamp, 0, data->small_footprint);
     106                 : 
     107              23 :                                 if (BZ_OK != status) {
     108               0 :                                         return PSFS_ERR_FATAL;
     109                 :                                 }
     110                 : 
     111              23 :                                 data->status = PHP_BZ2_RUNNING;
     112                 :                         }
     113                 : 
     114              38 :                         if (data->status != PHP_BZ2_RUNNING) {
     115               1 :                                 consumed += bucket->buflen;
     116               1 :                                 break;
     117                 :                         }
     118                 : 
     119              37 :                         desired = bucket->buflen - bin;
     120              37 :                         if (desired > data->inbuf_len) {
     121               2 :                                 desired = data->inbuf_len;
     122                 :                         }
     123              37 :                         memcpy(data->strm.next_in, bucket->buf.s + bin, desired);
     124              37 :                         data->strm.avail_in = desired;
     125                 : 
     126              37 :                         status = BZ2_bzDecompress(&(data->strm));
     127                 : 
     128              37 :                         if (status == BZ_STREAM_END) {
     129              23 :                                 BZ2_bzDecompressEnd(&(data->strm));
     130              23 :                                 if (data->expect_concatenated) {
     131               0 :                                         data->status = PHP_BZ2_UNITIALIZED;
     132                 :                                 } else {
     133              23 :                                         data->status = PHP_BZ2_FINISHED;
     134                 :                                 }
     135              14 :                         } else if (status != BZ_OK) {
     136                 :                                 /* Something bad happened */
     137               0 :                                 php_stream_bucket_delref(bucket TSRMLS_CC);
     138               0 :                                 return PSFS_ERR_FATAL;
     139                 :                         }
     140              37 :                         desired -= data->strm.avail_in; /* desired becomes what we consumed this round through */
     141              37 :                         data->strm.next_in = data->inbuf;
     142              37 :                         data->strm.avail_in = 0;
     143              37 :                         consumed += desired;
     144              37 :                         bin += desired;
     145                 : 
     146              37 :                         if (data->strm.avail_out < data->outbuf_len) {
     147                 :                                 php_stream_bucket *out_bucket;
     148              36 :                                 size_t bucketlen = data->outbuf_len - data->strm.avail_out;
     149              36 :                                 out_bucket = php_stream_bucket_new(stream, estrndup(data->outbuf, bucketlen), bucketlen, 1, 0 TSRMLS_CC);
     150              36 :                                 php_stream_bucket_append(buckets_out, out_bucket TSRMLS_CC);
     151              36 :                                 data->strm.avail_out = data->outbuf_len;
     152              36 :                                 data->strm.next_out = data->outbuf;
     153              36 :                                 exit_status = PSFS_PASS_ON;
     154               1 :                         } else if (status == BZ_STREAM_END && data->strm.avail_out >= data->outbuf_len) {
     155                 :                                 /* no more data to decompress, and nothing was spat out */
     156               0 :                                 php_stream_bucket_delref(bucket TSRMLS_CC);
     157               0 :                                 return PSFS_PASS_ON;
     158                 :                         }
     159                 :                 }
     160                 : 
     161              23 :                 php_stream_bucket_delref(bucket TSRMLS_CC);
     162                 :         }
     163                 : 
     164              59 :         if ((data->status == PHP_BZ2_RUNNING) && (flags & PSFS_FLAG_FLUSH_CLOSE)) {
     165                 :                 /* Spit it out! */
     166               0 :                 status = BZ_OK;
     167               0 :                 while (status == BZ_OK) {
     168               0 :                         status = BZ2_bzDecompress(&(data->strm));
     169               0 :                         if (data->strm.avail_out < data->outbuf_len) {
     170               0 :                                 size_t bucketlen = data->outbuf_len - data->strm.avail_out;
     171                 : 
     172               0 :                                 bucket = php_stream_bucket_new(stream, estrndup(data->outbuf, bucketlen), bucketlen, 1, 0 TSRMLS_CC);
     173               0 :                                 php_stream_bucket_append(buckets_out, bucket TSRMLS_CC);
     174               0 :                                 data->strm.avail_out = data->outbuf_len;
     175               0 :                                 data->strm.next_out = data->outbuf;
     176               0 :                                 exit_status = PSFS_PASS_ON;
     177               0 :                         } else if (status == BZ_OK) {
     178               0 :                                 break;
     179                 :                         }
     180                 :                 }
     181                 :         }
     182                 : 
     183              59 :         if (bytes_consumed) {
     184              34 :                 *bytes_consumed = consumed;
     185                 :         }
     186                 : 
     187              59 :         return exit_status;
     188                 : }
     189                 : 
     190                 : static void php_bz2_decompress_dtor(php_stream_filter *thisfilter TSRMLS_DC)
     191              23 : {
     192              23 :         if (thisfilter && thisfilter->abstract) {
     193              23 :                 php_bz2_filter_data *data = thisfilter->abstract;
     194              23 :                 if (data->status == PHP_BZ2_RUNNING) {
     195               0 :                         BZ2_bzDecompressEnd(&(data->strm));
     196                 :                 }
     197              23 :                 pefree(data->inbuf, data->persistent);
     198              23 :                 pefree(data->outbuf, data->persistent);
     199              23 :                 pefree(data, data->persistent);
     200                 :         }
     201              23 : }
     202                 : 
     203                 : static php_stream_filter_ops php_bz2_decompress_ops = {
     204                 :         php_bz2_decompress_filter,
     205                 :         php_bz2_decompress_dtor,
     206                 :         "bzip2.decompress",
     207                 :         PSFO_FLAG_ACCEPTS_STRING | PSFO_FLAG_OUTPUTS_STRING
     208                 : };
     209                 : /* }}} */
     210                 : 
     211                 : /* {{{ bzip2.compress filter implementation */
     212                 : 
     213                 : static php_stream_filter_status_t php_bz2_compress_filter(
     214                 :         php_stream *stream,
     215                 :         php_stream_filter *thisfilter,
     216                 :         php_stream_bucket_brigade *buckets_in,
     217                 :         php_stream_bucket_brigade *buckets_out,
     218                 :         size_t *bytes_consumed,
     219                 :         int flags
     220                 :         TSRMLS_DC)
     221              64 : {
     222                 :         php_bz2_filter_data *data;
     223                 :         php_stream_bucket *bucket;
     224              64 :         size_t consumed = 0;
     225                 :         int status;
     226              64 :         php_stream_filter_status_t exit_status = PSFS_FEED_ME;
     227                 :         bz_stream *streamp;
     228                 : 
     229              64 :         if (!thisfilter || !thisfilter->abstract) {
     230                 :                 /* Should never happen */
     231               0 :                 return PSFS_ERR_FATAL;
     232                 :         }
     233                 : 
     234              64 :         data = (php_bz2_filter_data *)(thisfilter->abstract);
     235              64 :         streamp = &(data->strm);
     236                 : 
     237             152 :         while (buckets_in->head) {
     238              24 :                 int bin = 0;
     239                 :                 size_t desired;
     240                 : 
     241              24 :                 bucket = buckets_in->head;
     242                 : 
     243              24 :                 if (bucket->buf_type == IS_UNICODE) {
     244                 :                         /* compression not allowed for unicode data */
     245               0 :                         return PSFS_ERR_FATAL;
     246                 :                 }
     247                 : 
     248              24 :                 bucket = php_stream_bucket_make_writeable(bucket TSRMLS_CC);
     249                 : 
     250              82 :                 while (bin < bucket->buflen) {
     251              34 :                         desired = bucket->buflen - bin;
     252              34 :                         if (desired > data->inbuf_len) {
     253              10 :                                 desired = data->inbuf_len;
     254                 :                         }
     255              34 :                         memcpy(data->strm.next_in, bucket->buf.s + bin, desired);
     256              34 :                         data->strm.avail_in = desired;
     257                 : 
     258              34 :                         status = BZ2_bzCompress(&(data->strm), flags & PSFS_FLAG_FLUSH_CLOSE ? BZ_FINISH : (flags & PSFS_FLAG_FLUSH_INC ? BZ_FLUSH : BZ_RUN));
     259              34 :                         if (status != BZ_RUN_OK && status != BZ_FLUSH_OK && status != BZ_FINISH_OK) {
     260                 :                                 /* Something bad happened */
     261               0 :                                 php_stream_bucket_delref(bucket TSRMLS_CC);
     262               0 :                                 return PSFS_ERR_FATAL;
     263                 :                         }
     264              34 :                         desired -= data->strm.avail_in; /* desired becomes what we consumed this round through */
     265              34 :                         data->strm.next_in = data->inbuf;
     266              34 :                         data->strm.avail_in = 0;
     267              34 :                         consumed += desired;
     268              34 :                         bin += desired;
     269                 : 
     270              34 :                         if (data->strm.avail_out < data->outbuf_len) {
     271                 :                                 php_stream_bucket *out_bucket;
     272               0 :                                 size_t bucketlen = data->outbuf_len - data->strm.avail_out;
     273                 : 
     274               0 :                                 out_bucket = php_stream_bucket_new(stream, estrndup(data->outbuf, bucketlen), bucketlen, 1, 0 TSRMLS_CC);
     275               0 :                                 php_stream_bucket_append(buckets_out, out_bucket TSRMLS_CC);
     276               0 :                                 data->strm.avail_out = data->outbuf_len;
     277               0 :                                 data->strm.next_out = data->outbuf;
     278               0 :                                 exit_status = PSFS_PASS_ON;
     279                 :                         }
     280                 :                 }
     281              24 :                 php_stream_bucket_delref(bucket TSRMLS_CC);
     282                 :         }
     283                 : 
     284              64 :         if (flags & PSFS_FLAG_FLUSH_CLOSE) {
     285                 :                 /* Spit it out! */
     286              24 :                 status = BZ_FINISH_OK;
     287              73 :                 while (status == BZ_FINISH_OK) {
     288              25 :                         status = BZ2_bzCompress(&(data->strm), BZ_FINISH);
     289              25 :                         if (data->strm.avail_out < data->outbuf_len) {
     290              25 :                                 size_t bucketlen = data->outbuf_len - data->strm.avail_out;
     291                 : 
     292              25 :                                 bucket = php_stream_bucket_new(stream, estrndup(data->outbuf, bucketlen), bucketlen, 1, 0 TSRMLS_CC);
     293              25 :                                 php_stream_bucket_append(buckets_out, bucket TSRMLS_CC);
     294              25 :                                 data->strm.avail_out = data->outbuf_len;
     295              25 :                                 data->strm.next_out = data->outbuf;
     296              25 :                                 exit_status = PSFS_PASS_ON;
     297                 :                         }
     298                 :                 }
     299                 :         }
     300                 : 
     301              64 :         if (bytes_consumed) {
     302              41 :                 *bytes_consumed = consumed;
     303                 :         }
     304              64 :         return exit_status;
     305                 : }
     306                 : 
     307                 : static void php_bz2_compress_dtor(php_stream_filter *thisfilter TSRMLS_DC)
     308              24 : {
     309              24 :         if (thisfilter && thisfilter->abstract) {
     310              24 :                 php_bz2_filter_data *data = thisfilter->abstract;
     311              24 :                 BZ2_bzCompressEnd(&(data->strm));
     312              24 :                 pefree(data->inbuf, data->persistent);
     313              24 :                 pefree(data->outbuf, data->persistent);
     314              24 :                 pefree(data, data->persistent);
     315                 :         }
     316              24 : }
     317                 : 
     318                 : static php_stream_filter_ops php_bz2_compress_ops = {
     319                 :         php_bz2_compress_filter,
     320                 :         php_bz2_compress_dtor,
     321                 :         "bzip2.compress",
     322                 :         PSFO_FLAG_ACCEPTS_STRING | PSFO_FLAG_OUTPUTS_STRING
     323                 : };
     324                 : 
     325                 : /* }}} */
     326                 : 
     327                 : /* {{{ bzip2.* common factory */
     328                 : 
     329                 : static php_stream_filter *php_bz2_filter_create(const char *filtername, zval *filterparams, int persistent TSRMLS_DC)
     330              47 : {
     331              47 :         php_stream_filter_ops *fops = NULL;
     332                 :         php_bz2_filter_data *data;
     333              47 :         int status = BZ_OK;
     334                 : 
     335                 :         /* Create this filter */
     336              47 :         data = pecalloc(1, sizeof(php_bz2_filter_data), persistent);
     337              47 :         if (!data) {
     338               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed allocating %zu bytes", sizeof(php_bz2_filter_data));
     339               0 :                 return NULL;
     340                 :         }
     341                 : 
     342                 :         /* Circular reference */
     343              47 :         data->strm.opaque = (void *) data;
     344                 : 
     345              47 :         data->strm.bzalloc = php_bz2_alloc;
     346              47 :         data->strm.bzfree = php_bz2_free;
     347              47 :         data->persistent = persistent;
     348              47 :         data->strm.avail_out = data->outbuf_len = data->inbuf_len = 2048;
     349              47 :         data->strm.next_in = data->inbuf = (char *) pemalloc(data->inbuf_len, persistent);
     350              47 :         if (!data->inbuf) {
     351               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed allocating %zu bytes", data->inbuf_len);
     352               0 :                 pefree(data, persistent);
     353               0 :                 return NULL;
     354                 :         }
     355              47 :         data->strm.avail_in = 0;
     356              47 :         data->strm.next_out = data->outbuf = (char *) pemalloc(data->outbuf_len, persistent);
     357              47 :         if (!data->outbuf) {
     358               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed allocating %zu bytes", data->outbuf_len);
     359               0 :                 pefree(data->inbuf, persistent);
     360               0 :                 pefree(data, persistent);
     361               0 :                 return NULL;
     362                 :         }
     363                 : 
     364              47 :         if (strcasecmp(filtername, "bzip2.decompress") == 0) {
     365              23 :                 data->small_footprint = 0;
     366              23 :                 data->expect_concatenated = 0;
     367                 : 
     368              23 :                 if (filterparams) {
     369               0 :                         zval **tmpzval = NULL;
     370                 : 
     371               0 :                         if (Z_TYPE_P(filterparams) == IS_ARRAY || Z_TYPE_P(filterparams) == IS_OBJECT) {
     372                 : 
     373               0 :                                 if (SUCCESS == zend_hash_find(HASH_OF(filterparams), "concatenated", sizeof("concatenated"), (void **) &tmpzval) ) {
     374                 :                                         zval tmp, *tmp2;
     375                 : 
     376               0 :                                         tmp = **tmpzval;
     377               0 :                                         zval_copy_ctor(&tmp);
     378               0 :                                         tmp2 = &tmp;
     379               0 :                                         convert_to_boolean_ex(&tmp2);
     380               0 :                                         data->expect_concatenated = Z_LVAL(tmp);
     381               0 :                                         tmpzval = NULL;
     382                 :                                 }
     383                 : 
     384               0 :                                 zend_hash_find(HASH_OF(filterparams), "small", sizeof("small"), (void **) &tmpzval);
     385                 :                         } else {
     386               0 :                                 tmpzval = &filterparams;
     387                 :                         }
     388                 : 
     389               0 :                         if (tmpzval) {
     390                 :                                 zval tmp, *tmp2;
     391                 : 
     392               0 :                                 tmp = **tmpzval;
     393               0 :                                 zval_copy_ctor(&tmp);
     394               0 :                                 tmp2 = &tmp;
     395               0 :                                 convert_to_boolean_ex(&tmp2);
     396               0 :                                 data->small_footprint = Z_LVAL(tmp);
     397                 :                         }
     398                 :                 }
     399                 : 
     400              23 :                 data->status = PHP_BZ2_UNITIALIZED;
     401              23 :                 fops = &php_bz2_decompress_ops;
     402              24 :         } else if (strcasecmp(filtername, "bzip2.compress") == 0) {
     403              24 :                 int blockSize100k = PHP_BZ2_FILTER_DEFAULT_BLOCKSIZE;
     404              24 :                 int workFactor = PHP_BZ2_FILTER_DEFAULT_WORKFACTOR;
     405                 : 
     406              24 :                 if (filterparams) {
     407                 :                         zval **tmpzval;
     408                 : 
     409               0 :                         if (Z_TYPE_P(filterparams) == IS_ARRAY || Z_TYPE_P(filterparams) == IS_OBJECT) {
     410               0 :                                 if (zend_hash_find(HASH_OF(filterparams), "blocks", sizeof("blocks"), (void**) &tmpzval) == SUCCESS) {
     411                 :                                         /* How much memory to allocate (1 - 9) x 100kb */
     412                 :                                         zval tmp;
     413                 :         
     414               0 :                                         tmp = **tmpzval;
     415               0 :                                         zval_copy_ctor(&tmp);
     416               0 :                                         convert_to_long(&tmp);
     417               0 :                                         if (Z_LVAL(tmp) < 1 || Z_LVAL(tmp) > 9) {
     418               0 :                                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter given for number of blocks to allocate. (%ld)", Z_LVAL_PP(tmpzval));
     419                 :                                         } else {
     420               0 :                                                 blockSize100k = Z_LVAL(tmp);
     421                 :                                         }
     422                 :                                 }
     423                 : 
     424               0 :                                 if (zend_hash_find(HASH_OF(filterparams), "work", sizeof("work"), (void**) &tmpzval) == SUCCESS) {
     425                 :                                         /* Work Factor (0 - 250) */
     426                 :                                         zval tmp;
     427                 :         
     428               0 :                                         tmp = **tmpzval;
     429               0 :                                         zval_copy_ctor(&tmp);
     430               0 :                                         convert_to_long(&tmp);
     431                 : 
     432               0 :                                         if (Z_LVAL(tmp) < 0 || Z_LVAL(tmp) > 250) {
     433               0 :                                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter given for work factor. (%ld)", Z_LVAL(tmp));
     434                 :                                         } else {
     435               0 :                                                 workFactor = Z_LVAL(tmp);
     436                 :                                         }
     437                 :                                 }
     438                 :                         }
     439                 :                 }
     440                 : 
     441              24 :                 status = BZ2_bzCompressInit(&(data->strm), blockSize100k, 0, workFactor);
     442              24 :                 fops = &php_bz2_compress_ops;
     443                 :         } else {
     444               0 :                 status = BZ_DATA_ERROR;
     445                 :         }
     446                 : 
     447              47 :         if (status != BZ_OK) {
     448                 :                 /* Unspecified (probably strm) error, let stream-filter error do its own whining */
     449               0 :                 pefree(data->strm.next_in, persistent);
     450               0 :                 pefree(data->strm.next_out, persistent);
     451               0 :                 pefree(data, persistent);
     452               0 :                 return NULL;
     453                 :         }
     454                 : 
     455              47 :         return php_stream_filter_alloc(fops, data, persistent);
     456                 : }
     457                 : 
     458                 : php_stream_filter_factory php_bz2_filter_factory = {
     459                 :         php_bz2_filter_create
     460                 : };
     461                 : /* }}} */
     462                 : 
     463                 : /*
     464                 :  * Local variables:
     465                 :  * tab-width: 4
     466                 :  * c-basic-offset: 4
     467                 :  * End:
     468                 :  * vim600: sw=4 ts=4 fdm=marker
     469                 :  * vim<600: sw=4 ts=4
     470                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:28 +0000 (35 hours ago)

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