Imlement clone for formatters that support it

# also some test fixes, more to follow
This commit is contained in:
Stanislav Malyshev 2011-01-03 03:58:57 +00:00
parent b059dfa1e7
commit 7d3a0e15f5
12 changed files with 190 additions and 19 deletions

2
NEWS
View File

@ -38,6 +38,8 @@
(Felipe)
. Fixed bug #53612 (Segmentation fault when using cloned several intl
objects). (Gustavo)
. Implemented clone functionality for number, date & message formatters.
(Stas).
- MySQL Improved extension:
. Fixed bug #53503 (mysqli::query returns false after successful LOAD DATA

View File

@ -145,7 +145,9 @@ void collator_register_Collator_class( TSRMLS_D )
memcpy(&Collator_handlers, zend_get_std_object_handlers(),
sizeof Collator_handlers);
Collator_handlers.clone_obj = NULL;
/* Collator has no usable clone semantics - ucol_cloneBinary/ucol_openBinary require binary buffer
for which we don't have the place to keep */
Collator_handlers.clone_obj = NULL;
/* Declare 'Collator' class properties. */
if( !Collator_ce_ptr )

View File

@ -80,6 +80,30 @@ zend_object_value IntlDateFormatter_object_create(zend_class_entry *ce TSRMLS_DC
}
/* }}} */
/* {{{ IntlDateFormatter_object_clone */
zend_object_value IntlDateFormatter_object_clone(zval *object TSRMLS_DC)
{
zend_object_value new_obj_val;
zend_object_handle handle = Z_OBJ_HANDLE_P(object);
IntlDateFormatter_object *dfo, *new_dfo;
DATE_FORMAT_METHOD_FETCH_OBJECT;
new_obj_val = IntlDateFormatter_ce_ptr->create_object(IntlDateFormatter_ce_ptr TSRMLS_CC);
new_dfo = (IntlDateFormatter_object *)zend_object_store_get_object_by_handle(new_obj_val.handle TSRMLS_CC);
/* clone standard parts */
zend_objects_clone_members(&new_dfo->zo, new_obj_val, &dfo->zo, handle TSRMLS_CC);
/* clone formatter object */
DATE_FORMAT_OBJECT(new_dfo) = udat_clone(DATE_FORMAT_OBJECT(dfo), &INTL_DATA_ERROR_CODE(new_dfo));
if(U_FAILURE(INTL_DATA_ERROR_CODE(new_dfo))) {
/* set up error in case error handler is interested */
intl_error_set( NULL, INTL_DATA_ERROR_CODE(new_dfo), "Failed to clone IntlDateFormatter object", 0 TSRMLS_CC );
IntlDateFormatter_object_dtor(new_dfo, new_obj_val.handle TSRMLS_CC); /* free new object */
zend_error(E_ERROR, "Failed to clone IntlDateFormatter object");
}
return new_obj_val;
}
/* }}} */
/*
* 'IntlDateFormatter' class registration structures & functions
*/
@ -164,7 +188,7 @@ void dateformat_register_IntlDateFormatter_class( TSRMLS_D )
memcpy(&IntlDateFormatter_handlers, zend_get_std_object_handlers(),
sizeof IntlDateFormatter_handlers);
IntlDateFormatter_handlers.clone_obj = NULL;
IntlDateFormatter_handlers.clone_obj = IntlDateFormatter_object_clone;
/* Declare 'IntlDateFormatter' class properties. */
if( !IntlDateFormatter_ce_ptr )

View File

