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

Reply via email to