Skip to content

Commit e6e5a66

Browse files
committed
ext/intl: Migrate NumberFormatter internals from ICU C API to C++ API.
Replace UNumberFormat*/unum_* with icu::NumberFormat C++ equivalents. Attribute get/set still use reinterpret_cast<UNumberFormat*> for now. Note: formatter_fail.phpt expectation updated because NumberFormat::createInstance() returns U_ILLEGAL_ARGUMENT_ERROR for out-of-range styles (style < 0), whereas unum_open() returned U_UNSUPPORTED_ERROR via its default switch case.
1 parent 507078f commit e6e5a66

File tree

9 files changed

+193
-169
lines changed

9 files changed

+193
-169
lines changed

ext/intl/formatter/formatter_attr.cpp

Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,16 @@
1616
#include <config.h>
1717
#endif
1818

19+
#include <unicode/unum.h>
20+
#include "../intl_convertcpp.h"
21+
#include "formatter_class.h"
22+
1923
extern "C" {
2024
#include "php_intl.h"
2125
#include "intl_convert.h"
2226
}
23-
#include "formatter_class.h"
2427

25-
#include <unicode/ustring.h>
28+
#define FORMATTER_UNUM(nfo) reinterpret_cast<UNumberFormat*>(FORMATTER_OBJECT(nfo))
2629

