]> granicus.if.org Git - php/commitdiff
Very initial work on chunked output buffering. It's really unoptimized at
authorZeev Suraski <zeev@php.net>
Thu, 23 Nov 2000 18:43:18 +0000 (18:43 +0000)
committerZeev Suraski <zeev@php.net>
Thu, 23 Nov 2000 18:43:18 +0000 (18:43 +0000)
this time, and it can crash under some circumstances, but that's the
concept...

ext/standard/output.c
ext/standard/php_output.h
main/main.c
main/output.c
main/php_output.h

index a64f81502f79833697b84261a47293838d736dfd..88f74b57f05e5bd5aae31f3cc4d2b10205d19853 100644 (file)
@@ -30,7 +30,7 @@ static int php_ub_body_write(const char *str, uint str_length);
 static int php_ub_body_write_no_header(const char *str, uint str_length);
 static int php_b_body_write(const char *str, uint str_length);
 
-static void php_ob_init(uint initial_size, uint block_size, zval *output_handler);
+static void php_ob_init(uint initial_size, uint block_size, zval *output_handler, int chunk_size);
 static void php_ob_append(const char *text, uint text_length);
 #if 0
 static void php_ob_prepend(const char *text, uint text_length);
@@ -88,14 +88,14 @@ PHPAPI int php_header_write(const char *str, uint str_length)
 }
 
 /* Start output buffering */
-PHPAPI int php_start_ob_buffer(zval *output_handler)
+PHPAPI int php_start_ob_buffer(zval *output_handler, int chunk_size)
 {
        OLS_FETCH();
 
        if (OG(lock)) {
                return FAILURE;
        }
-       php_ob_init(40*1024, 10*1024, output_handler);
+       php_ob_init(40*1024, 10*1024, output_handler, chunk_size);
        OG(php_body_write) = php_b_body_write;
        return SUCCESS;
 }
@@ -228,7 +228,7 @@ static inline void php_ob_allocate(void)
 }
 
 
