Everything fine again after "Fix EOF cases" :-)

marcus

At 20:41 04.10.2002, Marcus Börger wrote:
>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


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to