Commit: 20dd5ccf19916a290973a2e25de4eed59b169093 Author: Gustavo André dos Santos Lopes <cataphr...@php.net> Sun, 6 May 2012 16:31:52 +0200 Parents: 407455876e486df45a6b6c91b483060b0479a0b3 Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=20dd5ccf19916a290973a2e25de4eed59b169093 Log: Cache arguments type info in MessageFormatter. Changed paths: M ext/intl/msgformat/msgformat_attr.c M ext/intl/msgformat/msgformat_data.c M ext/intl/msgformat/msgformat_data.h M ext/intl/msgformat/msgformat_format.c M ext/intl/msgformat/msgformat_helpers.cpp M ext/intl/msgformat/msgformat_helpers.h A ext/intl/tests/msgfmt_setPattern_cache.phpt Diff: diff --git a/ext/intl/msgformat/msgformat_attr.c b/ext/intl/msgformat/msgformat_attr.c index cf34665..c7a4d1c 100755 --- a/ext/intl/msgformat/msgformat_attr.c +++ b/ext/intl/msgformat/msgformat_attr.c @@ -100,6 +100,12 @@ PHP_FUNCTION( msgfmt_set_pattern ) } mfo->mf_data.orig_format = estrndup(value, value_len); mfo->mf_data.orig_format_len = value_len; + /* invalidate cached format types */ + if (mfo->mf_data.arg_types) { + zend_hash_destroy(mfo->mf_data.arg_types); + efree(mfo->mf_data.arg_types); + mfo->mf_data.arg_types = NULL; + } RETURN_TRUE; } diff --git a/ext/intl/msgformat/msgformat_data.c b/ext/intl/msgformat/msgformat_data.c index 95e81d3..9ed129f 100755 --- a/ext/intl/msgformat/msgformat_data.c +++ b/ext/intl/msgformat/msgformat_data.c @@ -31,6 +31,7 @@ void msgformat_data_init( msgformat_data* mf_data TSRMLS_DC ) mf_data->umsgf = NULL; mf_data->orig_format = NULL; + mf_data->arg_types = NULL; intl_error_reset( &mf_data->error TSRMLS_CC ); } /* }}} */ @@ -38,21 +39,27 @@ void msgformat_data_init( msgformat_data* mf_data TSRMLS_DC ) /* {{{ void msgformat_data_free( msgformat_data* mf_data ) * Clean up memory allocated for msgformat_data */ -void msgformat_data_free( msgformat_data* mf_data TSRMLS_DC ) +void msgformat_data_free(msgformat_data* mf_data TSRMLS_DC) { - if( !mf_data ) + if (!mf_data) return; - if( mf_data->umsgf ) - umsg_close( mf_data->umsgf ); + if (mf_data->umsgf) + umsg_close(mf_data->umsgf); - if(mf_data->orig_format) { + if (mf_data->orig_format) { efree(mf_data->orig_format); mf_data->orig_format = NULL; } + if (mf_data->arg_types) { + zend_hash_destroy(mf_data->arg_types); + efree(mf_data->arg_types); + mf_data->arg_types = NULL; + } + mf_data->umsgf = NULL; - intl_error_reset( &mf_data->error TSRMLS_CC ); + intl_error_reset(&mf_data->error TSRMLS_CC); } /* }}} */ diff --git a/ext/intl/msgformat/msgformat_data.h b/ext/intl/msgformat/msgformat_data.h index 4400175..5a82003 100755 --- a/ext/intl/msgformat/msgformat_data.h +++ b/ext/intl/msgformat/msgformat_data.h @@ -31,6 +31,7 @@ typedef struct { UMessageFormat* umsgf; char* orig_format; ulong orig_format_len; + HashTable* arg_types; } msgformat_data; msgformat_data* msgformat_data_create( TSRMLS_D ); diff --git a/ext/intl/msgformat/msgformat_format.c b/ext/intl/msgformat/msgformat_format.c index 099dbcb..412a5f7 100755 --- a/ext/intl/msgformat/msgformat_format.c +++ b/ext/intl/msgformat/msgformat_format.c @@ -57,7 +57,7 @@ static void msgfmt_do_format(MessageFormatter_object *mfo, zval *args, zval *ret zend_hash_copy(args_copy, Z_ARRVAL_P(args), (copy_ctor_func_t)zval_add_ref, NULL, sizeof(zval*)); - umsg_format_helper(MSG_FORMAT_OBJECT(mfo), args_copy, + umsg_format_helper(mfo, args_copy, &formatted, &formatted_len, &INTL_DATA_ERROR_CODE(mfo) TSRMLS_CC); zend_hash_destroy(args_copy); diff --git a/ext/intl/msgformat/msgformat_helpers.cpp b/ext/intl/msgformat/msgformat_helpers.cpp index 503dca9..1a7dc89 100755 --- a/ext/intl/msgformat/msgformat_helpers.cpp +++ b/ext/intl/msgformat/msgformat_helpers.cpp @@ -100,7 +100,9 @@ double umsg_helper_zval_to_millis(zval *z, UErrorCode *status TSRMLS_DC) { return rv; } -static HashTable *umsg_parse_format(const MessagePattern& mp, UErrorCode& uec) +static HashTable *umsg_parse_format(MessageFormatter_object *mfo, + const MessagePattern& mp, + UErrorCode& uec) { HashTable *ret; int32_t parts_count; @@ -109,6 +111,11 @@ static HashTable *umsg_parse_format(const MessagePattern& mp, UErrorCode& uec) return NULL; } + if (mfo->mf_data.arg_types) { + /* already cached */ + return mfo->mf_data.arg_types; + } + /* Hash table will store Formattable::Type objects directly, * so no need for destructor */ ALLOC_HASHTABLE(ret); @@ -235,22 +242,24 @@ static HashTable *umsg_parse_format(const MessagePattern& mp, UErrorCode& uec) return NULL; } + mfo->mf_data.arg_types = ret; + return ret; } -U_CFUNC void umsg_format_helper(UMessageFormat *fmt, HashTable *args, UChar **formatted, int *formatted_len, UErrorCode *status TSRMLS_DC) +U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, HashTable *args, UChar **formatted, int *formatted_len, UErrorCode *status TSRMLS_DC) { int arg_count = zend_hash_num_elements(args); std::vector<Formattable> fargs; std::vector<UnicodeString> farg_names; - MessageFormat *mf = (MessageFormat *) fmt; + MessageFormat *mf = (MessageFormat *)mfo->mf_data.umsgf; const MessagePattern mp = MessageFormatAdapter::getMessagePattern(mf); HashTable *types; fargs.resize(arg_count); farg_names.resize(arg_count); - types = umsg_parse_format(mp, *status); + types = umsg_parse_format(mfo, mp, *status); if (U_FAILURE(*status)) { return; } @@ -391,9 +400,6 @@ string_arg: //XXX: make function } } // visiting each argument - zend_hash_destroy(types); - efree(types); - if (U_FAILURE(*status)){ return; } diff --git a/ext/intl/msgformat/msgformat_helpers.h b/ext/intl/msgformat/msgformat_helpers.h index 4e10471..7a04248 100755 --- a/ext/intl/msgformat/msgformat_helpers.h +++ b/ext/intl/msgformat/msgformat_helpers.h @@ -18,7 +18,7 @@ #define MSG_FORMAT_HELPERS_H int32_t umsg_format_arg_count(UMessageFormat *fmt); -void umsg_format_helper(UMessageFormat *fmt, HashTable *args, +void umsg_format_helper(MessageFormatter_object *mfo, HashTable *args, UChar **formatted, int *formatted_len, UErrorCode *status TSRMLS_DC); void umsg_parse_helper(UMessageFormat *fmt, int *count, zval ***args, UChar *source, int source_len, UErrorCode *status); diff --git a/ext/intl/tests/msgfmt_setPattern_cache.phpt b/ext/intl/tests/msgfmt_setPattern_cache.phpt new file mode 100644 index 0000000..35ec463 --- /dev/null +++ b/ext/intl/tests/msgfmt_setPattern_cache.phpt @@ -0,0 +1,26 @@ +--TEST-- +MessageFormatter::setPattern() invalidates arg types cache +--SKIPIF-- +<?php +if (!extension_loaded('intl')) + die('skip intl extension not enabled'); +--FILE-- +<?php +ini_set("intl.error_level", E_WARNING); +//ini_set("intl.default_locale", "nl"); + +$mf = new MessageFormatter('en_US', + "{0,number} -- {1,ordinal}"); + +var_dump($mf->format(array(1.3, 1.3))); +var_dump($mf->format(array(1.3, 1.3))); +$mf->setPattern("{0,ordinal} -- {1,number}"); +var_dump($mf->format(array(1.3, 1.3))); + +?> +==DONE== +--EXPECT-- +string(10) "1.3 -- 1st" +string(10) "1.3 -- 1st" +string(10) "1st -- 1.3" +==DONE== \ No newline at end of file -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php