No good idea it broke at least exif which was the
first extension that changed to streams.
marcus
At 20:21 04.10.2002, Sascha Schumann wrote:
>sas Fri Oct 4 14:21:40 2002 EDT
>
> Modified files:
> /php4/main network.c php_streams.h streams.c
> Log:
> Improve the general behaviour of stream_gets and fix its semantics
> with regard to sockets. The behaviour should be aligned with PHP 4.2 now.
> This has been verified to some degree.
>
> If the underlying stream operations block when no new data is readable,
> we need to take extra precautions.
>
> If there is buffered data available, we check for a EOL. If it exists,
> we pass the data immediately back to the caller. This saves a call
> to the read implementation and will not block where blocking
> is not necessary at all.
>
> If the stream buffer contains more data than the caller requested,
> we can also avoid that costly step and simply return that data.
>
>
>Index: php4/main/network.c
>diff -u php4/main/network.c:1.70 php4/main/network.c:1.71
>--- php4/main/network.c:1.70 Sat Sep 28 18:12:23 2002
>+++ php4/main/network.c Fri Oct 4 14:21:40 2002
>@@ -16,7 +16,7 @@
> | Streams work by Wez Furlong <[EMAIL PROTECTED]> |
> +----------------------------------------------------------------------+
> */
>-/* $Id: network.c,v 1.70 2002/09/28 22:12:23 wez Exp $ */
>+/* $Id: network.c,v 1.71 2002/10/04 18:21:40 sas Exp $ */
>
> /*#define DEBUG_MAIN_NETWORK 1*/
>
>@@ -923,7 +923,8 @@
> NULL, /* seek */
> php_sockop_cast,
> php_sockop_stat,
>- php_sockop_set_option
>+ php_sockop_set_option,
>+ 1
> };
>
>
>Index: php4/main/php_streams.h
>diff -u php4/main/php_streams.h:1.51 php4/main/php_streams.h:1.52
>--- php4/main/php_streams.h:1.51 Sat Sep 28 18:10:47 2002
>+++ php4/main/php_streams.h Fri Oct 4 14:21:40 2002
>@@ -153,6 +153,7 @@
> int (*cast)(php_stream *stream, int castas, void **ret TSRMLS_DC);
> int (*stat)(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC);
> int (*set_option)(php_stream *stream, int option, int value, void
> *ptrparam TSRMLS_DC);
>+ int dont_block;
> } php_stream_ops;
>
> typedef struct _php_stream_wrapper_ops {
>Index: php4/main/streams.c
>diff -u php4/main/streams.c:1.89 php4/main/streams.c:1.90
>--- php4/main/streams.c:1.89 Thu Oct 3 12:06:41 2002
>+++ php4/main/streams.c Fri Oct 4 14:21:40 2002
>@@ -20,7 +20,7 @@
> +----------------------------------------------------------------------+
> */
>
>-/* $Id: streams.c,v 1.89 2002/10/03 16:06:41 helly Exp $ */
>+/* $Id: streams.c,v 1.90 2002/10/04 18:21:40 sas Exp $ */
>
> #define _GNU_SOURCE
> #include "php.h"
>@@ -494,7 +494,11 @@
>
> if (justread <= 0)
> break;
>+
> stream->writepos += justread;
>+
>+ if (stream->ops->dont_block)
>+ break;
> }
> }
>
>@@ -615,74 +619,105 @@
> return stream->ops->stat(stream, ssb TSRMLS_CC);
> }
>
>-PHPAPI char *_php_stream_gets(php_stream *stream, char *buf, size_t
>maxlen TSRMLS_DC)
>+static char *php_stream_locate_eol(php_stream *stream TSRMLS_DC)
> {
>+ size_t avail;
> char *cr, *lf, *eol = NULL;
>- size_t toread = 0, didread = 0, justread = 0, avail = 0;
> char *readptr;
>
>+ readptr = stream->readbuf + stream->readpos;
>+ avail = stream->writepos - stream->readpos;
>+
>+ /* Look for EOL */
>+ if (stream->flags & PHP_STREAM_FLAG_DETECT_EOL) {
>+ cr = memchr(readptr, '\r', avail);
>+ lf = memchr(readptr, '\n', avail);
>+
>+ if (cr && lf != cr + 1) {
>+ /* mac */
>+ stream->flags ^= PHP_STREAM_FLAG_DETECT_EOL;
>+ stream->flags |= PHP_STREAM_FLAG_EOL_MAC;
>+ eol = cr;
>+ } else if ((cr && lf && cr == lf - 1) || (lf)) {
>+ /* dos or unix endings */
>+ stream->flags ^= PHP_STREAM_FLAG_DETECT_EOL;
>+ eol = lf;
>+ }
>+ } else if (stream->flags & PHP_STREAM_FLAG_EOL_MAC) {
>+ eol = memchr(readptr, '\r', avail);
>+ } else {
>+ /* unix (and dos) line endings */
>+ eol = memchr(readptr, '\n', avail);
>+ }
>+
>+ return eol;
>+}
>+
>+PHPAPI char *_php_stream_gets(php_stream *stream, char *buf, size_t
>maxlen TSRMLS_DC)
>+{
>+ size_t avail = 0;
>+
> if (maxlen == 0)
> return NULL;
>-
>- while (didread < maxlen - 1) {
>- toread = maxlen - 1;
>- if (toread > stream->chunk_size)
>- toread = stream->chunk_size;
>
>- php_stream_fill_read_buffer(stream, toread TSRMLS_CC);
>+ /*
>+ * If the underlying stream operations block when no new data is
>readable,
>+ * we need to take extra precautions.
>+ *
>+ * If there is buffered data available, we check for a EOL. If it
>exists,
>+ * we pass the data immediately back to the caller. This saves a call
>+ * to the read implementation and will not block where blocking
>+ * is not necessary at all.
>+ *
>+ * If the stream buffer contains more data than the caller requested,
>+ * we can also avoid that costly step and simply return that data.
>+ */
>
>- readptr = stream->readbuf + stream->readpos;
>+ for (;;) {
> avail = stream->writepos - stream->readpos;
>
>- if (avail == 0)
>- break;
>-
>- /* Look for EOL */
>- if (stream->flags & PHP_STREAM_FLAG_DETECT_EOL) {
>- cr = memchr(readptr, '\r', avail);
>- lf = memchr(readptr, '\n', avail);
>-
>- if (cr && lf != cr + 1) {
>- /* mac */
>- stream->flags ^= PHP_STREAM_FLAG_DETECT_EOL;
>- stream->flags |= PHP_STREAM_FLAG_EOL_MAC;
>- eol = cr;
>- } else if ((cr && lf && cr == lf - 1) || (lf)) {
>- /* dos or unix endings */
>- stream->flags ^= PHP_STREAM_FLAG_DETECT_EOL;
>- eol = lf;
>+ if (avail > 0) {
>+ size_t cpysz = 0;
>+ char *readptr;
>+ char *eol;
>+ int done = 0;
>+
>+ readptr = stream->readbuf + stream->readpos;
>+ eol = php_stream_locate_eol(stream TSRMLS_CC);
>+
>+ if (eol) {
>+ cpysz = eol - readptr + 1;
>+ done = 1;
>+ } else {
>+ cpysz = avail;
> }
>- } else if (stream->flags & PHP_STREAM_FLAG_EOL_MAC) {
>- eol = memchr(readptr, '\r', avail);
>- } else {
>- /* unix (and dos) line endings */
>- eol = memchr(readptr, '\n', avail);
>- }
>
>- if (eol && (size_t)((ptrdiff_t)eol + 1 -
>(ptrdiff_t)readptr) <= maxlen - 1) {
>- justread = eol + 1 - readptr;
>- } else {
>- eol = NULL;
>- justread = toread;
>- if (justread > avail)
>- justread = avail;
>- }
>+ if (cpysz >= maxlen - 1) {
>+ cpysz = maxlen - 1;
>+ done = 1;
>+ }
>
>- memcpy(buf, readptr, justread);
>- didread += justread;
>- buf += justread;
>- stream->readpos += justread;
>+ memcpy(buf, readptr, cpysz);
>
>- if (eol)
>- break;
>- }
>+ stream->position += cpysz;
>+ stream->readpos += cpysz;
>+ buf += cpysz;
>+ maxlen -= cpysz;
>
>- if (didread == 0)
>- return NULL;
>+ if (done) {
>+ break;
>+ }
>+ } else {
>+ size_t toread = maxlen - 1;
>+ if (toread > stream->chunk_size)
>+ toread = stream->chunk_size;
>+
>+ /* XXX: Should not the loop end, if the stream op
>fails? */
>+ php_stream_fill_read_buffer(stream, toread TSRMLS_CC);
>+ }
>+ }
>
>- /* terminate the buffer */
>- *buf = '\0';
>- stream->position += didread;
>+ buf[0] = '\0';
>
> return buf;
> }
>
>
>
>--
>PHP CVS Mailing List (http://www.php.net/)
>To unsubscribe, visit: http://www.php.net/unsub.php
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php