moriyoshi Tue Jul 20 15:41:37 2004 EDT Modified files: /php-src/ext/standard filters.c Log: - Cleanups.
http://cvs.php.net/diff.php/php-src/ext/standard/filters.c?r1=1.42&r2=1.43&ty=u Index: php-src/ext/standard/filters.c diff -u php-src/ext/standard/filters.c:1.42 php-src/ext/standard/filters.c:1.43 --- php-src/ext/standard/filters.c:1.42 Tue Jul 20 15:35:38 2004 +++ php-src/ext/standard/filters.c Tue Jul 20 15:41:37 2004 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: filters.c,v 1.42 2004/07/20 19:35:38 moriyoshi Exp $ */ +/* $Id: filters.c,v 1.43 2004/07/20 19:41:37 moriyoshi Exp $ */ #include "php.h" #include "php_globals.h" @@ -307,6 +307,7 @@ PHP_CONV_ERR_INVALID_SEQ, PHP_CONV_ERR_UNEXPECTED_EOS, PHP_CONV_ERR_EXISTS, + PHP_CONV_ERR_MORE, PHP_CONV_ERR_ALLOC, PHP_CONV_ERR_NOT_FOUND } php_conv_err_t; @@ -1151,6 +1152,8 @@ php_conv *cd; int persistent; char *filtername; + char stub[128]; + size_t stub_len; } php_convert_filter; #define PHP_CONV_BASE64_ENCODE 1 @@ -1446,6 +1449,7 @@ { inst->persistent = persistent; inst->filtername = pestrdup(filtername, persistent); + inst->stub_len = 0; if ((inst->cd = php_conv_open(conv_mode, conv_opts, persistent)) == NULL) { goto out_failure; @@ -1476,64 +1480,145 @@ } } -static php_stream_filter_status_t strfilter_convert_filter( - php_stream *stream, - php_stream_filter *thisfilter, - php_stream_bucket_brigade *buckets_in, - php_stream_bucket_brigade *buckets_out, - size_t *bytes_consumed, - int flags - TSRMLS_DC) +/* {{{ strfilter_convert_append_bucket */ +static int strfilter_convert_append_bucket( + php_convert_filter *inst, + php_stream *stream, php_stream_filter *filter, + php_stream_bucket_brigade *buckets_out, + const char *ps, size_t buf_len, size_t *consumed, + int persistent TSRMLS_DC) { - php_stream_bucket *bucket = NULL, *new_bucket; - size_t consumed = 0; php_conv_err_t err; - php_convert_filter *inst = (php_convert_filter *)thisfilter->abstract; + php_stream_bucket *new_bucket; char *out_buf = NULL; size_t out_buf_size; char *pd; - size_t ocnt; - - /* Always wind buckets_in whether this is a flush op or not */ - while (buckets_in->head != NULL) { - const char *ps; - size_t icnt; - - bucket = buckets_in->head; + const char *pt; + size_t ocnt, icnt, tcnt; + size_t initial_out_buf_size; + + if (ps == NULL) { + initial_out_buf_size = 64; + icnt = 1; + } else { + initial_out_buf_size = buf_len; + icnt = buf_len; + } - php_stream_bucket_unlink(bucket TSRMLS_CC); - icnt = bucket->buflen; - ps = bucket->buf; + out_buf_size = ocnt = initial_out_buf_size; + if (NULL == (out_buf = pemalloc(out_buf_size, persistent))) { + return FAILURE; + } - out_buf_size = bucket->buflen; - out_buf = pemalloc(out_buf_size, inst->persistent); - ocnt = out_buf_size; - pd = out_buf; + pd = out_buf; - /* trying hard to reduce the number of buckets to hand to the - * next filter */ + if (inst->stub_len > 0) { + pt = inst->stub; + tcnt = inst->stub_len; - while (icnt > 0) { - err = php_conv_convert(inst->cd, &ps, &icnt, &pd, &ocnt); + while (tcnt > 0) { + err = php_conv_convert(inst->cd, &pt, &tcnt, &pd, &ocnt); switch (err) { - case PHP_CONV_ERR_UNKNOWN: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream filter (%s): unknown error", inst->filtername); - goto out_failure; - case PHP_CONV_ERR_INVALID_SEQ: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream filter (%s): invalid base64 sequence", inst->filtername); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream filter (%s): invalid byte sequence", inst->filtername); goto out_failure; + case PHP_CONV_ERR_MORE: + if (ps != NULL) { + if (icnt > 0) { + if (inst->stub_len >= sizeof(inst->stub)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream filter (%s): insufficient buffer", inst->filtername); + goto out_failure; + } + inst->stub[inst->stub_len++] = *(ps++); + icnt--; + pt = inst->stub; + tcnt = inst->stub_len; + } else { + tcnt = 0; + break; + } + } + break; + case PHP_CONV_ERR_UNEXPECTED_EOS: php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream filter (%s): unexpected end of stream", inst->filtername); goto out_failure; + case PHP_CONV_ERR_TOO_BIG: { + char *new_out_buf; + size_t new_out_buf_size; + + new_out_buf_size = out_buf_size << 1; + + if (new_out_buf_size < out_buf_size) { + /* whoa! no bigger buckets are sold anywhere... */ + if (NULL == (new_bucket = php_stream_bucket_new(stream, out_buf, (out_buf_size - ocnt), 1, persistent TSRMLS_CC))) { + goto out_failure; + } + + php_stream_bucket_append(buckets_out, new_bucket TSRMLS_CC); + + out_buf_size = ocnt = initial_out_buf_size; + if (NULL == (out_buf = pemalloc(out_buf_size, persistent))) { + return FAILURE; + } + pd = out_buf; + } else { + if (NULL == (new_out_buf = perealloc(out_buf, new_out_buf_size, persistent))) { + if (NULL == (new_bucket = php_stream_bucket_new(stream, out_buf, (out_buf_size - ocnt), 1, persistent TSRMLS_CC))) { + goto out_failure; + } + + php_stream_bucket_append(buckets_out, new_bucket TSRMLS_CC); + return FAILURE; + } + + pd = new_out_buf + (pd - out_buf); + ocnt += (new_out_buf_size - out_buf_size); + out_buf = new_out_buf; + out_buf_size = new_out_buf_size; + } + } break; + + case PHP_CONV_ERR_UNKNOWN: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream filter (%s): unknown error", inst->filtername); + goto out_failure; + default: break; } + } + memmove(inst->stub, pt, tcnt); + inst->stub_len = tcnt; + } - if (err == PHP_CONV_ERR_TOO_BIG) { + while (icnt > 0) { + err = ((ps == NULL ? php_conv_convert(inst->cd, NULL, NULL, &pd, &ocnt): + php_conv_convert(inst->cd, &ps, &icnt, &pd, &ocnt))); + switch (err) { + case PHP_CONV_ERR_INVALID_SEQ: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream filter (%s): invalid byte sequence", inst->filtername); + goto out_failure; + + case PHP_CONV_ERR_MORE: + if (ps != NULL) { + if (icnt > sizeof(inst->stub)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream filter (%s): insufficient buffer", inst->filtername); + goto out_failure; + } + memcpy(inst->stub, ps, icnt); + inst->stub_len = icnt; + ps += icnt; + icnt = 0; + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream filter (%s): unexpected octet values", inst->filtername); + goto out_failure; + } + break; + + case PHP_CONV_ERR_TOO_BIG: { char *new_out_buf; size_t new_out_buf_size; @@ -1541,116 +1626,105 @@ if (new_out_buf_size < out_buf_size) { /* whoa! no bigger buckets are sold anywhere... */ - new_bucket = php_stream_bucket_new(stream, out_buf, (out_buf_size - ocnt), 1, inst->persistent TSRMLS_CC); + if (NULL == (new_bucket = php_stream_bucket_new(stream, out_buf, (out_buf_size - ocnt), 1, persistent TSRMLS_CC))) { + goto out_failure; + } php_stream_bucket_append(buckets_out, new_bucket TSRMLS_CC); - out_buf_size = bucket->buflen; - out_buf = pemalloc(out_buf_size, inst->persistent); - ocnt = out_buf_size; + out_buf_size = ocnt = initial_out_buf_size; + if (NULL == (out_buf = pemalloc(out_buf_size, persistent))) { + return FAILURE; + } pd = out_buf; } else { - new_out_buf = perealloc(out_buf, new_out_buf_size, inst->persistent); + if (NULL == (new_out_buf = perealloc(out_buf, new_out_buf_size, persistent))) { + if (NULL == (new_bucket = php_stream_bucket_new(stream, out_buf, (out_buf_size - ocnt), 1, persistent TSRMLS_CC))) { + goto out_failure; + } + + php_stream_bucket_append(buckets_out, new_bucket TSRMLS_CC); + return FAILURE; + } pd = new_out_buf + (pd - out_buf); ocnt += (new_out_buf_size - out_buf_size); out_buf = new_out_buf; out_buf_size = new_out_buf_size; } - } - } + } break; - /* update consumed by the number of bytes just used */ - consumed += bucket->buflen - icnt; + case PHP_CONV_ERR_UNKNOWN: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream filter (%s): unknown error", inst->filtername); + goto out_failure; - /* give output bucket to next in chain */ - if (out_buf_size - ocnt > 0) { - new_bucket = php_stream_bucket_new(stream, out_buf, (out_buf_size - ocnt), 1, inst->persistent TSRMLS_CC); - php_stream_bucket_append(buckets_out, new_bucket TSRMLS_CC); - } else { - pefree(out_buf, inst->persistent); + default: + if (ps == NULL) { + icnt = 0; + } + break; } - - php_stream_bucket_delref(bucket TSRMLS_CC); } - if (flags != PSFS_FLAG_NORMAL) { - /* flush operation */ - - out_buf_size = 64; - out_buf = pemalloc(out_buf_size, inst->persistent); - ocnt = out_buf_size; - pd = out_buf; - - /* trying hard to reduce the number of buckets to hand to the - * next filter */ - - for (;;) { - err = php_conv_convert(inst->cd, NULL, NULL, &pd, &ocnt); - - switch (err) { - case PHP_CONV_ERR_UNKNOWN: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream filter (%s): unknown error", inst->filtername); - goto out_failure; + if (out_buf_size - ocnt > 0) { + if (NULL == (new_bucket = php_stream_bucket_new(stream, out_buf, (out_buf_size - ocnt), 1, persistent TSRMLS_CC))) { + goto out_failure; + } + php_stream_bucket_append(buckets_out, new_bucket TSRMLS_CC); + } else { + pefree(out_buf, persistent); + } + *consumed += buf_len - icnt; - case PHP_CONV_ERR_INVALID_SEQ: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream filter (%s): invalid base64 sequence", inst->filtername); - goto out_failure; + return SUCCESS; - case PHP_CONV_ERR_UNEXPECTED_EOS: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream filter (%s): unexpected end of stream", inst->filtername); - goto out_failure; +out_failure: + pefree(out_buf, persistent); + return FAILURE; +} +/* }}} */ - default: - break; - } +static php_stream_filter_status_t strfilter_convert_filter( + php_stream *stream, + php_stream_filter *thisfilter, + php_stream_bucket_brigade *buckets_in, + php_stream_bucket_brigade *buckets_out, + size_t *bytes_consumed, + int flags + TSRMLS_DC) +{ + php_stream_bucket *bucket = NULL; + size_t consumed = 0; + php_convert_filter *inst = (php_convert_filter *)thisfilter->abstract; - if (err != PHP_CONV_ERR_TOO_BIG) { - break; - } else { - char *new_out_buf; - size_t new_out_buf_size; + while (buckets_in->head != NULL) { + bucket = buckets_in->head; - new_out_buf_size = out_buf_size << 1; + php_stream_bucket_unlink(bucket TSRMLS_CC); - if (new_out_buf_size < out_buf_size) { - /* whoa! no bigger buckets are sold anywhere... */ - new_bucket = php_stream_bucket_new(stream, out_buf, (out_buf_size - ocnt), 1, inst->persistent TSRMLS_CC); + if (strfilter_convert_append_bucket(inst, stream, thisfilter, + buckets_out, bucket->buf, bucket->buflen, &consumed, + php_stream_is_persistent(stream) TSRMLS_CC) != SUCCESS) { + goto out_failure; + } - php_stream_bucket_append(buckets_out, new_bucket TSRMLS_CC); + php_stream_bucket_delref(bucket TSRMLS_CC); + } - out_buf_size = bucket->buflen; - out_buf = pemalloc(out_buf_size, inst->persistent); - ocnt = out_buf_size; - pd = out_buf; - } else { - new_out_buf = perealloc(out_buf, new_out_buf_size, inst->persistent); - pd = new_out_buf + (pd - out_buf); - ocnt += (new_out_buf_size - out_buf_size); - out_buf = new_out_buf; - out_buf_size = new_out_buf_size; - } - } - } - /* give output bucket to next in chain */ - if (out_buf_size - ocnt > 0) { - new_bucket = php_stream_bucket_new(stream, out_buf, (out_buf_size - ocnt), 1, inst->persistent TSRMLS_CC); - php_stream_bucket_append(buckets_out, new_bucket TSRMLS_CC); - } else { - pefree(out_buf, inst->persistent); + if (flags != PSFS_FLAG_NORMAL) { + if (strfilter_convert_append_bucket(inst, stream, thisfilter, + buckets_out, NULL, 0, &consumed, + php_stream_is_persistent(stream) TSRMLS_CC) != SUCCESS) { + goto out_failure; } } - if (bytes_consumed) { *bytes_consumed = consumed; } - + return PSFS_PASS_ON; out_failure: - if (out_buf != NULL) { - pefree(out_buf, inst->persistent); - } if (bucket != NULL) { php_stream_bucket_delref(bucket TSRMLS_CC); }
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php