Annotation of embedaddon/php/ext/intl/msgformat/msgformat_format.c, revision 1.1.1.2
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:
1.1.1.2 ! misho 157: #ifdef MSG_FORMAT_QUOTE_APOS
1.1 misho 158: if(msgformat_fix_quotes(&spattern, &spattern_len, &INTL_DATA_ERROR_CODE(mfo)) != SUCCESS) {
159: intl_error_set( NULL, U_INVALID_FORMAT_ERROR,
160: "msgfmt_format_message: error converting pattern to quote-friendly format", 0 TSRMLS_CC );
161: RETURN_FALSE;
162: }
1.1.1.2 ! misho 163: #endif
1.1 misho 164:
165: /* Create an ICU message formatter. */
166: MSG_FORMAT_OBJECT(mfo) = umsg_open(spattern, spattern_len, slocale, NULL, &INTL_DATA_ERROR_CODE(mfo));
167: if(spattern && spattern_len) {
168: efree(spattern);
169: }
170: INTL_METHOD_CHECK_STATUS(mfo, "Creating message formatter failed");
171:
172: msgfmt_do_format(mfo, args, return_value TSRMLS_CC);
173:
174: /* drop the temporary formatter */
175: msgformat_data_free(&mfo->mf_data TSRMLS_CC);
176: }
177: /* }}} */
178:
179: /*
180: * Local variables:
181: * tab-width: 4
182: * c-basic-offset: 4
183: * End:
184: * vim600: noet sw=4 ts=4 fdm=marker
185: * vim<600: noet sw=4 ts=4
186: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>