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 "php_intl.h"
22 : #include "formatter_class.h"
23 : #include "formatter_attr.h"
24 : #include "intl_convert.h"
25 :
26 : #include <unicode/ustring.h>
27 :
28 : /* {{{ proto mixed NumberFormatter::getAttribute( int $attr )
29 : * Get formatter attribute value. }}} */
30 : /* {{{ proto mixed numfmt_get_attribute( NumberFormatter $nf, int $attr )
31 : * Get formatter attribute value.
32 : */
33 : PHP_FUNCTION( numfmt_get_attribute )
34 76 : {
35 : long attribute, value;
36 76 : FORMATTER_METHOD_INIT_VARS;
37 :
38 : /* Parse parameters. */
39 76 : if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol",
40 : &object, NumberFormatter_ce_ptr, &attribute ) == FAILURE )
41 : {
42 0 : intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
43 : "numfmt_get_attribute: unable to parse input params", 0 TSRMLS_CC );
44 :
45 0 : RETURN_FALSE;
46 : }
47 :
48 : /* Fetch the object. */
49 76 : FORMATTER_METHOD_FETCH_OBJECT;
50 :
51 76 : switch(attribute) {
52 : case UNUM_PARSE_INT_ONLY:
53 : case UNUM_GROUPING_USED:
54 : case UNUM_DECIMAL_ALWAYS_SHOWN:
55 : case UNUM_MAX_INTEGER_DIGITS:
56 : case UNUM_MIN_INTEGER_DIGITS:
57 : case UNUM_INTEGER_DIGITS:
58 : case UNUM_MAX_FRACTION_DIGITS:
59 : case UNUM_MIN_FRACTION_DIGITS:
60 : case UNUM_FRACTION_DIGITS:
61 : case UNUM_MULTIPLIER:
62 : case UNUM_GROUPING_SIZE:
63 : case UNUM_ROUNDING_MODE:
64 : case UNUM_FORMAT_WIDTH:
65 : case UNUM_PADDING_POSITION:
66 : case UNUM_SECONDARY_GROUPING_SIZE:
67 : case UNUM_SIGNIFICANT_DIGITS_USED:
68 : case UNUM_MIN_SIGNIFICANT_DIGITS:
69 : case UNUM_MAX_SIGNIFICANT_DIGITS:
70 : case UNUM_LENIENT_PARSE:
71 72 : value = unum_getAttribute(FORMATTER_OBJECT(nfo), attribute);
72 72 : if(value == -1) {
73 0 : INTL_DATA_ERROR_CODE(nfo) = U_UNSUPPORTED_ERROR;
74 : } else {
75 72 : RETVAL_LONG(value);
76 : }
77 72 : break;
78 : case UNUM_ROUNDING_INCREMENT:
79 : {
80 4 : double value = unum_getDoubleAttribute(FORMATTER_OBJECT(nfo), attribute);
81 4 : if(value == -1) {
82 0 : INTL_DATA_ERROR_CODE(nfo) = U_UNSUPPORTED_ERROR;
83 : } else {
84 4 : RETVAL_DOUBLE(value);
85 : }
86 : }
87 4 : break;
88 : default:
89 0 : INTL_DATA_ERROR_CODE(nfo) = U_UNSUPPORTED_ERROR;
90 : break;
91 : }
92 :
93 76 : INTL_METHOD_CHECK_STATUS( nfo, "Error getting attribute value" );
94 : }
95 : /* }}} */
96 :
97 : /* {{{ proto string NumberFormatter::getTextAttribute( int $attr )
98 : * Get formatter attribute value. }}} */
99 : /* {{{ proto string numfmt_get_text_attribute( NumberFormatter $nf, int $attr )
100 : * Get formatter attribute value.
101 : */
102 : PHP_FUNCTION( numfmt_get_text_attribute )
103 26 : {
104 : long attribute;
105 : UChar value_buf[64];
106 26 : int value_buf_size = USIZE( value_buf );
107 26 : UChar* value = value_buf;
108 26 : int length = 0;
109 26 : FORMATTER_METHOD_INIT_VARS;
110 :
111 : /* Parse parameters. */
112 26 : if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol",
113 : &object, NumberFormatter_ce_ptr, &attribute ) == FAILURE )
114 : {
115 0 : intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
116 : "numfmt_get_text_attribute: unable to parse input params", 0 TSRMLS_CC );
117 :
118 0 : RETURN_FALSE;
119 : }
120 :
121 : /* Fetch the object. */
122 26 : FORMATTER_METHOD_FETCH_OBJECT;
123 :
124 26 : length = unum_getTextAttribute( FORMATTER_OBJECT(nfo), attribute, value, value_buf_size, &INTL_DATA_ERROR_CODE(nfo) );
125 26 : if(INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR && length >= value_buf_size) {
126 2 : ++length; /* to avoid U_STRING_NOT_TERMINATED_WARNING */
127 2 : INTL_DATA_ERROR_CODE(nfo) = U_ZERO_ERROR;
128 2 : value = eumalloc(length);
129 2 : length = unum_getTextAttribute( FORMATTER_OBJECT(nfo), attribute, value, length, &INTL_DATA_ERROR_CODE(nfo) );
130 2 : if(U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) {
131 0 : efree(value);
132 0 : value = value_buf;
133 : }
134 : }
135 26 : INTL_METHOD_CHECK_STATUS( nfo, "Error getting attribute value" );
136 :
137 26 : INTL_METHOD_RETVAL_UTF8( nfo, value, length, ( value != value_buf ) );
138 : }
139 : /* }}} */
140 :
141 : /* {{{ proto bool NumberFormatter::setAttribute( int $attr, mixed $value )
142 : * Get formatter attribute value. }}} */
143 : /* {{{ proto bool numfmt_set_attribute( NumberFormatter $nf, int $attr, mixed $value )
144 : * Get formatter attribute value.
145 : */
146 : PHP_FUNCTION( numfmt_set_attribute )
147 72 : {
148 : long attribute;
149 : zval **value;
150 72 : FORMATTER_METHOD_INIT_VARS;
151 :
152 : /* Parse parameters. */
153 72 : if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OlZ",
154 : &object, NumberFormatter_ce_ptr, &attribute, &value ) == FAILURE)
155 : {
156 0 : intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
157 : "numfmt_set_attribute: unable to parse input params", 0 TSRMLS_CC );
158 :
159 0 : RETURN_FALSE;
160 : }
161 :
162 : /* Fetch the object. */
163 72 : FORMATTER_METHOD_FETCH_OBJECT;
164 :
165 72 : switch(attribute) {
166 : case UNUM_PARSE_INT_ONLY:
167 : case UNUM_GROUPING_USED:
168 : case UNUM_DECIMAL_ALWAYS_SHOWN:
169 : case UNUM_MAX_INTEGER_DIGITS:
170 : case UNUM_MIN_INTEGER_DIGITS:
171 : case UNUM_INTEGER_DIGITS:
172 : case UNUM_MAX_FRACTION_DIGITS:
173 : case UNUM_MIN_FRACTION_DIGITS:
174 : case UNUM_FRACTION_DIGITS:
175 : case UNUM_MULTIPLIER:
176 : case UNUM_GROUPING_SIZE:
177 : case UNUM_ROUNDING_MODE:
178 : case UNUM_FORMAT_WIDTH:
179 : case UNUM_PADDING_POSITION:
180 : case UNUM_SECONDARY_GROUPING_SIZE:
181 : case UNUM_SIGNIFICANT_DIGITS_USED:
182 : case UNUM_MIN_SIGNIFICANT_DIGITS:
183 : case UNUM_MAX_SIGNIFICANT_DIGITS:
184 : case UNUM_LENIENT_PARSE:
185 68 : convert_to_long_ex(value);
186 68 : unum_setAttribute(FORMATTER_OBJECT(nfo), attribute, Z_LVAL_PP(value));
187 68 : break;
188 : case UNUM_ROUNDING_INCREMENT:
189 4 : convert_to_double_ex(value);
190 4 : unum_setDoubleAttribute(FORMATTER_OBJECT(nfo), attribute, Z_DVAL_PP(value));
191 4 : break;
192 : default:
193 0 : INTL_DATA_ERROR_CODE(nfo) = U_UNSUPPORTED_ERROR;
194 : break;
195 : }
196 :
197 72 : INTL_METHOD_CHECK_STATUS( nfo, "Error setting attribute value" );
198 :
199 72 : RETURN_TRUE;
200 : }
201 : /* }}} */
202 :
203 : /* {{{ proto bool NumberFormatter::setTextAttribute( int $attr, string $value )
204 : * Get formatter attribute value. }}} */
205 : /* {{{ proto bool numfmt_set_text_attribute( NumberFormatter $nf, int $attr, string $value )
206 : * Get formatter attribute value.
207 : */
208 : PHP_FUNCTION( numfmt_set_text_attribute )
209 24 : {
210 24 : int slength = 0;
211 24 : UChar *svalue = NULL;
212 : long attribute;
213 : char *value;
214 : int len;
215 24 : FORMATTER_METHOD_INIT_VARS;
216 :
217 : /* Parse parameters. */
218 24 : if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ols",
219 : &object, NumberFormatter_ce_ptr, &attribute, &value, &len ) == FAILURE)
220 : {
221 0 : intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
222 : "numfmt_set_text_attribute: unable to parse input params", 0 TSRMLS_CC );
223 :
224 0 : RETURN_FALSE;
225 : }
226 :
227 : /* Fetch the object. */
228 24 : FORMATTER_METHOD_FETCH_OBJECT;
229 :
230 : /* Convert given attribute value to UTF-16. */
231 24 : intl_convert_utf8_to_utf16(&svalue, &slength, value, len, &INTL_DATA_ERROR_CODE(nfo));
232 24 : INTL_METHOD_CHECK_STATUS( nfo, "Error converting attribute value to UTF-16" );
233 :
234 : /* Actually set new attribute value. */
235 24 : unum_setTextAttribute(FORMATTER_OBJECT(nfo), attribute, svalue, slength, &INTL_DATA_ERROR_CODE(nfo));
236 24 : efree(svalue);
237 24 : INTL_METHOD_CHECK_STATUS( nfo, "Error setting text attribute" );
238 :
239 24 : RETURN_TRUE;
240 : }
241 : /* }}} */
242 :
243 : /* {{{ proto string NumberFormatter::getSymbol( int $attr )
244 : * Get formatter symbol value. }}} */
245 : /* {{{ proto string numfmt_get_symbol( NumberFormatter $nf, int $attr )
246 : * Get formatter symbol value.
247 : */
248 : PHP_FUNCTION( numfmt_get_symbol )
249 80 : {
250 : long symbol;
251 : UChar value_buf[4];
252 80 : UChar *value = value_buf;
253 80 : int length = USIZE(value);
254 80 : FORMATTER_METHOD_INIT_VARS;
255 :
256 : /* Parse parameters. */
257 80 : if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol",
258 : &object, NumberFormatter_ce_ptr, &symbol ) == FAILURE )
259 : {
260 0 : intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
261 : "numfmt_get_symbol: unable to parse input params", 0 TSRMLS_CC );
262 :
263 0 : RETURN_FALSE;
264 : }
265 :
266 : /* Fetch the object. */
267 80 : FORMATTER_METHOD_FETCH_OBJECT;
268 :
269 80 : length = unum_getSymbol(FORMATTER_OBJECT(nfo), symbol, value_buf, length, &INTL_DATA_ERROR_CODE(nfo));
270 80 : if(INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR && length >= USIZE( value )) {
271 44 : ++length; /* to avoid U_STRING_NOT_TERMINATED_WARNING */
272 44 : INTL_DATA_ERROR_CODE(nfo) = U_ZERO_ERROR;
273 44 : value = eumalloc(length);
274 44 : length = unum_getSymbol(FORMATTER_OBJECT(nfo), symbol, value, length, &INTL_DATA_ERROR_CODE(nfo));
275 44 : if(U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) {
276 0 : efree(value);
277 0 : value = value_buf;
278 : }
279 : }
280 80 : INTL_METHOD_CHECK_STATUS( nfo, "Error getting symbol value" );
281 :
282 80 : INTL_METHOD_RETVAL_UTF8( nfo, value, length, ( value_buf != value ) );
283 : }
284 : /* }}} */
285 :
286 : /* {{{ proto bool NumberFormatter::setSymbol( int $attr, string $symbol )
287 : * Set formatter symbol value. }}} */
288 : /* {{{ proto bool numfmt_set_symbol( NumberFormatter $nf, int $attr, string $symbol )
289 : * Set formatter symbol value.
290 : */
291 : PHP_FUNCTION( numfmt_set_symbol )
292 80 : {
293 : long symbol;
294 80 : char* value = NULL;
295 80 : int value_len = 0;
296 80 : UChar* svalue = 0;
297 80 : int slength = 0;
298 80 : FORMATTER_METHOD_INIT_VARS;
299 :
300 : /* Parse parameters. */
301 80 : if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ols",
302 : &object, NumberFormatter_ce_ptr, &symbol, &value, &value_len ) == FAILURE )
303 : {
304 0 : intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
305 : "numfmt_set_symbol: unable to parse input params", 0 TSRMLS_CC );
306 :
307 0 : RETURN_FALSE;
308 : }
309 :
310 : /* Fetch the object. */
311 80 : FORMATTER_METHOD_FETCH_OBJECT;
312 :
313 : /* Convert given symbol to UTF-16. */
314 80 : intl_convert_utf8_to_utf16(&svalue, &slength, value, value_len, &INTL_DATA_ERROR_CODE(nfo));
315 80 : INTL_METHOD_CHECK_STATUS( nfo, "Error converting symbol value to UTF-16" );
316 :
317 : /* Actually set the symbol. */
318 80 : unum_setSymbol(FORMATTER_OBJECT(nfo), symbol, svalue, slength, &INTL_DATA_ERROR_CODE(nfo));
319 80 : efree(svalue);
320 80 : INTL_METHOD_CHECK_STATUS( nfo, "Error setting symbol value" );
321 :
322 80 : RETURN_TRUE;
323 : }
324 : /* }}} */
325 :
326 : /* {{{ proto string NumberFormatter::getPattern( )
327 : * Get formatter pattern. }}} */
328 : /* {{{ proto string numfmt_get_pattern( NumberFormatter $nf )
329 : * Get formatter pattern.
330 : */
331 : PHP_FUNCTION( numfmt_get_pattern )
332 8 : {
333 : UChar value_buf[64];
334 8 : int length = USIZE( value_buf );
335 8 : UChar* value = value_buf;
336 8 : FORMATTER_METHOD_INIT_VARS;
337 :
338 : /* Parse parameters. */
339 8 : if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
340 : &object, NumberFormatter_ce_ptr ) == FAILURE )
341 : {
342 0 : intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
343 : "numfmt_get_pattern: unable to parse input params", 0 TSRMLS_CC );
344 :
345 0 : RETURN_FALSE;
346 : }
347 :
348 : /* Fetch the object. */
349 8 : FORMATTER_METHOD_FETCH_OBJECT;
350 :
351 8 : length = unum_toPattern(FORMATTER_OBJECT(nfo), 0, value, length, &INTL_DATA_ERROR_CODE(nfo));
352 8 : if(INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR && length >= USIZE( value_buf )) {
353 4 : ++length; /* to avoid U_STRING_NOT_TERMINATED_WARNING */
354 4 : INTL_DATA_ERROR_CODE(nfo) = U_ZERO_ERROR;
355 4 : value = eumalloc(length);
356 4 : length = unum_toPattern( FORMATTER_OBJECT(nfo), 0, value, length, &INTL_DATA_ERROR_CODE(nfo) );
357 4 : if(U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) {
358 0 : efree(value);
359 0 : value = value_buf;
360 : }
361 : }
362 8 : INTL_METHOD_CHECK_STATUS( nfo, "Error getting formatter pattern" );
363 :
364 8 : INTL_METHOD_RETVAL_UTF8( nfo, value, length, ( value != value_buf ) );
365 : }
366 : /* }}} */
367 :
368 : /* {{{ proto bool NumberFormatter::setPattern( string $pattern )
369 : * Set formatter pattern. }}} */
370 : /* {{{ proto bool numfmt_set_pattern( NumberFormatter $nf, string $pattern )
371 : * Set formatter pattern.
372 : */
373 : PHP_FUNCTION( numfmt_set_pattern )
374 4 : {
375 4 : char* value = NULL;
376 4 : int value_len = 0;
377 4 : int slength = 0;
378 4 : UChar* svalue = NULL;
379 4 : FORMATTER_METHOD_INIT_VARS;
380 :
381 : /* Parse parameters. */
382 4 : if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os",
383 : &object, NumberFormatter_ce_ptr, &value, &value_len ) == FAILURE )
384 : {
385 0 : intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
386 : "numfmt_set_pattern: unable to parse input params", 0 TSRMLS_CC );
387 :
388 0 : RETURN_FALSE;
389 : }
390 :
391 4 : FORMATTER_METHOD_FETCH_OBJECT;
392 :
393 : /* Convert given pattern to UTF-16. */
394 4 : intl_convert_utf8_to_utf16(&svalue, &slength, value, value_len, &INTL_DATA_ERROR_CODE(nfo));
395 4 : INTL_METHOD_CHECK_STATUS( nfo, "Error converting pattern to UTF-16" );
396 :
397 : /* TODO: add parse error information */
398 4 : unum_applyPattern(FORMATTER_OBJECT(nfo), 0, svalue, slength, NULL, &INTL_DATA_ERROR_CODE(nfo));
399 4 : efree(svalue);
400 4 : INTL_METHOD_CHECK_STATUS( nfo, "Error setting pattern value" );
401 :
402 4 : RETURN_TRUE;
403 : }
404 : /* }}} */
405 :
406 : /* {{{ proto string NumberFormatter::getLocale([int type])
407 : * Get formatter locale. }}} */
408 : /* {{{ proto string numfmt_get_locale( NumberFormatter $nf[, int type] )
409 : * Get formatter locale.
410 : */
411 : PHP_FUNCTION( numfmt_get_locale )
412 12 : {
413 12 : long type = ULOC_ACTUAL_LOCALE;
414 : char* loc;
415 12 : FORMATTER_METHOD_INIT_VARS;
416 :
417 : /* Parse parameters. */
418 12 : if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l",
419 : &object, NumberFormatter_ce_ptr, &type ) == FAILURE )
420 : {
421 0 : intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
422 : "numfmt_get_locale: unable to parse input params", 0 TSRMLS_CC );
423 :
424 0 : RETURN_FALSE;
425 : }
426 :
427 : /* Fetch the object. */
428 12 : FORMATTER_METHOD_FETCH_OBJECT;
429 :
430 12 : loc = (char *)unum_getLocaleByType(FORMATTER_OBJECT(nfo), type, &INTL_DATA_ERROR_CODE(nfo));
431 12 : INTL_METHOD_CHECK_STATUS( nfo, "Error getting locale" );
432 12 : RETURN_STRING(loc, 1);
433 : }
434 : /* }}} */
435 :
436 : /*
437 : * Local variables:
438 : * tab-width: 4
439 : * c-basic-offset: 4
440 : * End:
441 : * vim600: noet sw=4 ts=4 fdm=marker
442 : * vim<600: noet sw=4 ts=4
443 : */
|