2730
/* {{{ Get formatter attribute value. */
2831
U_CFUNC PHP_FUNCTION( numfmt_get_attribute )
@@ -62,7 +65,7 @@ U_CFUNC PHP_FUNCTION( numfmt_get_attribute )
6265
case UNUM_MIN_SIGNIFICANT_DIGITS:
6366
case UNUM_MAX_SIGNIFICANT_DIGITS:
6467
case UNUM_LENIENT_PARSE:
65-
value = unum_getAttribute(FORMATTER_OBJECT(nfo), attribute);
68+
value = unum_getAttribute(FORMATTER_UNUM(nfo), attribute);
6669
if(value == -1) {
6770
INTL_DATA_ERROR_CODE(nfo) = U_UNSUPPORTED_ERROR;
6871
} else {
@@ -71,7 +74,7 @@ U_CFUNC PHP_FUNCTION( numfmt_get_attribute )
7174
break;
7275
case UNUM_ROUNDING_INCREMENT:
7376
{
74-
double value_double = unum_getDoubleAttribute(FORMATTER_OBJECT(nfo), attribute);
77+
double value_double = unum_getDoubleAttribute(FORMATTER_UNUM(nfo), attribute);
7578
if(value_double == -1) {
7679
INTL_DATA_ERROR_CODE(nfo) = U_UNSUPPORTED_ERROR;
7780
} else {
@@ -110,12 +113,12 @@ U_CFUNC PHP_FUNCTION( numfmt_get_text_attribute )
110113

111114
UNumberFormatTextAttribute attribute = static_cast<UNumberFormatTextAttribute>(lattribute);
112115

113-
length = unum_getTextAttribute( FORMATTER_OBJECT(nfo), attribute, value, value_buf_size, &INTL_DATA_ERROR_CODE(nfo) );
116+
length = unum_getTextAttribute( FORMATTER_UNUM(nfo), attribute, value, value_buf_size, &INTL_DATA_ERROR_CODE(nfo) );
114117
if(INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR && length >= value_buf_size) {
115118
++length; /* to avoid U_STRING_NOT_TERMINATED_WARNING */
116119
INTL_DATA_ERROR_CODE(nfo) = U_ZERO_ERROR;
117120
value = eumalloc(length);
118-
length = unum_getTextAttribute( FORMATTER_OBJECT(nfo), attribute, value, length, &INTL_DATA_ERROR_CODE(nfo) );
121+
length = unum_getTextAttribute( FORMATTER_UNUM(nfo), attribute, value, length, &INTL_DATA_ERROR_CODE(nfo) );
119122
if(U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) {
120123
efree(value);
121124
value = value_buf;
@@ -166,10 +169,10 @@ U_CFUNC PHP_FUNCTION( numfmt_set_attribute )
166169
case UNUM_MIN_SIGNIFICANT_DIGITS:
167170
case UNUM_MAX_SIGNIFICANT_DIGITS:
168171
case UNUM_LENIENT_PARSE:
169-
unum_setAttribute(FORMATTER_OBJECT(nfo), attribute, zval_get_long(value));
172+
unum_setAttribute(FORMATTER_UNUM(nfo), attribute, zval_get_long(value));
170173
break;
171174
case UNUM_ROUNDING_INCREMENT:
172-
unum_setDoubleAttribute(FORMATTER_OBJECT(nfo), attribute, zval_get_double(value));
175+
unum_setDoubleAttribute(FORMATTER_UNUM(nfo), attribute, zval_get_double(value));
173176
break;
174177
default:
175178
INTL_DATA_ERROR_CODE(nfo) = U_UNSUPPORTED_ERROR;
@@ -185,8 +188,6 @@ U_CFUNC PHP_FUNCTION( numfmt_set_attribute )
185188
/* {{{ Get formatter attribute value. */
186189
U_CFUNC PHP_FUNCTION( numfmt_set_text_attribute )
187190
{
188-
int32_t slength = 0;
189-
UChar *svalue = NULL;
190191
zend_long attribute;
191192
char *value;
192193
size_t len;
@@ -203,14 +204,12 @@ U_CFUNC PHP_FUNCTION( numfmt_set_text_attribute )
203204
FORMATTER_METHOD_FETCH_OBJECT;
204205

205206
/* Convert given attribute value to UTF-16. */
206-
intl_convert_utf8_to_utf16(&svalue, &slength, value, len, &INTL_DATA_ERROR_CODE(nfo));
207+
UnicodeString svalue;
208+
intl_stringFromChar(svalue, value, len, &INTL_DATA_ERROR_CODE(nfo));
207209
INTL_METHOD_CHECK_STATUS( nfo, "Error converting attribute value to UTF-16" );
208210

209211
/* Actually set new attribute value. */
210-
unum_setTextAttribute(FORMATTER_OBJECT(nfo), static_cast<UNumberFormatTextAttribute>(attribute), svalue, slength, &INTL_DATA_ERROR_CODE(nfo));
211-
if (svalue) {
212-
efree(svalue);
213-
}
212+
unum_setTextAttribute(FORMATTER_UNUM(nfo), static_cast<UNumberFormatTextAttribute>(attribute), svalue.getBuffer(), svalue.length(), &INTL_DATA_ERROR_CODE(nfo));
214213
INTL_METHOD_CHECK_STATUS( nfo, "Error setting text attribute" );
215214

216215
RETURN_TRUE;
@@ -243,12 +242,12 @@ U_CFUNC PHP_FUNCTION( numfmt_get_symbol )
243242
/* Fetch the object. */
244243
FORMATTER_METHOD_FETCH_OBJECT;
245244

246-
length = unum_getSymbol(FORMATTER_OBJECT(nfo), symbol, value_buf, length, &INTL_DATA_ERROR_CODE(nfo));
245+
length = unum_getSymbol(FORMATTER_UNUM(nfo), symbol, value_buf, length, &INTL_DATA_ERROR_CODE(nfo));
247246
if(INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR && length >= USIZE( value_buf )) {
248247
++length; /* to avoid U_STRING_NOT_TERMINATED_WARNING */
249248
INTL_DATA_ERROR_CODE(nfo) = U_ZERO_ERROR;
250249
value = eumalloc(length);
251-
length = unum_getSymbol(FORMATTER_OBJECT(nfo), symbol, value, length, &INTL_DATA_ERROR_CODE(nfo));
250+
length = unum_getSymbol(FORMATTER_UNUM(nfo), symbol, value, length, &INTL_DATA_ERROR_CODE(nfo));
252251
if(U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) {
253252
efree(value);
254253
value = value_buf;
@@ -266,8 +265,6 @@ U_CFUNC PHP_FUNCTION( numfmt_set_symbol )
266265
zend_long lsymbol;
267266
char* value = NULL;
268267
size_t value_len = 0;
269-
UChar* svalue = 0;
270-
int32_t slength = 0;
271268
FORMATTER_METHOD_INIT_VARS;
272269

273270
/* Parse parameters. */
@@ -288,14 +285,12 @@ U_CFUNC PHP_FUNCTION( numfmt_set_symbol )
288285
FORMATTER_METHOD_FETCH_OBJECT;
289286

290287
/* Convert given symbol to UTF-16. */
291-
intl_convert_utf8_to_utf16(&svalue, &slength, value, value_len, &INTL_DATA_ERROR_CODE(nfo));
288+
UnicodeString svalue;
289+
intl_stringFromChar(svalue, value, value_len, &INTL_DATA_ERROR_CODE(nfo));
292290
INTL_METHOD_CHECK_STATUS( nfo, "Error converting symbol value to UTF-16" );
293291

294292
/* Actually set the symbol. */
295-
unum_setSymbol(FORMATTER_OBJECT(nfo), symbol, svalue, slength, &INTL_DATA_ERROR_CODE(nfo));
296-
if (svalue) {
297-
efree(svalue);
298-
}
293+
unum_setSymbol(FORMATTER_UNUM(nfo), symbol, svalue.getBuffer(), svalue.length(), &INTL_DATA_ERROR_CODE(nfo));
299294
INTL_METHOD_CHECK_STATUS( nfo, "Error setting symbol value" );
300295

301296
RETURN_TRUE;
@@ -320,12 +315,12 @@ U_CFUNC PHP_FUNCTION( numfmt_get_pattern )
320315
/* Fetch the object. */
321316
FORMATTER_METHOD_FETCH_OBJECT;
322317

323-
length = unum_toPattern(FORMATTER_OBJECT(nfo), 0, value, length, &INTL_DATA_ERROR_CODE(nfo));
318+
length = unum_toPattern(FORMATTER_UNUM(nfo), 0, value, length, &INTL_DATA_ERROR_CODE(nfo));
324319
if(INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR && length >= USIZE( value_buf )) {
325320
++length; /* to avoid U_STRING_NOT_TERMINATED_WARNING */
326321
INTL_DATA_ERROR_CODE(nfo) = U_ZERO_ERROR;
327322
value = eumalloc(length);
328-
length = unum_toPattern( FORMATTER_OBJECT(nfo), 0, value, length, &INTL_DATA_ERROR_CODE(nfo) );
323+
length = unum_toPattern( FORMATTER_UNUM(nfo), 0, value, length, &INTL_DATA_ERROR_CODE(nfo) );
329324
if(U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) {
330325
efree(value);
331326
value = value_buf;
@@ -342,8 +337,6 @@ U_CFUNC PHP_FUNCTION( numfmt_set_pattern )
342337
{
343338
char* value = NULL;
344339
size_t value_len = 0;
345-
int32_t slength = 0;
346-
UChar* svalue = NULL;
347340
UParseError spattern_error = {0};
348341
FORMATTER_METHOD_INIT_VARS;
349342

@@ -357,13 +350,11 @@ U_CFUNC PHP_FUNCTION( numfmt_set_pattern )
357350
FORMATTER_METHOD_FETCH_OBJECT;
358351

359352
/* Convert given pattern to UTF-16. */
360-
intl_convert_utf8_to_utf16(&svalue, &slength, value, value_len, &INTL_DATA_ERROR_CODE(nfo));
353+
UnicodeString svalue;
354+
intl_stringFromChar(svalue, value, value_len, &INTL_DATA_ERROR_CODE(nfo));
361355
INTL_METHOD_CHECK_STATUS( nfo, "Error converting pattern to UTF-16" );
362356

363-
unum_applyPattern(FORMATTER_OBJECT(nfo), 0, svalue, slength, &spattern_error, &INTL_DATA_ERROR_CODE(nfo));
364-
if (svalue) {
365-
efree(svalue);
366-
}
357+
unum_applyPattern(FORMATTER_UNUM(nfo), 0, svalue.getBuffer(), svalue.length(), &spattern_error, &INTL_DATA_ERROR_CODE(nfo));
367358
if (U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) {
368359
char *msg;
369360
spprintf(&msg, 0, "Error setting pattern value at line %d, offset %d", spattern_error.line, spattern_error.offset);
@@ -393,7 +384,7 @@ U_CFUNC PHP_FUNCTION( numfmt_get_locale )
393384
/* Fetch the object. */
394385
FORMATTER_METHOD_FETCH_OBJECT;
395386

396-
loc = unum_getLocaleByType(FORMATTER_OBJECT(nfo), static_cast<ULocDataLocaleType>(type), &INTL_DATA_ERROR_CODE(nfo));
387+
loc = unum_getLocaleByType(FORMATTER_UNUM(nfo), static_cast<ULocDataLocaleType>(type), &INTL_DATA_ERROR_CODE(nfo));
397388
INTL_METHOD_CHECK_STATUS( nfo, "Error getting locale" );
398389
RETURN_STRING(loc);
399390
}

ext/intl/formatter/formatter_class.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
+----------------------------------------------------------------------+
1313
*/
1414

15-
#include <unicode/unum.h>
16-
1715
#include "formatter_class.h"
1816
extern "C" {
1917
#include "php_intl.h"
@@ -72,10 +70,9 @@ U_CFUNC zend_object *NumberFormatter_object_clone(zend_object *object)
7270
zend_objects_clone_members(&new_nfo->zo, &nfo->zo);
7371

7472
/* clone formatter object. It may fail, the destruction code must handle this case */
75-
if (FORMATTER_OBJECT(nfo) != NULL) {
76-
UErrorCode error = U_ZERO_ERROR;
77-
FORMATTER_OBJECT(new_nfo) = unum_clone(FORMATTER_OBJECT(nfo), &error);
78-
if (U_FAILURE(error)) {
73+
if (FORMATTER_OBJECT(nfo) != nullptr) {
74+
FORMATTER_OBJECT(new_nfo) = FORMATTER_OBJECT(nfo)->clone();
75+
if (FORMATTER_OBJECT(new_nfo) == nullptr) {
7976
zend_throw_error(NULL, "Failed to clone NumberFormatter");
8077
}
8178
} else {

ext/intl/formatter/formatter_class.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,14 @@
1515
#ifndef FORMATTER_CLASS_H
1616
#define FORMATTER_CLASS_H
1717

18-
#include <php.h>
18+
#include "formatter_data.h"
1919

2020
#ifdef __cplusplus
2121
extern "C" {
2222
#endif
2323
#include "intl_common.h"
2424
#include "intl_error.h"
2525
#include "intl_data.h"
26-
#include "formatter_data.h"
2726
#ifdef __cplusplus
2827
}
2928
#endif

ext/intl/formatter/formatter_data.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ void formatter_data_init( formatter_data* nf_data )
2626
if( !nf_data )
2727
return;
2828

29-
nf_data->unum = NULL;
29+
nf_data->unum = nullptr;
3030
intl_error_reset( &nf_data->error );
3131
}
3232
/* }}} */
@@ -39,10 +39,8 @@ void formatter_data_free( formatter_data* nf_data )
3939
if( !nf_data )
4040
return;
4141

42-
if( nf_data->unum )
43-
unum_close( nf_data->unum );
44-
45-
nf_data->unum = NULL;
42+
delete nf_data->unum;
43+
nf_data->unum = nullptr;
4644
intl_error_reset( &nf_data->error );
4745
}
4846
/* }}} */

ext/intl/formatter/formatter_data.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,21 @@
1515
#ifndef FORMATTER_DATA_H
1616
#define FORMATTER_DATA_H
1717

18+
#ifdef __cplusplus
19+
extern "C" {
20+
#endif
1821
#include <php.h>
22+
#ifdef __cplusplus
23+
}
24+
#endif
25+
26+
#include <unicode/numfmt.h>
1927

20-
#include <unicode/unum.h>
28+
#ifdef __cplusplus
29+
using icu::NumberFormat;
30+
#else
31+
typedef void NumberFormat;
32+
#endif
2133

2234
#ifdef __cplusplus
2335
extern "C" {
@@ -32,7 +44,7 @@ typedef struct {
3244
intl_error error;
3345

3446
// formatter handling
35-
UNumberFormat* unum;
47+
NumberFormat* unum;
3648
} formatter_data;
3749

3850
#ifdef __cplusplus

0 commit comments

Comments
 (0)