Annotation of embedaddon/php/ext/intl/formatter/formatter_format.c, revision 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 "formatter_class.h"
! 25: #include "formatter_format.h"
! 26: #include "intl_convert.h"
! 27:
! 28: /* {{{ proto mixed NumberFormatter::format( mixed $num[, int $type] )
! 29: * Format a number. }}} */
! 30: /* {{{ proto mixed numfmt_format( NumberFormatter $nf, mixed $num[, int type] )
! 31: * Format a number.
! 32: */
! 33: PHP_FUNCTION( numfmt_format )
! 34: {
! 35: zval **number;
! 36: long type = FORMAT_TYPE_DEFAULT;
! 37: UChar format_buf[32];
! 38: UChar* formatted = format_buf;
! 39: int formatted_len = USIZE(format_buf);
! 40: FORMATTER_METHOD_INIT_VARS;
! 41:
! 42: /* Parse parameters. */
! 43: if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OZ|l",
! 44: &object, NumberFormatter_ce_ptr, &number, &type ) == FAILURE )
! 45: {
! 46: intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
! 47: "numfmt_format: unable to parse input params", 0 TSRMLS_CC );
! 48:
! 49: RETURN_FALSE;
! 50: }
! 51:
! 52: /* Fetch the object. */
! 53: FORMATTER_METHOD_FETCH_OBJECT;
! 54:
! 55: if(type == FORMAT_TYPE_DEFAULT) {
! 56: if(Z_TYPE_PP(number) == IS_STRING) {
! 57: convert_scalar_to_number_ex(number);
! 58: }
! 59:
! 60: if(Z_TYPE_PP(number) == IS_LONG) {
! 61: /* take INT32 on 32-bit, int64 on 64-bit */
! 62: type = (sizeof(long) == 8)?FORMAT_TYPE_INT64:FORMAT_TYPE_INT32;
! 63: } else if(Z_TYPE_PP(number) == IS_DOUBLE) {
! 64: type = FORMAT_TYPE_DOUBLE;
! 65: } else {
! 66: type = FORMAT_TYPE_INT32;
! 67: }
! 68: }
! 69:
! 70: if(Z_TYPE_PP(number) != IS_DOUBLE && Z_TYPE_PP(number) != IS_LONG) {
! 71: SEPARATE_ZVAL_IF_NOT_REF(number);
! 72: convert_scalar_to_number( *number TSRMLS_CC );
! 73: }
! 74:
! 75: switch(type) {
! 76: case FORMAT_TYPE_INT32:
! 77: convert_to_long_ex(number);
! 78: formatted_len = unum_format(FORMATTER_OBJECT(nfo), (int32_t)Z_LVAL_PP(number),
! 79: formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo));
! 80: if (INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR) {
! 81: intl_error_reset(INTL_DATA_ERROR_P(nfo) TSRMLS_CC);
! 82: formatted = eumalloc(formatted_len);
! 83: formatted_len = unum_format(FORMATTER_OBJECT(nfo), (int32_t)Z_LVAL_PP(number),
! 84: formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo));
! 85: if (U_FAILURE( INTL_DATA_ERROR_CODE(nfo) ) ) {
! 86: efree(formatted);
! 87: }
! 88: }
! 89: INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" );
! 90: break;
! 91:
! 92: case FORMAT_TYPE_INT64:
! 93: {
! 94: int64_t value = (Z_TYPE_PP(number) == IS_DOUBLE)?(int64_t)Z_DVAL_PP(number):Z_LVAL_PP(number);
! 95: formatted_len = unum_formatInt64(FORMATTER_OBJECT(nfo), value, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo));
! 96: if (INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR) {
! 97: intl_error_reset(INTL_DATA_ERROR_P(nfo) TSRMLS_CC);
! 98: formatted = eumalloc(formatted_len);
! 99: formatted_len = unum_formatInt64(FORMATTER_OBJECT(nfo), value, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo));
! 100: if (U_FAILURE( INTL_DATA_ERROR_CODE(nfo) ) ) {
! 101: efree(formatted);
! 102: }
! 103: }
! 104: INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" );
! 105: }
! 106: break;
! 107:
! 108: case FORMAT_TYPE_DOUBLE:
! 109: convert_to_double_ex(number);
! 110: formatted_len = unum_formatDouble(FORMATTER_OBJECT(nfo), Z_DVAL_PP(number), formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo));
! 111: if (INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR) {
! 112: intl_error_reset(INTL_DATA_ERROR_P(nfo) TSRMLS_CC);
! 113: formatted = eumalloc(formatted_len);
! 114: unum_formatDouble(FORMATTER_OBJECT(nfo), Z_DVAL_PP(number), formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo));
! 115: if (U_FAILURE( INTL_DATA_ERROR_CODE(nfo) ) ) {
! 116: efree(formatted);
! 117: }
! 118: }
! 119: INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" );
! 120: break;
! 121:
! 122: default:
! 123: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported format type %ld", type);
! 124: RETURN_FALSE;
! 125: break;
! 126: }
! 127:
! 128: INTL_METHOD_RETVAL_UTF8( nfo, formatted, formatted_len, ( formatted != format_buf ) );
! 129: }
! 130: /* }}} */
! 131:
! 132: /* {{{ proto mixed NumberFormatter::formatCurrency( double $num, string $currency )
! 133: * Format a number as currency. }}} */
! 134: /* {{{ proto mixed numfmt_format_currency( NumberFormatter $nf, double $num, string $currency )
! 135: * Format a number as currency.
! 136: */
! 137: PHP_FUNCTION( numfmt_format_currency )
! 138: {
! 139: double number;
! 140: UChar format_buf[32];
! 141: UChar* formatted = format_buf;
! 142: int formatted_len = USIZE(format_buf);
! 143: char* currency = NULL;
! 144: int currency_len = 0;
! 145: UChar* scurrency = NULL;
! 146: int scurrency_len = 0;
! 147: FORMATTER_METHOD_INIT_VARS;
! 148:
! 149: /* Parse parameters. */
! 150: if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ods",
! 151: &object, NumberFormatter_ce_ptr, &number, ¤cy, ¤cy_len ) == FAILURE )
! 152: {
! 153: intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
! 154: "numfmt_format_currency: unable to parse input params", 0 TSRMLS_CC );
! 155:
! 156: RETURN_FALSE;
! 157: }
! 158:
! 159: /* Fetch the object. */
! 160: FORMATTER_METHOD_FETCH_OBJECT;
! 161:
! 162: /* Convert currency to UTF-16. */
! 163: intl_convert_utf8_to_utf16(&scurrency, &scurrency_len, currency, currency_len, &INTL_DATA_ERROR_CODE(nfo));
! 164: INTL_METHOD_CHECK_STATUS( nfo, "Currency conversion to UTF-16 failed" );
! 165:
! 166: /* Format the number using a fixed-length buffer. */
! 167: formatted_len = unum_formatDoubleCurrency(FORMATTER_OBJECT(nfo), number, scurrency, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo));
! 168:
! 169: /* If the buffer turned out to be too small
! 170: * then allocate another buffer dynamically
! 171: * and use it to format the number.
! 172: */
! 173: if (INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR) {
! 174: intl_error_reset(INTL_DATA_ERROR_P(nfo) TSRMLS_CC);
! 175: formatted = eumalloc(formatted_len);
! 176: unum_formatDoubleCurrency(FORMATTER_OBJECT(nfo), number, scurrency, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo));
! 177: }
! 178:
! 179: if( U_FAILURE( INTL_DATA_ERROR_CODE((nfo)) ) ) {
! 180: intl_error_set_code( NULL, INTL_DATA_ERROR_CODE((nfo)) TSRMLS_CC );
! 181: intl_errors_set_custom_msg( INTL_DATA_ERROR_P(nfo), "Number formatting failed", 0 TSRMLS_CC );
! 182: RETVAL_FALSE;
! 183: if (formatted != format_buf) {
! 184: efree(formatted);
! 185: }
! 186: } else {
! 187: INTL_METHOD_RETVAL_UTF8( nfo, formatted, formatted_len, ( formatted != format_buf ) );
! 188: }
! 189:
! 190: if(scurrency) {
! 191: efree(scurrency);
! 192: }
! 193: }
! 194:
! 195: /* }}} */
! 196:
! 197: /*
! 198: * Local variables:
! 199: * tab-width: 4
! 200: * c-basic-offset: 4
! 201: * End:
! 202: * vim600: noet sw=4 ts=4 fdm=marker
! 203: * vim<600: noet sw=4 ts=4
! 204: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>