pollita Mon Mar 13 20:54:06 2006 UTC Modified files: /php-src/main/streams streams.c Log: Make php_stream_write_buffer() return characters written, not bytes http://cvs.php.net/viewcvs.cgi/php-src/main/streams/streams.c?r1=1.100&r2=1.101&diff_format=u Index: php-src/main/streams/streams.c diff -u php-src/main/streams/streams.c:1.100 php-src/main/streams/streams.c:1.101 --- php-src/main/streams/streams.c:1.100 Mon Mar 13 15:01:44 2006 +++ php-src/main/streams/streams.c Mon Mar 13 20:54:06 2006 @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: streams.c,v 1.100 2006/03/13 15:01:44 derick Exp $ */ +/* $Id: streams.c,v 1.101 2006/03/13 20:54:06 pollita Exp $ */ #define _GNU_SOURCE #include "php.h" @@ -1128,7 +1128,8 @@ /* Writes a buffer directly to a stream, using multiple of the chunk size */ static size_t _php_stream_write_buffer(php_stream *stream, int buf_type, zstr buf, int buflen TSRMLS_DC) { - size_t didwrite = 0, towrite, justwrote; + size_t didwrite = 0, towrite, justwrote, shouldwrite, buflen_orig = buflen; + zstr buf_orig = buf; char *freeme = NULL; /* if we have a seekable stream we need to ensure that data is written at the @@ -1155,6 +1156,8 @@ } } + shouldwrite = buflen; + while (buflen > 0) { towrite = buflen; if (towrite > stream->chunk_size) { @@ -1179,6 +1182,36 @@ } } + + if (stream->output_encoding) { + /* Map didwrite back to the original character count */ + if (didwrite == shouldwrite) { + /* Everything wrote okay, no need to count */ + didwrite = buflen_orig; + } else { + UErrorCode status = U_ZERO_ERROR; + char *t = freeme; + UChar *p = buf_orig.u; + + switch (ucnv_getType(stream->output_encoding)) { + case UCNV_SBCS: + case UCNV_LATIN_1: + case UCNV_US_ASCII: + /* 1:1 character->byte mapping, didwrite really does mean the number of characters written */ + break; + default: + /* Reconvert into junk buffer to see where conversion stops in source string */ + ucnv_resetFromUnicode(stream->output_encoding); + ucnv_fromUnicode(stream->output_encoding, &t, t + didwrite, &p, p + buflen_orig, NULL, TRUE, &status); + /* p stops at the first unconvertable UChar when t runs out of space */ + didwrite = p - buf_orig.u; + } + } + } else if (buf_type == IS_UNICODE) { + /* Was slopily converted */ + didwrite /= UBYTES(1); + } + if (freeme) { efree(freeme); } @@ -1296,10 +1329,6 @@ ret = _php_stream_write_buffer(stream, IS_UNICODE, (zstr)((UChar*)buf), count TSRMLS_CC); } - /* Return data points, not bytes */ - if (ret > 0) { - ret >>= 1; - } return ret; }
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php