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

Reply via email to