]> granicus.if.org Git - php/commitdiff
- Add an extra parameter to the cast_object handler that can be used by
authorAndrei Zmievski <andrei@php.net>
Fri, 13 Oct 2006 14:52:19 +0000 (14:52 +0000)
committerAndrei Zmievski <andrei@php.net>
Fri, 13 Oct 2006 14:52:19 +0000 (14:52 +0000)
  various types as needed.
- Use that parameter to pass a specific converter for
  IS_UNICODE/IS_STRING types.

Zend/zend.c
Zend/zend_API.c
Zend/zend_builtin_functions.c
Zend/zend_execute.h
Zend/zend_object_handlers.c
Zend/zend_object_handlers.h
Zend/zend_operators.c
ext/com_dotnet/com_handlers.c
ext/simplexml/simplexml.c
ext/spl/spl_directory.c
ext/tidy/tidy.c

index b260500e1428dbf937d2663f07877b981d321091..e44d1f4f3aad70eaaa12965bd4a4fafaa030f1a6 100644 (file)
@@ -315,7 +315,7 @@ ZEND_API void zend_make_string_zval(zval *expr, zval *expr_copy, int *use_copy)
                        {
                                TSRMLS_FETCH();
 
-                               if(Z_OBJ_HT_P(expr)->cast_object && Z_OBJ_HANDLER_P(expr, cast_object)(expr, expr_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
+                               if(Z_OBJ_HT_P(expr)->cast_object && Z_OBJ_HANDLER_P(expr, cast_object)(expr, expr_copy, IS_STRING, NULL TSRMLS_CC) == SUCCESS) {
                                        break;
                                }
                                if (Z_OBJ_HANDLER_P(expr, get)) {
@@ -384,7 +384,7 @@ ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_cop
                        Z_STRVAL_P(expr_copy) = estrndup("Array", Z_STRLEN_P(expr_copy));
                        break;
                case IS_OBJECT:
-                       if(Z_OBJ_HT_P(expr)->cast_object && Z_OBJ_HANDLER_P(expr, cast_object)(expr, expr_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
+                       if(Z_OBJ_HT_P(expr)->cast_object && Z_OBJ_HANDLER_P(expr, cast_object)(expr, expr_copy, IS_STRING, ZEND_U_CONVERTER(UG(output_encoding_conv)) TSRMLS_CC) == SUCCESS) {
                                break;
                        }
                        if (Z_OBJ_HANDLER_P(expr, get)) {
@@ -436,7 +436,7 @@ ZEND_API void zend_make_unicode_zval(zval *expr, zval *expr_copy, int *use_copy)
        }
        switch (Z_TYPE_P(expr)) {
                case IS_OBJECT:
-                       if(Z_OBJ_HT_P(expr)->cast_object && Z_OBJ_HANDLER_P(expr, cast_object)(expr, expr_copy, IS_UNICODE TSRMLS_CC) == SUCCESS) {
+                       if(Z_OBJ_HT_P(expr)->cast_object && Z_OBJ_HANDLER_P(expr, cast_object)(expr, expr_copy, IS_UNICODE, NULL TSRMLS_CC) == SUCCESS) {
                                break;
                        }
                        if (Z_OBJ_HANDLER_P(expr, get)) {
index 3ebede95a5b915950e8e84bf59676ab576c9abd7..29bf9d30ffd2e067dc4f2ba0e68434e1aa5e8964 100644 (file)
@@ -271,7 +271,7 @@ static int parse_arg_object_to_string(zval **arg, char **p, int *pl, int type TS
 {
        if (Z_OBJ_HANDLER_PP(arg, cast_object)) {
                SEPARATE_ZVAL_IF_NOT_REF(arg);
-               if (Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, type TSRMLS_CC) == SUCCESS) {
+               if (Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, type, NULL TSRMLS_CC) == SUCCESS) {
                        *pl = Z_STRLEN_PP(arg);
                        *p = Z_STRVAL_PP(arg);
                        return SUCCESS;
@@ -280,7 +280,7 @@ static int parse_arg_object_to_string(zval **arg, char **p, int *pl, int type TS
        /* Standard PHP objects */
        if (Z_OBJ_HT_PP(arg) == &std_object_handlers || !Z_OBJ_HANDLER_PP(arg, cast_object)) {
                SEPARATE_ZVAL_IF_NOT_REF(arg);
-               if (zend_std_cast_object_tostring(*arg, *arg, type TSRMLS_CC) == SUCCESS) {
+               if (zend_std_cast_object_tostring(*arg, *arg, type, NULL TSRMLS_CC) == SUCCESS) {
                        *pl = Z_STRLEN_PP(arg);
                        *p = Z_STRVAL_PP(arg);
                        return SUCCESS;
index 5277a11c65057675a17a6f620e2a63f29124801b..68a52e37607ceb2a51618734c690d3e2f77d4a2b 100644 (file)
@@ -532,7 +532,7 @@ repeat:
                                        goto repeat;
                                } else if (Z_OBJ_HT_PP(val)->cast_object) {
                                        ALLOC_INIT_ZVAL(val_free);
-                                       if (Z_OBJ_HT_PP(val)->cast_object(*val, val_free, UG(unicode)?IS_UNICODE:IS_STRING TSRMLS_CC) == SUCCESS) {
+                                       if (Z_OBJ_HT_PP(val)->cast_object(*val, val_free, UG(unicode)?IS_UNICODE:IS_STRING, NULL TSRMLS_CC) == SUCCESS) {
                                                val = &val_free;
                                                break;
                                        }
index 79e62376fe0d46604782eaf95f256a3a22bd56ca..787467b7614875214768e5a67fe3414e8a4c0ff2 100644 (file)
@@ -118,7 +118,7 @@ static inline int i_zend_is_true(zval *op)
 
                                if (Z_OBJ_HT_P(op)->cast_object) {
                                        zval tmp;
-                                       if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, IS_BOOL TSRMLS_CC) == SUCCESS) {
+                                       if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, IS_BOOL, NULL TSRMLS_CC) == SUCCESS) {
                                                result = Z_LVAL(tmp);
                                                break;
                                        }
index 9314a5a01b170277985d6de95b509bd99e38c7b0..79e64b25428f8a2c563320d690c7355f9655f119 100644 (file)
@@ -1091,14 +1091,20 @@ int zend_std_object_get_class_name(zval *object, zstr *class_name, zend_uint *cl
        return SUCCESS;
 }
 
-ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int type TSRMLS_DC)
+ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int type, void *extra TSRMLS_DC)
 {
        zval *retval;
        zend_class_entry *ce;
+       UConverter *conv;
 
        switch (type) {
                case IS_STRING:
                case IS_UNICODE:
+                       if (extra) {
+                               conv = (UConverter *) extra;
+                       } else {
+                               conv = ZEND_U_CONVERTER(UG(runtime_encoding_conv));
+                       }
                        ce = Z_OBJCE_P(readobj);
                        if (ce->__tostring &&
                 (zend_call_method_with_0_params(&readobj, ce, &ce->__tostring, "__tostring", &retval) || EG(exception))) {
@@ -1113,7 +1119,11 @@ ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int ty
                                        INIT_PZVAL(writeobj);
                                        ZVAL_ZVAL(writeobj, retval, 1, 1);
                                        if (Z_TYPE_P(writeobj) != type) {
-                                               convert_to_explicit_type(writeobj, type);
+                                               if (type == IS_UNICODE) {
+                                                       convert_to_unicode_with_converter(writeobj, conv);
+                                               } else {
+                                                       convert_to_string_with_converter(writeobj, conv);
+                                               }
                                        }
                                        return SUCCESS;
                                } else {
index edea755dde0f5490dff23d6520fa06b068e3ba11..7202da17616a136342c1a92b50c30e485f0407a1 100644 (file)
@@ -100,7 +100,7 @@ typedef int (*zend_object_compare_t)(zval *object1, zval *object2 TSRMLS_DC);
 
 /* Cast an object to some other type
  */
-typedef int (*zend_object_cast_t)(zval *readobj, zval *retval, int type TSRMLS_DC);
+typedef int (*zend_object_cast_t)(zval *readobj, zval *retval, int type, void *extra TSRMLS_DC);
 
 /* updates *count to hold the number of elements present and returns SUCCESS.
  * Returns FAILURE if the object does not have any sense of overloaded dimensions */
@@ -143,7 +143,7 @@ ZEND_API zend_bool zend_std_unset_static_property(zend_class_entry *ce, zend_uch
 ZEND_API union _zend_function *zend_std_get_constructor(zval *object TSRMLS_DC);
 ZEND_API struct _zend_property_info *zend_get_property_info(zend_class_entry *ce, zval *member, int silent TSRMLS_DC);
 
-ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int type TSRMLS_DC);
+ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int type, void *extra TSRMLS_DC);
 
 
 #define IS_ZEND_STD_OBJECT(z)  (Z_TYPE(z) == IS_OBJECT && (Z_OBJ_HT((z))->get_class_entry != NULL))
index 398dddc8dde5674b96b557258de3d1753e8b6746..75617cc8308d9967469ec4e6c82c216de83bcff4 100644 (file)
@@ -320,7 +320,7 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC)
 #define convert_object_to_type(op, ctype, conv_func)                                                                           \
        if (Z_OBJ_HT_P(op)->cast_object) {                                                                                                              \
                zval dst;                                                                                                                                                       \
-               if (Z_OBJ_HT_P(op)->cast_object(op, &dst, ctype TSRMLS_CC) == FAILURE) {                        \
+               if (Z_OBJ_HT_P(op)->cast_object(op, &dst, ctype, NULL TSRMLS_CC) == FAILURE) {          \
                        zend_error(E_RECOVERABLE_ERROR,                                                                                                 \
                        "Object of class %v could not be converted to %s", Z_OBJCE_P(op)->name,                 \
                        zend_get_type_by_const(ctype));                                                                                                 \
@@ -493,7 +493,7 @@ ZEND_API void convert_to_null(zval *op)
 
                        ALLOC_ZVAL(org);
                        *org = *op;
-                       if (Z_OBJ_HT_P(op)->cast_object(org, op, IS_NULL TSRMLS_CC) == SUCCESS) {
+                       if (Z_OBJ_HT_P(op)->cast_object(org, op, IS_NULL, NULL TSRMLS_CC) == SUCCESS) {
                                zval_dtor(org);
                                return;
                        }
@@ -875,7 +875,29 @@ ZEND_API void _convert_to_unicode_with_converter(zval *op, UConverter *conv TSRM
                        Z_USTRLEN_P(op) = sizeof("Array")-1;
                        break;
                case IS_OBJECT: {
-                       convert_object_to_type(op, IS_UNICODE, convert_to_unicode);
+                       if (Z_OBJ_HT_P(op)->cast_object) {
+                               zval dst;
+                               if (Z_OBJ_HT_P(op)->cast_object(op, &dst, IS_UNICODE, conv TSRMLS_CC) == FAILURE) {
+                                       zend_error(E_RECOVERABLE_ERROR,
+                                                          "Object of class %v could not be converted to %s", Z_OBJCE_P(op)->name,
+                                                          zend_get_type_by_const(IS_UNICODE));
+                               } else {
+                                       zval_dtor(op);
+                                       Z_TYPE_P(op) = IS_UNICODE;
+                                       op->value = dst.value;
+                               }
+                       } else {
+                               if(Z_OBJ_HT_P(op)->get) {
+                                       zval *newop = Z_OBJ_HT_P(op)->get(op TSRMLS_CC);
+                                       if(Z_TYPE_P(newop) != IS_OBJECT) {
+                                               /* for safety - avoid loop */
+                                               zval_dtor(op);
+                                               *op = *newop;
+                                               FREE_ZVAL(newop);
+                                               convert_to_string_with_converter(op, conv);
+                                       }
+                               }
+                       }
 
                        if (Z_TYPE_P(op) == IS_UNICODE) {
                                return;
@@ -958,7 +980,29 @@ ZEND_API void _convert_to_string_with_converter(zval *op, UConverter *conv TSRML
                case IS_OBJECT: {
                        TSRMLS_FETCH();
 
-                       convert_object_to_type(op, IS_STRING, convert_to_string);
+                       if (Z_OBJ_HT_P(op)->cast_object) {
+                               zval dst;
+                               if (Z_OBJ_HT_P(op)->cast_object(op, &dst, IS_STRING, conv TSRMLS_CC) == FAILURE) {
+                                       zend_error(E_RECOVERABLE_ERROR,
+                                                          "Object of class %v could not be converted to %s", Z_OBJCE_P(op)->name,
+                                                          zend_get_type_by_const(IS_STRING));
+                               } else {
+                                       zval_dtor(op);
+                                       Z_TYPE_P(op) = IS_STRING;
+                                       op->value = dst.value;
+                               }
+                       } else {
+                               if(Z_OBJ_HT_P(op)->get) {
+                                       zval *newop = Z_OBJ_HT_P(op)->get(op TSRMLS_CC);
+                                       if(Z_TYPE_P(newop) != IS_OBJECT) {
+                                               /* for safety - avoid loop */
+                                               zval_dtor(op);
+                                               *op = *newop;
+                                               FREE_ZVAL(newop);
+                                               convert_to_string_with_converter(op, conv);
+                                       }
+                               }
+                       }
 
                        if (Z_TYPE_P(op) == IS_STRING) {
                                return;
@@ -1775,7 +1819,7 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
                        op1 = op1_free = Z_OBJ_HT_P(op1)->get(op1 TSRMLS_CC);
                } else if (!op2_obj && Z_OBJ_HT_P(op1)->cast_object) {
                        ALLOC_INIT_ZVAL(op1_free);
-                       if (Z_OBJ_HT_P(op1)->cast_object(op1, op1_free, Z_TYPE_P(op2) TSRMLS_CC) == FAILURE) {
+                       if (Z_OBJ_HT_P(op1)->cast_object(op1, op1_free, Z_TYPE_P(op2), NULL TSRMLS_CC) == FAILURE) {
                                op2_free = NULL;
                                ZVAL_LONG(result, 1);
                                COMPARE_RETURN_AND_FREE(SUCCESS);
@@ -1799,7 +1843,7 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
                        op2 = op2_free = Z_OBJ_HT_P(op2)->get(op2 TSRMLS_CC);
                } else if (!op1_obj && Z_OBJ_HT_P(op2)->cast_object) {
                        ALLOC_INIT_ZVAL(op2_free);
-                       if (Z_OBJ_HT_P(op2)->cast_object(op2, op2_free, Z_TYPE_P(op1) TSRMLS_CC) == FAILURE) {
+                       if (Z_OBJ_HT_P(op2)->cast_object(op2, op2_free, Z_TYPE_P(op1), NULL TSRMLS_CC) == FAILURE) {
                                ZVAL_LONG(result, -1);
                                COMPARE_RETURN_AND_FREE(SUCCESS);
                        }
index fde29e500af94c3004f53ec3f4226484a9b082ba..57bbd7452703b8aecf48156ab531219308e6aeac 100644 (file)
@@ -486,7 +486,7 @@ static int com_objects_compare(zval *object1, zval *object2 TSRMLS_DC)
        return ret;
 }
 
-static int com_object_cast(zval *readobj, zval *writeobj, int type TSRMLS_DC)
+static int com_object_cast(zval *readobj, zval *writeobj, int type, void *extra TSRMLS_DC)
 {
        php_com_dotnet_object *obj;
        VARIANT v;
@@ -530,6 +530,7 @@ static int com_object_cast(zval *readobj, zval *writeobj, int type TSRMLS_DC)
        }
 
        if (SUCCEEDED(res)) {
+               /* FIXME use 'extra' here for IS_STRING/IS_UNICODE */
                php_com_zval_from_variant(writeobj, &v, obj->code_page TSRMLS_CC);
        }
 
@@ -539,7 +540,7 @@ static int com_object_cast(zval *readobj, zval *writeobj, int type TSRMLS_DC)
                return SUCCESS;
        }
 
-       return zend_std_cast_object_tostring(readobj, writeobj, type TSRMLS_CC);
+       return zend_std_cast_object_tostring(readobj, writeobj, type, extra TSRMLS_CC);
 }
 
 static int com_object_count(zval *object, long *count TSRMLS_DC)
index 85b39a7fbccfaae5efd8700efe2a56618595538b..909bdef2f358428ae5b6f871228eab14b87821b4 100644 (file)
@@ -1608,8 +1608,18 @@ SXE_METHOD(addAttribute)
 
 /* {{{ cast_object()
  */
-static int cast_object(zval *object, int type, char *contents TSRMLS_DC)
+static int cast_object(zval *object, int type, char *contents, void *extra TSRMLS_DC)
 {
+       UConverter *conv;
+
+       if (type == IS_STRING || type == IS_UNICODE) {
+               if (extra) {
+                       conv = (UConverter *) extra;
+               } else {
+                       conv = ZEND_U_CONVERTER(UG(runtime_encoding_conv));
+               }
+       }
+
        if (contents) {
                ZVAL_XML_STRING(object, contents, ZSTR_DUPLICATE);
        } else {
@@ -1620,10 +1630,10 @@ static int cast_object(zval *object, int type, char *contents TSRMLS_DC)
 
        switch (type) {
                case IS_STRING:
-                       convert_to_string(object);
+                       convert_to_string_with_converter(object, conv);
                        break;
                case IS_UNICODE:
-                       convert_to_unicode(object);
+                       convert_to_unicode_with_converter(object, conv);
                        break;
                case IS_BOOL:
                        convert_to_boolean(object);
@@ -1643,7 +1653,7 @@ static int cast_object(zval *object, int type, char *contents TSRMLS_DC)
 
 /* {{{ sxe_object_cast()
  */
-static int sxe_object_cast(zval *readobj, zval *writeobj, int type TSRMLS_DC)
+static int sxe_object_cast(zval *readobj, zval *writeobj, int type, void *extra TSRMLS_DC)
 {
        php_sxe_object *sxe;
        xmlChar           *contents = NULL;
@@ -1678,7 +1688,7 @@ static int sxe_object_cast(zval *readobj, zval *writeobj, int type TSRMLS_DC)
                }
        }
 
-       rv = cast_object(writeobj, type, (char *)contents TSRMLS_CC);
+       rv = cast_object(writeobj, type, (char *)contents, extra TSRMLS_CC);
 
        if (contents) {
                xmlFree(contents);
@@ -1722,7 +1732,7 @@ static zval *sxe_get_value(zval *z TSRMLS_DC)
 
        MAKE_STD_ZVAL(retval);
 
-       if (sxe_object_cast(z, retval, UG(unicode)?IS_UNICODE:IS_STRING TSRMLS_CC)==FAILURE) {
+       if (sxe_object_cast(z, retval, UG(unicode)?IS_UNICODE:IS_STRING, NULL TSRMLS_CC)==FAILURE) {
                zend_error(E_ERROR, "Unable to cast node to string");
                /* FIXME: Should not be fatal */
        }
index 7b946e0ce001c523fe831f3c6e3ca9fa4ce9abe3..9aac17aacd00805a57981b5dcf22c32cdc976510 100755 (executable)
@@ -1234,7 +1234,7 @@ zend_object_iterator *spl_filesystem_tree_get_iterator(zend_class_entry *ce, zva
 /* }}} */
 
 /* {{{ spl_filesystem_object_cast */
-static int spl_filesystem_object_cast(zval *readobj, zval *writeobj, int type TSRMLS_DC)
+static int spl_filesystem_object_cast(zval *readobj, zval *writeobj, int type, void *extra TSRMLS_DC)
 {
        spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(readobj TSRMLS_CC);
 
index 65a0e3104199a15c86459738c21eca0479867623..a71b9bb4131f434be2ef8b9910548ef998841e8d 100644 (file)
@@ -210,8 +210,8 @@ static zend_object_value tidy_object_new_doc(zend_class_entry * TSRMLS_DC);
 static zend_class_entry *tidy_get_ce_node(zval * TSRMLS_DC);
 static zend_class_entry *tidy_get_ce_doc(zval * TSRMLS_DC);
 static zval * tidy_instanciate(zend_class_entry *, zval * TSRMLS_DC);
-static int tidy_doc_cast_handler(zval *, zval *, int TSRMLS_DC);
-static int tidy_node_cast_handler(zval *, zval *, int TSRMLS_DC);
+static int tidy_doc_cast_handler(zval *, zval *, int, void * TSRMLS_DC);
+static int tidy_node_cast_handler(zval *, zval *, int, void * TSRMLS_DC);
 static void tidy_doc_update_properties(PHPTidyObj * TSRMLS_DC);
 static void tidy_add_default_properties(PHPTidyObj *, tidy_obj_type TSRMLS_DC);
 static void *php_tidy_get_opt_val(PHPTidyDoc *, TidyOption, TidyOptionType * TSRMLS_DC);
@@ -659,7 +659,7 @@ static zval * tidy_instanciate(zend_class_entry *pce, zval *object TSRMLS_DC)
        return object;
 }
 
-static int tidy_doc_cast_handler(zval *in, zval *out, int type TSRMLS_DC)
+static int tidy_doc_cast_handler(zval *in, zval *out, int type, void *extra TSRMLS_DC)
 {
        TidyBuffer output = {0};
        PHPTidyObj *obj;
@@ -691,7 +691,7 @@ static int tidy_doc_cast_handler(zval *in, zval *out, int type TSRMLS_DC)
        return SUCCESS;
 }
 
-static int tidy_node_cast_handler(zval *in, zval *out, int type TSRMLS_DC)
+static int tidy_node_cast_handler(zval *in, zval *out, int type, void *extra TSRMLS_DC)
 {
        TidyBuffer buf = {0};
        PHPTidyObj *obj;