php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
formatter_format.c
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | This source file is subject to version 3.01 of the PHP license, |
4 | that is bundled with this package in the file LICENSE, and is |
5 | available through the world-wide-web at the following url: |
6 | https://www.php.net/license/3_01.txt |
7 | If you did not receive a copy of the PHP license and are unable to |
8 | obtain it through the world-wide-web, please send a note to |
9 | license@php.net so we can mail you a copy immediately. |
10 +----------------------------------------------------------------------+
11 | Authors: Stanislav Malyshev <stas@zend.com> |
12 +----------------------------------------------------------------------+
13 */
14
15#ifdef HAVE_CONFIG_H
16#include <config.h>
17#endif
18
19#include "php_intl.h"
20
21#include <unicode/ustring.h>
22
23#include "formatter_class.h"
24#include "formatter_format.h"
25#include "intl_convert.h"
26
27/* {{{ Format a number. */
29{
30 zval *number;
32 UChar format_buf[32];
33 UChar* formatted = format_buf;
34 int32_t formatted_len = USIZE(format_buf);
36
37 /* Parse parameters. */
39 &object, NumberFormatter_ce_ptr, &number, &type ) == FAILURE )
40 {
42 }
43
44 /* Fetch the object. */
46
48 switch(Z_TYPE_P(number)) {
49 case IS_LONG:
50 /* take INT32 on 32-bit, int64 on 64-bit */
52 break;
53 case IS_DOUBLE:
55 break;
57 }
58 }
59
60 switch(type) {
62 convert_to_long(number);
63 formatted_len = unum_format(FORMATTER_OBJECT(nfo), (int32_t)Z_LVAL_P(number),
64 formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo));
67 formatted = eumalloc(formatted_len);
68 formatted_len = unum_format(FORMATTER_OBJECT(nfo), (int32_t)Z_LVAL_P(number),
69 formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo));
70 if (U_FAILURE( INTL_DATA_ERROR_CODE(nfo) ) ) {
71 efree(formatted);
72 }
73 }
74 INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" );
75 break;
76
78 {
79 int64_t value = (Z_TYPE_P(number) == IS_DOUBLE)?(int64_t)Z_DVAL_P(number):Z_LVAL_P(number);
80 formatted_len = unum_formatInt64(FORMATTER_OBJECT(nfo), value, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo));
83 formatted = eumalloc(formatted_len);
84 formatted_len = unum_formatInt64(FORMATTER_OBJECT(nfo), value, 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 }
91 break;
92
94 convert_to_double(number);
95 formatted_len = unum_formatDouble(FORMATTER_OBJECT(nfo), Z_DVAL_P(number), formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo));
98 formatted = eumalloc(formatted_len);
99 unum_formatDouble(FORMATTER_OBJECT(nfo), Z_DVAL_P(number), 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 break;
107 if (getThis()) {
108 const char *space;
109 const char *class_name = get_active_class_name(&space);
110 zend_argument_value_error(2, "cannot be NumberFormatter::TYPE_CURRENCY constant, "
111 "use %s%sformatCurrency() method instead", class_name, space);
112 } else {
113 zend_argument_value_error(3, "cannot be NumberFormatter::TYPE_CURRENCY constant, use numfmt_format_currency() function instead");
114 }
116 default:
117 zend_argument_value_error(hasThis() ? 2 : 3, "must be a NumberFormatter::TYPE_* constant");
119 }
120
121 INTL_METHOD_RETVAL_UTF8( nfo, formatted, formatted_len, ( formatted != format_buf ) );
122}
123/* }}} */
124
125/* {{{ Format a number as currency. */
127{
128 double number;
129 UChar format_buf[32];
130 UChar* formatted = format_buf;
131 int32_t formatted_len = USIZE(format_buf);
132 char* currency = NULL;
133 size_t currency_len = 0;
134 UChar* scurrency = NULL;
135 int32_t scurrency_len = 0;
137
138 /* Parse parameters. */
140 &object, NumberFormatter_ce_ptr, &number, &currency, &currency_len ) == FAILURE )
141 {
143 }
144
145 /* Fetch the object. */
147
148 /* Convert currency to UTF-16. */
149 intl_convert_utf8_to_utf16(&scurrency, &scurrency_len, currency, currency_len, &INTL_DATA_ERROR_CODE(nfo));
150 INTL_METHOD_CHECK_STATUS( nfo, "Currency conversion to UTF-16 failed" );
151
152 /* Format the number using a fixed-length buffer. */
153 formatted_len = unum_formatDoubleCurrency(FORMATTER_OBJECT(nfo), number, scurrency, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo));
154
155 /* If the buffer turned out to be too small
156 * then allocate another buffer dynamically
157 * and use it to format the number.
158 */
161 formatted = eumalloc(formatted_len);
162 unum_formatDoubleCurrency(FORMATTER_OBJECT(nfo), number, scurrency, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo));
163 }
164
165 if( U_FAILURE( INTL_DATA_ERROR_CODE((nfo)) ) ) {
167 intl_errors_set_custom_msg( INTL_DATA_ERROR_P(nfo), "Number formatting failed", 0 );
169 if (formatted != format_buf) {
170 efree(formatted);
171 }
172 } else {
173 INTL_METHOD_RETVAL_UTF8( nfo, formatted, formatted_len, ( formatted != format_buf ) );
174 }
175
176 if(scurrency) {
177 efree(scurrency);
178 }
179}
180
181/* }}} */
const U_BUFFER_OVERFLOW_ERROR
zend_ffi_type * type
Definition ffi.c:3812
zend_class_entry * NumberFormatter_ce_ptr
#define FORMATTER_METHOD_FETCH_OBJECT
#define FORMATTER_METHOD_INIT_VARS
#define FORMATTER_OBJECT(nfo)
#define FORMAT_TYPE_INT64
#define FORMAT_TYPE_CURRENCY
#define FORMAT_TYPE_DOUBLE
#define FORMAT_TYPE_DEFAULT
#define FORMAT_TYPE_INT32
#define NULL
Definition gdcache.h:45
#define USIZE(data)
Definition intl_common.h:38
#define eumalloc(size)
Definition intl_common.h:31
void intl_convert_utf8_to_utf16(UChar **target, int32_t *target_len, const char *src, size_t src_len, UErrorCode *status)
#define INTL_DATA_ERROR_P(obj)
Definition intl_data.h:39
#define INTL_DATA_ERROR_CODE(obj)
Definition intl_data.h:40
#define INTL_METHOD_CHECK_STATUS(obj, msg)
Definition intl_data.h:66
#define INTL_METHOD_RETVAL_UTF8(obj, ustring, ulen, free_it)
Definition intl_data.h:103
void intl_errors_set_custom_msg(intl_error *err, const char *msg, int copyMsg)
Definition intl_error.c:187
void intl_error_reset(intl_error *err)
Definition intl_error.c:78
void intl_error_set_code(intl_error *err, UErrorCode err_code)
Definition intl_error.c:141
#define PHP_FUNCTION
Definition php.h:364
numfmt_format_currency(NumberFormatter $formatter, float $amount, string $currency)
numfmt_format(NumberFormatter $formatter, int|float $num, int $type=NumberFormatter::TYPE_DEFAULT)
ZEND_API zend_result zend_parse_method_parameters(uint32_t num_args, zval *this_ptr, const char *type_spec,...)
Definition zend_API.c:1314
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
Definition zend_API.c:433
#define ZEND_NUM_ARGS()
Definition zend_API.h:530
#define hasThis()
Definition zend_API.h:525
#define RETURN_THROWS()
Definition zend_API.h:1060
#define getThis()
Definition zend_API.h:526
#define RETVAL_FALSE
Definition zend_API.h:1032
#define efree(ptr)
Definition zend_alloc.h:155
struct _zval_struct zval
ZEND_API const char * get_active_class_name(const char **space)
int32_t zend_long
Definition zend_long.h:42
ZEND_API void ZEND_FASTCALL convert_to_double(zval *op)
ZEND_API void ZEND_FASTCALL convert_to_long(zval *op)
#define EMPTY_SWITCH_DEFAULT_CASE()
#define Z_TYPE_P(zval_p)
Definition zend_types.h:660
#define IS_DOUBLE
Definition zend_types.h:605
@ FAILURE
Definition zend_types.h:61
#define IS_LONG
Definition zend_types.h:604
#define Z_DVAL_P(zval_p)
Definition zend_types.h:969
#define Z_LVAL_P(zval_p)
Definition zend_types.h:966
value