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

Reply via email to