-static void php_ob_init(uint initial_size, uint block_size, zval *output_handler)
+static void php_ob_init(uint initial_size, uint block_size, zval *output_handler, int chunk_size)
 {
        OLS_FETCH();
 
@@ -244,6 +244,7 @@ static void php_ob_init(uint initial_size, uint block_size, zval *output_handler
        OG(active_ob_buffer).buffer = (char *) emalloc(initial_size+1);
        OG(active_ob_buffer).text_length = 0;
        OG(active_ob_buffer).output_handler = output_handler;
+       OG(active_ob_buffer).chunk_size = chunk_size;
 }
 
 
@@ -251,11 +252,27 @@ static void php_ob_append(const char *text, uint text_length)
 {
        char *target;
        int original_ob_text_length;
+       int new_size;
        OLS_FETCH();
 
        original_ob_text_length=OG(active_ob_buffer).text_length;
 
-       OG(active_ob_buffer).text_length += text_length;
+       new_size = OG(active_ob_buffer).text_length + text_length;
+
+       if (OG(active_ob_buffer).chunk_size
+               && new_size > OG(active_ob_buffer).chunk_size) {
+               zval *output_handler = OG(active_ob_buffer).output_handler;
+               int chunk_size = OG(active_ob_buffer).chunk_size;
+
+               if (output_handler) {
+                       output_handler->refcount++;
+               }
+               php_end_ob_buffer(1);
+               php_start_ob_buffer(output_handler, chunk_size);
+               php_ob_append(text, text_length);
+               return;
+       }
+       OG(active_ob_buffer).text_length = new_size;
        php_ob_allocate();
        target = OG(active_ob_buffer).buffer+original_ob_text_length;
        memcpy(target, text, text_length);
@@ -396,6 +413,7 @@ static int php_ub_body_write(const char *str, uint str_length)
 PHP_FUNCTION(ob_start)
 {
        zval *output_handler;
+       int chunk_size=0;
 
        switch (ZEND_NUM_ARGS()) {
                case 0:
@@ -412,11 +430,24 @@ PHP_FUNCTION(ob_start)
                                output_handler->refcount++;
                        }
                        break;
+               case 2: {
+                               zval **output_handler_p, **chunk_size_p;
+
+                               if (zend_get_parameters_ex(2, &output_handler_p, &chunk_size_p)==FAILURE) {
+                                       RETURN_FALSE;
+                               }
+                               SEPARATE_ZVAL(output_handler_p);
+                               output_handler = *output_handler_p;
+                               output_handler->refcount++;
+                               convert_to_long_ex(chunk_size_p);
+                               chunk_size = Z_LVAL_PP(chunk_size_p);
+                       }
+                       break;
                default:
                        ZEND_WRONG_PARAM_COUNT();
                        break;
        }
-       if (php_start_ob_buffer(output_handler)==FAILURE) {
+       if (php_start_ob_buffer(output_handler, chunk_size)==FAILURE) {
                php_error(E_WARNING, "Cannot use output buffering in output buffering display handlers");
                RETURN_FALSE;
        }
index 7d2269879664d7ef9d8cc4d4da583505fab2a79b..7a2154f54c74390e8c90311e4df94b1023368965 100644 (file)
@@ -26,7 +26,7 @@
 PHPAPI void php_output_startup(void);
 PHPAPI int  php_body_write(const char *str, uint str_length);
 PHPAPI int  php_header_write(const char *str, uint str_length);
-PHPAPI int php_start_ob_buffer(zval *output_handler);
+PHPAPI int php_start_ob_buffer(zval *output_handler, int chunk_size);
 PHPAPI void php_end_ob_buffer(int send_buffer);
 PHPAPI void php_end_ob_buffers(int send_buffer);
 PHPAPI int php_ob_get_buffer(pval *p);
@@ -51,6 +51,7 @@ typedef struct _php_ob_buffer {
        uint text_length;
        int block_size;
        zval *output_handler;
+       int chunk_size;
 } php_ob_buffer;
 
 typedef struct _php_output_globals {
index e9ec85919882ae38c8c169c4956f25e74f6a9744..4d92d309d21c267a567e6c5a50538ff4eb9be309 100644 (file)
@@ -632,9 +632,9 @@ int php_request_startup(CLS_D ELS_DC PLS_DC SLS_DC)
                Z_STRLEN_P(output_handler) = strlen(PG(output_handler));        /* this can be optimized */
                Z_STRVAL_P(output_handler) = estrndup(PG(output_handler), Z_STRLEN_P(output_handler));
                Z_TYPE_P(output_handler) = IS_STRING;
-               php_start_ob_buffer(output_handler);
+               php_start_ob_buffer(output_handler, 0);
        } else if (PG(output_buffering)) {
-               php_start_ob_buffer(NULL);
+               php_start_ob_buffer(NULL, 0);
        } else if (PG(implicit_flush)) {
                php_start_implicit_flush();
        }
index a64f81502f79833697b84261a47293838d736dfd..88f74b57f05e5bd5aae31f3cc4d2b10205d19853 100644 (file)
@@ -30,7 +30,7 @@ static int php_ub_body_write(const char *str, uint str_length);
 static int php_ub_body_write_no_header(const char *str, uint str_length);
 static int php_b_body_write(const char *str, uint str_length);
 
-static void php_ob_init(uint initial_size, uint block_size, zval *output_handler);
+static void php_ob_init(uint initial_size, uint block_size, zval *output_handler, int chunk_size);
 static void php_ob_append(const char *text, uint text_length);
 #if 0
 static void php_ob_prepend(const char *text, uint text_length);
@@ -88,14 +88,14 @@ PHPAPI int php_header_write(const char *str, uint str_length)
 }
 
 /* Start output buffering */
-PHPAPI int php_start_ob_buffer(zval *output_handler)
+PHPAPI int php_start_ob_buffer(zval *output_handler, int chunk_size)
 {
        OLS_FETCH();
 
        if (OG(lock)) {
                return FAILURE;
        }
-       php_ob_init(40*1024, 10*1024, output_handler);
+       php_ob_init(40*1024, 10*1024, output_handler, chunk_size);
        OG(php_body_write) = php_b_body_write;
        return SUCCESS;
 }
@@ -228,7 +228,7 @@ static inline void php_ob_allocate(void)
 }
 
 
-static void php_ob_init(uint initial_size, uint block_size, zval *output_handler)
+static void php_ob_init(uint initial_size, uint block_size, zval *output_handler, int chunk_size)
 {
        OLS_FETCH();
 
@@ -244,6 +244,7 @@ static void php_ob_init(uint initial_size, uint block_size, zval *output_handler
        OG(active_ob_buffer).buffer = (char *) emalloc(initial_size+1);
        OG(active_ob_buffer).text_length = 0;
        OG(active_ob_buffer).output_handler = output_handler;
+       OG(active_ob_buffer).chunk_size = chunk_size;
 }
 
 
@@ -251,11 +252,27 @@ static void php_ob_append(const char *text, uint text_length)
 {
        char *target;
        int original_ob_text_length;
+       int new_size;
        OLS_FETCH();
 
        original_ob_text_length=OG(active_ob_buffer).text_length;
 
-       OG(active_ob_buffer).text_length += text_length;
+       new_size = OG(active_ob_buffer).text_length + text_length;
+
+       if (OG(active_ob_buffer).chunk_size
+               && new_size > OG(active_ob_buffer).chunk_size) {
+               zval *output_handler = OG(active_ob_buffer).output_handler;
+               int chunk_size = OG(active_ob_buffer).chunk_size;
+
+               if (output_handler) {
+                       output_handler->refcount++;
+               }
+               php_end_ob_buffer(1);
+               php_start_ob_buffer(output_handler, chunk_size);
+               php_ob_append(text, text_length);
+               return;
+       }
+       OG(active_ob_buffer).text_length = new_size;
        php_ob_allocate();
        target = OG(active_ob_buffer).buffer+original_ob_text_length;
        memcpy(target, text, text_length);
@@ -396,6 +413,7 @@ static int php_ub_body_write(const char *str, uint str_length)
 PHP_FUNCTION(ob_start)
 {
        zval *output_handler;
+       int chunk_size=0;
 
        switch (ZEND_NUM_ARGS()) {
                case 0:
@@ -412,11 +430,24 @@ PHP_FUNCTION(ob_start)
                                output_handler->refcount++;
                        }
                        break;
+               case 2: {
+                               zval **output_handler_p, **chunk_size_p;
+
+                               if (zend_get_parameters_ex(2, &output_handler_p, &chunk_size_p)==FAILURE) {
+                                       RETURN_FALSE;
+                               }
+                               SEPARATE_ZVAL(output_handler_p);
+                               output_handler = *output_handler_p;
+                               output_handler->refcount++;
+                               convert_to_long_ex(chunk_size_p);
+                               chunk_size = Z_LVAL_PP(chunk_size_p);
+                       }
+                       break;
                default:
                        ZEND_WRONG_PARAM_COUNT();
                        break;
        }
-       if (php_start_ob_buffer(output_handler)==FAILURE) {
+       if (php_start_ob_buffer(output_handler, chunk_size)==FAILURE) {
                php_error(E_WARNING, "Cannot use output buffering in output buffering display handlers");
                RETURN_FALSE;
        }
index 7d2269879664d7ef9d8cc4d4da583505fab2a79b..7a2154f54c74390e8c90311e4df94b1023368965 100644 (file)
@@ -26,7 +26,7 @@
 PHPAPI void php_output_startup(void);
 PHPAPI int  php_body_write(const char *str, uint str_length);
 PHPAPI int  php_header_write(const char *str, uint str_length);
-PHPAPI int php_start_ob_buffer(zval *output_handler);
+PHPAPI int php_start_ob_buffer(zval *output_handler, int chunk_size);
 PHPAPI void php_end_ob_buffer(int send_buffer);
 PHPAPI void php_end_ob_buffers(int send_buffer);
 PHPAPI int php_ob_get_buffer(pval *p);
@@ -51,6 +51,7 @@ typedef struct _php_ob_buffer {
        uint text_length;
        int block_size;
        zval *output_handler;
+       int chunk_size;
 } php_ob_buffer;
 
 typedef struct _php_output_globals {