rolland Tue Aug 16 08:04:14 2005 EDT
Modified files:
/php-src/ext/standard string.c
Log:
Unicode capable impl of implode()
http://cvs.php.net/diff.php/php-src/ext/standard/string.c?r1=1.454&r2=1.455&ty=u
Index: php-src/ext/standard/string.c
diff -u php-src/ext/standard/string.c:1.454 php-src/ext/standard/string.c:1.455
--- php-src/ext/standard/string.c:1.454 Tue Aug 16 02:02:56 2005
+++ php-src/ext/standard/string.c Tue Aug 16 08:04:13 2005
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: string.c,v 1.454 2005/08/16 06:02:56 rolland Exp $ */
+/* $Id: string.c,v 1.455 2005/08/16 12:04:13 rolland Exp $ */
/* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */
@@ -1141,36 +1141,115 @@
/* {{{ php_implode
*/
-PHPAPI void php_implode(zval *delim, zval *arr, zval *return_value)
+PHPAPI void php_implode(zval *delim, zval *arr, zval *retval)
{
- zval **tmp;
- HashPosition pos;
- smart_str implstr = {0};
- int numelems, i = 0;
+ zend_uchar return_type;
+ int numelems, i;
+ HashPosition pos;
+ zval **tmp;
+ void *elem;
+ int32_t elem_chars, elem_len;
+
+ if (Z_TYPE_P(delim) != IS_UNICODE && Z_TYPE_P(delim) != IS_BINARY) {
+ convert_to_string_ex(&delim);
+ }
+ Z_TYPE_P(retval) = return_type = Z_TYPE_P(delim); /* ... to start off */
+
+ /* Setup return value */
+ if (return_type == IS_UNICODE) {
+ ZVAL_EMPTY_UNICODE(retval);
+ } else if (return_type == IS_BINARY) {
+ ZVAL_EMPTY_BINARY(retval);
+ } else {
+ ZVAL_EMPTY_STRING(retval);
+ }
numelems = zend_hash_num_elements(Z_ARRVAL_P(arr));
-
if (numelems == 0) {
- RETURN_EMPTY_STRING();
+ return;
}
zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos);
-
- while (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **) &tmp,
&pos) == SUCCESS) {
- if ((*tmp)->type != IS_STRING) {
- SEPARATE_ZVAL(tmp);
- convert_to_string(*tmp);
- }
-
- smart_str_appendl(&implstr, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
- if (++i != numelems) {
- smart_str_appendl(&implstr, Z_STRVAL_P(delim),
Z_STRLEN_P(delim));
+ for (i = 1 ; i <= numelems ; i++) {
+ if (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void
**)&tmp, &pos) != SUCCESS) {
+ /* Shouldn't happen ? */
+ return;
}
zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos);
+ if (Z_TYPE_PP(tmp) != return_type) {
+ /* Convert to common type, if possible */
+ if (return_type == IS_UNICODE) {
+ if (Z_TYPE_PP(tmp) == IS_BINARY) {
+ /* ERROR */
+ php_error_docref(NULL TSRMLS_CC,
E_WARNING, "Mixed string types");
+ efree(Z_USTRVAL_P(retval));
+ ZVAL_FALSE(retval);
+ return;
+ } else {
+ SEPARATE_ZVAL(tmp);
+ convert_to_unicode_ex(tmp);
+ }
+ } else if (return_type == IS_BINARY) {
+ if (Z_TYPE_PP(tmp) == IS_UNICODE ||
Z_TYPE_PP(tmp) == IS_STRING) {
+ /* ERROR */
+ php_error_docref(NULL TSRMLS_CC,
E_WARNING, "Mixed string types");
+ efree(Z_BINVAL_P(retval));
+ ZVAL_FALSE(retval);
+ return;
+ } else {
+ SEPARATE_ZVAL(tmp);
+ convert_to_binary_ex(tmp);
+ }
+ } else {
+ if (Z_TYPE_PP(tmp) == IS_UNICODE) {
+ /* Convert IS_STRING up to IS_UNICODE */
+ convert_to_unicode_ex(&retval);
+ convert_to_unicode_ex(&delim);
+ Z_TYPE_P(retval) = return_type =
IS_UNICODE;
+ } else if (Z_TYPE_PP(tmp) == IS_BINARY) {
+ /* ERROR */
+ php_error_docref(NULL TSRMLS_CC,
E_WARNING, "Mixed string types");
+ efree(Z_STRVAL_P(retval));
+ ZVAL_FALSE(retval);
+ return;
+ } else {
+ SEPARATE_ZVAL(tmp);
+ convert_to_string_ex(tmp);
+ }
+ }
+ }
+
+ /* Append elem */
+ if (return_type == IS_UNICODE) {
+ Z_USTRVAL_P(retval) = eurealloc(Z_USTRVAL_P(retval),
+
Z_USTRLEN_P(retval)+Z_USTRLEN_PP(tmp));
+ memcpy(Z_USTRVAL_P(retval)+Z_USTRLEN_P(retval),
+ Z_USTRVAL_PP(tmp),
Z_USTRLEN_PP(tmp)*sizeof(UChar));
+ Z_USTRLEN_P(retval) += Z_USTRLEN_PP(tmp);
+ if (i < numelems) { /* Append delim */
+ Z_USTRVAL_P(retval) =
eurealloc(Z_USTRVAL_P(retval),
+
Z_USTRLEN_P(retval)+Z_USTRLEN_P(delim));
+ memcpy(Z_USTRVAL_P(retval)+Z_USTRLEN_P(retval),
+ Z_USTRVAL_P(delim),
Z_USTRLEN_P(delim)*sizeof(UChar));
+ Z_USTRLEN_P(retval) += Z_USTRLEN_P(delim);
+ }
+ } else {
+ Z_STRVAL_P(retval) = (char
*)erealloc(Z_STRVAL_P(retval),
+
Z_STRLEN_P(retval)+Z_STRLEN_PP(tmp));
+ memcpy(Z_STRVAL_P(retval)+Z_STRLEN_P(retval),
+ Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+ Z_STRLEN_P(retval) += Z_STRLEN_PP(tmp);
+ if (i < numelems) { /* Append delim */
+ Z_STRVAL_P(retval) = (char
*)erealloc(Z_STRVAL_P(retval),
+
Z_STRLEN_P(retval)+Z_STRLEN_P(delim));
+ memcpy(Z_STRVAL_P(retval)+Z_STRLEN_P(retval),
+ Z_STRVAL_P(delim),
Z_STRLEN_P(delim));
+ Z_STRLEN_P(retval) += Z_STRLEN_P(delim);
+ }
+ }
}
- smart_str_0(&implstr);
- RETURN_STRINGL(implstr.c, implstr.len, 0);
+ return;
}
/* }}} */
@@ -1178,41 +1257,41 @@
Joins array elements placing glue string between items and return one
string */
PHP_FUNCTION(implode)
{
- zval **arg1 = NULL, **arg2 = NULL, *delim, *arr;
- int argc = ZEND_NUM_ARGS();
+ zval **arg1 = NULL, **arg2 = NULL;
+ zval *delim, *arr;
+ int argc = ZEND_NUM_ARGS();
- if (argc < 1 || argc > 2 ||
- zend_get_parameters_ex(argc, &arg1, &arg2) == FAILURE) {
+ if (argc < 1 || argc > 2) {
WRONG_PARAM_COUNT;
}
+ if (zend_get_parameters_ex(argc, &arg1, &arg2) == FAILURE) {
+ return;
+ }
if (argc == 1) {
if (Z_TYPE_PP(arg1) != IS_ARRAY) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument
to implode must be an array.");
- return;
+ RETURN_FALSE;
+ } else {
+ MAKE_STD_ZVAL(delim);
+ ZVAL_STRINGL(delim, "", sizeof("")-1, 0);
+ SEPARATE_ZVAL(arg1);
+ arr = *arg1;
}
-
- MAKE_STD_ZVAL(delim);
-#define _IMPL_EMPTY ""
- ZVAL_STRINGL(delim, _IMPL_EMPTY, sizeof(_IMPL_EMPTY) - 1, 0);
-
- SEPARATE_ZVAL(arg1);
- arr = *arg1;
} else {
if (Z_TYPE_PP(arg1) == IS_ARRAY) {
SEPARATE_ZVAL(arg1);
arr = *arg1;
- convert_to_string_ex(arg2);
delim = *arg2;
} else if (Z_TYPE_PP(arg2) == IS_ARRAY) {
SEPARATE_ZVAL(arg2);
arr = *arg2;
- convert_to_string_ex(arg1);
delim = *arg1;
} else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad
arguments.");
- return;
+ RETURN_FALSE;
}
+ SEPARATE_ZVAL(&delim);
}
php_implode(delim, arr, return_value);
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php