diff options
author | Thies C. Arntzen <thies@php.net> | 1999-10-27 18:30:41 +0000 |
---|---|---|
committer | Thies C. Arntzen <thies@php.net> | 1999-10-27 18:30:41 +0000 |
commit | ea880d2b86729f8dc68c5cb4d7572463d089d9b1 (patch) | |
tree | 9ca5eb989986c52c6aa6ac5c75c93d2790d902a3 | |
parent | c171eecd7aea11c22a8d7b111fc6b8a34b243216 (diff) | |
download | php-git-ea880d2b86729f8dc68c5cb4d7572463d089d9b1.tar.gz |
moved output.c into ext/standart and made it thread-safe.
moved output-buffering related functions from basic_functions to output.c
Win32 project need to be updated to reflect new position.
# i'm not really happy with this solution, but it seemed the easiest one!
# the whole output code is a bit hard to understand...
@- Output-Buffering system is now Thread-Safe. (Thies)
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | ext/standard/Makefile.am | 2 | ||||
-rw-r--r-- | ext/standard/basic_functions.c | 31 | ||||
-rw-r--r-- | ext/standard/basic_functions.h | 5 | ||||
-rw-r--r-- | ext/standard/output.c | 385 | ||||
-rw-r--r-- | ext/standard/php_output.h (renamed from output.h) | 15 | ||||
-rw-r--r-- | main/internal_functions.c.in | 2 | ||||
-rw-r--r-- | main/internal_functions_win32.c | 4 | ||||
-rw-r--r-- | main/output.c | 385 | ||||
-rw-r--r-- | main/php.h | 2 | ||||
-rw-r--r-- | main/php_output.h | 34 | ||||
-rw-r--r-- | output.c | 232 |
12 files changed, 818 insertions, 281 deletions
diff --git a/Makefile.am b/Makefile.am index 29bfdb7e98..9dd8979fbd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,7 +11,7 @@ phptemp_LTLIBRARIES = libphp4.la libphp4_la_SOURCES = \ main.c internal_functions.c snprintf.c php3_sprintf.c \ configuration-parser.y configuration-scanner.l request_info.c \ - safe_mode.c fopen-wrappers.c php3_realpath.c alloca.c output.c \ + safe_mode.c fopen-wrappers.c php3_realpath.c alloca.c \ php_ini.c SAPI.c rfc1867.c dlist.c php_content_types.c strlcpy.c \ strlcat.c mergesort.c diff --git a/ext/standard/Makefile.am b/ext/standard/Makefile.am index e3a4d8cc59..743c88aa58 100644 --- a/ext/standard/Makefile.am +++ b/ext/standard/Makefile.am @@ -7,7 +7,7 @@ libphpext_standard_la_SOURCES=\ formatted_print.c fsock.c head.c html.c image.c info.c iptc.c lcg.c \ link.c mail.c math.c md5.c metaphone.c microtime.c pack.c pageinfo.c \ parsedate.y post.c quot_print.c rand.c reg.c soundex.c string.c \ - syslog.c type.c uniqid.c url.c url_scanner.c var.c + syslog.c type.c uniqid.c url.c url_scanner.c var.c output.c $(srcdir)/url_scanner.c: $(srcdir)/url_scanner.re -re2c $< > $@.new && mv $@.new $@ diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 09d06f2ef0..c6dbbcdd50 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -304,11 +304,6 @@ function_entry basic_functions[] = { PHP_NAMED_FE(show_source, php3_highlight_file, NULL) PHP_FE(highlight_string, NULL) - PHP_FE(ob_start, NULL) - PHP_FE(ob_end_flush, NULL) - PHP_FE(ob_end_clean, NULL) - PHP_FE(ob_get_contents, NULL) - PHP_FE(ini_get, NULL) PHP_FE(ini_alter, NULL) PHP_FE(ini_restore, NULL) @@ -1973,32 +1968,6 @@ void test_class_startup() } -PHP_FUNCTION(ob_start) -{ - php_start_ob_buffering(); -} - - -PHP_FUNCTION(ob_end_flush) -{ - php_end_ob_buffering(1); -} - - -PHP_FUNCTION(ob_end_clean) -{ - php_end_ob_buffering(0); -} - - -PHP_FUNCTION(ob_get_contents) -{ - if (php_ob_get_buffer(return_value)==FAILURE) { - RETURN_FALSE; - } -} - - PHP_FUNCTION(ini_get) { pval **varname; diff --git a/ext/standard/basic_functions.h b/ext/standard/basic_functions.h index 3b266a99e0..a65848e647 100644 --- a/ext/standard/basic_functions.h +++ b/ext/standard/basic_functions.h @@ -104,11 +104,6 @@ PHP_FUNCTION(highlight_file); PHP_FUNCTION(highlight_string); ZEND_API void php_get_highlight_struct(zend_syntax_highlighter_ini *syntax_highlighter_ini); -PHP_FUNCTION(ob_start); -PHP_FUNCTION(ob_end_flush); -PHP_FUNCTION(ob_end_clean); -PHP_FUNCTION(ob_get_contents); - PHP_FUNCTION(ini_get); PHP_FUNCTION(ini_alter); PHP_FUNCTION(ini_restore); diff --git a/ext/standard/output.c b/ext/standard/output.c new file mode 100644 index 0000000000..e1c0226afd --- /dev/null +++ b/ext/standard/output.c @@ -0,0 +1,385 @@ +/* + +----------------------------------------------------------------------+ + | PHP version 4.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997, 1998, 1999 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available at through the world-wide-web at | + | http://www.php.net/license/2_0.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Andi Gutmans <andi@zend.com> | + | Zeev Suraski <zeev@zend.com> | + | Thies C. Arntzen <thies@digicol.de> | + +----------------------------------------------------------------------+ +*/ + + +#include "php.h" +#include "ext/standard/head.h" +#include "ext/session/php_session.h" +#include "SAPI.h" + +/* output functions */ +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); +static void php_ob_destroy(); +static void php_ob_append(const char *text, uint text_length); +static void php_ob_prepend(const char *text, uint text_length); +static inline void php_ob_send(); + +void php_start_ob_buffering(); +void php_end_ob_buffering(int send_buffer); +int php_ob_get_buffer(pval *p); + +/* HEAD support */ +void set_header_request(int value); + +typedef struct { + int (*php_body_write)(const char *str, uint str_length); /* string output */ + int (*php_header_write)(const char *str, uint str_length); /* unbuffer string output */ + char *ob_buffer; + uint ob_size; + uint ob_block_size; + uint ob_text_length; +} php_output_globals; + +#ifdef ZTS +#define OUTPUT(v) (output_globals->v) +#define OUTPUTLS_FETCH() php_output_globals *output_globals = ts_resource(output_globals_id) +int output_globals_id; +#else +#define OUTPUT(v) (output_globals.v) +#define OUTPUTLS_FETCH() +php_output_globals output_globals; +#endif + + +PHP_FUNCTION(ob_start); +PHP_FUNCTION(ob_end_flush); +PHP_FUNCTION(ob_end_clean); +PHP_FUNCTION(ob_get_contents); + + +#ifdef ZTS +static void php_output_init_globals(php_output_globals *output_globals) +{ + OUTPUT(php_body_write) = NULL; + OUTPUT(php_header_write) = NULL; + OUTPUT(ob_buffer) = NULL; + OUTPUT(ob_size) = 0; + OUTPUT(ob_block_size) = 0; + OUTPUT(ob_text_length) = 0; +} +#endif + + +PHP_MINIT_FUNCTION(output) +{ +#ifdef ZTS + output_globals_id = ts_allocate_id(sizeof(php_output_globals), NULL, NULL); +#else + OUTPUT(php_body_write) = NULL; + OUTPUT(php_header_write) = NULL; + OUTPUT(ob_buffer) = NULL; + OUTPUT(ob_size) = 0; + OUTPUT(ob_block_size) = 0; + OUTPUT(ob_text_length) = 0; +#endif + + return SUCCESS; +} + +static zend_function_entry php_output_functions[] = { + PHP_FE(ob_start, NULL) + PHP_FE(ob_end_flush, NULL) + PHP_FE(ob_end_clean, NULL) + PHP_FE(ob_get_contents, NULL) + {NULL, NULL, NULL} +}; + +PHP_RINIT_FUNCTION(output); +PHP_RSHUTDOWN_FUNCTION(output); + +php3_module_entry output_module_entry = { + "PHP_output", + php_output_functions, + PHP_MINIT(output), /* extension-wide startup function */ + NULL, /* extension-wide shutdown function */ + PHP_RINIT(output), /* per-request startup function */ + PHP_RSHUTDOWN(output), /* per-request shutdown function */ + NULL, /* information function */ + STANDARD_MODULE_PROPERTIES +}; + +PHP_RINIT_FUNCTION(output) +{ + php_output_startup(); + + return SUCCESS; +} + +PHP_RSHUTDOWN_FUNCTION(output) +{ + /* XXX needs filling in */ + return SUCCESS; +} + +/* Start output layer */ +PHPAPI void php_output_startup() +{ + OUTPUTLS_FETCH(); + + OUTPUT(ob_buffer) = NULL; + OUTPUT(php_body_write) = php_ub_body_write; + OUTPUT(php_header_write) = sapi_module.ub_write; +} + +PHPAPI int php_body_write(const char *str, uint str_length) +{ + OUTPUTLS_FETCH(); + return OUTPUT(php_body_write)(str, str_length); +} + +PHPAPI int php_header_write(const char *str, uint str_length) +{ + OUTPUTLS_FETCH(); + return OUTPUT(php_header_write)(str, str_length); +} + +/* Start output buffering */ +PHPAPI void php_start_ob_buffering() +{ + OUTPUTLS_FETCH(); + + php_ob_init(4096, 1024); + OUTPUT(php_body_write) = php_b_body_write; +} + + +/* End output buffering */ +PHPAPI void php_end_ob_buffering(int send_buffer) +{ + SLS_FETCH(); + OUTPUTLS_FETCH(); + + if (!OUTPUT(ob_buffer)) { + return; + } + if (SG(headers_sent) && !SG(request_info).headers_only) { + OUTPUT(php_body_write) = php_ub_body_write_no_header; + } else { + OUTPUT(php_body_write) = php_ub_body_write; + } + if (send_buffer) { + php_ob_send(); + } + php_ob_destroy(); +} + + +/* + * Output buffering - implementation + */ + +static inline void php_ob_allocate() +{ + OUTPUTLS_FETCH(); + + if (OUTPUT(ob_size)<OUTPUT(ob_text_length)) { + while (OUTPUT(ob_size) <= OUTPUT(ob_text_length)) + OUTPUT(ob_size)+=OUTPUT(ob_block_size); + + OUTPUT(ob_buffer) = (char *) erealloc(OUTPUT(ob_buffer), OUTPUT(ob_size)+1); + } +} + + +static void php_ob_init(uint initial_size, uint block_size) +{ + OUTPUTLS_FETCH(); + + if (OUTPUT(ob_buffer)) { + return; + } + OUTPUT(ob_block_size) = block_size; + OUTPUT(ob_size) = initial_size; + OUTPUT(ob_buffer) = (char *) emalloc(initial_size+1); + OUTPUT(ob_text_length) = 0; +} + + +static void php_ob_destroy() +{ + OUTPUTLS_FETCH(); + + if (OUTPUT(ob_buffer)) { + efree(OUTPUT(ob_buffer)); + OUTPUT(ob_buffer) = NULL; + } +} + + +static void php_ob_append(const char *text, uint text_length) +{ + char *target; + int original_ob_text_length; + OUTPUTLS_FETCH(); + + original_ob_text_length=OUTPUT(ob_text_length); + + OUTPUT(ob_text_length) += text_length; + php_ob_allocate(); + target = OUTPUT(ob_buffer)+original_ob_text_length; + memcpy(target, text, text_length); + target[text_length]=0; +} + + +static void php_ob_prepend(const char *text, uint text_length) +{ + char *p, *start; + OUTPUTLS_FETCH(); + + OUTPUT(ob_text_length) += text_length; + php_ob_allocate(); + + /* php_ob_allocate() may change OUTPUT(ob_buffer), so we can't initialize p&start earlier */ + p = OUTPUT(ob_buffer)+OUTPUT(ob_text_length); + start = OUTPUT(ob_buffer); + + while (--p>=start) { + p[text_length] = *p; + } + memcpy(OUTPUT(ob_buffer), text, text_length); + OUTPUT(ob_buffer)[OUTPUT(ob_text_length)]=0; +} + + +static inline void php_ob_send() +{ + OUTPUTLS_FETCH(); + + /* header_write is a simple, unbuffered output function */ + OUTPUT(php_body_write)(OUTPUT(ob_buffer), OUTPUT(ob_text_length)); +} + + +/* Return the current output buffer */ +int php_ob_get_buffer(pval *p) +{ + OUTPUTLS_FETCH(); + + if (!OUTPUT(ob_buffer)) { + return FAILURE; + } + p->type = IS_STRING; + p->value.str.val = estrndup(OUTPUT(ob_buffer), OUTPUT(ob_text_length)); + p->value.str.len = OUTPUT(ob_text_length); + return SUCCESS; +} + + +/* + * Wrapper functions - implementation + */ + + +/* buffered output function */ +static int php_b_body_write(const char *str, uint str_length) +{ + php_ob_append(str, str_length); + return str_length; +} + + +static int php_ub_body_write_no_header(const char *str, uint str_length) +{ + char *newstr = NULL; + uint new_length=0; + int result; + OUTPUTLS_FETCH(); + + session_adapt_uris(str, str_length, &newstr, &new_length); + + if (newstr) { + str = newstr; + str_length = new_length; + } + + result = OUTPUT(php_header_write)(str, str_length); + + if (newstr) { + free(newstr); + } + + return result; +} + + +static int php_ub_body_write(const char *str, uint str_length) +{ + int result = 0; + SLS_FETCH(); + OUTPUTLS_FETCH(); + + if (SG(request_info).headers_only) { + zend_bailout(); + } + if (php3_header()) { + OUTPUT(php_body_write) = php_ub_body_write_no_header; + result = php_ub_body_write_no_header(str, str_length); + } + + return result; +} + + +/* + * HEAD support + */ + +void set_header_request(int value) +{ + /* deprecated */ +} + +PHP_FUNCTION(ob_start) +{ + php_start_ob_buffering(); +} + + +PHP_FUNCTION(ob_end_flush) +{ + php_end_ob_buffering(1); +} + + +PHP_FUNCTION(ob_end_clean) +{ + php_end_ob_buffering(0); +} + + +PHP_FUNCTION(ob_get_contents) +{ + if (php_ob_get_buffer(return_value)==FAILURE) { + RETURN_FALSE; + } +} + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/output.h b/ext/standard/php_output.h index 73d053e309..00fd789078 100644 --- a/output.h +++ b/ext/standard/php_output.h @@ -23,15 +23,12 @@ #include "php.h" PHPAPI void php_output_startup(); +PHPAPI int php_body_write(const char *str, uint str_length); +PHPAPI int php_header_write(const char *str, uint str_length); +PHPAPI void php_start_ob_buffering(); +PHPAPI void php_end_ob_buffering(int send_buffer); -/* exported output functions */ -PHPAPI int (*php_body_write)(const char *str, uint str_length); /* string output */ -PHPAPI int (*php_header_write)(const char *str, uint str_length); /* unbuffer string output */ -void php_start_ob_buffering(); -void php_end_ob_buffering(int send_buffer); -int php_ob_get_buffer(pval *p); - -/* HEAD support */ -void set_header_request(int value); +extern zend_module_entry output_module_entry; +#define phpext_output_ptr &output_module_entry #endif /* _OUTPUT_BUFFER */ diff --git a/main/internal_functions.c.in b/main/internal_functions.c.in index 8ac4f47862..4e558e352e 100644 --- a/main/internal_functions.c.in +++ b/main/internal_functions.c.in @@ -54,6 +54,7 @@ #include "ext/standard/php3_syslog.h" #include "ext/standard/php_lcg.h" #include "ext/standard/php_metaphone.h" +#include "ext/standard/php_output.h" @EXT_INCLUDE_CODE@ /* SNMP has to be moved to ext */ @@ -79,6 +80,7 @@ zend_module_entry *php3_builtin_modules[] = { phpext_syslog_ptr, phpext_lcg_ptr, phpext_metaphone_ptr, + phpext_output_ptr, @EXT_MODULE_PTRS@ }; diff --git a/main/internal_functions_win32.c b/main/internal_functions_win32.c index 389b50714e..73ceb20b8d 100644 --- a/main/internal_functions_win32.c +++ b/main/internal_functions_win32.c @@ -45,6 +45,7 @@ #include "ext/standard/php3_syslog.h" #include "ext/standard/php3_standard.h" #include "ext/standard/php_lcg.h" +#include "ext/standard/php_output.h" #include "ext/COM/php_COM.h" #include "ext/standard/reg.h" #include "ext/pcre/php_pcre.h" @@ -80,7 +81,8 @@ zend_module_entry *php3_builtin_modules[] = { phpext_pcre_ptr, phpext_odbc_ptr, phpext_lcg_ptr, - phpext_session_ptr + phpext_session_ptr, + phpext_output_ptr }; diff --git a/main/output.c b/main/output.c new file mode 100644 index 0000000000..e1c0226afd --- /dev/null +++ b/main/output.c @@ -0,0 +1,385 @@ +/* + +----------------------------------------------------------------------+ + | PHP version 4.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997, 1998, 1999 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available at through the world-wide-web at | + | http://www.php.net/license/2_0.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Andi Gutmans <andi@zend.com> | + | Zeev Suraski <zeev@zend.com> | + | Thies C. Arntzen <thies@digicol.de> | + +----------------------------------------------------------------------+ +*/ + + +#include "php.h" +#include "ext/standard/head.h" +#include "ext/session/php_session.h" +#include "SAPI.h" + +/* output functions */ +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); +static void php_ob_destroy(); +static void php_ob_append(const char *text, uint text_length); +static void php_ob_prepend(const char *text, uint text_length); +static inline void php_ob_send(); + +void php_start_ob_buffering(); +void php_end_ob_buffering(int send_buffer); +int php_ob_get_buffer(pval *p); + +/* HEAD support */ +void set_header_request(int value); + +typedef struct { + int (*php_body_write)(const char *str, uint str_length); /* string output */ + int (*php_header_write)(const char *str, uint str_length); /* unbuffer string output */ + char *ob_buffer; + uint ob_size; + uint ob_block_size; + uint ob_text_length; +} php_output_globals; + +#ifdef ZTS +#define OUTPUT(v) (output_globals->v) +#define OUTPUTLS_FETCH() php_output_globals *output_globals = ts_resource(output_globals_id) +int output_globals_id; +#else +#define OUTPUT(v) (output_globals.v) +#define OUTPUTLS_FETCH() +php_output_globals output_globals; +#endif + + +PHP_FUNCTION(ob_start); +PHP_FUNCTION(ob_end_flush); +PHP_FUNCTION(ob_end_clean); +PHP_FUNCTION(ob_get_contents); + + +#ifdef ZTS +static void php_output_init_globals(php_output_globals *output_globals) +{ + OUTPUT(php_body_write) = NULL; + OUTPUT(php_header_write) = NULL; + OUTPUT(ob_buffer) = NULL; + OUTPUT(ob_size) = 0; + OUTPUT(ob_block_size) = 0; + OUTPUT(ob_text_length) = 0; +} +#endif + + +PHP_MINIT_FUNCTION(output) +{ +#ifdef ZTS + output_globals_id = ts_allocate_id(sizeof(php_output_globals), NULL, NULL); +#else + OUTPUT(php_body_write) = NULL; + OUTPUT(php_header_write) = NULL; + OUTPUT(ob_buffer) = NULL; + OUTPUT(ob_size) = 0; + OUTPUT(ob_block_size) = 0; + OUTPUT(ob_text_length) = 0; +#endif + + return SUCCESS; +} + +static zend_function_entry php_output_functions[] = { + PHP_FE(ob_start, NULL) + PHP_FE(ob_end_flush, NULL) + PHP_FE(ob_end_clean, NULL) + PHP_FE(ob_get_contents, NULL) + {NULL, NULL, NULL} +}; + +PHP_RINIT_FUNCTION(output); +PHP_RSHUTDOWN_FUNCTION(output); + +php3_module_entry output_module_entry = { + "PHP_output", + php_output_functions, + PHP_MINIT(output), /* extension-wide startup function */ + NULL, /* extension-wide shutdown function */ + PHP_RINIT(output), /* per-request startup function */ + PHP_RSHUTDOWN(output), /* per-request shutdown function */ + NULL, /* information function */ + STANDARD_MODULE_PROPERTIES +}; + +PHP_RINIT_FUNCTION(output) +{ + php_output_startup(); + + return SUCCESS; +} + +PHP_RSHUTDOWN_FUNCTION(output) +{ + /* XXX needs filling in */ + return SUCCESS; +} + +/* Start output layer */ +PHPAPI void php_output_startup() +{ + OUTPUTLS_FETCH(); + + OUTPUT(ob_buffer) = NULL; + OUTPUT(php_body_write) = php_ub_body_write; + OUTPUT(php_header_write) = sapi_module.ub_write; +} + +PHPAPI int php_body_write(const char *str, uint str_length) +{ + OUTPUTLS_FETCH(); + return OUTPUT(php_body_write)(str, str_length); +} + +PHPAPI int php_header_write(const char *str, uint str_length) +{ + OUTPUTLS_FETCH(); + return OUTPUT(php_header_write)(str, str_length); +} + +/* Start output buffering */ +PHPAPI void php_start_ob_buffering() +{ + OUTPUTLS_FETCH(); + + php_ob_init(4096, 1024); + OUTPUT(php_body_write) = php_b_body_write; +} + + +/* End output buffering */ +PHPAPI void php_end_ob_buffering(int send_buffer) +{ + SLS_FETCH(); + OUTPUTLS_FETCH(); + + if (!OUTPUT(ob_buffer)) { + return; + } + if (SG(headers_sent) && !SG(request_info).headers_only) { + OUTPUT(php_body_write) = php_ub_body_write_no_header; + } else { + OUTPUT(php_body_write) = php_ub_body_write; + } + if (send_buffer) { + php_ob_send(); + } + php_ob_destroy(); +} + + +/* + * Output buffering - implementation + */ + +static inline void php_ob_allocate() +{ + OUTPUTLS_FETCH(); + + if (OUTPUT(ob_size)<OUTPUT(ob_text_length)) { + while (OUTPUT(ob_size) <= OUTPUT(ob_text_length)) + OUTPUT(ob_size)+=OUTPUT(ob_block_size); + + OUTPUT(ob_buffer) = (char *) erealloc(OUTPUT(ob_buffer), OUTPUT(ob_size)+1); + } +} + + +static void php_ob_init(uint initial_size, uint block_size) +{ + OUTPUTLS_FETCH(); + + if (OUTPUT(ob_buffer)) { + return; + } + OUTPUT(ob_block_size) = block_size; + OUTPUT(ob_size) = initial_size; + OUTPUT(ob_buffer) = (char *) emalloc(initial_size+1); + OUTPUT(ob_text_length) = 0; +} + + +static void php_ob_destroy() +{ + OUTPUTLS_FETCH(); + + if (OUTPUT(ob_buffer)) { + efree(OUTPUT(ob_buffer)); + OUTPUT(ob_buffer) = NULL; + } +} + + +static void php_ob_append(const char *text, uint text_length) +{ + char *target; + int original_ob_text_length; + OUTPUTLS_FETCH(); + + original_ob_text_length=OUTPUT(ob_text_length); + + OUTPUT(ob_text_length) += text_length; + php_ob_allocate(); + target = OUTPUT(ob_buffer)+original_ob_text_length; + memcpy(target, text, text_length); + target[text_length]=0; +} + + +static void php_ob_prepend(const char *text, uint text_length) +{ + char *p, *start; + OUTPUTLS_FETCH(); + + OUTPUT(ob_text_length) += text_length; + php_ob_allocate(); + + /* php_ob_allocate() may change OUTPUT(ob_buffer), so we can't initialize p&start earlier */ + p = OUTPUT(ob_buffer)+OUTPUT(ob_text_length); + start = OUTPUT(ob_buffer); + + while (--p>=start) { + p[text_length] = *p; + } + memcpy(OUTPUT(ob_buffer), text, text_length); + OUTPUT(ob_buffer)[OUTPUT(ob_text_length)]=0; +} + + +static inline void php_ob_send() +{ + OUTPUTLS_FETCH(); + + /* header_write is a simple, unbuffered output function */ + OUTPUT(php_body_write)(OUTPUT(ob_buffer), OUTPUT(ob_text_length)); +} + + +/* Return the current output buffer */ +int php_ob_get_buffer(pval *p) +{ + OUTPUTLS_FETCH(); + + if (!OUTPUT(ob_buffer)) { + return FAILURE; + } + p->type = IS_STRING; + p->value.str.val = estrndup(OUTPUT(ob_buffer), OUTPUT(ob_text_length)); + p->value.str.len = OUTPUT(ob_text_length); + return SUCCESS; +} + + +/* + * Wrapper functions - implementation + */ + + +/* buffered output function */ +static int php_b_body_write(const char *str, uint str_length) +{ + php_ob_append(str, str_length); + return str_length; +} + + +static int php_ub_body_write_no_header(const char *str, uint str_length) +{ + char *newstr = NULL; + uint new_length=0; + int result; + OUTPUTLS_FETCH(); + + session_adapt_uris(str, str_length, &newstr, &new_length); + + if (newstr) { + str = newstr; + str_length = new_length; + } + + result = OUTPUT(php_header_write)(str, str_length); + + if (newstr) { + free(newstr); + } + + return result; +} + + +static int php_ub_body_write(const char *str, uint str_length) +{ + int result = 0; + SLS_FETCH(); + OUTPUTLS_FETCH(); + + if (SG(request_info).headers_only) { + zend_bailout(); + } + if (php3_header()) { + OUTPUT(php_body_write) = php_ub_body_write_no_header; + result = php_ub_body_write_no_header(str, str_length); + } + + return result; +} + + +/* + * HEAD support + */ + +void set_header_request(int value) +{ + /* deprecated */ +} + +PHP_FUNCTION(ob_start) +{ + php_start_ob_buffering(); +} + + +PHP_FUNCTION(ob_end_flush) +{ + php_end_ob_buffering(1); +} + + +PHP_FUNCTION(ob_end_clean) +{ + php_end_ob_buffering(0); +} + + +PHP_FUNCTION(ob_get_contents) +{ + if (php_ob_get_buffer(return_value)==FAILURE) { + RETURN_FALSE; + } +} + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/main/php.h b/main/php.h index 285fa15f00..98f1dfacb6 100644 --- a/main/php.h +++ b/main/php.h @@ -318,7 +318,7 @@ PHPAPI int cfg_get_string(char *varname, char **result); /* Output support */ -#include "output.h" +#include "ext/standard/php_output.h" #define PHPWRITE(str, str_len) php_body_write((str), (str_len)) #define PUTS(str) php_body_write((str), strlen((str))) #define PUTC(c) (php_body_write(&(c), 1), (c)) diff --git a/main/php_output.h b/main/php_output.h new file mode 100644 index 0000000000..00fd789078 --- /dev/null +++ b/main/php_output.h @@ -0,0 +1,34 @@ +/* + +----------------------------------------------------------------------+ + | PHP version 4.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997, 1998, 1999 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available at through the world-wide-web at | + | http://www.php.net/license/2_0.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Zeev Suraski <zeev@zend.com> | + +----------------------------------------------------------------------+ +*/ + + +#ifndef _OUTPUT_BUFFER +#define _OUTPUT_BUFFER + +#include "php.h" + +PHPAPI void php_output_startup(); +PHPAPI int php_body_write(const char *str, uint str_length); +PHPAPI int php_header_write(const char *str, uint str_length); +PHPAPI void php_start_ob_buffering(); +PHPAPI void php_end_ob_buffering(int send_buffer); + +extern zend_module_entry output_module_entry; +#define phpext_output_ptr &output_module_entry + +#endif /* _OUTPUT_BUFFER */ diff --git a/output.c b/output.c deleted file mode 100644 index a748ed5cbb..0000000000 --- a/output.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP version 4.0 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997, 1998, 1999 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 2.0 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available at through the world-wide-web at | - | http://www.php.net/license/2_0.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Andi Gutmans <andi@zend.com> | - | Zeev Suraski <zeev@zend.com> | - +----------------------------------------------------------------------+ -*/ - - -#include "php.h" -#include "ext/standard/head.h" -#include "ext/session/php_session.h" -#include "SAPI.h" - -/* output functions */ -PHPAPI int (*php_body_write)(const char *str, uint str_length); /* string output */ -PHPAPI int (*php_header_write)(const char *str, uint str_length); /* unbuffer string output */ -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); - -/* output buffering */ -static char *ob_buffer; -static uint ob_buffer_size; -static uint ob_block_size; -static uint ob_text_length; -static void php_ob_init(uint initial_size, uint block_size); -static void php_ob_destroy(); -static void php_ob_append(const char *text, uint text_length); -static void php_ob_prepend(const char *text, uint text_length); -static inline void php_ob_send(); - - -/* - * Main - */ - -/* Start output layer */ -PHPAPI void php_output_startup() -{ - ob_buffer = NULL; - php_body_write = php_ub_body_write; - php_header_write = sapi_module.ub_write; -} - - -/* Start output buffering */ -void php_start_ob_buffering() -{ - php_ob_init(4096, 1024); - php_body_write = php_b_body_write; -} - - -/* End output buffering */ -void php_end_ob_buffering(int send_buffer) -{ - SLS_FETCH(); - - if (!ob_buffer) { - return; - } - if (SG(headers_sent) && !SG(request_info).headers_only) { - php_body_write = php_ub_body_write_no_header; - } else { - php_body_write = php_ub_body_write; - } - if (send_buffer) { - php_ob_send(); - } - php_ob_destroy(); -} - - -/* - * Output buffering - implementation - */ - -static inline void php_ob_allocate() -{ - if (ob_buffer_size<ob_text_length) { - while ((ob_buffer_size+=ob_block_size) < ob_text_length); - ob_buffer = (char *) erealloc(ob_buffer, ob_buffer_size+1); - } -} - - -static void php_ob_init(uint initial_size, uint block_size) -{ - if (ob_buffer) { - return; - } - ob_block_size = block_size; - ob_buffer_size = initial_size; - ob_buffer = (char *) emalloc(initial_size+1); - ob_text_length = 0; -} - - -static void php_ob_destroy() -{ - if (ob_buffer) { - efree(ob_buffer); - ob_buffer = NULL; - } -} - - -static void php_ob_append(const char *text, uint text_length) -{ - char *target; - int original_ob_text_length=ob_text_length; - - ob_text_length += text_length; - php_ob_allocate(); - target = ob_buffer+original_ob_text_length; - memcpy(target, text, text_length); - target[text_length]=0; -} - - -static void php_ob_prepend(const char *text, uint text_length) -{ - char *p, *start; - - ob_text_length += text_length; - php_ob_allocate(); - - /* php_ob_allocate() may change ob_buffer, so we can't initialize p&start earlier */ - p = ob_buffer+ob_text_length; - start = ob_buffer; - - while (--p>=start) { - p[text_length] = *p; - } - memcpy(ob_buffer, text, text_length); - ob_buffer[ob_text_length]=0; -} - - -static inline void php_ob_send() -{ - /* header_write is a simple, unbuffered output function */ - php_body_write(ob_buffer, ob_text_length); -} - - -/* Return the current output buffer */ -int php_ob_get_buffer(pval *p) -{ - if (!ob_buffer) { - return FAILURE; - } - p->type = IS_STRING; - p->value.str.val = estrndup(ob_buffer, ob_text_length); - p->value.str.len = ob_text_length; - return SUCCESS; -} - - -/* - * Wrapper functions - implementation - */ - - -/* buffered output function */ -static int php_b_body_write(const char *str, uint str_length) -{ - php_ob_append(str, str_length); - return str_length; -} - - -static int php_ub_body_write_no_header(const char *str, uint str_length) -{ - char *newstr = NULL; - uint new_length=0; - int result; - - session_adapt_uris(str, str_length, &newstr, &new_length); - - if (newstr) { - str = newstr; - str_length = new_length; - } - - result = php_header_write(str, str_length); - - if (newstr) { - free(newstr); - } - - return result; -} - - -static int php_ub_body_write(const char *str, uint str_length) -{ - int result = 0; - SLS_FETCH(); - - if (SG(request_info).headers_only) { - zend_bailout(); - } - if (php3_header()) { - php_body_write = php_ub_body_write_no_header; - result = php_ub_body_write_no_header(str, str_length); - } - - return result; -} - - -/* - * HEAD support - */ - -void set_header_request(int value) -{ - /* deprecated */ -} |