From: Arnaud Le Blanc Date: Sun, 17 May 2009 16:52:35 +0000 (+0000) Subject: un-duplicated code (merged unicode/string variants of stream_copy_to_stream X-Git-Tag: php-5.4.0alpha1~191^2~3634 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=587137b2d3d17cf047abb5b12b29b0a1a68f3d48;p=php un-duplicated code (merged unicode/string variants of stream_copy_to_stream and let the compiler optimize specializations) --- diff --git a/main/php_streams.h b/main/php_streams.h index 77eaaf0040..a13c323620 100755 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -305,6 +305,12 @@ PHPAPI size_t _php_stream_read_unicode(php_stream *stream, UChar *buf, int maxle #define php_stream_read_unicode(stream, buf, maxlen) _php_stream_read_unicode((stream), (buf), (maxlen), -1 TSRMLS_CC) #define php_stream_read_unicode_ex(stream, buf, maxlen, maxchars) _php_stream_read_unicode((stream), (buf), (maxlen), (maxchars) TSRMLS_CC) +#define php_stream_u_read_ex(stream, type, zbuf, maxlen, maxchars) ((type == IS_UNICODE) ? \ + php_stream_read_unicode_ex(stream, zbuf.u, maxlen, maxchars) : \ + php_stream_read(stream, zbuf.s, maxlen)) + +#define php_stream_u_read(stream, type, zbuf, maxlen) php_stream_u_read_ex(stream, type, zbuf, maxlen, -1) + PHPAPI UChar *_php_stream_read_unicode_chars(php_stream *stream, int *pchars TSRMLS_DC); #define php_stream_read_unicode_chars(stream, pchars) _php_stream_read_unicode_chars((stream), (pchars) TSRMLS_CC) diff --git a/main/streams/streams.c b/main/streams/streams.c index caab99f92f..5bb85acef1 100755 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -1767,112 +1767,8 @@ PHPAPI size_t _php_stream_copy_to_mem_ex(php_stream *src, zend_uchar rettype, vo return len; } -/* Designed for copying UChars (taking into account both maxlen and maxchars) */ -PHPAPI size_t _php_stream_ucopy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t maxchars, size_t *len STREAMS_DC TSRMLS_DC) -{ - size_t haveread = 0; - php_stream_statbuf ssbuf; - size_t dummy; - - if (!len) { - len = &dummy; - } - - if (src->readbuf_type == IS_STRING) { - /* Called incorrectly, don't do that. */ - return _php_stream_copy_to_stream_ex(src, dest, maxlen, len STREAMS_CC TSRMLS_CC); - } - - if (maxlen == 0 || maxchars == 0) { - *len = 0; - return SUCCESS; - } - - if (maxlen == PHP_STREAM_COPY_ALL) { - maxlen = 0; - } - - if (php_stream_stat(src, &ssbuf) == 0) { - if (ssbuf.sb.st_size == 0 -#ifdef S_ISREG - && S_ISREG(ssbuf.sb.st_mode) -#endif - ) { - *len = 0; - return SUCCESS; - } - } - - while(1) { - UChar buf[CHUNK_SIZE]; - size_t readchunk = CHUNK_SIZE; - size_t didread; - - if (maxlen && (maxlen - haveread) < readchunk) { - readchunk = maxlen - haveread; - } - - didread = php_stream_read_unicode_ex(src, buf, readchunk, maxchars); - - if (didread) { - /* extra paranoid */ - size_t didwrite, towrite; - UChar *writeptr; - - if (maxchars > 0) { - /* Determine number of chars in this buf */ - maxchars -= u_countChar32(buf, didread); - } - - towrite = didread; - writeptr = buf; - haveread += didread; - - while(towrite) { - didwrite = php_stream_write_unicode(dest, writeptr, towrite); - if (didwrite == 0) { - *len = haveread - (didread - towrite); - return FAILURE; - } - - towrite -= didwrite; - writeptr += didwrite; - } - } else { - break; - } - - if (maxchars == 0 || maxlen - haveread == 0) { - break; - } - } - - *len = haveread; - - /* we've got at least 1 byte to read. - * less than 1 is an error */ - - if (haveread > 0) { - return SUCCESS; - } - return FAILURE; -} - -/* see _php_stream_copy_to_stream() */ -ZEND_ATTRIBUTE_DEPRECATED -PHPAPI size_t _php_stream_ucopy_to_stream(php_stream *src, php_stream *dest, size_t maxlen, size_t maxchars STREAMS_DC TSRMLS_DC) -{ - size_t len; - int ret = _php_stream_ucopy_to_stream_ex(src, dest, maxlen, maxchars, &len STREAMS_REL_CC TSRMLS_CC); - if (ret == SUCCESS && maxlen != 0 && maxchars != 0) { - return 1; - } - return len; -} - -/* Optimized for copying octets from source stream */ -/* Returns SUCCESS/FAILURE and sets *len to the number of bytes moved */ -PHPAPI size_t _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t *len STREAMS_DC TSRMLS_DC) +zend_always_inline +static size_t _php_stream_copy_to_stream_common(php_stream *src, php_stream *dest, size_t maxlen, size_t maxchars, size_t *len, int utype STREAMS_DC TSRMLS_DC) { size_t haveread = 0; php_stream_statbuf ssbuf; @@ -1882,12 +1778,7 @@ PHPAPI size_t _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, s len = &dummy; } - if (src->readbuf_type == IS_UNICODE) { - /* Called incorrectly, don't do that. */ - return _php_stream_ucopy_to_stream_ex(src, dest, maxlen, -1, len STREAMS_CC TSRMLS_CC); - } - - if (maxlen == 0) { + if (maxlen == 0 || (utype == IS_UNICODE && maxchars == 0)) { *len = 0; return SUCCESS; } @@ -1907,7 +1798,7 @@ PHPAPI size_t _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, s } } - if (php_stream_mmap_possible(src)) { + if (utype == IS_STRING && php_stream_mmap_possible(src)) { char *p; size_t mapped; @@ -1931,40 +1822,48 @@ PHPAPI size_t _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, s } while(1) { - char buf[CHUNK_SIZE]; - size_t readchunk = sizeof(buf); + zstr buf; + union { char s; UChar u; } _buf[CHUNK_SIZE]; + size_t readchunk = sizeof(_buf) / sizeof(_buf[0]); size_t didread; + buf.v = _buf; + if (maxlen && (maxlen - haveread) < readchunk) { readchunk = maxlen - haveread; } - didread = php_stream_read(src, buf, readchunk); + didread = php_stream_u_read_ex(src, utype, buf, readchunk, maxchars); if (didread) { /* extra paranoid */ size_t didwrite, towrite; - char *writeptr; + zstr writeptr; + + if (utype == IS_UNICODE && maxchars > 0) { + /* Determine number of chars in this buf */ + maxchars -= u_countChar32(buf.u, didread); + } towrite = didread; writeptr = buf; haveread += didread; while(towrite) { - didwrite = php_stream_write(dest, writeptr, towrite); + didwrite = php_stream_u_write(dest, utype, writeptr, towrite); if (didwrite == 0) { *len = haveread - (didread - towrite); return FAILURE; } towrite -= didwrite; - writeptr += didwrite; + writeptr.v += ZBYTES(utype, didwrite); } } else { break; } - if (maxlen - haveread == 0) { + if (maxlen - haveread == 0 || (utype == IS_UNICODE && maxchars == 0)) { break; } } @@ -1980,6 +1879,31 @@ PHPAPI size_t _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, s return FAILURE; } +/* Designed for copying UChars (taking into account both maxlen and maxchars) */ +PHPAPI size_t _php_stream_ucopy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t maxchars, size_t *len STREAMS_DC TSRMLS_DC) +{ + return _php_stream_copy_to_stream_common(src, dest, maxlen, maxchars, len, IS_UNICODE STREAMS_REL_CC TSRMLS_CC); +} + +/* see _php_stream_copy_to_stream() */ +ZEND_ATTRIBUTE_DEPRECATED +PHPAPI size_t _php_stream_ucopy_to_stream(php_stream *src, php_stream *dest, size_t maxlen, size_t maxchars STREAMS_DC TSRMLS_DC) +{ + size_t len; + int ret = _php_stream_ucopy_to_stream_ex(src, dest, maxlen, maxchars, &len STREAMS_REL_CC TSRMLS_CC); + if (ret == SUCCESS && maxlen != 0 && maxchars != 0) { + return 1; + } + return len; +} + +/* Optimized for copying octets from source stream */ +/* Returns SUCCESS/FAILURE and sets *len to the number of bytes moved */ +PHPAPI size_t _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t *len STREAMS_DC TSRMLS_DC) +{ + return _php_stream_copy_to_stream_common(src, dest, maxlen, 0, len, IS_STRING STREAMS_REL_CC TSRMLS_CC); +} + /* Returns the number of bytes moved. * Returns 1 when source len is 0. * Deprecated in favor of php_stream_copy_to_stream_ex() */