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