You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
4.2 KiB

28 years ago
28 years ago
28 years ago
28 years ago
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Zend Engine |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
  6. +----------------------------------------------------------------------+
  7. | The contents of this source file is the sole property of Andi |
  8. | Gutmans and Zeev Suraski, and may not be distributed without prior |
  9. | written permission from both of them. |
  10. +----------------------------------------------------------------------+
  11. | Authors: Andi Gutmans <andi@zend.com> |
  12. | Zeev Suraski <zeev@zend.com> |
  13. +----------------------------------------------------------------------+
  14. */
  15. #include "php.h"
  16. #include "ext/standard/head.h"
  17. #include "SAPI.h"
  18. /* output functions */
  19. int (*zend_body_write)(const char *str, uint str_length); /* string output */
  20. int (*zend_header_write)(const char *str, uint str_length); /* unbuffer string output */
  21. static int zend_ub_body_write(const char *str, uint str_length);
  22. static int zend_b_body_write(const char *str, uint str_length);
  23. /* output buffering */
  24. static char *ob_buffer;
  25. static uint ob_buffer_size;
  26. static uint ob_block_size;
  27. static uint ob_text_length;
  28. void zend_ob_init(uint initial_size, uint block_size);
  29. void zend_ob_destroy();
  30. void zend_ob_append(const char *text, uint text_length);
  31. void zend_ob_prepend(const char *text, uint text_length);
  32. static inline void zend_ob_send();
  33. /* HEAD support */
  34. static int header_request;
  35. /*
  36. * Main
  37. */
  38. PHPAPI void zend_output_startup()
  39. {
  40. ob_buffer = NULL;
  41. zend_body_write = zend_ub_body_write;
  42. header_request=0;
  43. zend_header_write = sapi_functions.ub_write;
  44. }
  45. void zend_start_ob_buffering()
  46. {
  47. zend_ob_init(4096, 1024);
  48. zend_body_write = zend_b_body_write;
  49. }
  50. void zend_end_ob_buffering(int send_buffer)
  51. {
  52. if (!ob_buffer) {
  53. return;
  54. }
  55. zend_body_write = zend_ub_body_write;
  56. if (send_buffer) {
  57. zend_ob_send();
  58. }
  59. zend_ob_destroy();
  60. }
  61. /*
  62. * Output buffering - implementation
  63. */
  64. static inline void zend_ob_allocate()
  65. {
  66. if (ob_buffer_size<ob_text_length) {
  67. while ((ob_buffer_size+=ob_block_size) < ob_text_length);
  68. ob_buffer = (char *) erealloc(ob_buffer, ob_buffer_size+1);
  69. }
  70. }
  71. void zend_ob_init(uint initial_size, uint block_size)
  72. {
  73. if (ob_buffer) {
  74. return;
  75. }
  76. ob_block_size = block_size;
  77. ob_buffer_size = initial_size;
  78. ob_buffer = (char *) emalloc(initial_size+1);
  79. ob_text_length = 0;
  80. }
  81. void zend_ob_destroy()
  82. {
  83. if (ob_buffer) {
  84. efree(ob_buffer);
  85. ob_buffer = NULL;
  86. }
  87. }
  88. void zend_ob_append(const char *text, uint text_length)
  89. {
  90. char *target;
  91. int original_ob_text_length=ob_text_length;
  92. ob_text_length += text_length;
  93. zend_ob_allocate();
  94. target = ob_buffer+original_ob_text_length;
  95. memcpy(target, text, text_length);
  96. target[text_length]=0;
  97. }
  98. void zend_ob_prepend(const char *text, uint text_length)
  99. {
  100. char *p, *start;
  101. ob_text_length += text_length;
  102. zend_ob_allocate();
  103. /* zend_ob_allocate() may change ob_buffer, so we can't initialize p&start earlier */
  104. p = ob_buffer+ob_text_length;
  105. start = ob_buffer;
  106. while (--p>=start) {
  107. p[text_length] = *p;
  108. }
  109. memcpy(ob_buffer, text, text_length);
  110. ob_buffer[ob_text_length]=0;
  111. }
  112. static inline void zend_ob_send()
  113. {
  114. /* header_write is a simple, unbuffered output function */
  115. zend_body_write(ob_buffer, ob_text_length);
  116. }
  117. int zend_ob_get_buffer(pval *p)
  118. {
  119. if (!ob_buffer) {
  120. return FAILURE;
  121. }
  122. p->type = IS_STRING;
  123. p->value.str.val = estrndup(ob_buffer, ob_text_length);
  124. p->value.str.len = ob_text_length;
  125. return SUCCESS;
  126. }
  127. /*
  128. * Wrapper functions - implementation
  129. */
  130. /* buffered output function */
  131. static int zend_b_body_write(const char *str, uint str_length)
  132. {
  133. zend_ob_append(str, str_length);
  134. return str_length;
  135. }
  136. static int zend_ub_body_write(const char *str, uint str_length)
  137. {
  138. if (header_request) {
  139. zend_bailout();
  140. }
  141. if (php3_header()) {
  142. return zend_header_write(str, str_length);
  143. } else {
  144. return 0;
  145. }
  146. }
  147. /*
  148. * HEAD support
  149. */
  150. void set_header_request(int value)
  151. {
  152. header_request = value;
  153. }