Annotation of embedaddon/php/ext/intl/msgformat/msgformat_format.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
                      5:    | This source file is subject to version 3.01 of the PHP license,      |
                      6:    | that is bundled with this package in the file LICENSE, and is        |
                      7:    | available through the world-wide-web at the following url:           |
                      8:    | http://www.php.net/license/3_01.txt                                  |
                      9:    | If you did not receive a copy of the PHP license and are unable to   |
                     10:    | obtain it through the world-wide-web, please send a note to          |
                     11:    | license@php.net so we can mail you a copy immediately.               |
                     12:    +----------------------------------------------------------------------+
                     13:    | Authors: Stanislav Malyshev <stas@zend.com>                          |
                     14:    +----------------------------------------------------------------------+
                     15:  */
                     16: 
                     17: #ifdef HAVE_CONFIG_H
                     18: #include "config.h"
                     19: #endif
                     20: 
                     21: #include <unicode/ustring.h>
                     22: 
                     23: #include "php_intl.h"
                     24: #include "msgformat_class.h"
                     25: #include "msgformat_format.h"
                     26: #include "msgformat_data.h"
                     27: #include "msgformat_helpers.h"
                     28: #include "intl_convert.h"
                     29: 
                     30: #ifndef Z_ADDREF_P
                     31: #define Z_ADDREF_P(z) ((z)->refcount++)
                     32: #endif
                     33: 
                     34: /* {{{ */
                     35: static void msgfmt_do_format(MessageFormatter_object *mfo, zval *args, zval *return_value TSRMLS_DC) 
                     36: {
                     37:        zval **fargs;
                     38:        int count;
                     39:        UChar* formatted = NULL;
                     40:        int formatted_len = 0;
                     41:        HashPosition pos;
                     42:        int i;
                     43: 
                     44:        count = zend_hash_num_elements(Z_ARRVAL_P(args));
                     45: 
                     46:        if(count < umsg_format_arg_count(MSG_FORMAT_OBJECT(mfo))) {
                     47:                /* Not enough aguments for format! */
                     48:                intl_error_set( INTL_DATA_ERROR_P(mfo), U_ILLEGAL_ARGUMENT_ERROR,
                     49:                        "msgfmt_format: not enough parameters", 0 TSRMLS_CC );
                     50:                RETVAL_FALSE;
                     51:                return;
                     52:        }
                     53: 
                     54:        fargs = safe_emalloc(count, sizeof(zval *), 0);
                     55: 
                     56:        zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(args), &pos);
                     57:        for(i=0;i<count;i++) {
                     58:                zval **val;
                     59:                zend_hash_get_current_data_ex(Z_ARRVAL_P(args), (void **)&val, &pos);
                     60:                fargs[i] = *val;
                     61:                Z_ADDREF_P(fargs[i]);
                     62:                /* TODO: needs refcount increase here? */
                     63:                zend_hash_move_forward_ex(Z_ARRVAL_P(args), &pos);
                     64:        }
                     65: 
                     66:        umsg_format_helper(MSG_FORMAT_OBJECT(mfo), count, fargs, &formatted, &formatted_len, &INTL_DATA_ERROR_CODE(mfo) TSRMLS_CC);
                     67: 
                     68:        for(i=0;i<count;i++) {
                     69:                zval_ptr_dtor(&fargs[i]);
                     70:        }
                     71: 
                     72:        efree(fargs);
                     73: 
                     74:        if (formatted && U_FAILURE( INTL_DATA_ERROR_CODE(mfo) ) ) {
                     75:                        efree(formatted);
                     76:        }
                     77: 
                     78:        INTL_METHOD_CHECK_STATUS( mfo, "Number formatting failed" );
                     79:        INTL_METHOD_RETVAL_UTF8( mfo, formatted, formatted_len, 1 );
                     80: }
                     81: /* }}} */
                     82: 
                     83: /* {{{ proto mixed MessageFormatter::format( array $args )
                     84:  * Format a message. }}} */
                     85: /* {{{ proto mixed msgfmt_format( MessageFormatter $nf, array $args )
                     86:  * Format a message.
                     87:  */
                     88: PHP_FUNCTION( msgfmt_format )
                     89: {
                     90:        zval *args;
                     91:        MSG_FORMAT_METHOD_INIT_VARS;
                     92: 
                     93: 
                     94:        /* Parse parameters. */
                     95:        if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oa",
                     96:                &object, MessageFormatter_ce_ptr,  &args ) == FAILURE )
                     97:        {
                     98:                intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
                     99:                        "msgfmt_format: unable to parse input params", 0 TSRMLS_CC );
                    100: 
                    101:                RETURN_FALSE;
                    102:        }
                    103: 
                    104:        /* Fetch the object. */
                    105:        MSG_FORMAT_METHOD_FETCH_OBJECT;
                    106: 
                    107:        msgfmt_do_format(mfo, args, return_value TSRMLS_CC);
                    108: }
                    109: /* }}} */
                    110: 
                    111: /* {{{ proto mixed MessageFormatter::formatMessage( string $locale, string $pattern, array $args )
                    112:  * Format a message. }}} */
                    113: /* {{{ proto mixed msgfmt_format_message( string $locale, string $pattern, array $args )
                    114:  * Format a message.
                    115:  */
                    116: PHP_FUNCTION( msgfmt_format_message )
                    117: {
                    118:        zval       *args;
                    119:        UChar      *spattern = NULL;
                    120:        int         spattern_len = 0;
                    121:        char       *pattern = NULL;
                    122:        int         pattern_len = 0;
                    123:        char       *slocale = NULL;
                    124:        int         slocale_len = 0;
                    125:        MessageFormatter_object mf = {0};
                    126:        MessageFormatter_object *mfo = &mf;
                    127: 
                    128:        /* Parse parameters. */
                    129:        if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "ssa",
                    130:                  &slocale, &slocale_len, &pattern, &pattern_len, &args ) == FAILURE )
                    131:        {
                    132:                intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
                    133:                        "msgfmt_format_message: unable to parse input params", 0 TSRMLS_CC );
                    134: 
                    135:                RETURN_FALSE;
                    136:        }
                    137: 
                    138:        msgformat_data_init(&mfo->mf_data TSRMLS_CC);
                    139: 
                    140:        if(pattern && pattern_len) {
                    141:                intl_convert_utf8_to_utf16(&spattern, &spattern_len, pattern, pattern_len, &INTL_DATA_ERROR_CODE(mfo));
                    142:                if( U_FAILURE(INTL_DATA_ERROR_CODE((mfo))) )
                    143:                {
                    144:                        intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
                    145:                                "msgfmt_format_message: error converting pattern to UTF-16", 0 TSRMLS_CC );
                    146:                        RETURN_FALSE;
                    147:                }
                    148:        } else {
                    149:                spattern_len = 0;
                    150:                spattern = NULL;
                    151:        }
                    152: 
                    153:        if(slocale_len == 0) {
                    154:                slocale = INTL_G(default_locale);
                    155:        }
                    156: 
                    157:        if(msgformat_fix_quotes(&spattern, &spattern_len, &INTL_DATA_ERROR_CODE(mfo)) != SUCCESS) {
                    158:                intl_error_set( NULL, U_INVALID_FORMAT_ERROR,
                    159:                        "msgfmt_format_message: error converting pattern to quote-friendly format", 0 TSRMLS_CC );
                    160:                RETURN_FALSE;
                    161:        }
                    162: 
                    163:        /* Create an ICU message formatter. */
                    164:        MSG_FORMAT_OBJECT(mfo) = umsg_open(spattern, spattern_len, slocale, NULL, &INTL_DATA_ERROR_CODE(mfo));
                    165:        if(spattern && spattern_len) {
                    166:                efree(spattern);
                    167:        }
                    168:        INTL_METHOD_CHECK_STATUS(mfo, "Creating message formatter failed");
                    169: 
                    170:        msgfmt_do_format(mfo, args, return_value TSRMLS_CC);
                    171: 
                    172:        /* drop the temporary formatter */
                    173:        msgformat_data_free(&mfo->mf_data TSRMLS_CC);
                    174: }
                    175: /* }}} */
                    176: 
                    177: /*
                    178:  * Local variables:
                    179:  * tab-width: 4
                    180:  * c-basic-offset: 4
                    181:  * End:
                    182:  * vim600: noet sw=4 ts=4 fdm=marker
                    183:  * vim<600: noet sw=4 ts=4
                    184:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>