Skip to content

Commit 4879802

Browse files
committed
Refactor streams layer for PHP6.
Don't be frightened by the size of this commit. A significant portion of it is restoring the read buffer semantics back to what PHP4/5 use. (Or a close aproximation thereof). See main/streams/streams.c and ext/standard/file.c for a set of UTODO comments covering work yet to be done.
1 parent fe2842d commit 4879802

File tree

12 files changed

+805
-1126
lines changed

12 files changed

+805
-1126
lines changed

ext/bz2/bz2_filter.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,18 +82,18 @@ static php_stream_filter_status_t php_bz2_decompress_filter(
8282

8383
bucket = buckets_in->head;
8484

85-
if (bucket->is_unicode) {
85+
if (bucket->buf_type == IS_UNICODE) {
8686
/* decompression not allowed for unicode data */
8787
return PSFS_ERR_FATAL;
8888
}
8989

9090
bucket = php_stream_bucket_make_writeable(bucket TSRMLS_CC);
91-
while (bin < bucket->buf.str.len) {
92-
desired = bucket->buf.str.len - bin;
91+
while (bin < bucket->buflen) {
92+
desired = bucket->buflen - bin;
9393
if (desired > data->inbuf_len) {
9494
desired = data->inbuf_len;
9595
}
96-
memcpy(data->strm.next_in, bucket->buf.str.val + bin, desired);
96+
memcpy(data->strm.next_in, bucket->buf.s + bin, desired);
9797
data->strm.avail_in = desired;
9898

9999
status = BZ2_bzDecompress(&(data->strm));
@@ -195,19 +195,19 @@ static php_stream_filter_status_t php_bz2_compress_filter(
195195

196196
bucket = buckets_in->head;
197197

198-
if (bucket->is_unicode) {
198+
if (bucket->buf_type == IS_UNICODE) {
199199
/* compression not allowed for unicode data */
200200
return PSFS_ERR_FATAL;
201201
}
202202

203203
bucket = php_stream_bucket_make_writeable(bucket TSRMLS_CC);
204204

205-
while (bin < bucket->buf.str.len) {
206-
desired = bucket->buf.str.len - bin;
205+
while (bin < bucket->buflen) {
206+
desired = bucket->buflen - bin;
207207
if (desired > data->inbuf_len) {
208208
desired = data->inbuf_len;
209209
}
210-
memcpy(data->strm.next_in, bucket->buf.str.val + bin, desired);
210+
memcpy(data->strm.next_in, bucket->buf.s + bin, desired);
211211
data->strm.avail_in = desired;
212212

213213
status = BZ2_bzCompress(&(data->strm), flags & PSFS_FLAG_FLUSH_CLOSE ? BZ_FINISH : (flags & PSFS_FLAG_FLUSH_INC ? BZ_FLUSH : BZ_RUN));

ext/standard/file.c

Lines changed: 72 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ PHP_FUNCTION(file_get_contents)
507507
char *contents;
508508
zend_bool use_include_path = 0;
509509
php_stream *stream;
510-
int len, newlen;
510+
int len;
511511
long offset = -1;
512512
long maxlen = PHP_STREAM_COPY_ALL;
513513
zval *zcontext = NULL;
@@ -555,7 +555,7 @@ PHP_FUNCTION(file_put_contents)
555555
char *filename;
556556
int filename_len;
557557
zval *data;
558-
int numbytes = 0;
558+
int numchars = 0;
559559
long flags = 0;
560560
zval *zcontext = NULL;
561561
php_stream_context *context = NULL;
@@ -592,52 +592,53 @@ PHP_FUNCTION(file_put_contents)
592592
php_stream *srcstream;
593593
php_stream_from_zval(srcstream, &data);
594594

595-
numbytes = php_stream_copy_to_stream(srcstream, stream, PHP_STREAM_COPY_ALL);
595+
numchars = php_stream_copy_to_stream(srcstream, stream, PHP_STREAM_COPY_ALL);
596596

597597
break;
598598
}
599599
case IS_ARRAY:
600600
if (zend_hash_num_elements(Z_ARRVAL_P(data))) {
601-
int bytes_written;
602601
zval **tmp;
603602
HashPosition pos;
604603

605604
zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(data), &pos);
606605
while (zend_hash_get_current_data_ex(Z_ARRVAL_P(data), (void **) &tmp, &pos) == SUCCESS) {
607606
if (Z_TYPE_PP(tmp) == IS_UNICODE) {
608-
int wrote_bytes = php_stream_u_write(stream, Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp));
609-
if (wrote_bytes < 0) {
610-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write %d characters to %s", Z_USTRLEN_PP(tmp), filename);
611-
numbytes = -1;
607+
int ustrlen = u_countChar32(Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp));
608+
int wrote_u16 = php_stream_write_unicode(stream, Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp));
609+
if (wrote_u16 < 0) {
610+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write %d characters to %s", ustrlen, filename);
611+
numchars = -1;
612612
break;
613-
} else if (wrote_bytes != UBYTES(Z_USTRLEN_PP(tmp))) {
614-
int ustrlen = u_countChar32(Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp));
615-
int numchars = u_countChar32(Z_USTRVAL_PP(tmp), wrote_bytes / UBYTES(1));
613+
} else if (wrote_u16 != Z_USTRLEN_PP(tmp)) {
614+
int numchars = u_countChar32(Z_USTRVAL_PP(tmp), wrote_u16);
616615

617616
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %d of %d characters written, possibly out of free disk space", numchars, ustrlen);
618-
numbytes = -1;
617+
numchars = -1;
619618
break;
620619
}
621-
numbytes += wrote_bytes;
620+
numchars += ustrlen;
622621
} else { /* non-unicode */
623622
int free_val = 0;
624623
zval strval = **tmp;
624+
int wrote_bytes;
625625

626626
if (Z_TYPE(strval) != IS_STRING) {
627627
zval_copy_ctor(&strval);
628628
convert_to_string(&strval);
629629
free_val = 1;
630630
}
631631
if (Z_STRLEN(strval)) {
632-
numbytes += Z_STRLEN(strval);
633-
bytes_written = php_stream_write(stream, Z_STRVAL(strval), Z_STRLEN(strval));
634-
if (bytes_written < 0 || bytes_written != Z_STRLEN(strval)) {
635-
if (bytes_written < 0) {
636-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write %d bytes to %s", Z_STRLEN(strval), filename);
637-
} else {
638-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %d of %d bytes written, possibly out of free disk space", bytes_written, Z_STRLEN(strval));
639-
}
640-
numbytes = -1;
632+
numchars += Z_STRLEN(strval);
633+
wrote_bytes = php_stream_write(stream, Z_STRVAL(strval), Z_STRLEN(strval));
634+
if (wrote_bytes < 0) {
635+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write %d bytes to %s", Z_STRLEN(strval), filename);
636+
numchars = -1;
637+
break;
638+
}
639+
if (wrote_bytes != Z_STRLEN(strval)) {
640+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %d of %d bytes written, possibly out of free disk space", wrote_bytes, Z_STRLEN(strval));
641+
numchars = -1;
641642
break;
642643
}
643644
}
@@ -652,20 +653,20 @@ PHP_FUNCTION(file_put_contents)
652653
case IS_OBJECT:
653654
/* TODO */
654655
php_error_docref(NULL TSRMLS_CC, E_WARNING, "2nd parameter must be non-object (for now)");
655-
numbytes = -1;
656+
numchars = -1;
656657
break;
657658
case IS_UNICODE:
658659
if (Z_USTRLEN_P(data)) {
659-
numbytes = php_stream_u_write(stream, Z_USTRVAL_P(data), Z_USTRLEN_P(data));
660-
if (numbytes < 0) {
661-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write %d characters to %s", Z_USTRLEN_P(data), filename);
662-
numbytes = -1;
663-
} else if (numbytes != UBYTES(Z_USTRLEN_P(data))) {
664-
int ustrlen = u_countChar32(Z_USTRVAL_P(data), Z_USTRLEN_P(data));
665-
int numchars = u_countChar32(Z_USTRVAL_P(data), numbytes / UBYTES(1));
660+
int ustrlen = u_countChar32(Z_USTRVAL_P(data), Z_USTRLEN_P(data));
661+
numchars = php_stream_write_unicode(stream, Z_USTRVAL_P(data), Z_USTRLEN_P(data));
662+
if (numchars < 0) {
663+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write %d characters to %s", ustrlen, filename);
664+
numchars = -1;
665+
} else if (numchars != UBYTES(Z_USTRLEN_P(data))) {
666+
int numchars = u_countChar32(Z_USTRVAL_P(data), numchars);
666667

667668
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %d of %d characters written, possibly out of free disk space", numchars, ustrlen);
668-
numbytes = -1;
669+
numchars = -1;
669670
}
670671
}
671672
break;
@@ -680,22 +681,22 @@ PHP_FUNCTION(file_put_contents)
680681
convert_to_string_ex(&data);
681682
}
682683
if (Z_STRLEN_P(data)) {
683-
numbytes = php_stream_write(stream, Z_STRVAL_P(data), Z_STRLEN_P(data));
684-
if (numbytes != Z_STRLEN_P(data)) {
685-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %d of %d bytes written, possibly out of free disk space", numbytes, Z_STRLEN_P(data));
686-
numbytes = -1;
684+
numchars = php_stream_write(stream, Z_STRVAL_P(data), Z_STRLEN_P(data));
685+
if (numchars != Z_STRLEN_P(data)) {
686+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %d of %d bytes written, possibly out of free disk space", numchars, Z_STRLEN_P(data));
687+
numchars = -1;
687688
}
688689
}
689690
break;
690691

691692
}
692693
php_stream_close(stream);
693694

694-
if (numbytes < 0) {
695+
if (numchars < 0) {
695696
RETURN_FALSE;
696697
}
697698

698-
RETURN_LONG(numbytes);
699+
RETURN_LONG(numchars);
699700
}
700701
/* }}} */
701702

@@ -709,9 +710,9 @@ PHP_FUNCTION(file)
709710
{
710711
char *filename;
711712
int filename_len;
712-
char *slashed, *target_buf=NULL, *p, *s, *e;
713+
char *target_buf=NULL, *p, *s, *e;
713714
register int i = 0;
714-
int target_len, len;
715+
int target_len;
715716
char eol_marker = '\n';
716717
long flags = 0;
717718
zend_bool use_include_path;
@@ -748,7 +749,7 @@ PHP_FUNCTION(file)
748749
s = target_buf;
749750
e = target_buf + target_len;
750751

751-
if (!(p = php_stream_locate_eol(stream, target_buf, target_len TSRMLS_CC))) {
752+
if (!(p = php_stream_locate_eol(stream, (zstr)target_buf, target_len TSRMLS_CC))) {
752753
p = e;
753754
goto parse_eol;
754755
}
@@ -1024,29 +1025,28 @@ PHPAPI PHP_FUNCTION(fgets)
10241025
PHPAPI PHP_FUNCTION(fgetc)
10251026
{
10261027
zval **arg1;
1027-
char buf[2 * sizeof(UChar)];
1028-
int is_unicode;
10291028
php_stream *stream;
1030-
int32_t num_bytes = UBYTES(2), num_chars = 1;
10311029

10321030
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
10331031
WRONG_PARAM_COUNT;
10341032
}
10351033

10361034
PHP_STREAM_TO_ZVAL(stream, arg1);
10371035

1038-
if (!php_stream_u_read(stream, buf, &num_bytes, &num_chars, &is_unicode)) {
1039-
RETVAL_FALSE;
1040-
} else {
1041-
if (is_unicode) {
1042-
UChar *ubuf = (UChar *)buf;
1043-
int num_u16 = num_bytes >> 1;
1044-
ubuf[num_u16] = 0;
1045-
RETURN_UNICODEL(ubuf, num_u16, 1);
1046-
} else {
1047-
buf[1] = 0;
1048-
RETURN_STRINGL(buf, 1, 1);
1036+
if (php_stream_reads_unicode(stream)) {
1037+
int buflen = 1;
1038+
UChar *buf = php_stream_read_unicode_chars(stream, &buflen);
1039+
1040+
if (!buf) {
1041+
RETURN_FALSE;
10491042
}
1043+
RETURN_UNICODEL(buf, buflen, 0);
1044+
} else {
1045+
char buf[2];
1046+
1047+
buf[0] = php_stream_getc(stream);
1048+
buf[1] = 0;
1049+
RETURN_STRINGL(buf, 1, 1);
10501050
}
10511051
}
10521052
/* }}} */
@@ -1213,26 +1213,19 @@ PHPAPI PHP_FUNCTION(fwrite)
12131213
if (write_len < 0 || write_len > Z_USTRLEN_P(zstring)) {
12141214
write_len = Z_USTRLEN_P(zstring);
12151215
}
1216-
ret = php_stream_u_write(stream, Z_USTRVAL_P(zstring), write_len);
1216+
ret = php_stream_write_unicode(stream, Z_USTRVAL_P(zstring), write_len);
12171217

12181218
/* Convert data points back to code units */
12191219
if (ret > 0) {
12201220
ret = u_countChar32(Z_USTRVAL_P(zstring), ret);
12211221
}
12221222
} else {
1223-
char *buffer = NULL;
1224-
int num_bytes;
1225-
12261223
convert_to_string(zstring);
12271224
if (write_len < 0 || write_len > Z_STRLEN_P(zstring)) {
12281225
write_len = Z_STRLEN_P(zstring);
12291226
}
12301227

1231-
num_bytes = write_len;
1232-
ret = php_stream_write(stream, buffer ? buffer : Z_STRVAL_P(zstring), num_bytes);
1233-
if (buffer) {
1234-
efree(buffer);
1235-
}
1228+
ret = php_stream_write(stream, Z_STRVAL_P(zstring), write_len);
12361229
}
12371230

12381231
RETURN_LONG(ret);
@@ -1759,11 +1752,8 @@ PHPAPI int php_copy_file(char *src, char *dest TSRMLS_DC)
17591752
PHPAPI PHP_FUNCTION(fread)
17601753
{
17611754
zval *zstream;
1762-
char *buf;
17631755
long len;
17641756
php_stream *stream;
1765-
int is_unicode;
1766-
int32_t num_bytes, num_chars;
17671757

17681758
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zstream, &len) == FAILURE) {
17691759
RETURN_NULL();
@@ -1776,22 +1766,25 @@ PHPAPI PHP_FUNCTION(fread)
17761766
RETURN_FALSE;
17771767
}
17781768

1779-
num_chars = len;
1780-
num_bytes = UBYTES(len);
1781-
buf = emalloc(num_bytes + UBYTES(1));
1769+
if (php_stream_reads_unicode(stream)) {
1770+
int buflen = len;
1771+
UChar *buf = php_stream_read_unicode_chars(stream, &buflen);
17821772

1783-
if (!php_stream_u_read(stream, buf, &num_bytes, &num_chars, &is_unicode)) {
1784-
efree(buf);
1785-
RETURN_FALSE;
1786-
}
1773+
if (!buf) {
1774+
RETURN_FALSE;
1775+
}
17871776

1788-
if (is_unicode) {
1789-
buf[num_bytes] = 0;
1790-
buf[num_bytes + 1] = 0;
1791-
RETURN_UNICODEL((UChar *)buf, num_bytes >> 1, 0);
1777+
RETURN_UNICODEL(buf, buflen, 0);
17921778
} else {
1793-
buf[num_bytes] = 0;
1794-
RETURN_STRINGL(buf, num_bytes, 0);
1779+
char *buf = emalloc(len + 1);
1780+
int buflen = php_stream_read(stream, buf, len);
1781+
1782+
if (!buflen) {
1783+
efree(buf);
1784+
RETURN_FALSE;
1785+
}
1786+
buf[buflen] = 0;
1787+
RETURN_STRINGL(buf, buflen, 0);
17951788
}
17961789
}
17971790
/* }}} */

0 commit comments

Comments
 (0)