/* {{{ clone handler for Transliterator */ static zend_object *Transliterator_clone_obj( zval *object ) { Transliterator_object *to_orig, *to_new; zend_object *ret_val; intl_error_reset( NULL ); to_orig = Z_INTL_TRANSLITERATOR_P( object ); intl_error_reset( INTL_DATA_ERROR_P( to_orig ) ); ret_val = Transliterator_ce_ptr->create_object( Z_OBJCE_P( object ) ); to_new = php_intl_transliterator_fetch_object( ret_val ); zend_objects_clone_members( &to_new->zo, &to_orig->zo ); if( to_orig->utrans != NULL ) { zval tempz; /* dummy zval to pass to transliterator_object_construct */ /* guaranteed to return NULL if it fails */ UTransliterator *utrans = utrans_clone( to_orig->utrans, TRANSLITERATOR_ERROR_CODE_P( to_orig ) ); if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to_orig ) ) ) goto err; ZVAL_OBJ(&tempz, ret_val); transliterator_object_construct( &tempz, utrans, TRANSLITERATOR_ERROR_CODE_P( to_orig ) ); if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to_orig ) ) ) { zend_string *err_msg; err: if( utrans != NULL ) transliterator_object_destroy( to_new ); /* set the error anyway, in case in the future we decide not to * throw an error. It also helps build the error message */ intl_error_set_code( NULL, INTL_DATA_ERROR_CODE( to_orig ) ); intl_errors_set_custom_msg( TRANSLITERATOR_ERROR_P( to_orig ), "Could not clone transliterator", 0 ); err_msg = intl_error_get_message( TRANSLITERATOR_ERROR_P( to_orig ) ); zend_throw_error( NULL, "%s", ZSTR_VAL(err_msg) ); zend_string_free( err_msg ); /* if it's changed into a warning */ /* do not destroy tempz; we need to return something */ } } else { /* We shouldn't have unconstructed objects in the first place */ php_error_docref( NULL, E_WARNING, "Cloning unconstructed transliterator." ); } return ret_val; }
static int create_transliterator( char *str_id, int str_id_len, zend_long direction, zval *object ) { Transliterator_object *to; UChar *ustr_id = NULL; int32_t ustr_id_len = 0; UTransliterator *utrans; UParseError parse_error = {0, -1}; intl_error_reset( NULL ); if( ( direction != TRANSLITERATOR_FORWARD ) && (direction != TRANSLITERATOR_REVERSE ) ) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "transliterator_create: invalid direction", 0 ); return FAILURE; } object_init_ex( object, Transliterator_ce_ptr ); TRANSLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK; /* fetch zend object from zval "object" into "to" */ /* Convert transliterator id to UTF-16 */ intl_convert_utf8_to_utf16( &ustr_id, &ustr_id_len, str_id, str_id_len, TRANSLITERATOR_ERROR_CODE_P( to ) ); if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to ) ) ) { intl_error_set_code( NULL, TRANSLITERATOR_ERROR_CODE( to ) ); intl_error_set_custom_msg( NULL, "String conversion of id to UTF-16 failed", 0 ); zval_dtor( object ); return FAILURE; } /* Open ICU Transliterator. */ utrans = utrans_openU( ustr_id, ustr_id_len, (UTransDirection ) direction, NULL, -1, &parse_error, TRANSLITERATOR_ERROR_CODE_P( to ) ); if (ustr_id) { efree( ustr_id ); } if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to ) ) ) { char *buf = NULL; intl_error_set_code( NULL, TRANSLITERATOR_ERROR_CODE( to ) ); spprintf( &buf, 0, "transliterator_create: unable to open ICU transliterator" " with id \"%s\"", str_id ); if( buf == NULL ) { intl_error_set_custom_msg( NULL, "transliterator_create: unable to open ICU transliterator", 0 ); } else { intl_error_set_custom_msg( NULL, buf, /* copy message */ 1 ); efree( buf ); } zval_dtor( object ); return FAILURE; } transliterator_object_construct( object, utrans, TRANSLITERATOR_ERROR_CODE_P( to ) ); /* no need to close the transliterator manually on construction error */ if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to ) ) ) { intl_error_set_code( NULL, TRANSLITERATOR_ERROR_CODE( to ) ); intl_error_set_custom_msg( NULL, "transliterator_create: internal constructor call failed", 0 ); zval_dtor( object ); return FAILURE; } return SUCCESS; }