pollita         Wed Mar 29 22:52:24 2006 UTC

  Modified files:              
    /php-src/ext/standard       file.c 
    /php-src/main/streams       streams.c 
  Log:
  Update php_stream_passthru() to handle unicode data.
  This updates userspace functions fpassthru() and readfile()
  
  UG(output_encoding) is used by php_stream_passthru() to translate
  unicode stream contents back to an outputable character set.
  
  Note: readfile()'s second parameter (use_include_path) has been changed
  to be a bitmask "flags" parameter instead.
  
  For the most commonly used values (TRUE, 1) this will continue functioning
  as expected since the value of FILE_USE_INCLUDE_PATH is (coincidentally) 1.
  The impact to other values should be noted in the migration6 guide.
  
  This change makes it possible to allow readfile() to output binary file
  contents (default) or unicode transcoded contents (using FILE_TEXT flag).
  
  
  
http://cvs.php.net/viewcvs.cgi/php-src/ext/standard/file.c?r1=1.431&r2=1.432&diff_format=u
Index: php-src/ext/standard/file.c
diff -u php-src/ext/standard/file.c:1.431 php-src/ext/standard/file.c:1.432
--- php-src/ext/standard/file.c:1.431   Wed Mar 29 01:20:42 2006
+++ php-src/ext/standard/file.c Wed Mar 29 22:52:24 2006
@@ -21,7 +21,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: file.c,v 1.431 2006/03/29 01:20:42 pollita Exp $ */
+/* $Id: file.c,v 1.432 2006/03/29 22:52:24 pollita Exp $ */
 
 /* Synced with php 3.0 revision 1.218 1999-06-16 [ssb] */
 
@@ -547,7 +547,7 @@
 }
 /* }}} */
 
-/* {{{ proto int file_put_contents(string file, mixed data [, int flags [, 
resource context]])
+/* {{{ proto int file_put_contents(string file, mixed data [, int flags [, 
resource context]]) U
    Write/Create a file with contents data and return the number of bytes 
written */
 PHP_FUNCTION(file_put_contents)
 {
@@ -991,7 +991,7 @@
 }
 /* }}} */
 
-/* {{{ proto string fgets(resource fp[, int length])
+/* {{{ proto string fgets(resource fp[, int length]) U
    Get a line from file pointer */
 PHPAPI PHP_FUNCTION(fgets)
 {
@@ -1021,7 +1021,7 @@
 }
 /* }}} */
 
-/* {{{ proto string fgetc(resource fp)
+/* {{{ proto string fgetc(resource fp) U
    Get a character from file pointer */
 PHPAPI PHP_FUNCTION(fgetc)
 {
@@ -1052,7 +1052,7 @@
 }
 /* }}} */
 
-/* {{{ proto string fgetss(resource fp [, int length, string allowable_tags])
+/* {{{ proto string fgetss(resource fp [, int length, string allowable_tags]) U
    Get a line from file pointer and strip HTML tags */
 PHPAPI PHP_FUNCTION(fgetss)
 {
@@ -1168,7 +1168,7 @@
 }
 /* }}} */
 
-/* {{{ proto int fwrite(resource fp, string str [, int length])
+/* {{{ proto int fwrite(resource fp, string str [, int length]) U
    Binary-safe file write */
 PHPAPI PHP_FUNCTION(fwrite)
 {
@@ -1371,26 +1371,30 @@
 }
 /* }}} */
 
-/* {{{ proto int readfile(string filename [, bool use_include_path[, resource 
context]])
+/* {{{ proto int readfile(string filename [, int flags[, resource context]]) U
    Output a file or a URL */
-/* UTODO: Accept unicode contents */
 PHP_FUNCTION(readfile)
 {
        char *filename;
        int size = 0;
        int filename_len;
-       zend_bool use_include_path = 0;
+       long flags = 0;
        zval *zcontext = NULL;
        php_stream *stream;
        php_stream_context *context = NULL;
+       char *mode = "rb";
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|br!", 
&filename, &filename_len, &use_include_path, &zcontext) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lr!", 
&filename, &filename_len, &flags, &zcontext) == FAILURE) {
                RETURN_FALSE;
        }
 
        context = php_stream_context_from_zval(zcontext, 0);
 
