summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThies C. Arntzen <thies@php.net>1999-10-27 18:30:41 +0000
committerThies C. Arntzen <thies@php.net>1999-10-27 18:30:41 +0000
commitea880d2b86729f8dc68c5cb4d7572463d089d9b1 (patch)
tree9ca5eb989986c52c6aa6ac5c75c93d2790d902a3
parentc171eecd7aea11c22a8d7b111fc6b8a34b243216 (diff)
downloadphp-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.am2
-rw-r--r--ext/standard/Makefile.am2
-rw-r--r--ext/standard/basic_functions.c31
-rw-r--r--ext/standard/basic_functions.h5
-rw-r--r--ext/standard/output.c385
-rw-r--r--ext/standard/php_output.h (renamed from output.h)15
-rw-r--r--main/internal_functions.c.in2
-rw-r--r--main/internal_functions_win32.c4
-rw-r--r--main/output.c385
-rw-r--r--main/php.h2
-rw-r--r--main/php_output.h34
-rw-r--r--output.c232
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 */
-}