@ -54,8 +54,7 @@ void NumberFormatter_object_free( zend_object *object TSRMLS_DC )
/* }}} */
/* {{{ NumberFormatter_object_create */
zend_object_value NumberFormatter_object_create(
zend_class_entry *ce TSRMLS_DC )
zend_object_value NumberFormatter_object_create(zend_class_entry *ce TSRMLS_DC)
{
zend_object_value retval;
NumberFormatter_object* intern;
@ -76,6 +75,30 @@ zend_object_value NumberFormatter_object_create(
}
/* }}} */
/* {{{ NumberFormatter_object_clone */
zend_object_value NumberFormatter_object_clone(zval *object TSRMLS_DC)
{
zend_object_value new_obj_val;
zend_object_handle handle = Z_OBJ_HANDLE_P(object);
NumberFormatter_object *nfo, *new_nfo;
FORMATTER_METHOD_FETCH_OBJECT;
new_obj_val = NumberFormatter_ce_ptr->create_object(NumberFormatter_ce_ptr TSRMLS_CC);
new_nfo = (NumberFormatter_object *)zend_object_store_get_object_by_handle(new_obj_val.handle TSRMLS_CC);
/* clone standard parts */
zend_objects_clone_members(&new_nfo->zo, new_obj_val, &nfo->zo, handle TSRMLS_CC);
/* clone formatter object */
FORMATTER_OBJECT(new_nfo) = unum_clone(FORMATTER_OBJECT(nfo), &INTL_DATA_ERROR_CODE(new_nfo));
if(U_FAILURE(INTL_DATA_ERROR_CODE(new_nfo))) {
/* set up error in case error handler is interested */
intl_error_set( NULL, INTL_DATA_ERROR_CODE(new_nfo), "Failed to clone NumberFormatter object", 0 TSRMLS_CC );
NumberFormatter_object_dtor(new_nfo, new_obj_val.handle TSRMLS_CC); /* free new object */
zend_error(E_ERROR, "Failed to clone NumberFormatter object");
}
return new_obj_val;
}
/* }}} */
/*
* 'NumberFormatter' class registration structures & functions
*/
@ -173,8 +196,8 @@ void formatter_register_class( TSRMLS_D )
NumberFormatter_ce_ptr = zend_register_internal_class( &ce TSRMLS_CC );
memcpy(&NumberFormatter_handlers, zend_get_std_object_handlers(),
sizeof NumberFormatter_handlers);
NumberFormatter_handlers.clone_obj = NULL;
sizeof(NumberFormatter_handlers));
NumberFormatter_handlers.clone_obj = NumberFormatter_object_clone;
/* Declare 'NumberFormatter' class properties. */
if( !NumberFormatter_ce_ptr )

View File

@ -73,6 +73,30 @@ zend_object_value MessageFormatter_object_create(zend_class_entry *ce TSRMLS_DC)
}
/* }}} */
/* {{{ MessageFormatter_object_clone */
zend_object_value MessageFormatter_object_clone(zval *object TSRMLS_DC)
{
zend_object_value new_obj_val;
zend_object_handle handle = Z_OBJ_HANDLE_P(object);
MessageFormatter_object *mfo, *new_mfo;
MSG_FORMAT_METHOD_FETCH_OBJECT;
new_obj_val = MessageFormatter_ce_ptr->create_object(MessageFormatter_ce_ptr TSRMLS_CC);
new_mfo = (MessageFormatter_object *)zend_object_store_get_object_by_handle(new_obj_val.handle TSRMLS_CC);
/* clone standard parts */
zend_objects_clone_members(&new_mfo->zo, new_obj_val, &mfo->zo, handle TSRMLS_CC);
/* clone formatter object */
MSG_FORMAT_OBJECT(new_mfo) = umsg_clone(MSG_FORMAT_OBJECT(mfo), &INTL_DATA_ERROR_CODE(new_mfo));
if(U_FAILURE(INTL_DATA_ERROR_CODE(new_mfo))) {
/* set up error in case error handler is interested */
intl_error_set( NULL, INTL_DATA_ERROR_CODE(new_mfo), "Failed to clone MessageFormatter object", 0 TSRMLS_CC );
MessageFormatter_object_dtor(new_mfo, new_obj_val.handle TSRMLS_CC); /* free new object */
zend_error(E_ERROR, "Failed to clone MessageFormatter object");
}
return new_obj_val;
}
/* }}} */
/*
* 'MessageFormatter' class registration structures & functions
*/
@ -138,7 +162,7 @@ void msgformat_register_class( TSRMLS_D )
memcpy(&MessageFormatter_handlers, zend_get_std_object_handlers(),
sizeof MessageFormatter_handlers);
MessageFormatter_handlers.clone_obj = NULL;
MessageFormatter_handlers.clone_obj = MessageFormatter_object_clone;
/* Declare 'MessageFormatter' class properties. */
if( !MessageFormatter_ce_ptr )

