}
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;
}
mf_data->umsgf = NULL;
mf_data->orig_format = NULL;
+ mf_data->arg_types = NULL;
intl_error_reset( &mf_data->error TSRMLS_CC );
}
/* }}} */
/* {{{ 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);
}
/* }}} */
UMessageFormat* umsgf;
char* orig_format;
ulong orig_format_len;
+ HashTable* arg_types;
} msgformat_data;
msgformat_data* msgformat_data_create( TSRMLS_D );
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);
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;
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);
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;
}
}
} // visiting each argument
- zend_hash_destroy(types);
- efree(types);
-
if (U_FAILURE(*status)){
return;
}
#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);
--- /dev/null
+--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