Skip to content

Commit 92708e3

Browse files
committed
Cleanup: avoid reallocations
1 parent 57575c0 commit 92708e3

File tree

1 file changed

+60
-54
lines changed

1 file changed

+60
-54
lines changed

ext/intl/locale/locale_methods.c

Lines changed: 60 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -256,9 +256,9 @@ PHP_NAMED_FUNCTION(zif_locale_set_default)
256256
* common code shared by get_primary_language,get_script or get_region or get_variant
257257
* result = 0 if error, 1 if successful , -1 if no value
258258
*/
259-
static char* get_icu_value_internal( const char* loc_name , char* tag_name, int* result , int fromParseLocale)
259+
static zend_string* get_icu_value_internal( const char* loc_name , char* tag_name, int* result , int fromParseLocale)
260260
{
261-
char* tag_value = NULL;
261+
zend_string* tag_value = NULL;
262262
int32_t tag_value_len = 512;
263263

264264
int singletonPos = 0;
@@ -274,7 +274,7 @@ static char* get_icu_value_internal( const char* loc_name , char* tag_name, int*
274274
grOffset = findOffset( LOC_GRANDFATHERED , loc_name );
275275
if( grOffset >= 0 ){
276276
if( strcmp(tag_name , LOC_LANG_TAG)==0 ){
277-
return estrdup(loc_name);
277+
return zend_string_init(loc_name, strlen(loc_name), 0);
278278
} else {
279279
/* Since Grandfathered , no value , do nothing , retutn NULL */
280280
return NULL;
@@ -285,7 +285,7 @@ static char* get_icu_value_internal( const char* loc_name , char* tag_name, int*
285285
/* Handle singletons */
286286
if( strcmp(tag_name , LOC_LANG_TAG)==0 ){
287287
if( strlen(loc_name)>1 && (isIDPrefix(loc_name) == 1) ){
288-
return estrdup(loc_name);
288+
return zend_string_init(loc_name, strlen(loc_name), 0);
289289
}
290290
}
291291

@@ -308,24 +308,28 @@ static char* get_icu_value_internal( const char* loc_name , char* tag_name, int*
308308
}
309309

310310
/* Proceed to ICU */
311-
do{
312-
tag_value = erealloc( tag_value , buflen );
311+
do{
312+
if (tag_value) {
313+
tag_value = zend_string_realloc( tag_value , buflen, 0);
314+
} else {
315+
tag_value = zend_string_alloc( buflen, 0);
316+
}
313317
tag_value_len = buflen;
314318

315319
if( strcmp(tag_name , LOC_SCRIPT_TAG)==0 ){
316-
buflen = uloc_getScript ( mod_loc_name ,tag_value , tag_value_len , &status);
320+
buflen = uloc_getScript ( mod_loc_name , tag_value->val , tag_value_len , &status);
317321
}
318322
if( strcmp(tag_name , LOC_LANG_TAG )==0 ){
319-
buflen = uloc_getLanguage ( mod_loc_name ,tag_value , tag_value_len , &status);
323+
buflen = uloc_getLanguage ( mod_loc_name , tag_value->val , tag_value_len , &status);
320324
}
321325
if( strcmp(tag_name , LOC_REGION_TAG)==0 ){
322-
buflen = uloc_getCountry ( mod_loc_name ,tag_value , tag_value_len , &status);
326+
buflen = uloc_getCountry ( mod_loc_name , tag_value->val , tag_value_len , &status);
323327
}
324328
if( strcmp(tag_name , LOC_VARIANT_TAG)==0 ){
325-
buflen = uloc_getVariant ( mod_loc_name ,tag_value , tag_value_len , &status);
329+
buflen = uloc_getVariant ( mod_loc_name , tag_value->val , tag_value_len , &status);
326330
}
327331
if( strcmp(tag_name , LOC_CANONICALIZE_TAG)==0 ){
328-
buflen = uloc_canonicalize ( mod_loc_name ,tag_value , tag_value_len , &status);
332+
buflen = uloc_canonicalize ( mod_loc_name , tag_value->val , tag_value_len , &status);
329333
}
330334

331335
if( U_FAILURE( status ) ) {
@@ -337,7 +341,7 @@ static char* get_icu_value_internal( const char* loc_name , char* tag_name, int*
337341
/* Error in retriving data */
338342
*result = 0;
339343
if( tag_value ){
340-
efree( tag_value );
344+
zend_string_release( tag_value );
341345
}
342346
if( mod_loc_name ){
343347
efree( mod_loc_name);
@@ -350,7 +354,7 @@ static char* get_icu_value_internal( const char* loc_name , char* tag_name, int*
350354
/* No value found */
351355
*result = -1;
352356
if( tag_value ){
353-
efree( tag_value );
357+
zend_string_release( tag_value );
354358
}
355359
if( mod_loc_name ){
356360
efree( mod_loc_name);
@@ -363,6 +367,8 @@ static char* get_icu_value_internal( const char* loc_name , char* tag_name, int*
363367
if( mod_loc_name ){
364368
efree( mod_loc_name);
365369
}
370+
371+
tag_value->len = strlen(tag_value->val);
366372
return tag_value;
367373
}
368374
/* }}} */
@@ -377,7 +383,7 @@ static void get_icu_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAMETERS)
377383
const char* loc_name = NULL;
378384
size_t loc_name_len = 0;
379385

380-
char* tag_value = NULL;
386+
zend_string* tag_value = NULL;
381387
char* empty_result = "";
382388

383389
int result = 0;
@@ -406,16 +412,14 @@ static void get_icu_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAMETERS)
406412
/* No value found */
407413
if( result == -1 ) {
408414
if( tag_value){
409-
efree( tag_value);
415+
zend_string_release( tag_value);
410416
}
411417
RETURN_STRING( empty_result);
412418
}
413419

414420
/* value found */
415421
if( tag_value){
416-
RETVAL_STRING( tag_value );
417-
//???
418-
efree(tag_value);
422+
RETVAL_STR( tag_value );
419423
return;
420424
}
421425

@@ -985,9 +989,9 @@ PHP_FUNCTION(locale_compose)
985989
* e.g. for locale='en_US-x-prv1-prv2-prv3'
986990
* returns a pointer to the string 'prv1-prv2-prv3'
987991
*/
988-
static char* get_private_subtags(const char* loc_name)
992+
static zend_string* get_private_subtags(const char* loc_name)
989993
{
990-
char* result =NULL;
994+
zend_string* result =NULL;
991995
int singletonPos = 0;
992996
int len =0;
993997
const char* mod_loc_name =NULL;
@@ -1005,7 +1009,7 @@ static char* get_private_subtags(const char* loc_name)
10051009
}
10061010
else{
10071011
/* result = mod_loc_name + singletonPos +2; */
1008-
result = estrndup(mod_loc_name + singletonPos+2 , (len -( singletonPos +2) ) );
1012+
result = zend_string_init(mod_loc_name + singletonPos+2 , (len -( singletonPos +2) ), 0);
10091013
}
10101014
break;
10111015
}
@@ -1032,7 +1036,7 @@ static char* get_private_subtags(const char* loc_name)
10321036
*/
10331037
static int add_array_entry(const char* loc_name, zval* hash_arr, char* key_name)
10341038
{
1035-
char* key_value = NULL;
1039+
zend_string* key_value = NULL;
10361040
char* cur_key_name = NULL;
10371041
char* token = NULL;
10381042
char* last_ptr = NULL;
@@ -1052,7 +1056,7 @@ static int add_array_entry(const char* loc_name, zval* hash_arr, char* key_name)
10521056
( strcmp(key_name , LOC_VARIANT_TAG)==0) ){
10531057
if( result > 0 && key_value){
10541058
/* Tokenize on the "_" or "-" */
1055-
token = php_strtok_r( key_value , DELIMITER ,&last_ptr);
1059+
token = php_strtok_r( key_value->val , DELIMITER ,&last_ptr);
10561060
if( cur_key_name ){
10571061
efree( cur_key_name);
10581062
}
@@ -1069,20 +1073,22 @@ static int add_array_entry(const char* loc_name, zval* hash_arr, char* key_name)
10691073
}
10701074
*/
10711075
}
1076+
if (key_value) {
1077+
zend_string_release(key_value);
1078+
}
10721079
} else {
10731080
if( result == 1 ){
1074-
add_assoc_string( hash_arr, key_name , key_value);
1081+
add_assoc_str( hash_arr, key_name , key_value);
10751082
cur_result = 1;
1083+
} else if (key_value) {
1084+
zend_string_release(key_value);
10761085
}
10771086
}
10781087

10791088
if( cur_key_name ){
10801089
efree( cur_key_name);
10811090
}
10821091
/*if( key_name != LOC_PRIVATE_TAG && key_value){*/
1083-
if( key_value){
1084-
efree(key_value);
1085-
}
10861092
return cur_result;
10871093
}
10881094
/* }}} */
@@ -1144,7 +1150,7 @@ PHP_FUNCTION(locale_get_all_variants)
11441150

11451151
int result = 0;
11461152
char* token = NULL;
1147-
char* variant = NULL;
1153+
zend_string* variant = NULL;
11481154
char* saved_ptr = NULL;
11491155

11501156
intl_error_reset( NULL );
@@ -1174,15 +1180,15 @@ PHP_FUNCTION(locale_get_all_variants)
11741180
variant = get_icu_value_internal( loc_name , LOC_VARIANT_TAG , &result ,0);
11751181
if( result > 0 && variant){
11761182
/* Tokenize on the "_" or "-" */
1177-
token = php_strtok_r( variant , DELIMITER , &saved_ptr);
1183+
token = php_strtok_r( variant->val , DELIMITER , &saved_ptr);
11781184
add_next_index_stringl( return_value, token , strlen(token));
11791185
/* tokenize on the "_" or "-" and stop at singleton if any */
11801186
while( (token = php_strtok_r(NULL , DELIMITER, &saved_ptr)) && (strlen(token)>1) ){
11811187
add_next_index_stringl( return_value, token , strlen(token));
11821188
}
11831189
}
11841190
if( variant ){
1185-
efree( variant );
1191+
zend_string_release( variant );
11861192
}
11871193
}
11881194

@@ -1241,8 +1247,8 @@ PHP_FUNCTION(locale_filter_matches)
12411247
char* token = 0;
12421248
char* chrcheck = NULL;
12431249

1244-
char* can_lang_tag = NULL;
1245-
char* can_loc_range = NULL;
1250+
zend_string* can_lang_tag = NULL;
1251+
zend_string* can_loc_range = NULL;
12461252

12471253
char* cur_lang_tag = NULL;
12481254
char* cur_loc_range = NULL;
@@ -1288,23 +1294,23 @@ PHP_FUNCTION(locale_filter_matches)
12881294
}
12891295

12901296
/* Convert to lower case for case-insensitive comparison */
1291-
cur_lang_tag = ecalloc( 1, strlen(can_lang_tag) + 1);
1297+
cur_lang_tag = ecalloc( 1, can_lang_tag->len + 1);
12921298

12931299
/* Convert to lower case for case-insensitive comparison */
1294-
result = strToMatch( can_lang_tag , cur_lang_tag);
1300+
result = strToMatch( can_lang_tag->val , cur_lang_tag);
12951301
if( result == 0) {
12961302
efree( cur_lang_tag );
1297-
efree( can_lang_tag );
1303+
zend_string_release( can_lang_tag );
12981304
RETURN_FALSE;
12991305
}
13001306

1301-
cur_loc_range = ecalloc( 1, strlen(can_loc_range) + 1);
1302-
result = strToMatch( can_loc_range , cur_loc_range );
1307+
cur_loc_range = ecalloc( 1, can_loc_range->len + 1);
1308+
result = strToMatch( can_loc_range->val , cur_loc_range );
13031309
if( result == 0) {
13041310
efree( cur_lang_tag );
1305-
efree( can_lang_tag );
1311+
zend_string_release( can_lang_tag );
13061312
efree( cur_loc_range );
1307-
efree( can_loc_range );
1313+
zend_string_release( can_loc_range );
13081314
RETURN_FALSE;
13091315
}
13101316

@@ -1322,10 +1328,10 @@ PHP_FUNCTION(locale_filter_matches)
13221328
efree( cur_loc_range );
13231329
}
13241330
if( can_lang_tag){
1325-
efree( can_lang_tag );
1331+
zend_string_release( can_lang_tag );
13261332
}
13271333
if( can_loc_range){
1328-
efree( can_loc_range );
1334+
zend_string_release( can_loc_range );
13291335
}
13301336
RETURN_TRUE;
13311337
}
@@ -1339,10 +1345,10 @@ PHP_FUNCTION(locale_filter_matches)
13391345
efree( cur_loc_range );
13401346
}
13411347
if( can_lang_tag){
1342-
efree( can_lang_tag );
1348+
zend_string_release( can_lang_tag );
13431349
}
13441350
if( can_loc_range){
1345-
efree( can_loc_range );
1351+
zend_string_release( can_loc_range );
13461352
}
13471353
RETURN_FALSE;
13481354

@@ -1416,12 +1422,12 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr,
14161422
int cur_arr_len = 0;
14171423
int result = 0;
14181424

1419-
char* lang_tag = NULL;
1425+
zend_string* lang_tag = NULL;
14201426
zval* ele_value = NULL;
14211427
char** cur_arr = NULL;
14221428

14231429
char* cur_loc_range = NULL;
1424-
char* can_loc_range = NULL;
1430+
zend_string* can_loc_range = NULL;
14251431
int saved_pos = 0;
14261432

14271433
zend_string* return_value = NULL;
@@ -1448,16 +1454,16 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr,
14481454
if(canonicalize) {
14491455
for(i=0; i<cur_arr_len; i++) {
14501456
lang_tag = get_icu_value_internal(cur_arr[i*2], LOC_CANONICALIZE_TAG, &result, 0);
1451-
if(result != 1 || lang_tag == NULL || !lang_tag[0]) {
1457+
if(result != 1 || lang_tag == NULL || !lang_tag->val[0]) {
14521458
if(lang_tag) {
1453-
efree(lang_tag);
1459+
zend_string_release(lang_tag);
14541460
}
14551461
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "lookup_loc_range: unable to canonicalize lang_tag" , 0);
14561462
LOOKUP_CLEAN_RETURN(NULL);
14571463
}
1458-
cur_arr[i*2] = erealloc(cur_arr[i*2], strlen(lang_tag)+1);
1459-
result = strToMatch(lang_tag, cur_arr[i*2]);
1460-
efree(lang_tag);
1464+
cur_arr[i*2] = erealloc(cur_arr[i*2], lang_tag->len+1);
1465+
result = strToMatch(lang_tag->val, cur_arr[i*2]);
1466+
zend_string_release(lang_tag);
14611467
if(result == 0) {
14621468
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "lookup_loc_range: unable to canonicalize lang_tag" , 0);
14631469
LOOKUP_CLEAN_RETURN(NULL);
@@ -1469,23 +1475,23 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr,
14691475
if(canonicalize) {
14701476
/* Canonicalize the loc_range */
14711477
can_loc_range = get_icu_value_internal(loc_range, LOC_CANONICALIZE_TAG, &result , 0);
1472-
if( result != 1 || can_loc_range == NULL || !can_loc_range[0]) {
1478+
if( result != 1 || can_loc_range == NULL || !can_loc_range->val[0]) {
14731479
/* Error */
14741480
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "lookup_loc_range: unable to canonicalize loc_range" , 0 );
14751481
if(can_loc_range) {
1476-
efree(can_loc_range);
1482+
zend_string_release(can_loc_range);
14771483
}
14781484
LOOKUP_CLEAN_RETURN(NULL);
14791485
} else {
1480-
loc_range = can_loc_range;
1486+
loc_range = can_loc_range->val;
14811487
}
14821488
}
14831489

14841490
cur_loc_range = ecalloc(1, strlen(loc_range)+1);
14851491
/* convert to lower and replace hyphens */
14861492
result = strToMatch(loc_range, cur_loc_range);
14871493
if(can_loc_range) {
1488-
efree(can_loc_range);
1494+
zend_string_release(can_loc_range);
14891495
}
14901496
if(result == 0) {
14911497
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "lookup_loc_range: unable to canonicalize lang_tag" , 0);

0 commit comments

Comments
 (0)