]> granicus.if.org Git - php/commitdiff
moved output.c into ext/standart and made it thread-safe.
authorThies C. Arntzen <thies@php.net>
Wed, 27 Oct 1999 18:30:41 +0000 (18:30 +0000)
committerThies C. Arntzen <thies@php.net>
Wed, 27 Oct 1999 18:30:41 +0000 (18:30 +0000)
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)

12 files changed:
Makefile.am
ext/standard/Makefile.am
ext/standard/basic_functions.c
ext/standard/basic_functions.h
ext/standard/output.c [new file with mode: 0644]
ext/standard/php_output.h [moved from output.h with 77% similarity]
main/internal_functions.c.in
main/internal_functions_win32.c
main/output.c [new file with mode: 0644]
main/php.h
main/php_output.h [new file with mode: 0644]
output.c [deleted file]

index 29bfdb7e98c6fa321ae3476dfe3eae693a149ce4..9dd8979fbd2e688369a91b8d2112cb02c210be5d 100644 (file)
@@ -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
 
index e3a4d8cc590a2e584b3e3ccc64ab222f3d1e712b..743c88aa58b36bb4f8a40efff96706fefa30f2cb 100644 (file)
@@ -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 $@
index 09d06f2ef096194bf13bfcd9d339556a5b5ce30b..c6dbbcdd5052fe31ab88e10ecde56068f81895a7 100644 (file)
@@ -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;
index 3b266a99e0e759a42adbb294f95dc5cb16680037..a65848e64711b5ae4edc9f2f34eecca62b759d8c 100644 (file)
@@ -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 (file)
index 0000000..e1c0226
--- /dev/null
@@ -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:
+ */
similarity index 77%
rename from output.h
rename to ext/standard/php_output.h
index 73d053e309cf179b253a1b944cc45b835c706dda..00fd789078b09e33d0646da346697b4ea278d27b 100644 (file)
--- a/output.h
 #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 */
index 8ac4f47862370d3796a7500036e1fdc9ca2a34b6..4e558e352e8626b35da6c63de5b018b5bb02dacd 100644 (file)
@@ -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@
 };
 
index 389b50714e95ae42e35fcf081222f3b256d3703c..73ceb20b8d5fb6987de1b2f19bf4d22f72387603 100644 (file)
@@ -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 (file)
index 0000000..e1c0226
--- /dev/null
@@ -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:
+ */
index 285fa15f00af7301ba3ad2b15be750624b40d655..98f1dfacb647dc2dccc1f621d3f007d66c3d20ed 100644 (file)
@@ -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 (file)
index 0000000..00fd789
--- /dev/null
@@ -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 (file)
index a748ed5..0000000
--- 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 */
-}