diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2017-07-23 23:10:53 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2017-07-23 23:17:12 +0200 |
commit | 445e13b149fe68faa9aa4cd7b0921519266dc2e5 (patch) | |
tree | e90cf31b7fcbff282d3c747ba01a7b3cdbd17739 /ext/mbstring/mbstring.c | |
parent | 0e8346bd16af9d7ef26f61033ba979fc547d1d8b (diff) | |
download | php-git-445e13b149fe68faa9aa4cd7b0921519266dc2e5.tar.gz |
Add MBFL_SUBSTR_TO_END mode to mbfl_substr
This takes the substr from the offset to the end of the string.
This avoids pointless searching for the end position and also
saves us a length calculation in the strstr family of functions.
Diffstat (limited to 'ext/mbstring/mbstring.c')
-rw-r--r-- | ext/mbstring/mbstring.c | 58 |
1 files changed, 24 insertions, 34 deletions
diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 58556410d1..4f3b7dc08e 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -2595,7 +2595,6 @@ PHP_FUNCTION(mb_strstr) n = mbfl_strpos(&haystack, &needle, 0, 0); if (!mbfl_is_error(n)) { - size_t mblen = mbfl_strlen(&haystack); if (part) { ret = mbfl_substr(&haystack, &result, 0, n); if (ret != NULL) { @@ -2606,8 +2605,7 @@ PHP_FUNCTION(mb_strstr) RETVAL_FALSE; } } else { - size_t len = (mblen - n); - ret = mbfl_substr(&haystack, &result, n, len); + ret = mbfl_substr(&haystack, &result, n, MBFL_SUBSTR_UNTIL_END); if (ret != NULL) { // TODO: avoid reallocation ??? RETVAL_STRINGL((char *)ret->val, ret->len); @@ -2654,7 +2652,6 @@ PHP_FUNCTION(mb_strrchr) n = mbfl_strpos(&haystack, &needle, 0, 1); if (!mbfl_is_error(n)) { - size_t mblen = mbfl_strlen(&haystack); if (part) { ret = mbfl_substr(&haystack, &result, 0, n); if (ret != NULL) { @@ -2665,8 +2662,7 @@ PHP_FUNCTION(mb_strrchr) RETVAL_FALSE; } } else { - size_t len = (mblen - n); - ret = mbfl_substr(&haystack, &result, n, len); + ret = mbfl_substr(&haystack, &result, n, MBFL_SUBSTR_UNTIL_END); if (ret != NULL) { // TODO: avoid reallocation ??? RETVAL_STRINGL((char *)ret->val, ret->len); @@ -2686,7 +2682,7 @@ PHP_FUNCTION(mb_strrchr) PHP_FUNCTION(mb_stristr) { zend_bool part = 0; - size_t from_encoding_len, n, len, mblen; + size_t from_encoding_len, n; mbfl_string haystack, needle, result, *ret = NULL; const char *from_encoding = NULL; mbfl_string_init(&haystack); @@ -2712,8 +2708,6 @@ PHP_FUNCTION(mb_stristr) RETURN_FALSE; } - mblen = mbfl_strlen(&haystack); - if (part) { ret = mbfl_substr(&haystack, &result, 0, n); if (ret != NULL) { @@ -2724,8 +2718,7 @@ PHP_FUNCTION(mb_stristr) RETVAL_FALSE; } } else { - len = (mblen - n); - ret = mbfl_substr(&haystack, &result, n, len); + ret = mbfl_substr(&haystack, &result, n, MBFL_SUBSTR_UNTIL_END); if (ret != NULL) { // TODO: avoid reallocaton ??? RETVAL_STRINGL((char *)ret->val, ret->len); @@ -2742,7 +2735,7 @@ PHP_FUNCTION(mb_stristr) PHP_FUNCTION(mb_strrichr) { zend_bool part = 0; - size_t n, len, mblen; + size_t n; size_t from_encoding_len; mbfl_string haystack, needle, result, *ret = NULL; const char *from_encoding = NULL; @@ -2764,8 +2757,6 @@ PHP_FUNCTION(mb_strrichr) RETURN_FALSE; } - mblen = mbfl_strlen(&haystack); - if (part) { ret = mbfl_substr(&haystack, &result, 0, n); if (ret != NULL) { @@ -2776,8 +2767,7 @@ PHP_FUNCTION(mb_strrichr) RETVAL_FALSE; } } else { - len = (mblen - n); - ret = mbfl_substr(&haystack, &result, n, len); + ret = mbfl_substr(&haystack, &result, n, MBFL_SUBSTR_UNTIL_END); if (ret != NULL) { // TODO: avoid reallocation ??? RETVAL_STRINGL((char *)ret->val, ret->len); @@ -2831,7 +2821,7 @@ PHP_FUNCTION(mb_substr) { char *str, *encoding = NULL; zend_long from, len; - size_t mblen; + size_t mblen, real_from, real_len; size_t str_len, encoding_len; zend_bool len_is_null = 1; mbfl_string string, result, *ret; @@ -2850,42 +2840,42 @@ PHP_FUNCTION(mb_substr) string.val = (unsigned char *)str; string.len = str_len; - if (len_is_null) { - len = str_len; - } - /* measures length */ mblen = 0; - if (from < 0 || len < 0) { + if (from < 0 || (!len_is_null && len < 0)) { mblen = mbfl_strlen(&string); } /* if "from" position is negative, count start position from the end * of the string */ - if (from < 0) { - from = mblen + from; - if (from < 0) { - from = 0; - } + if (from >= 0) { + real_from = (size_t) from; + } else if (-from < mblen) { + real_from = mblen + from; + } else { + real_from = 0; } /* if "length" position is negative, set it to the length * needed to stop that many chars from the end of the string */ - if (len < 0) { - len = (mblen - from) + len; - if (len < 0) { - len = 0; - } + if (len_is_null) { + real_len = MBFL_SUBSTR_UNTIL_END; + } else if (len >= 0) { + real_len = (size_t) len; + } else if (real_from < mblen && -len < mblen - real_from) { + real_len = (mblen - real_from) + len; + } else { + real_len = 0; } if (((MBSTRG(func_overload) & MB_OVERLOAD_STRING) == MB_OVERLOAD_STRING) - && (from >= mbfl_strlen(&string))) { + && (real_from >= mbfl_strlen(&string))) { RETURN_FALSE; } - ret = mbfl_substr(&string, &result, from, len); + ret = mbfl_substr(&string, &result, real_from, real_len); if (NULL == ret) { RETURN_FALSE; } |