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