@@ -63,6 +63,17 @@ static _FORCE_INLINE_ char32_t lower_case(char32_t c) {
6363 return (is_ascii_upper_case (c) ? (c + (' a' - ' A' )) : c);
6464}
6565
66+ // Case-insensitive version of are_spans_equal
67+ template <typename T1, typename T2>
68+ static bool strings_equal_lower (const T1 *p_lhs_begin, const T2 *p_rhs_begin, size_t p_len) {
69+ for (size_t i = 0 ; i < p_len; ++i) {
70+ if (_find_lower (p_lhs_begin[i]) != _find_lower (p_rhs_begin[i])) {
71+ return false ;
72+ }
73+ }
74+ return true ;
75+ }
76+
6677Error String::parse_url (String &r_scheme, String &r_host, int &r_port, String &r_path, String &r_fragment) const {
6778 // Splits the URL into scheme, host, port, path, fragment. Strip credentials when present.
6879 String base = *this ;
@@ -3043,41 +3054,7 @@ int String::find(const char *p_str, int p_from) const {
30433054 return find_char (*p_str, p_from); // Optimize with single-char find.
30443055 }
30453056
3046- const char32_t *src = get_data ();
3047-
3048- if (str_len == 1 ) {
3049- const char32_t needle = p_str[0 ];
3050-
3051- for (int i = p_from; i < len; i++) {
3052- if (src[i] == needle) {
3053- return i;
3054- }
3055- }
3056-
3057- } else {
3058- for (int i = p_from; i <= (len - str_len); i++) {
3059- bool found = true ;
3060- for (int j = 0 ; j < str_len; j++) {
3061- int read_pos = i + j;
3062-
3063- if (read_pos >= len) {
3064- ERR_PRINT (" read_pos>=length()" );
3065- return -1 ;
3066- }
3067-
3068- if (src[read_pos] != (char32_t )p_str[j]) {
3069- found = false ;
3070- break ;
3071- }
3072- }
3073-
3074- if (found) {
3075- return i;
3076- }
3077- }
3078- }
3079-
3080- return -1 ;
3057+ return span ().find_sequence (Span ((const unsigned char *)p_str, str_len), p_from);
30813058}
30823059
30833060int String::find_char (char32_t p_char, int p_from) const {
@@ -3110,36 +3087,21 @@ int String::findmk(const Vector<String> &p_keys, int p_from, int *r_key) const {
31103087 const char32_t *src = get_data ();
31113088
31123089 for (int i = p_from; i < len; i++) {
3113- bool found = true ;
31143090 for (int k = 0 ; k < key_count; k++) {
3115- found = true ;
3116- if (r_key) {
3117- *r_key = k;
3118- }
3119- const char32_t *cmp = keys[k].get_data ();
3120- int l = keys[k].length ();
3121-
3122- for (int j = 0 ; j < l; j++) {
3123- int read_pos = i + j;
3091+ const int str_len = keys[k].length ();
31243092
3125- if (read_pos >= len) {
3126- found = false ;
3127- break ;
3128- }
3093+ if (i + str_len > len) {
3094+ continue ; // Can't find this key here.
3095+ }
31293096
3130- if (src[read_pos] != cmp[j]) {
3131- found = false ;
3132- break ;
3097+ const char32_t *str = keys[k].get_data ();
3098+ if (are_spans_equal (src + i, str, str_len)) {
3099+ if (r_key) {
3100+ *r_key = k;
31333101 }
3134- }
3135- if (found) {
3136- break ;
3102+ return i;
31373103 }
31383104 }
3139-
3140- if (found) {
3141- return i;
3142- }
31433105 }
31443106
31453107 return -1 ;
@@ -3156,28 +3118,11 @@ int String::findn(const String &p_str, int p_from) const {
31563118 return -1 ; // Still out of bounds
31573119 }
31583120
3159- const char32_t *srcd = get_data ();
3121+ const char32_t *src = get_data ();
3122+ const char32_t *str = p_str.get_data ();
31603123
31613124 for (int i = p_from; i <= (len - str_len); i++) {
3162- bool found = true ;
3163- for (int j = 0 ; j < str_len; j++) {
3164- int read_pos = i + j;
3165-
3166- if (read_pos >= len) {
3167- ERR_PRINT (" read_pos>=length()" );
3168- return -1 ;
3169- }
3170-
3171- char32_t src = _find_lower (srcd[read_pos]);
3172- char32_t dst = _find_lower (p_str[j]);
3173-
3174- if (src != dst) {
3175- found = false ;
3176- break ;
3177- }
3178- }
3179-
3180- if (found) {
3125+ if (strings_equal_lower (src + i, str, str_len)) {
31813126 return i;
31823127 }
31833128 }
@@ -3196,28 +3141,10 @@ int String::findn(const char *p_str, int p_from) const {
31963141 return -1 ; // Still out of bounds
31973142 }
31983143
3199- const char32_t *srcd = get_data ();
3144+ const char32_t *src = get_data ();
32003145
32013146 for (int i = p_from; i <= (len - str_len); i++) {
3202- bool found = true ;
3203- for (int j = 0 ; j < str_len; j++) {
3204- int read_pos = i + j;
3205-
3206- if (read_pos >= len) {
3207- ERR_PRINT (" read_pos>=length()" );
3208- return -1 ;
3209- }
3210-
3211- char32_t src = _find_lower (srcd[read_pos]);
3212- char32_t dst = _find_lower (p_str[j]);
3213-
3214- if (src != dst) {
3215- found = false ;
3216- break ;
3217- }
3218- }
3219-
3220- if (found) {
3147+ if (strings_equal_lower (src + i, p_str, str_len)) {
32213148 return i;
32223149 }
32233150 }
@@ -3255,31 +3182,12 @@ int String::rfind(const char *p_str, int p_from) const {
32553182 return -1 ; // Still out of bounds
32563183 }
32573184
3258- const char32_t *source = get_data ();
3259-
3260- for (int i = p_from; i >= 0 ; i--) {
3261- bool found = true ;
3262- for (int j = 0 ; j < str_len; j++) {
3263- int read_pos = i + j;
3264-
3265- if (read_pos >= length ()) {
3266- ERR_PRINT (" read_pos>=length()" );
3267- return -1 ;
3268- }
3269-
3270- const char32_t key_needle = p_str[j];
3271- if (source[read_pos] != key_needle) {
3272- found = false ;
3273- break ;
3274- }
3275- }
3276-
3277- if (found) {
3278- return i;
3279- }
3185+ if (str_len == 1 ) {
3186+ // Optimize with single-char implementation.
3187+ return span ().rfind (p_str[0 ], p_from);
32803188 }
32813189
3282- return - 1 ;
3190+ return span (). rfind_sequence ( Span (( const unsigned char *)p_str, str_len), p_from) ;
32833191}
32843192
32853193int String::rfind_char (char32_t p_char, int p_from) const {
@@ -3303,28 +3211,16 @@ int String::rfindn(const String &p_str, int p_from) const {
33033211 return -1 ; // Still out of bounds
33043212 }
33053213
3214+ if (str_len == 1 ) {
3215+ // Optimize with single-char implementation.
3216+ return span ().rfind (p_str[0 ], p_from);
3217+ }
3218+
33063219 const char32_t *src = get_data ();
3220+ const char32_t *str = p_str.get_data ();
33073221
33083222 for (int i = p_from; i >= 0 ; i--) {
3309- bool found = true ;
3310- for (int j = 0 ; j < str_len; j++) {
3311- int read_pos = i + j;
3312-
3313- if (read_pos >= len) {
3314- ERR_PRINT (" read_pos>=length()" );
3315- return -1 ;
3316- }
3317-
3318- char32_t srcc = _find_lower (src[read_pos]);
3319- char32_t dstc = _find_lower (p_str[j]);
3320-
3321- if (srcc != dstc) {
3322- found = false ;
3323- break ;
3324- }
3325- }
3326-
3327- if (found) {
3223+ if (strings_equal_lower (src + i, str, str_len)) {
33283224 return i;
33293225 }
33303226 }
@@ -3343,29 +3239,10 @@ int String::rfindn(const char *p_str, int p_from) const {
33433239 return -1 ; // Still out of bounds
33443240 }
33453241
3346- const char32_t *source = get_data ();
3242+ const char32_t *src = get_data ();
33473243
33483244 for (int i = p_from; i >= 0 ; i--) {
3349- bool found = true ;
3350- for (int j = 0 ; j < str_len; j++) {
3351- int read_pos = i + j;
3352-
3353- if (read_pos >= len) {
3354- ERR_PRINT (" read_pos>=length()" );
3355- return -1 ;
3356- }
3357-
3358- const char32_t key_needle = p_str[j];
3359- int srcc = _find_lower (source[read_pos]);
3360- int keyc = _find_lower (key_needle);
3361-
3362- if (srcc != keyc) {
3363- found = false ;
3364- break ;
3365- }
3366- }
3367-
3368- if (found) {
3245+ if (strings_equal_lower (src + i, p_str, str_len)) {
33693246 return i;
33703247 }
33713248 }
0 commit comments