From: Dmitry Stogov Date: Wed, 1 Jul 2015 10:26:39 +0000 (+0300) Subject: Cleanup (avoid string reallocations) X-Git-Tag: php-7.1.0alpha3~25^2~89 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f7b6de5b5eea4554a1eb3e7bfc64877567693985;p=php Cleanup (avoid string reallocations) --- diff --git a/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp b/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp index 1988e7477d..8ab8194b17 100644 --- a/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp +++ b/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp @@ -114,20 +114,18 @@ U_CFUNC PHP_FUNCTION(rbbi_get_rules) BREAKITER_METHOD_FETCH_OBJECT; - char *str; - size_t str_len; + zend_string *u8str; const UnicodeString rules = fetch_rbbi(bio)->getRules(); - if (intl_charFromString(rules, &str, &str_len, BREAKITER_ERROR_CODE_P(bio)) == FAILURE) + u8str = intl_charFromString(rules, BREAKITER_ERROR_CODE_P(bio)); + if (!u8str) { intl_errors_set(BREAKITER_ERROR_P(bio), BREAKITER_ERROR_CODE(bio), "rbbi_hash_code: Error converting result to UTF-8 string", 0); RETURN_FALSE; } - RETVAL_STRINGL(str, str_len); - //??? - efree(str); + RETVAL_STR(u8str); } U_CFUNC PHP_FUNCTION(rbbi_get_rule_status) diff --git a/ext/intl/collator/collator_convert.c b/ext/intl/collator/collator_convert.c index 1ee13d8b39..8f06c8f1ca 100644 --- a/ext/intl/collator/collator_convert.c +++ b/ext/intl/collator/collator_convert.c @@ -87,8 +87,7 @@ static void collator_convert_hash_item_from_utf16_to_utf8( { const char* old_val; size_t old_val_len; - char* new_val = NULL; - size_t new_val_len = 0; + zend_string* u8str; zval znew_val; /* Process string values only. */ @@ -99,15 +98,13 @@ static void collator_convert_hash_item_from_utf16_to_utf8( old_val_len = Z_STRLEN_P( hashData ); /* Convert it from UTF-16LE to UTF-8 and save the result to new_val[_len]. */ - intl_convert_utf16_to_utf8( &new_val, &new_val_len, + u8str = intl_convert_utf16_to_utf8( (UChar*)old_val, UCHARS(old_val_len), status ); - if( U_FAILURE( *status ) ) + if( !u8str ) return; /* Update current hash item with the converted value. */ - ZVAL_STRINGL( &znew_val, new_val, new_val_len); - //??? - efree(new_val); + ZVAL_NEW_STR( &znew_val, u8str); if( hashKey ) { @@ -169,23 +166,19 @@ void collator_convert_hash_from_utf16_to_utf8( HashTable* hash, UErrorCode* stat */ zval* collator_convert_zstr_utf16_to_utf8( zval* utf16_zval, zval *rv ) { - zval* utf8_zval = NULL; - char* str = NULL; - size_t str_len = 0; + zend_string* u8str; UErrorCode status = U_ZERO_ERROR; /* Convert to utf8 then. */ - intl_convert_utf16_to_utf8( &str, &str_len, + u8str = intl_convert_utf16_to_utf8( (UChar*) Z_STRVAL_P(utf16_zval), UCHARS( Z_STRLEN_P(utf16_zval) ), &status ); - if( U_FAILURE( status ) ) + if( !u8str ) { php_error( E_WARNING, "Error converting utf16 to utf8 in collator_convert_zval_utf16_to_utf8()" ); - - utf8_zval = rv; - ZVAL_STRINGL( utf8_zval, str, str_len); - //??? - efree(str); - - return utf8_zval; + ZVAL_EMPTY_STRING( rv ); + } else { + ZVAL_NEW_STR( rv, u8str ); + } + return rv; } /* }}} */ diff --git a/ext/intl/collator/collator_sort.c b/ext/intl/collator/collator_sort.c index 549c3a116a..8727c1d8ab 100644 --- a/ext/intl/collator/collator_sort.c +++ b/ext/intl/collator/collator_sort.c @@ -549,8 +549,8 @@ PHP_FUNCTION( collator_get_sort_key ) size_t str_len = 0; UChar* ustr = NULL; int32_t ustr_len = 0; - uint8_t* key = NULL; int key_len = 0; + zend_string* key_str; COLLATOR_METHOD_INIT_VARS @@ -597,20 +597,19 @@ PHP_FUNCTION( collator_get_sort_key ) /* ucol_getSortKey is exception in that the key length includes the * NUL terminator*/ - key_len = ucol_getSortKey(co->ucoll, ustr, ustr_len, key, 0); + key_len = ucol_getSortKey(co->ucoll, ustr, ustr_len, NULL, 0); if(!key_len) { efree( ustr ); RETURN_FALSE; } - key = emalloc(key_len); - key_len = ucol_getSortKey(co->ucoll, ustr, ustr_len, key, key_len); + key_str = zend_string_alloc(key_len, 0); + key_len = ucol_getSortKey(co->ucoll, ustr, ustr_len, (uint8_t*)ZSTR_VAL(key_str), key_len); efree( ustr ); if(!key_len) { RETURN_FALSE; } - RETVAL_STRINGL((char *)key, key_len - 1); - //???? - efree(key); + ZSTR_LEN(key_str) = key_len - 1; + RETVAL_NEW_STR(key_str); } /* }}} */ diff --git a/ext/intl/converter/converter.c b/ext/intl/converter/converter.c index fe8c32be6f..5653b46365 100644 --- a/ext/intl/converter/converter.c +++ b/ext/intl/converter/converter.c @@ -652,27 +652,26 @@ static PHP_METHOD(UConverter, getSubstChars) { /* }}} */ /* {{{ php_converter_do_convert */ -static zend_bool php_converter_do_convert(UConverter *dest_cnv, char **pdest, int32_t *pdest_len, - UConverter *src_cnv, const char *src, int32_t src_len, - php_converter_object *objval - ) { +static zend_string* php_converter_do_convert(UConverter *dest_cnv, + UConverter *src_cnv, const char *src, int32_t src_len, + php_converter_object *objval + ) { UErrorCode error = U_ZERO_ERROR; - int32_t dest_len, - temp_len; - char *dest; + int32_t temp_len, ret_len; + zend_string *ret; UChar *temp; if (!src_cnv || !dest_cnv) { php_converter_throw_failure(objval, U_INVALID_STATE_ERROR, "Internal converters not initialized"); - return 0; + return NULL; } /* Get necessary buffer size first */ temp_len = 1 + ucnv_toUChars(src_cnv, NULL, 0, src, src_len, &error); if (U_FAILURE(error) && error != U_BUFFER_OVERFLOW_ERROR) { THROW_UFAILURE(objval, "ucnv_toUChars", error); - return 0; + return NULL; } temp = safe_emalloc(sizeof(UChar), temp_len, sizeof(UChar)); @@ -682,36 +681,31 @@ static zend_bool php_converter_do_convert(UConverter *dest_cnv, char **pdest, in if (U_FAILURE(error)) { THROW_UFAILURE(objval, "ucnv_toUChars", error); efree(temp); - return 0; + return NULL; } temp[temp_len] = 0; /* Get necessary output buffer size */ - dest_len = 1 + ucnv_fromUChars(dest_cnv, NULL, 0, temp, temp_len, &error); + ret_len = ucnv_fromUChars(dest_cnv, NULL, 0, temp, temp_len, &error); if (U_FAILURE(error) && error != U_BUFFER_OVERFLOW_ERROR) { THROW_UFAILURE(objval, "ucnv_fromUChars", error); efree(temp); - return 0; + return NULL; } - dest = safe_emalloc(sizeof(char), dest_len, sizeof(char)); + ret = zend_string_alloc(ret_len, 0); /* Convert to final encoding */ error = U_ZERO_ERROR; - dest_len = ucnv_fromUChars(dest_cnv, dest, dest_len, temp, temp_len, &error); + ZSTR_LEN(ret) = ucnv_fromUChars(dest_cnv, ZSTR_VAL(ret), ret_len+1, temp, temp_len, &error); efree(temp); if (U_FAILURE(error)) { THROW_UFAILURE(objval, "ucnv_fromUChars", error); - efree(dest); - return 0; + zend_string_free(ret); + return NULL; } - *pdest = dest; - if (pdest_len) { - *pdest_len = dest_len; - } - - return 1; + return ret; } /* }}} */ @@ -752,9 +746,9 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(UConverter, convert) { php_converter_object *objval = CONV_GET(getThis()); - char *str, *dest; + char *str; size_t str_len; - int32_t dest_len; + zend_string *ret; zend_bool reverse = 0; if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|b", @@ -765,15 +759,12 @@ static PHP_METHOD(UConverter, convert) { } intl_errors_reset(&objval->error); - if (php_converter_do_convert(reverse ? objval->src : objval->dest, - &dest, &dest_len, - reverse ? objval->dest : objval->src, - str, str_len, - objval)) { - RETVAL_STRINGL(dest, dest_len); - //??? - efree(dest); - return; + ret = php_converter_do_convert(reverse ? objval->src : objval->dest, + reverse ? objval->dest : objval->src, + str, str_len, + objval); + if (ret) { + RETURN_NEW_STR(ret); } else { RETURN_FALSE; } @@ -804,8 +795,7 @@ static PHP_METHOD(UConverter, transcode) { if (php_converter_set_encoding(NULL, &src_cnv, src, src_len) && php_converter_set_encoding(NULL, &dest_cnv, dest, dest_len)) { - char *out = NULL; - int out_len = 0; + zend_string *ret; UErrorCode error = U_ZERO_ERROR; if (options && zend_hash_num_elements(Z_ARRVAL_P(options))) { @@ -826,11 +816,8 @@ static PHP_METHOD(UConverter, transcode) { } if (U_SUCCESS(error) && - php_converter_do_convert(dest_cnv, &out, &out_len, src_cnv, str, str_len, NULL)) { - RETVAL_STRINGL(out, out_len); - //??? - efree(out); - return; + (ret = php_converter_do_convert(dest_cnv, src_cnv, str, str_len, NULL)) != NULL) { + RETURN_NEW_STR(ret); } if (U_FAILURE(error)) { diff --git a/ext/intl/dateformat/dateformat_attrcpp.cpp b/ext/intl/dateformat/dateformat_attrcpp.cpp index 49c4094a40..858cbf5d4d 100644 --- a/ext/intl/dateformat/dateformat_attrcpp.cpp +++ b/ext/intl/dateformat/dateformat_attrcpp.cpp @@ -44,8 +44,7 @@ static inline DateFormat *fetch_datefmt(IntlDateFormatter_object *dfo) { */ U_CFUNC PHP_FUNCTION(datefmt_get_timezone_id) { - char *str; - size_t str_len; + zend_string *u8str; DATE_FORMAT_METHOD_INIT_VARS; if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", @@ -59,12 +58,10 @@ U_CFUNC PHP_FUNCTION(datefmt_get_timezone_id) UnicodeString res = UnicodeString(); fetch_datefmt(dfo)->getTimeZone().getID(res); - intl_charFromString(res, &str, &str_len, &INTL_DATA_ERROR_CODE(dfo)); + u8str = intl_charFromString(res, &INTL_DATA_ERROR_CODE(dfo)); INTL_METHOD_CHECK_STATUS(dfo, "Could not convert time zone id to UTF-8"); - RETVAL_STRINGL(str, str_len); - //???? - efree(str); + RETVAL_STR(u8str); } /* {{{ proto IntlTimeZone IntlDateFormatter::getTimeZone() diff --git a/ext/intl/dateformat/dateformat_format_object.cpp b/ext/intl/dateformat/dateformat_format_object.cpp index 7246778486..3be76332a8 100644 --- a/ext/intl/dateformat/dateformat_format_object.cpp +++ b/ext/intl/dateformat/dateformat_format_object.cpp @@ -221,21 +221,19 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object) timeZone = NULL; { - char *ret_str; - size_t ret_str_len; + zend_string *u8str; UnicodeString result = UnicodeString(); df->format(date, result); - if (intl_charFromString(result, &ret_str, &ret_str_len, &status) == FAILURE) { + u8str = intl_charFromString(result, &status); + if (!u8str) { intl_error_set(NULL, status, "datefmt_format_object: error converting result to UTF-8", 0); RETVAL_FALSE; goto cleanup; } - RETVAL_STRINGL(ret_str, ret_str_len); - //??? - efree(ret_str); + RETVAL_STR(u8str); } diff --git a/ext/intl/formatter/formatter_parse.c b/ext/intl/formatter/formatter_parse.c index 43f6780e57..f0d42cfabe 100644 --- a/ext/intl/formatter/formatter_parse.c +++ b/ext/intl/formatter/formatter_parse.c @@ -129,8 +129,7 @@ PHP_FUNCTION( numfmt_parse_currency ) UChar currency[5] = {0}; UChar* sstr = NULL; int32_t sstr_len = 0; - char *currency_str = NULL; - size_t currency_len = 0; + zend_string *u8str; char *str; size_t str_len; int32_t* position_p = NULL; @@ -173,12 +172,10 @@ PHP_FUNCTION( numfmt_parse_currency ) INTL_METHOD_CHECK_STATUS( nfo, "Number parsing failed" ); /* Convert parsed currency to UTF-8 and pass it back to caller. */ - intl_convert_utf16_to_utf8(¤cy_str, ¤cy_len, currency, u_strlen(currency), &INTL_DATA_ERROR_CODE(nfo)); + u8str = intl_convert_utf16_to_utf8(currency, u_strlen(currency), &INTL_DATA_ERROR_CODE(nfo)); INTL_METHOD_CHECK_STATUS( nfo, "Currency conversion to UTF-8 failed" ); zval_dtor( zcurrency ); - ZVAL_STRINGL(zcurrency, currency_str, currency_len); - //???? - efree(currency_str); + ZVAL_NEW_STR(zcurrency, u8str); RETVAL_DOUBLE( number ); } diff --git a/ext/intl/grapheme/grapheme_string.c b/ext/intl/grapheme/grapheme_string.c index 17dac7a1e5..b5a1902025 100644 --- a/ext/intl/grapheme/grapheme_string.c +++ b/ext/intl/grapheme/grapheme_string.c @@ -370,11 +370,11 @@ PHP_FUNCTION(grapheme_strripos) Returns part of a string */ PHP_FUNCTION(grapheme_substr) { - char *str, *sub_str; + char *str; + zend_string *u8_sub_str; UChar *ustr; size_t str_len; int32_t ustr_len; - size_t sub_str_len; zend_long lstart = 0, length = 0; int32_t start = 0; int iter_val; @@ -413,6 +413,7 @@ PHP_FUNCTION(grapheme_substr) if ( grapheme_ascii_check((unsigned char *)str, str_len) >= 0 ) { int32_t asub_str_len; + char *sub_str; grapheme_substr_ascii(str, str_len, start, (int32_t)length, &sub_str, &asub_str_len); if ( NULL == sub_str ) { @@ -486,34 +487,26 @@ PHP_FUNCTION(grapheme_substr) /* no length supplied or length is too big, return the rest of the string */ - sub_str = NULL; - sub_str_len = 0; status = U_ZERO_ERROR; - intl_convert_utf16_to_utf8(&sub_str, &sub_str_len, ustr + sub_str_start_pos, ustr_len - sub_str_start_pos, &status); + u8_sub_str = intl_convert_utf16_to_utf8(ustr + sub_str_start_pos, ustr_len - sub_str_start_pos, &status); if (ustr) { efree( ustr ); } ubrk_close( bi ); - if ( U_FAILURE( status ) ) { + if ( !u8_sub_str ) { /* Set global error code. */ intl_error_set_code( NULL, status ); /* Set error messages. */ intl_error_set_custom_msg( NULL, "Error converting output string to UTF-8", 0 ); - if (sub_str) { - efree( sub_str ); - } - RETURN_FALSE; } /* return the allocated string, not a duplicate */ - RETVAL_STRINGL(sub_str, sub_str_len); - //??? - efree(sub_str); + RETVAL_NEW_STR(u8_sub_str); return; } @@ -570,30 +563,23 @@ PHP_FUNCTION(grapheme_substr) RETURN_FALSE; } - sub_str = NULL; status = U_ZERO_ERROR; - intl_convert_utf16_to_utf8(&sub_str, &sub_str_len, ustr + sub_str_start_pos, ( sub_str_end_pos - sub_str_start_pos ), &status); + u8_sub_str = intl_convert_utf16_to_utf8(ustr + sub_str_start_pos, ( sub_str_end_pos - sub_str_start_pos ), &status); efree( ustr ); - if ( U_FAILURE( status ) ) { + if ( !u8_sub_str ) { /* Set global error code. */ intl_error_set_code( NULL, status ); /* Set error messages. */ intl_error_set_custom_msg( NULL, "Error converting output string to UTF-8", 0 ); - if ( NULL != sub_str ) - efree( sub_str ); - RETURN_FALSE; } /* return the allocated string, not a duplicate */ - RETVAL_STRINGL(sub_str, sub_str_len); - //???? - efree(sub_str); - + RETVAL_NEW_STR(u8_sub_str); } /* }}} */ diff --git a/ext/intl/idn/idn.c b/ext/intl/idn/idn.c index 5dd742b87e..6e699604df 100644 --- a/ext/intl/idn/idn.c +++ b/ext/intl/idn/idn.c @@ -207,8 +207,7 @@ static void php_intl_idn_to(INTERNAL_FUNCTION_PARAMETERS, UChar* ustring = NULL; int ustring_len = 0; UErrorCode status; - char *converted_utf8; - size_t converted_utf8_len; + zend_string *u8str; UChar converted[MAXPATHLEN]; int32_t converted_ret_len; @@ -242,23 +241,20 @@ static void php_intl_idn_to(INTERNAL_FUNCTION_PARAMETERS, } status = U_ZERO_ERROR; - intl_convert_utf16_to_utf8(&converted_utf8, &converted_utf8_len, converted, converted_ret_len, &status); + u8str = intl_convert_utf16_to_utf8(converted, converted_ret_len, &status); - if (U_FAILURE(status)) { + if (!u8str) { /* Set global error code. */ intl_error_set_code(NULL, status); /* Set error messages. */ intl_error_set_custom_msg( NULL, "Error converting output string to UTF-8", 0 ); - efree(converted_utf8); RETURN_FALSE; } } /* return the allocated string, not a duplicate */ - RETVAL_STRINGL(converted_utf8, converted_utf8_len); - //???? - efree(converted_utf8); + RETVAL_NEW_STR(u8str); } static void php_intl_idn_handoff(INTERNAL_FUNCTION_PARAMETERS, int mode) diff --git a/ext/intl/intl_convert.c b/ext/intl/intl_convert.c index 51537062f5..2ae43fbb96 100644 --- a/ext/intl/intl_convert.c +++ b/ext/intl/intl_convert.c @@ -109,21 +109,18 @@ void intl_convert_utf8_to_utf16( /* {{{ intl_convert_utf16_to_utf8 * Convert given string from UTF-16 to UTF-8. * - * @param target Where to place the result. - * @param target_len Result length. * @param source String to convert. * @param source_len Length of the source string. * @param status Conversion status. * - * @return void This function does not return anything. + * @return zend_string */ -void intl_convert_utf16_to_utf8( - char** target, size_t* target_len, +zend_string* intl_convert_utf16_to_utf8( const UChar* src, int32_t src_len, UErrorCode* status ) { - char* dst_buf = NULL; - int32_t dst_len; + zend_string* dst; + int32_t dst_len; /* Determine required destination buffer size (pre-flighting). */ *status = U_ZERO_ERROR; @@ -134,26 +131,25 @@ void intl_convert_utf16_to_utf8( * (U_STRING_NOT_TERMINATED_WARNING usually means that the input string is empty). */ if( *status != U_BUFFER_OVERFLOW_ERROR && *status != U_STRING_NOT_TERMINATED_WARNING ) - return; + return NULL; /* Allocate memory for the destination buffer (it will be zero-terminated). */ - dst_buf = emalloc( dst_len+1 ); + dst = zend_string_alloc(dst_len, 0); /* Convert source string from UTF-8 to UTF-16. */ *status = U_ZERO_ERROR; - u_strToUTF8( dst_buf, dst_len, NULL, src, src_len, status ); + u_strToUTF8( ZSTR_VAL(dst), dst_len, NULL, src, src_len, status ); if( U_FAILURE( *status ) ) { - efree( dst_buf ); - return; + zend_string_free(dst); + return NULL; } /* U_STRING_NOT_TERMINATED_WARNING is OK for us => reset 'status'. */ *status = U_ZERO_ERROR; - dst_buf[dst_len] = 0; - *target = dst_buf; - *target_len = (size_t)dst_len; + ZSTR_VAL(dst)[dst_len] = 0; + return dst; } /* }}} */ diff --git a/ext/intl/intl_convert.h b/ext/intl/intl_convert.h index 2885890ef3..3c6308a352 100644 --- a/ext/intl/intl_convert.h +++ b/ext/intl/intl_convert.h @@ -25,8 +25,7 @@ void intl_convert_utf8_to_utf16( const char* src, size_t src_len, UErrorCode* status ); -void intl_convert_utf16_to_utf8( - char** target, size_t* target_len, +zend_string* intl_convert_utf16_to_utf8( const UChar* src, int32_t src_len, UErrorCode* status ); diff --git a/ext/intl/intl_convertcpp.cpp b/ext/intl/intl_convertcpp.cpp index e33d845a72..67fb946edd 100644 --- a/ext/intl/intl_convertcpp.cpp +++ b/ext/intl/intl_convertcpp.cpp @@ -53,42 +53,39 @@ int intl_stringFromChar(UnicodeString &ret, char *str, size_t str_len, UErrorCod /* }}} */ /* {{{ intl_charFromString - * faster than doing intl_convert_utf16_to_utf8(&res, &res_len, + * faster than doing intl_convert_utf16_to_utf8( * from.getBuffer(), from.length(), &status), * but consumes more memory */ -int intl_charFromString(const UnicodeString &from, char **res, size_t *res_len, UErrorCode *status) +zend_string* intl_charFromString(const UnicodeString &from, UErrorCode *status) { + zend_string *u8res; + if (from.isBogus()) { - return FAILURE; + return NULL; } //the number of UTF-8 code units is not larger than that of UTF-16 code - //units * 3 + 1 for the terminator - int32_t capacity = from.length() * 3 + 1; + //units * 3 + int32_t capacity = from.length() * 3; if (from.isEmpty()) { - *res = (char*)emalloc(1); - **res = '\0'; - *res_len = 0; - return SUCCESS; + return ZSTR_EMPTY_ALLOC(); } - *res = (char*)emalloc(capacity); - *res_len = 0; //tbd + u8res = zend_string_alloc(capacity, 0); const UChar *utf16buf = from.getBuffer(); int32_t actual_len; - u_strToUTF8WithSub(*res, capacity - 1, &actual_len, utf16buf, from.length(), + u_strToUTF8WithSub(ZSTR_VAL(u8res), capacity, &actual_len, utf16buf, from.length(), U_SENTINEL, NULL, status); if (U_FAILURE(*status)) { - efree(*res); - *res = NULL; - return FAILURE; + zend_string_free(u8res); + return NULL; } - (*res)[actual_len] = '\0'; - *res_len = actual_len; + ZSTR_VAL(u8res)[actual_len] = '\0'; + ZSTR_LEN(u8res) = actual_len; - return SUCCESS; + return u8res; } /* }}} */ diff --git a/ext/intl/intl_convertcpp.h b/ext/intl/intl_convertcpp.h index c4b689166d..45ba7a2cd7 100644 --- a/ext/intl/intl_convertcpp.h +++ b/ext/intl/intl_convertcpp.h @@ -23,10 +23,11 @@ #error Should be included only in C++ Files #endif +#include #include int intl_stringFromChar(UnicodeString &ret, char *str, size_t str_len, UErrorCode *status); -int intl_charFromString(const UnicodeString &from, char **res, size_t *res_len, UErrorCode *status); +zend_string* intl_charFromString(const UnicodeString &from, UErrorCode *status); #endif /* INTL_CONVERTCPP_H */ diff --git a/ext/intl/intl_data.h b/ext/intl/intl_data.h index 8a11639047..12e0a9924e 100644 --- a/ext/intl/intl_data.h +++ b/ext/intl/intl_data.h @@ -84,15 +84,13 @@ typedef struct _intl_data { #define INTL_METHOD_RETVAL_UTF8(obj, ustring, ulen, free_it) \ { \ - char *u8value; \ - size_t u8len; \ - intl_convert_utf16_to_utf8(&u8value, &u8len, ustring, ulen, &INTL_DATA_ERROR_CODE((obj))); \ + zend_string *u8str; \ + u8str = intl_convert_utf16_to_utf8(ustring, ulen, &INTL_DATA_ERROR_CODE((obj))); \ if((free_it)) { \ efree(ustring); \ } \ INTL_METHOD_CHECK_STATUS((obj), "Error converting value to UTF-8"); \ - RETVAL_STRINGL(u8value, u8len); \ - efree(u8value); \ + RETVAL_NEW_STR(u8str); \ } #define INTL_MAX_LOCALE_LEN 80 diff --git a/ext/intl/intl_error.c b/ext/intl/intl_error.c index a480c5ab11..d5e246efb1 100644 --- a/ext/intl/intl_error.c +++ b/ext/intl/intl_error.c @@ -246,11 +246,10 @@ void intl_register_IntlException_class( void ) smart_str intl_parse_error_to_string( UParseError* pe ) { - smart_str ret = {0}; - char *buf; - size_t u8len; - UErrorCode status; - int any = 0; + smart_str ret = {0}; + zend_string *u8str; + UErrorCode status; + int any = 0; assert( pe != NULL ); @@ -277,14 +276,14 @@ smart_str intl_parse_error_to_string( UParseError* pe ) smart_str_appends( &ret, ", " ); smart_str_appends( &ret, "after \"" ); - intl_convert_utf16_to_utf8( &buf, &u8len, pe->preContext, -1, &status ); - if( U_FAILURE( status ) ) + u8str = intl_convert_utf16_to_utf8(pe->preContext, -1, &status ); + if( !u8str ) { smart_str_appends( &ret, "(could not convert parser error pre-context to UTF-8)" ); } else { - smart_str_appendl( &ret, buf, u8len ); - efree( buf ); + smart_str_append( &ret, u8str ); + zend_string_release( u8str ); } smart_str_appends( &ret, "\"" ); any = 1; @@ -296,15 +295,15 @@ smart_str intl_parse_error_to_string( UParseError* pe ) smart_str_appends( &ret, ", " ); smart_str_appends( &ret, "before or at \"" ); - intl_convert_utf16_to_utf8( &buf, &u8len, pe->postContext, -1, &status ); - if( U_FAILURE( status ) ) + u8str = intl_convert_utf16_to_utf8(pe->postContext, -1, &status ); + if( !u8str ) { smart_str_appends( &ret, "(could not convert parser error post-context to UTF-8)" ); } else { - smart_str_appendl( &ret, buf, u8len ); - efree( buf ); + smart_str_append( &ret, u8str ); + zend_string_release( u8str ); } smart_str_appends( &ret, "\"" ); any = 1; diff --git a/ext/intl/locale/locale_methods.c b/ext/intl/locale/locale_methods.c index 7b36d61c02..895d803ef9 100644 --- a/ext/intl/locale/locale_methods.c +++ b/ext/intl/locale/locale_methods.c @@ -487,8 +487,7 @@ static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAME int32_t buflen = 512; UErrorCode status = U_ZERO_ERROR; - char* utf8value = NULL; - size_t utf8value_len = 0; + zend_string* u8str; char* msg = NULL; int grOffset = 0; @@ -591,9 +590,9 @@ static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAME disp_loc_name = NULL; } /* Convert display locale name from UTF-16 to UTF-8. */ - intl_convert_utf16_to_utf8( &utf8value, &utf8value_len, disp_name, buflen, &status ); + u8str = intl_convert_utf16_to_utf8(disp_name, buflen, &status ); efree( disp_name ); - if( U_FAILURE( status ) ) + if( !u8str ) { spprintf(&msg, 0, "locale_get_display_%s :error converting display name for %s to UTF-8", tag_name , tag_name ); intl_error_set( NULL, status, msg , 1 ); @@ -601,10 +600,7 @@ static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAME RETURN_FALSE; } - RETVAL_STRINGL( utf8value, utf8value_len ); - //???? - efree(utf8value); - + RETVAL_NEW_STR( u8str ); } /* }}} */ @@ -695,8 +691,8 @@ PHP_FUNCTION( locale_get_keywords ) ICU uloc.h #define ULOC_KEYWORD_AND_VALUES_CAPACITY 100 hence the kw_value buffer size is 100 */ - char* kw_value = NULL; - int32_t kw_value_len = 100; + zend_string *kw_value_str; + int32_t kw_value_len = 100; intl_error_reset( NULL ); @@ -721,29 +717,28 @@ PHP_FUNCTION( locale_get_keywords ) array_init( return_value ); while( ( kw_key = uenum_next( e, &kw_key_len, &status ) ) != NULL ){ - kw_value = ecalloc( 1 , kw_value_len ); + kw_value_len = 100; + kw_value_str = zend_string_alloc(kw_value_len, 0); /* Get the keyword value for each keyword */ - kw_value_len=uloc_getKeywordValue( loc_name,kw_key, kw_value, kw_value_len , &status ); + kw_value_len=uloc_getKeywordValue( loc_name, kw_key, ZSTR_VAL(kw_value_str), kw_value_len, &status ); if (status == U_BUFFER_OVERFLOW_ERROR) { status = U_ZERO_ERROR; - kw_value = erealloc( kw_value , kw_value_len+1); - kw_value_len=uloc_getKeywordValue( loc_name,kw_key, kw_value, kw_value_len+1 , &status ); + kw_value_str = zend_string_extend(kw_value_str, kw_value_len, 0); + kw_value_len=uloc_getKeywordValue( loc_name,kw_key, ZSTR_VAL(kw_value_str), kw_value_len+1, &status ); } else if(!U_FAILURE(status)) { - kw_value = erealloc( kw_value , kw_value_len+1); + kw_value_str = zend_string_truncate(kw_value_str, kw_value_len, 0); } if (U_FAILURE(status)) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "locale_get_keywords: Error encountered while getting the keyword value for the keyword", 0 ); - if( kw_value){ - efree( kw_value ); + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "locale_get_keywords: Error encountered while getting the keyword value for the keyword", 0 ); + if( kw_value_str){ + zend_string_free( kw_value_str ); } zval_dtor(return_value); RETURN_FALSE; } - // TODO: avoid reallocation ??? - add_assoc_stringl( return_value, (char *)kw_key, kw_value , kw_value_len); - efree(kw_value); + add_assoc_str( return_value, (char *)kw_key, kw_value_str); } /* end of while */ } /* end of if e!=NULL */ @@ -1415,7 +1410,7 @@ static void array_cleanup( char* arr[] , int arr_size) * returns the lookup result to lookup_loc_range_src_php * internal function */ -static char* lookup_loc_range(const char* loc_range, HashTable* hash_arr, int canonicalize ) +static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr, int canonicalize ) { int i = 0; int cur_arr_len = 0; @@ -1429,7 +1424,7 @@ static char* lookup_loc_range(const char* loc_range, HashTable* hash_arr, int ca char* can_loc_range = NULL; int saved_pos = 0; - char* return_value = NULL; + zend_string* return_value = NULL; cur_arr = ecalloc(zend_hash_num_elements(hash_arr)*2, sizeof(char *)); ZEND_HASH_FOREACH_VAL(hash_arr, ele_value) { @@ -1503,7 +1498,8 @@ static char* lookup_loc_range(const char* loc_range, HashTable* hash_arr, int ca for(i=0; i< cur_arr_len; i++){ if(cur_arr[i*2] != NULL && strlen(cur_arr[i*2]) == saved_pos && strncmp(cur_loc_range, cur_arr[i*2], saved_pos) == 0) { /* Match found */ - return_value = estrdup(canonicalize?cur_arr[i*2]:cur_arr[i*2+1]); + char *str = canonicalize ? cur_arr[i*2] : cur_arr[i*2+1]; + return_value = zend_string_init(str, strlen(str), 0); efree(cur_loc_range); LOOKUP_CLEAN_RETURN(return_value); } @@ -1528,20 +1524,19 @@ static char* lookup_loc_range(const char* loc_range, HashTable* hash_arr, int ca */ PHP_FUNCTION(locale_lookup) { - char* fallback_loc = NULL; - size_t fallback_loc_len = 0; + zend_string* fallback_loc_str = NULL; const char* loc_range = NULL; size_t loc_range_len = 0; zval* arr = NULL; HashTable* hash_arr = NULL; zend_bool boolCanonical = 0; - char* result =NULL; + zend_string* result_str = NULL; intl_error_reset( NULL ); - if(zend_parse_parameters( ZEND_NUM_ARGS(), "as|bs", &arr, &loc_range, &loc_range_len, - &boolCanonical, &fallback_loc, &fallback_loc_len) == FAILURE) { + if(zend_parse_parameters( ZEND_NUM_ARGS(), "as|bS", &arr, &loc_range, &loc_range_len, + &boolCanonical, &fallback_loc_str) == FAILURE) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "locale_lookup: unable to parse input params", 0 ); RETURN_FALSE; } @@ -1556,18 +1551,16 @@ PHP_FUNCTION(locale_lookup) RETURN_EMPTY_STRING(); } - result = lookup_loc_range(loc_range, hash_arr, boolCanonical); - if(result == NULL || result[0] == '\0') { - if( fallback_loc ) { - result = estrndup(fallback_loc, fallback_loc_len); + result_str = lookup_loc_range(loc_range, hash_arr, boolCanonical); + if(result_str == NULL || ZSTR_VAL(result_str)[0] == '\0') { + if( fallback_loc_str ) { + result_str = zend_string_copy(fallback_loc_str); } else { RETURN_EMPTY_STRING(); } } - RETVAL_STRINGL(result, strlen(result)); - //???? - efree(result); + RETURN_STR(result_str); } /* }}} */ diff --git a/ext/intl/msgformat/msgformat_helpers.cpp b/ext/intl/msgformat/msgformat_helpers.cpp index a2bede910a..ed63105fa7 100644 --- a/ext/intl/msgformat/msgformat_helpers.cpp +++ b/ext/intl/msgformat/msgformat_helpers.cpp @@ -536,14 +536,15 @@ retry_kint64: { double dd = intl_zval_to_millis(elem, &err, "msgfmt_format"); if (U_FAILURE(err.code)) { - char *message, *key_char; - size_t key_len; + char *message; + zend_string *u8key; UErrorCode status = UErrorCode(); - if (intl_charFromString(key, &key_char, &key_len, &status) == SUCCESS) { + u8key = intl_charFromString(key, &status); + if (u8key) { spprintf(&message, 0, "The argument for key '%s' " - "cannot be used as a date or time", key_char); + "cannot be used as a date or time", ZSTR_VAL(u8key)); intl_errors_set(&err, err.code, message, 1); - efree(key_char); + zend_string_release(u8key); efree(message); } continue; @@ -579,17 +580,17 @@ retry_kint64: goto string_arg; default: { - char *message, *key_char; - size_t key_len; + char *message; + zend_string *u8key; UErrorCode status = UErrorCode(); - if (intl_charFromString(key, &key_char, &key_len, - &status) == SUCCESS) { + u8key = intl_charFromString(key, &status); + if (u8key) { spprintf(&message, 0, "No strategy to convert the " "value given for the argument with key '%s' " - "is available", key_char); + "is available", ZSTR_VAL(u8key)); intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, message, 1); - efree(key_char); + zend_string_release(u8key); efree(message); } } @@ -643,8 +644,7 @@ U_CFUNC void umsg_parse_helper(UMessageFormat *fmt, int *count, zval **args, UCh int64_t aInt64; double aDate; UnicodeString temp; - char *stmp; - size_t stmp_len; + zend_string *u8str; switch(fargs[i].getType()) { case Formattable::kDate: @@ -671,14 +671,12 @@ U_CFUNC void umsg_parse_helper(UMessageFormat *fmt, int *count, zval **args, UCh case Formattable::kString: fargs[i].getString(temp); - intl_convert_utf16_to_utf8(&stmp, &stmp_len, temp.getBuffer(), temp.length(), status); - if(U_FAILURE(*status)) { + u8str = intl_convert_utf16_to_utf8(temp.getBuffer(), temp.length(), status); + if(!u8str) { cleanup_zvals(); return; } - ZVAL_STRINGL(&(*args)[i], stmp, stmp_len); - //??? - efree(stmp); + ZVAL_NEW_STR(&(*args)[i], u8str); break; case Formattable::kObject: diff --git a/ext/intl/normalizer/normalizer_normalize.c b/ext/intl/normalizer/normalizer_normalize.c index 116a141d91..52780acdbc 100644 --- a/ext/intl/normalizer/normalizer_normalize.c +++ b/ext/intl/normalizer/normalizer_normalize.c @@ -45,8 +45,7 @@ PHP_FUNCTION( normalizer_normalize ) UChar* uret_buf = NULL; int32_t uret_len = 0; - char* ret_buf = NULL; - size_t ret_len = 0; + zend_string* u8str; int32_t size_needed; @@ -149,9 +148,9 @@ PHP_FUNCTION( normalizer_normalize ) uret_len = size_needed; /* Convert normalized string from UTF-16 to UTF-8. */ - intl_convert_utf16_to_utf8( &ret_buf, &ret_len, uret_buf, uret_len, &status ); + u8str = intl_convert_utf16_to_utf8(uret_buf, uret_len, &status ); efree( uret_buf ); - if( U_FAILURE( status ) ) + if( !u8str ) { intl_error_set( NULL, status, "normalizer_normalize: error converting normalized text UTF-8", 0 ); @@ -159,9 +158,7 @@ PHP_FUNCTION( normalizer_normalize ) } /* Return it. */ - RETVAL_STRINGL( ret_buf, ret_len ); - //??? - efree(ret_buf); + RETVAL_NEW_STR( u8str ); } /* }}} */ diff --git a/ext/intl/timezone/timezone_class.cpp b/ext/intl/timezone/timezone_class.cpp index 77569c09e2..d1e8e2e0a6 100644 --- a/ext/intl/timezone/timezone_class.cpp +++ b/ext/intl/timezone/timezone_class.cpp @@ -86,18 +86,16 @@ U_CFUNC zval *timezone_convert_to_datetimezone(const TimeZone *timeZone, //convert offset from milliseconds to minutes tzobj->tzi.utc_offset = -1 * timeZone->getRawOffset() / (60 * 1000); } else { - char *str; - size_t str_len; + zend_string *u8str; /* Call the constructor! */ - if (intl_charFromString(id, &str, &str_len, &INTL_ERROR_CODE(*outside_error)) == FAILURE) { + u8str = intl_charFromString(id, &INTL_ERROR_CODE(*outside_error)); + if (!u8str) { spprintf(&message, 0, "%s: could not convert id to UTF-8", func); intl_errors_set(outside_error, INTL_ERROR_CODE(*outside_error), message, 1); goto error; } - ZVAL_STRINGL(&arg, str, str_len); - //??? - efree(str); + ZVAL_STR(&arg, u8str); zend_call_method_with_1_params(ret, NULL, NULL, "__construct", NULL, &arg); if (EG(exception)) { spprintf(&message, 0, @@ -291,8 +289,7 @@ static HashTable *TimeZone_get_debug_info(zval *object, int *is_temp) TimeZone_object *to; const TimeZone *tz; UnicodeString ustr; - char *str; - size_t str_len; + zend_string *u8str; HashTable *debug_info; UErrorCode uec = U_ZERO_ERROR; @@ -314,15 +311,13 @@ static HashTable *TimeZone_get_debug_info(zval *object, int *is_temp) zend_hash_str_update(debug_info, "valid", sizeof("valid") - 1, &zv); tz->getID(ustr); - intl_convert_utf16_to_utf8(&str, &str_len, + u8str = intl_convert_utf16_to_utf8( ustr.getBuffer(), ustr.length(), &uec); - if (U_FAILURE(uec)) { + if (!u8str) { return debug_info; } - ZVAL_STRINGL(&zv, str, str_len); + ZVAL_NEW_STR(&zv, u8str); zend_hash_str_update(debug_info, "id", sizeof("id") - 1, &zv); - // TODO: avoid reallocation ??? - efree(str); int32_t rawOffset, dstOffset; UDate now = Calendar::getNow(); diff --git a/ext/intl/timezone/timezone_methods.cpp b/ext/intl/timezone/timezone_methods.cpp index 728f9bde8b..c46b448bbe 100644 --- a/ext/intl/timezone/timezone_methods.cpp +++ b/ext/intl/timezone/timezone_methods.cpp @@ -305,14 +305,10 @@ U_CFUNC PHP_FUNCTION(intltz_get_canonical_id) TimeZone::getCanonicalID(id, result, isSystemID, status); INTL_CHECK_STATUS(status, "intltz_get_canonical_id: error obtaining canonical ID"); - char *str; - size_t str_len; - intl_convert_utf16_to_utf8(&str, &str_len, result.getBuffer(), result.length(), &status); + zend_string *u8str =intl_convert_utf16_to_utf8(result.getBuffer(), result.length(), &status); INTL_CHECK_STATUS(status, "intltz_get_canonical_id: could not convert time zone id to UTF-16"); - RETVAL_STRINGL(str, str_len); - //???? - efree(str); + RETVAL_NEW_STR(u8str); if (is_systemid) { /* by-ref argument passed */ ZVAL_DEREF(is_systemid); @@ -393,15 +389,12 @@ U_CFUNC PHP_FUNCTION(intltz_get_equivalent_id) } const UnicodeString result = TimeZone::getEquivalentID(id, (int32_t)index); - char *str; - size_t str_len; + zend_string *u8str; - intl_convert_utf16_to_utf8(&str, &str_len, result.getBuffer(), result.length(), &status); + u8str = intl_convert_utf16_to_utf8(result.getBuffer(), result.length(), &status); INTL_CHECK_STATUS(status, "intltz_get_equivalent_id: " "could not convert resulting time zone id to UTF-16"); - RETVAL_STRINGL(str, str_len); - //???? - efree(str); + RETVAL_NEW_STR(u8str); } U_CFUNC PHP_FUNCTION(intltz_get_id) @@ -420,16 +413,13 @@ U_CFUNC PHP_FUNCTION(intltz_get_id) UnicodeString id_us; to->utimezone->getID(id_us); - char *id = NULL; - size_t id_len = 0; + zend_string *u8str; - intl_convert_utf16_to_utf8(&id, &id_len, + u8str = intl_convert_utf16_to_utf8( id_us.getBuffer(), id_us.length(), TIMEZONE_ERROR_CODE_P(to)); INTL_METHOD_CHECK_STATUS(to, "intltz_get_id: Could not convert id to UTF-8"); - RETVAL_STRINGL(id, id_len); - //??? - efree(id); + RETVAL_NEW_STR(u8str); } U_CFUNC PHP_FUNCTION(intltz_use_daylight_time) @@ -569,15 +559,11 @@ U_CFUNC PHP_FUNCTION(intltz_get_display_name) to->utimezone->getDisplayName((UBool)daylight, (TimeZone::EDisplayType)display_type, Locale::createFromName(locale_str), result); - char *str; - size_t str_len; - intl_convert_utf16_to_utf8(&str, &str_len, result.getBuffer(), result.length(), TIMEZONE_ERROR_CODE_P(to)); + zend_string *u8str = intl_convert_utf16_to_utf8(result.getBuffer(), result.length(), TIMEZONE_ERROR_CODE_P(to)); INTL_METHOD_CHECK_STATUS(to, "intltz_get_display_name: " "could not convert resulting time zone id to UTF-16"); - RETVAL_STRINGL(str, str_len); - //???? - efree(str); + RETVAL_NEW_STR(u8str); } U_CFUNC PHP_FUNCTION(intltz_get_dst_savings) diff --git a/ext/intl/transliterator/transliterator_class.c b/ext/intl/transliterator/transliterator_class.c index f2cb9f42e4..ce8c7e6291 100644 --- a/ext/intl/transliterator/transliterator_class.c +++ b/ext/intl/transliterator/transliterator_class.c @@ -36,8 +36,8 @@ int transliterator_object_construct( zval *object, { const UChar *ustr_id; int32_t ustr_id_len; - char *str_id; - size_t str_id_len; + zend_string *u8str; + zval tmp; Transliterator_object *to; TRANSLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK; @@ -49,15 +49,16 @@ int transliterator_object_construct( zval *object, to->utrans = utrans; ustr_id = utrans_getUnicodeID( utrans, &ustr_id_len ); - intl_convert_utf16_to_utf8( &str_id, &str_id_len, ustr_id, (int ) ustr_id_len, status ); - if( U_FAILURE( *status ) ) + u8str = intl_convert_utf16_to_utf8(ustr_id, (int ) ustr_id_len, status ); + if( !u8str ) { return FAILURE; } - zend_update_property_stringl(Transliterator_ce_ptr, object, - "id", sizeof( "id" ) - 1, str_id, str_id_len ); - efree( str_id ); + ZVAL_NEW_STR(&tmp, u8str); + zend_update_property(Transliterator_ce_ptr, object, + "id", sizeof( "id" ) - 1, &tmp ); + GC_REFCOUNT(u8str)--; return SUCCESS; } /* }}} */ diff --git a/ext/intl/transliterator/transliterator_methods.c b/ext/intl/transliterator/transliterator_methods.c index 4fcdf3dea2..e7b0870891 100644 --- a/ext/intl/transliterator/transliterator_methods.c +++ b/ext/intl/transliterator/transliterator_methods.c @@ -265,21 +265,15 @@ PHP_FUNCTION( transliterator_list_ids ) array_init( return_value ); while( (elem = uenum_unext( en, &elem_len, &status )) ) { - char *el_char = NULL; - size_t el_len = 0; + zend_string *el = intl_convert_utf16_to_utf8(elem, elem_len, &status ); - intl_convert_utf16_to_utf8( &el_char, &el_len, elem, elem_len, &status ); - - if( U_FAILURE( status ) ) + if( !el ) { - efree( el_char ); break; } else { - // TODO: avoid reallocation ??? - add_next_index_stringl( return_value, el_char, el_len); - efree(el_char); + add_next_index_str( return_value, el); } } uenum_close( en ); diff --git a/ext/intl/uchar/uchar.c b/ext/intl/uchar/uchar.c index a38723ea9c..0dbe9c9cf8 100644 --- a/ext/intl/uchar/uchar.c +++ b/ext/intl/uchar/uchar.c @@ -533,9 +533,8 @@ IC_METHOD(getFC_NFKC_Closure) { UChar32 cp; zval *zcp; UChar *closure; - char *ret; + zend_string *u8str; int32_t closure_len; - size_t ret_len; UErrorCode error = U_ZERO_ERROR; if ((zend_parse_parameters(ZEND_NUM_ARGS(), "z", &zcp) == FAILURE) || @@ -556,11 +555,10 @@ IC_METHOD(getFC_NFKC_Closure) { } error = U_ZERO_ERROR; - intl_convert_utf16_to_utf8(&ret, &ret_len, closure, closure_len, &error); + u8str = intl_convert_utf16_to_utf8(closure, closure_len, &error); efree(closure); INTL_CHECK_STATUS(error, "Failed converting output to UTF8"); - RETVAL_STRINGL(ret, ret_len); - efree(ret); + RETVAL_NEW_STR(u8str); } /* }}} */