-       stream = php_stream_open_wrapper_ex(filename, "rb", (use_include_path ? 
USE_PATH : 0) | REPORT_ERRORS, NULL, context);
+       if (flags & PHP_FILE_TEXT) {
+               mode = "rt";
+       }
+
+       stream = php_stream_open_wrapper_ex(filename, mode, ((flags & 
PHP_FILE_USE_INCLUDE_PATH) ? USE_PATH : 0) | REPORT_ERRORS, NULL, context);
        if (stream) {
                size = php_stream_passthru(stream);
                php_stream_close(stream);
@@ -1429,9 +1433,8 @@
 
 /* }}} */
 
-/* {{{ proto int fpassthru(resource fp)
+/* {{{ proto int fpassthru(resource fp) U
    Output all remaining data from a file pointer */
-/* UTODO: Accept unicode contents */
 PHPAPI PHP_FUNCTION(fpassthru)
 {
        zval **arg1;
@@ -1733,7 +1736,7 @@
 }
 /* }}} */
 
-/* {{{ proto string fread(resource fp, int length)
+/* {{{ proto string fread(resource fp, int length) U
    Binary-safe file read */
 PHPAPI PHP_FUNCTION(fread)
 {
http://cvs.php.net/viewcvs.cgi/php-src/main/streams/streams.c?r1=1.115&r2=1.116&diff_format=u
Index: php-src/main/streams/streams.c
diff -u php-src/main/streams/streams.c:1.115 
php-src/main/streams/streams.c:1.116
--- php-src/main/streams/streams.c:1.115        Wed Mar 29 01:20:43 2006
+++ php-src/main/streams/streams.c      Wed Mar 29 22:52:24 2006
@@ -19,7 +19,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: streams.c,v 1.115 2006/03/29 01:20:43 pollita Exp $ */
+/* $Id: streams.c,v 1.116 2006/03/29 22:52:24 pollita Exp $ */
 
 #define _GNU_SOURCE
 #include "php.h"
@@ -1507,11 +1507,10 @@
 
 PHPAPI size_t _php_stream_passthru(php_stream * stream STREAMS_DC TSRMLS_DC)
 {
-       size_t bcount = 0;
-       char buf[8192];
-       int b;
+       size_t count = 0;
 
        if (php_stream_mmap_possible(stream)) {
+               /* mmap_possible == non-filtered stream == binary stream */
                char *p;
                size_t mapped;
 
@@ -1526,12 +1525,46 @@
                }
        }
 
-       while ((b = php_stream_read(stream, buf, sizeof(buf))) > 0) {
-               PHPWRITE(buf, b);
-               bcount += b;
+       if (stream->readbuf_type == IS_UNICODE) {
+               UChar inbuf_start[8192];
+               UConverter *conv = ZEND_U_CONVERTER(UG(output_encoding_conv));
+               int outbuflen = UCNV_GET_MAX_BYTES_FOR_STRING(8192, 
ucnv_getMaxCharSize(conv));
+               char *outbuf_start = emalloc(outbuflen + 1);
+               int b;
+
+               ucnv_resetFromUnicode(conv);
+
+               while ((b = php_stream_read_unicode(stream, inbuf_start, 
sizeof(inbuf_start))) > 0) {
+                       char *outbuf = outbuf_start;
+                       UChar *inbuf = inbuf_start;
+                       UErrorCode status = U_ZERO_ERROR;
+                       int len;
+
+                       ucnv_fromUnicode(conv, &outbuf, outbuf + outbuflen, 
&inbuf, inbuf + b, NULL, TRUE, &status);
+                       len = u_countChar32(inbuf_start, inbuf - inbuf_start);
+                       if (U_FAILURE(status)) {
+                               /* Memory overflow isn't a problem becuase 
MAX_BYTES_FOR_STRING was allocated,
+                                  anything else is a more serious problem */
+                               zend_raise_conversion_error_ex("Unable to 
convert unicode character using output_encoding, at least one character was 
lost",
+                                                                       conv, 
ZEND_FROM_UNICODE, len, (UG(from_error_mode) & ZEND_CONV_ERROR_EXCEPTION) 
TSRMLS_CC);
+                       }
+                       if (outbuf > outbuf_start) {
+                               PHPWRITE(outbuf_start, outbuf - outbuf_start);
+                               count += len;
+                       }
+               }
+               efree(outbuf_start);
+       } else {
+               char buf[8192];
+               int b;
+
+               while ((b = php_stream_read(stream, buf, sizeof(buf))) > 0) {
+                       PHPWRITE(buf, b);
+                       count += b;
+               }
        }
 
-       return bcount;
+       return count;
 }
 
 

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

Reply via email to