View File

@ -109,7 +109,7 @@ static void resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS)
if (!fallback && (INTL_DATA_ERROR_CODE(rb) == U_USING_FALLBACK_WARNING || INTL_DATA_ERROR_CODE(rb) == U_USING_DEFAULT_WARNING)) {
intl_errors_set_code( NULL, INTL_DATA_ERROR_CODE(rb) TSRMLS_CC );
spprintf( &pbuf, 0, "resourcebundle_ctor: Cannot load libICU resource '%s' without fallback from %s to %s",
bundlename, locale, ures_getLocale( rb->me, &INTL_DATA_ERROR_CODE(rb)) );
bundlename, locale, ures_getLocaleByType( rb->me, ULOC_ACTUAL_LOCALE, &INTL_DATA_ERROR_CODE(rb)) );
intl_errors_set_custom_msg( INTL_DATA_ERROR_P(rb), pbuf, 1 TSRMLS_CC );
efree(pbuf);
zval_dtor( return_value );
@ -187,7 +187,7 @@ static void resourcebundle_array_fetch(zval *object, zval *offset, zval *return_
if (!fallback && (INTL_DATA_ERROR_CODE(rb) == U_USING_FALLBACK_WARNING || INTL_DATA_ERROR_CODE(rb) == U_USING_DEFAULT_WARNING)) {
UErrorCode icuerror;
const char * locale = ures_getLocale( rb->me, &icuerror );
const char * locale = ures_getLocaleByType( rb->me, ULOC_ACTUAL_LOCALE, &icuerror );
if (is_numeric) {
spprintf( &pbuf, 0, "Cannot load element %d without fallback from to %s", meindex, locale );
} else {
@ -420,7 +420,7 @@ void resourcebundle_register_class( TSRMLS_D )
}
ResourceBundle_object_handlers = std_object_handlers;
ResourceBundle_object_handlers.clone_obj = NULL;
ResourceBundle_object_handlers.clone_obj = NULL; /* ICU ResourceBundle has no clone implementation */
ResourceBundle_object_handlers.read_dimension = resourcebundle_array_get;
ResourceBundle_object_handlers.count_elements = resourcebundle_array_count;
}

View File

@ -0,0 +1,36 @@
--TEST--
Cloning datefmt
--SKIPIF--
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
--FILE--
<?php
include_once( 'ut_common.inc' );
$GLOBALS['oo-mode'] = true;
$res_str = '';
/*
* Clone
*/
$start_pattern = 'dd-MM-YY';
$fmt = ut_datefmt_create( "en-US", IntlDateFormatter::FULL, IntlDateFormatter::FULL, 'America/New_York', IntlDateFormatter::GREGORIAN , $start_pattern );
$formatted = ut_datefmt_format($fmt,0);
$res_str .= "\nResult of formatting timestamp=0 is : \n$formatted";
$fmt_clone = clone $fmt;
ut_datefmt_set_pattern( $fmt , 'yyyy-DDD.hh:mm:ss z' );
$formatted = ut_datefmt_format($fmt,0);
$res_str .= "\nResult of formatting timestamp=0 is : \n$formatted";
$formatted = ut_datefmt_format($fmt_clone,0);
$res_str .= "\nResult of clone formatting timestamp=0 is : \n$formatted";
echo $res_str;
?>
--EXPECTF--
Result of formatting timestamp=0 is :
31-12-69
Result of formatting timestamp=0 is :
1969-365.07:00:00 EST
Result of clone formatting timestamp=0 is :
31-12-69

View File

@ -58,12 +58,12 @@ ut_run();
Creating IntlDateFormatter with pattern = dd-MM-YY
After call to get_pattern : pattern= dd-MM-YY
Result of formatting timestamp=0 is :
31-12-70
31-12-69
-------------------
Setting IntlDateFormatter with pattern = DD-MM-YYYY hh:mm:ss
After call to get_pattern : pattern= DD-MM-YYYY hh:mm:ss
Result of formatting timestamp=0 with the new pattern is :
365-12-1970 07:00:00
365-12-1969 07:00:00
-------------------
Setting IntlDateFormatter with pattern = yyyy-DDD.hh:mm:ss z

View File

@ -0,0 +1,30 @@
--TEST--
Cloning numfmt
--SKIPIF--
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
--FILE--
<?php
include_once( 'ut_common.inc' );
$GLOBALS['oo-mode'] = true;
$res_str = '';
/*
* Clone
*/
$test_value = 12345.123456;
$fmt = new NumberFormatter( "en_US", NumberFormatter::PATTERN_DECIMAL );
$res_str .= "Formatted number: " . ut_nfmt_format( $fmt, $test_value ) . "\n";
$fmt_clone = clone $fmt;
$res = $fmt->setPattern("0.0" );
if( $res === false )
$res_str .= ut_nfmt_get_error_message( $fmt ) . " (" . ut_nfmt_get_error_code( $fmt ) . ")\n";
$res_str .= "Formatted number: " . ut_nfmt_format( $fmt, $test_value ) . "\n";
$res_str .= "Formatted(clone) number: " . ut_nfmt_format( $fmt_clone, $test_value ) . "\n";
echo $res_str;
?>
--EXPECTF--
Formatted number: 12345.123456
Formatted number: 12345.1
Formatted(clone) number: 12345.123456

View File

@ -25,7 +25,7 @@ function ut_main()
'FRACTION_DIGITS' => array( NumberFormatter::FRACTION_DIGITS, 5, 12345.123456 ),
'MULTIPLIER' => array( NumberFormatter::MULTIPLIER, 2, 12345.123456 ),
'GROUPING_SIZE' => array( NumberFormatter::GROUPING_SIZE, 2, 12345.123456 ),
'ROUNDING_MODE' => array( NumberFormatter::ROUNDING_MODE, 7, 12345.123456 ),
'ROUNDING_MODE' => array( NumberFormatter::ROUNDING_MODE, 1, 12345.123456 ),
'ROUNDING_INCREMENT' => array( NumberFormatter::ROUNDING_INCREMENT, (float)2, 12345.123456 ),
'FORMAT_WIDTH' => array( NumberFormatter::FORMAT_WIDTH, 27, 12345.123456 ),
'PADDING_POSITION' => array( NumberFormatter::PADDING_POSITION, 21, 12345.123456 ),
@ -155,10 +155,10 @@ New attribute value: 2 ; Format result: '0,01,23,45.12346' ; Parse result: 1234
Attribute ROUNDING_MODE
Old attribute value: 4 ; Format result: '0,012,345.12346' ; Parse result: 12345.12346
Setting attribute: ok
New attribute value: 7 ; Format result: '0,012,345.12346' ; Parse result: 12345.12346
New attribute value: 1 ; Format result: '0,012,345.12345' ; Parse result: 12345.12345
Attribute ROUNDING_INCREMENT
Old attribute value: 0 ; Format result: '0,012,345.12346' ; Parse result: 12345.12346
Old attribute value: 1.0E-5 ; Format result: '0,012,345.12346' ; Parse result: 12345.12346
Setting attribute: ok
New attribute value: 2 ; Format result: '0,012,346.00000' ; Parse result: 12346

View File

@ -0,0 +1,30 @@
--TEST--
Cloning msgfmt
--SKIPIF--
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
--FILE--
<?php
include_once( 'ut_common.inc' );
$GLOBALS['oo-mode'] = true;
$res_str = '';
/*
* Clone
*/
$fmt = ut_msgfmt_create( "en_US", "{0,number} monkeys on {1,number} trees" );
// Get default patten.
$res_str .= "Formatting result: " . ut_msgfmt_format( $fmt, array(123, 456) ) . "\n";
$fmt_clone = clone $fmt;
// Set a new pattern.
$pattern = "{0,number} trees hosting {1,number} monkeys";
$res = ut_msgfmt_set_pattern( $fmt, $pattern );
$res_str .= "Formatting result: " . ut_msgfmt_format( $fmt, array(123, 456) ) . "\n";
$res_str .= "Formatting clone result: " . ut_msgfmt_format( $fmt_clone, array(123, 456) ) . "\n";
echo $res_str;
?>
--EXPECTF--
Formatting result: 123 monkeys on 456 trees
Formatting result: 123 trees hosting 456 monkeys
Formatting clone result: 123 monkeys on 456 trees

View File

@ -30,11 +30,11 @@ function ut_main()
if( $res === false )
$res_str .= ut_msgfmt_get_error_message( $fmt ) . " (" . ut_msgfmt_get_error_code( $fmt ) . ")\n";
$res_str .= "New pattern: '" . ut_msgfmt_get_pattern( $fmt ) . "'\n";
$res_str .= "Formatted number: " . ut_msgfmt_format( $fmt, array(123, 456) ) . "\n";
$res_str .= "Formatted message: " . ut_msgfmt_format( $fmt, array(123, 456) ) . "\n";
ut_msgfmt_set_pattern($fmt, str_repeat($pattern, 10));
$res_str .= "New pattern: '" . ut_msgfmt_get_pattern( $fmt ) . "'\n";
$res_str .= "Formatted number: " . ut_msgfmt_format( $fmt, array(123, 456) ) . "\n";
$res_str .= "Formatted message: " . ut_msgfmt_format( $fmt, array(123, 456) ) . "\n";
return $res_str;
@ -48,6 +48,6 @@ ut_run();
Default pattern: '{0,number} monkeys on {1,number} trees'
Formatting result: 123 monkeys on 456 trees
New pattern: '{0,number} trees hosting {1,number} monkeys'
Formatted number: 123 trees hosting 456 monkeys
Formatted message: 123 trees hosting 456 monkeys
New pattern: '{0,number} trees hosting {1,number} monkeys{0,number} trees hosting {1,number} monkeys{0,number} trees hosting {1,number} monkeys{0,number} trees hosting {1,number} monkeys{0,number} trees hosting {1,number} monkeys{0,number} trees hosting {1,number} monkeys{0,number} trees hosting {1,number} monkeys{0,number} trees hosting {1,number} monkeys{0,number} trees hosting {1,number} monkeys{0,number} trees hosting {1,number} monkeys'
Formatted number: 123 trees hosting 456 monkeys123 trees hosting 456 monkeys123 trees hosting 456 monkeys123 trees hosting 456 monkeys123 trees hosting 456 monkeys123 trees hosting 456 monkeys123 trees hosting 456 monkeys123 trees hosting 456 monkeys123 trees hosting 456 monkeys123 trees hosting 456 monkeys
Formatted message: 123 trees hosting 456 monkeys123 trees hosting 456 monkeys123 trees hosting 456 monkeys123 trees hosting 456 monkeys123 trees hosting 456 monkeys123 trees hosting 456 monkeys123 trees hosting 456 monkeys123 trees hosting 456 monkeys123 trees hosting 456 monkeys123 trees hosting 456 monkeys