back to dev
[m6w6/ext-http] / php_http_buffer.c
index 84272d016339ad6265da0e21b2df85820da81979..e24a4e18baa2e4d7e7a6c8cbdbf7d7c7967fc31b 100644 (file)
@@ -6,7 +6,7 @@
     | modification, are permitted provided that the conditions mentioned |
     | in the accompanying LICENSE file are met.                          |
     +--------------------------------------------------------------------+
-    | Copyright (c) 2004-2013, Michael Wallner <mike@php.net>            |
+    | Copyright (c) 2004-2014, Michael Wallner <mike@php.net>            |
     +--------------------------------------------------------------------+
 */
 
@@ -45,7 +45,7 @@ PHP_HTTP_BUFFER_API size_t php_http_buffer_resize_ex(php_http_buffer_t *buf, siz
 {
        char *ptr = NULL;
 #if 0
-       fprintf(stderr, "RESIZE: len=%lu, size=%lu, used=%lu, free=%lu\n", len, buf->size, buf->used, buf->free);
+       fprintf(stderr, "RESIZE: len=%lu, size=%lu, used=%lu, free=%lu, total=%lu\n", len, buf->size, buf->used, buf->free, buf->free+buf->used);
 #endif
        if (buf->free < len) {
                size_t size = override_size ? override_size : buf->size;
@@ -74,10 +74,7 @@ PHP_HTTP_BUFFER_API size_t php_http_buffer_resize_ex(php_http_buffer_t *buf, siz
 
 PHP_HTTP_BUFFER_API char *php_http_buffer_account(php_http_buffer_t *buf, size_t to_account)
 {
-       /* it's probably already too late but check anyway */
-       if (to_account > buf->free) {
-               return NULL;
-       }
+       assert(to_account <= buf->free);
 
        buf->free -= to_account;
        buf->used += to_account;
@@ -103,7 +100,7 @@ PHP_HTTP_BUFFER_API size_t php_http_buffer_shrink(php_http_buffer_t *buf)
 
 PHP_HTTP_BUFFER_API size_t php_http_buffer_append(php_http_buffer_t *buf, const char *append, size_t append_len)
 {
-       if (PHP_HTTP_BUFFER_NOMEM == php_http_buffer_resize(buf, append_len)) {
+       if (buf->free < append_len && PHP_HTTP_BUFFER_NOMEM == php_http_buffer_resize(buf, append_len)) {
                return PHP_HTTP_BUFFER_NOMEM;
        }
        memcpy(buf->data + buf->used, append, append_len);
@@ -160,7 +157,7 @@ PHP_HTTP_BUFFER_API size_t php_http_buffer_cut(php_http_buffer_t *buf, size_t of
 
 PHP_HTTP_BUFFER_API php_http_buffer_t *php_http_buffer_fix(php_http_buffer_t *buf)
 {
-       if (PHP_HTTP_BUFFER_NOMEM == php_http_buffer_resize_ex(buf, 1, 1, 0)) {
+       if (buf->free < 1 && PHP_HTTP_BUFFER_NOMEM == php_http_buffer_resize_ex(buf, 1, 1, 0)) {
                return NULL;
        }
        buf->data[buf->used] = '\0';
@@ -222,13 +219,17 @@ PHP_HTTP_BUFFER_API size_t php_http_buffer_chunk_buffer(php_http_buffer_t **s, c
        return 0;
 }
 
-PHP_HTTP_BUFFER_API void php_http_buffer_chunked_output(php_http_buffer_t **s, const char *data, size_t data_len, size_t chunk_len, php_http_buffer_pass_func_t passout, void *opaque TSRMLS_DC)
+PHP_HTTP_BUFFER_API size_t php_http_buffer_chunked_output(php_http_buffer_t **s, const char *data, size_t data_len, size_t chunk_len, php_http_buffer_pass_func_t passout, void *opaque TSRMLS_DC)
 {
        char *chunk = NULL;
-       size_t got = 0;
+       size_t passed = 0, got = 0;
 
        while ((got = php_http_buffer_chunk_buffer(s, data, data_len, &chunk, chunk_len))) {
-               passout(opaque, chunk, got TSRMLS_CC);
+               if (PHP_HTTP_BUFFER_PASS0 == passout(opaque, chunk, got TSRMLS_CC)) {
+                       PTR_SET(chunk, NULL);
+                       return PHP_HTTP_BUFFER_PASS0;
+               }
+               ++passed;
                if (!chunk_len) {
                        /*      we already got the last chunk,
                                and freed all resources */
@@ -236,9 +237,10 @@ PHP_HTTP_BUFFER_API void php_http_buffer_chunked_output(php_http_buffer_t **s, c
                }
                data = NULL;
                data_len = 0;
-               STR_SET(chunk, NULL);
+               PTR_SET(chunk, NULL);
        }
-       STR_FREE(chunk);
+       PTR_FREE(chunk);
+       return passed;
 }
 
 PHP_HTTP_BUFFER_API ssize_t php_http_buffer_passthru(php_http_buffer_t **s, size_t chunk_size, php_http_buffer_pass_func_t passin, void *passin_arg, php_http_buffer_pass_func_t passon, void *passon_arg TSRMLS_DC)