various types as needed.
- Use that parameter to pass a specific converter for
IS_UNICODE/IS_STRING types.
{
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)) {
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)) {
}
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)) {
{
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;
/* 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;
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;
}
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;
}
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))) {
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 {
/* 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 */
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))
#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)); \
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;
}
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;
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;
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);
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);
}
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;
}
if (SUCCEEDED(res)) {
+ /* FIXME use 'extra' here for IS_STRING/IS_UNICODE */
php_com_zval_from_variant(writeobj, &v, obj->code_page TSRMLS_CC);
}
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)
/* {{{ 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 {
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);
/* {{{ 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;
}
}
- rv = cast_object(writeobj, type, (char *)contents TSRMLS_CC);
+ rv = cast_object(writeobj, type, (char *)contents, extra TSRMLS_CC);
if (contents) {
xmlFree(contents);
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 */
}
/* }}} */
/* {{{ 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);
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);
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;
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;