1 /*************************************************************************/
2 /*  ustring.cpp                                                          */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
10 /*                                                                       */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the       */
13 /* "Software"), to deal in the Software without restriction, including   */
14 /* without limitation the rights to use, copy, modify, merge, publish,   */
15 /* distribute, sublicense, and/or sell copies of the Software, and to    */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions:                                             */
18 /*                                                                       */
19 /* The above copyright notice and this permission notice shall be        */
20 /* included in all copies or substantial portions of the Software.       */
21 /*                                                                       */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
29 /*************************************************************************/
30 
31 #ifdef _MSC_VER
32 #define _CRT_SECURE_NO_WARNINGS // to disable build-time warning which suggested to use strcpy_s instead strcpy
33 #endif
34 
35 #include "ustring.h"
36 
37 #include "core/color.h"
38 #include "core/crypto/crypto_core.h"
39 #include "core/math/math_funcs.h"
40 #include "core/os/memory.h"
41 #include "core/print_string.h"
42 #include "core/translation.h"
43 #include "core/ucaps.h"
44 #include "core/variant.h"
45 
46 #include <wchar.h>
47 #include <cstdint>
48 
49 #ifndef NO_USE_STDLIB
50 #include <stdio.h>
51 #include <stdlib.h>
52 #endif
53 
54 #if defined(MINGW_ENABLED) || defined(_MSC_VER)
55 #define snprintf _snprintf_s
56 #endif
57 
58 #define MAX_DIGITS 6
59 #define UPPERCASE(m_c) (((m_c) >= 'a' && (m_c) <= 'z') ? ((m_c) - ('a' - 'A')) : (m_c))
60 #define LOWERCASE(m_c) (((m_c) >= 'A' && (m_c) <= 'Z') ? ((m_c) + ('a' - 'A')) : (m_c))
61 #define IS_DIGIT(m_d) ((m_d) >= '0' && (m_d) <= '9')
62 #define IS_HEX_DIGIT(m_d) (((m_d) >= '0' && (m_d) <= '9') || ((m_d) >= 'a' && (m_d) <= 'f') || ((m_d) >= 'A' && (m_d) <= 'F'))
63 
64 const char CharString::_null = 0;
65 const CharType String::_null = 0;
66 
is_symbol(CharType c)67 bool is_symbol(CharType c) {
68 	return c != '_' && ((c >= '!' && c <= '/') || (c >= ':' && c <= '@') || (c >= '[' && c <= '`') || (c >= '{' && c <= '~') || c == '\t' || c == ' ');
69 }
70 
select_word(const String & p_s,int p_col,int & r_beg,int & r_end)71 bool select_word(const String &p_s, int p_col, int &r_beg, int &r_end) {
72 
73 	const String &s = p_s;
74 	int beg = CLAMP(p_col, 0, s.length());
75 	int end = beg;
76 
77 	if (s[beg] > 32 || beg == s.length()) {
78 
79 		bool symbol = beg < s.length() && is_symbol(s[beg]);
80 
81 		while (beg > 0 && s[beg - 1] > 32 && (symbol == is_symbol(s[beg - 1]))) {
82 			beg--;
83 		}
84 		while (end < s.length() && s[end + 1] > 32 && (symbol == is_symbol(s[end + 1]))) {
85 			end++;
86 		}
87 
88 		if (end < s.length())
89 			end += 1;
90 
91 		r_beg = beg;
92 		r_end = end;
93 
94 		return true;
95 	} else {
96 
97 		return false;
98 	}
99 }
100 
101 /** STRING **/
102 
operator <(const CharString & p_right) const103 bool CharString::operator<(const CharString &p_right) const {
104 
105 	if (length() == 0) {
106 		return p_right.length() != 0;
107 	}
108 
109 	return is_str_less(get_data(), p_right.get_data());
110 }
111 
operator +=(char p_char)112 CharString &CharString::operator+=(char p_char) {
113 
114 	resize(size() ? size() + 1 : 2);
115 	set(length(), 0);
116 	set(length() - 1, p_char);
117 
118 	return *this;
119 }
120 
get_data() const121 const char *CharString::get_data() const {
122 
123 	if (size())
124 		return &operator[](0);
125 	else
126 		return "";
127 }
128 
operator =(const char * p_cstr)129 CharString &CharString::operator=(const char *p_cstr) {
130 
131 	copy_from(p_cstr);
132 	return *this;
133 }
134 
copy_from(const char * p_cstr)135 void CharString::copy_from(const char *p_cstr) {
136 
137 	if (!p_cstr) {
138 		resize(0);
139 		return;
140 	}
141 
142 	size_t len = strlen(p_cstr);
143 
144 	if (len == 0) {
145 		resize(0);
146 		return;
147 	}
148 
149 	resize(len + 1); // include terminating null char
150 
151 	strcpy(ptrw(), p_cstr);
152 }
153 
copy_from(const char * p_cstr)154 void String::copy_from(const char *p_cstr) {
155 
156 	if (!p_cstr) {
157 
158 		resize(0);
159 		return;
160 	}
161 
162 	int len = 0;
163 	const char *ptr = p_cstr;
164 	while (*(ptr++) != 0)
165 		len++;
166 
167 	if (len == 0) {
168 
169 		resize(0);
170 		return;
171 	}
172 
173 	resize(len + 1); // include 0
174 
175 	CharType *dst = this->ptrw();
176 
177 	for (int i = 0; i < len + 1; i++) {
178 
179 		dst[i] = p_cstr[i];
180 	}
181 }
182 
copy_from(const CharType * p_cstr,const int p_clip_to)183 void String::copy_from(const CharType *p_cstr, const int p_clip_to) {
184 
185 	if (!p_cstr) {
186 
187 		resize(0);
188 		return;
189 	}
190 
191 	int len = 0;
192 	const CharType *ptr = p_cstr;
193 	while ((p_clip_to < 0 || len < p_clip_to) && *(ptr++) != 0)
194 		len++;
195 
196 	if (len == 0) {
197 
198 		resize(0);
199 		return;
200 	}
201 
202 	copy_from_unchecked(p_cstr, len);
203 }
204 
205 // assumes the following have already been validated:
206 // p_char != NULL
207 // p_length > 0
208 // p_length <= p_char strlen
copy_from_unchecked(const CharType * p_char,const int p_length)209 void String::copy_from_unchecked(const CharType *p_char, const int p_length) {
210 	resize(p_length + 1);
211 	set(p_length, 0);
212 
213 	CharType *dst = ptrw();
214 
215 	for (int i = 0; i < p_length; i++) {
216 		dst[i] = p_char[i];
217 	}
218 }
219 
copy_from(const CharType & p_char)220 void String::copy_from(const CharType &p_char) {
221 
222 	resize(2);
223 	set(0, p_char);
224 	set(1, 0);
225 }
226 
operator ==(const String & p_str) const227 bool String::operator==(const String &p_str) const {
228 
229 	if (length() != p_str.length())
230 		return false;
231 	if (empty())
232 		return true;
233 
234 	int l = length();
235 
236 	const CharType *src = c_str();
237 	const CharType *dst = p_str.c_str();
238 
239 	/* Compare char by char */
240 	for (int i = 0; i < l; i++) {
241 
242 		if (src[i] != dst[i])
243 			return false;
244 	}
245 
246 	return true;
247 }
248 
operator !=(const String & p_str) const249 bool String::operator!=(const String &p_str) const {
250 
251 	return !(*this == p_str);
252 }
253 
operator +(const String & p_str) const254 String String::operator+(const String &p_str) const {
255 
256 	String res = *this;
257 	res += p_str;
258 	return res;
259 }
260 
261 /*
262 String String::operator+(CharType p_chr)  const {
263 
264 	String res=*this;
265 	res+=p_chr;
266 	return res;
267 }
268 */
operator +=(const String & p_str)269 String &String::operator+=(const String &p_str) {
270 
271 	if (empty()) {
272 		*this = p_str;
273 		return *this;
274 	}
275 
276 	if (p_str.empty())
277 		return *this;
278 
279 	int from = length();
280 
281 	resize(length() + p_str.size());
282 
283 	const CharType *src = p_str.c_str();
284 	CharType *dst = ptrw();
285 
286 	set(length(), 0);
287 
288 	for (int i = 0; i < p_str.length(); i++)
289 		dst[from + i] = src[i];
290 
291 	return *this;
292 }
293 
operator +=(const CharType * p_str)294 String &String::operator+=(const CharType *p_str) {
295 
296 	*this += String(p_str);
297 	return *this;
298 }
299 
operator +=(CharType p_char)300 String &String::operator+=(CharType p_char) {
301 
302 	resize(size() ? size() + 1 : 2);
303 	set(length(), 0);
304 	set(length() - 1, p_char);
305 
306 	return *this;
307 }
308 
operator +=(const char * p_str)309 String &String::operator+=(const char *p_str) {
310 
311 	if (!p_str || p_str[0] == 0)
312 		return *this;
313 
314 	int src_len = 0;
315 	const char *ptr = p_str;
316 	while (*(ptr++) != 0)
317 		src_len++;
318 
319 	int from = length();
320 
321 	resize(from + src_len + 1);
322 
323 	CharType *dst = ptrw();
324 
325 	set(length(), 0);
326 
327 	for (int i = 0; i < src_len; i++)
328 		dst[from + i] = p_str[i];
329 
330 	return *this;
331 }
332 
operator =(const char * p_str)333 void String::operator=(const char *p_str) {
334 
335 	copy_from(p_str);
336 }
337 
operator =(const CharType * p_str)338 void String::operator=(const CharType *p_str) {
339 
340 	copy_from(p_str);
341 }
342 
operator ==(const StrRange & p_str_range) const343 bool String::operator==(const StrRange &p_str_range) const {
344 
345 	int len = p_str_range.len;
346 
347 	if (length() != len)
348 		return false;
349 	if (empty())
350 		return true;
351 
352 	const CharType *c_str = p_str_range.c_str;
353 	const CharType *dst = &operator[](0);
354 
355 	/* Compare char by char */
356 	for (int i = 0; i < len; i++) {
357 
358 		if (c_str[i] != dst[i])
359 			return false;
360 	}
361 
362 	return true;
363 }
364 
operator ==(const char * p_str) const365 bool String::operator==(const char *p_str) const {
366 
367 	int len = 0;
368 	const char *aux = p_str;
369 
370 	while (*(aux++) != 0)
371 		len++;
372 
373 	if (length() != len)
374 		return false;
375 	if (empty())
376 		return true;
377 
378 	int l = length();
379 
380 	const CharType *dst = c_str();
381 
382 	/* Compare char by char */
383 	for (int i = 0; i < l; i++) {
384 
385 		if (p_str[i] != dst[i])
386 			return false;
387 	}
388 
389 	return true;
390 }
391 
operator ==(const CharType * p_str) const392 bool String::operator==(const CharType *p_str) const {
393 
394 	int len = 0;
395 	const CharType *aux = p_str;
396 
397 	while (*(aux++) != 0)
398 		len++;
399 
400 	if (length() != len)
401 		return false;
402 	if (empty())
403 		return true;
404 
405 	int l = length();
406 
407 	const CharType *dst = c_str();
408 
409 	/* Compare char by char */
410 	for (int i = 0; i < l; i++) {
411 
412 		if (p_str[i] != dst[i])
413 			return false;
414 	}
415 
416 	return true;
417 }
418 
operator !=(const char * p_str) const419 bool String::operator!=(const char *p_str) const {
420 
421 	return (!(*this == p_str));
422 }
423 
operator !=(const CharType * p_str) const424 bool String::operator!=(const CharType *p_str) const {
425 
426 	return (!(*this == p_str));
427 }
428 
operator <(const CharType * p_str) const429 bool String::operator<(const CharType *p_str) const {
430 
431 	if (empty() && p_str[0] == 0)
432 		return false;
433 	if (empty())
434 		return true;
435 
436 	return is_str_less(c_str(), p_str);
437 }
438 
operator <=(const String & p_str) const439 bool String::operator<=(const String &p_str) const {
440 
441 	return (*this < p_str) || (*this == p_str);
442 }
443 
operator <(const char * p_str) const444 bool String::operator<(const char *p_str) const {
445 
446 	if (empty() && p_str[0] == 0)
447 		return false;
448 	if (empty())
449 		return true;
450 
451 	return is_str_less(c_str(), p_str);
452 }
453 
operator <(const String & p_str) const454 bool String::operator<(const String &p_str) const {
455 
456 	return operator<(p_str.c_str());
457 }
458 
nocasecmp_to(const String & p_str) const459 signed char String::nocasecmp_to(const String &p_str) const {
460 
461 	if (empty() && p_str.empty())
462 		return 0;
463 	if (empty())
464 		return -1;
465 	if (p_str.empty())
466 		return 1;
467 
468 	const CharType *that_str = p_str.c_str();
469 	const CharType *this_str = c_str();
470 
471 	while (true) {
472 
473 		if (*that_str == 0 && *this_str == 0)
474 			return 0; //we're equal
475 		else if (*this_str == 0)
476 			return -1; //if this is empty, and the other one is not, then we're less.. I think?
477 		else if (*that_str == 0)
478 			return 1; //otherwise the other one is smaller..
479 		else if (_find_upper(*this_str) < _find_upper(*that_str)) //more than
480 			return -1;
481 		else if (_find_upper(*this_str) > _find_upper(*that_str)) //less than
482 			return 1;
483 
484 		this_str++;
485 		that_str++;
486 	}
487 }
488 
casecmp_to(const String & p_str) const489 signed char String::casecmp_to(const String &p_str) const {
490 
491 	if (empty() && p_str.empty())
492 		return 0;
493 	if (empty())
494 		return -1;
495 	if (p_str.empty())
496 		return 1;
497 
498 	const CharType *that_str = p_str.c_str();
499 	const CharType *this_str = c_str();
500 
501 	while (true) {
502 
503 		if (*that_str == 0 && *this_str == 0)
504 			return 0; //we're equal
505 		else if (*this_str == 0)
506 			return -1; //if this is empty, and the other one is not, then we're less.. I think?
507 		else if (*that_str == 0)
508 			return 1; //otherwise the other one is smaller..
509 		else if (*this_str < *that_str) //more than
510 			return -1;
511 		else if (*this_str > *that_str) //less than
512 			return 1;
513 
514 		this_str++;
515 		that_str++;
516 	}
517 }
518 
naturalnocasecmp_to(const String & p_str) const519 signed char String::naturalnocasecmp_to(const String &p_str) const {
520 
521 	const CharType *this_str = c_str();
522 	const CharType *that_str = p_str.c_str();
523 
524 	if (this_str && that_str) {
525 
526 		while (*this_str == '.' || *that_str == '.') {
527 			if (*this_str++ != '.')
528 				return 1;
529 			if (*that_str++ != '.')
530 				return -1;
531 			if (!*that_str)
532 				return 1;
533 			if (!*this_str)
534 				return -1;
535 		}
536 
537 		while (*this_str) {
538 
539 			if (!*that_str)
540 				return 1;
541 			else if (IS_DIGIT(*this_str)) {
542 
543 				int64_t this_int, that_int;
544 
545 				if (!IS_DIGIT(*that_str))
546 					return -1;
547 
548 				/* Compare the numbers */
549 				this_int = to_int(this_str);
550 				that_int = to_int(that_str);
551 
552 				if (this_int < that_int)
553 					return -1;
554 				else if (this_int > that_int)
555 					return 1;
556 
557 				/* Skip */
558 				while (IS_DIGIT(*this_str))
559 					this_str++;
560 				while (IS_DIGIT(*that_str))
561 					that_str++;
562 			} else if (IS_DIGIT(*that_str))
563 				return 1;
564 			else {
565 				if (_find_upper(*this_str) < _find_upper(*that_str)) //more than
566 					return -1;
567 				else if (_find_upper(*this_str) > _find_upper(*that_str)) //less than
568 					return 1;
569 
570 				this_str++;
571 				that_str++;
572 			}
573 		}
574 		if (*that_str)
575 			return -1;
576 	}
577 
578 	return 0;
579 }
580 
erase(int p_pos,int p_chars)581 void String::erase(int p_pos, int p_chars) {
582 
583 	*this = left(p_pos) + substr(p_pos + p_chars, length() - ((p_pos + p_chars)));
584 }
585 
capitalize() const586 String String::capitalize() const {
587 
588 	String aux = this->camelcase_to_underscore(true).replace("_", " ").strip_edges();
589 	String cap;
590 	for (int i = 0; i < aux.get_slice_count(" "); i++) {
591 
592 		String slice = aux.get_slicec(' ', i);
593 		if (slice.length() > 0) {
594 
595 			slice[0] = _find_upper(slice[0]);
596 			if (i > 0)
597 				cap += " ";
598 			cap += slice;
599 		}
600 	}
601 
602 	return cap;
603 }
604 
camelcase_to_underscore(bool lowercase) const605 String String::camelcase_to_underscore(bool lowercase) const {
606 	const CharType *cstr = c_str();
607 	String new_string;
608 	const char A = 'A', Z = 'Z';
609 	const char a = 'a', z = 'z';
610 	int start_index = 0;
611 
612 	for (int i = 1; i < this->size(); i++) {
613 		bool is_upper = cstr[i] >= A && cstr[i] <= Z;
614 		bool is_number = cstr[i] >= '0' && cstr[i] <= '9';
615 		bool are_next_2_lower = false;
616 		bool is_next_lower = false;
617 		bool is_next_number = false;
618 		bool was_precedent_upper = cstr[i - 1] >= A && cstr[i - 1] <= Z;
619 		bool was_precedent_number = cstr[i - 1] >= '0' && cstr[i - 1] <= '9';
620 
621 		if (i + 2 < this->size()) {
622 			are_next_2_lower = cstr[i + 1] >= a && cstr[i + 1] <= z && cstr[i + 2] >= a && cstr[i + 2] <= z;
623 		}
624 
625 		if (i + 1 < this->size()) {
626 			is_next_lower = cstr[i + 1] >= a && cstr[i + 1] <= z;
627 			is_next_number = cstr[i + 1] >= '0' && cstr[i + 1] <= '9';
628 		}
629 
630 		const bool cond_a = is_upper && !was_precedent_upper && !was_precedent_number;
631 		const bool cond_b = was_precedent_upper && is_upper && are_next_2_lower;
632 		const bool cond_c = is_number && !was_precedent_number;
633 		const bool can_break_number_letter = is_number && !was_precedent_number && is_next_lower;
634 		const bool can_break_letter_number = !is_number && was_precedent_number && (is_next_lower || is_next_number);
635 
636 		bool should_split = cond_a || cond_b || cond_c || can_break_number_letter || can_break_letter_number;
637 		if (should_split) {
638 			new_string += this->substr(start_index, i - start_index) + "_";
639 			start_index = i;
640 		}
641 	}
642 
643 	new_string += this->substr(start_index, this->size() - start_index);
644 	return lowercase ? new_string.to_lower() : new_string;
645 }
646 
get_slice_count(String p_splitter) const647 int String::get_slice_count(String p_splitter) const {
648 
649 	if (empty())
650 		return 0;
651 	if (p_splitter.empty())
652 		return 0;
653 
654 	int pos = 0;
655 	int slices = 1;
656 
657 	while ((pos = find(p_splitter, pos)) >= 0) {
658 
659 		slices++;
660 		pos += p_splitter.length();
661 	}
662 
663 	return slices;
664 }
665 
get_slice(String p_splitter,int p_slice) const666 String String::get_slice(String p_splitter, int p_slice) const {
667 
668 	if (empty() || p_splitter.empty())
669 		return "";
670 
671 	int pos = 0;
672 	int prev_pos = 0;
673 	//int slices=1;
674 	if (p_slice < 0)
675 		return "";
676 	if (find(p_splitter) == -1)
677 		return *this;
678 
679 	int i = 0;
680 	while (true) {
681 
682 		pos = find(p_splitter, pos);
683 		if (pos == -1)
684 			pos = length(); //reached end
685 
686 		int from = prev_pos;
687 		//int to=pos;
688 
689 		if (p_slice == i) {
690 
691 			return substr(from, pos - from);
692 		}
693 
694 		if (pos == length()) //reached end and no find
695 			break;
696 		pos += p_splitter.length();
697 		prev_pos = pos;
698 		i++;
699 	}
700 
701 	return ""; //no find!
702 }
703 
get_slicec(CharType p_splitter,int p_slice) const704 String String::get_slicec(CharType p_splitter, int p_slice) const {
705 
706 	if (empty())
707 		return String();
708 
709 	if (p_slice < 0)
710 		return String();
711 
712 	const CharType *c = this->ptr();
713 	int i = 0;
714 	int prev = 0;
715 	int count = 0;
716 	while (true) {
717 
718 		if (c[i] == 0 || c[i] == p_splitter) {
719 
720 			if (p_slice == count) {
721 
722 				return substr(prev, i - prev);
723 			} else if (c[i] == 0) {
724 				return String();
725 			} else {
726 				count++;
727 				prev = i + 1;
728 			}
729 		}
730 
731 		i++;
732 	}
733 }
734 
split_spaces() const735 Vector<String> String::split_spaces() const {
736 
737 	Vector<String> ret;
738 	int from = 0;
739 	int i = 0;
740 	int len = length();
741 	if (len == 0)
742 		return ret;
743 
744 	bool inside = false;
745 
746 	while (true) {
747 
748 		bool empty = operator[](i) < 33;
749 
750 		if (i == 0)
751 			inside = !empty;
752 
753 		if (!empty && !inside) {
754 			inside = true;
755 			from = i;
756 		}
757 
758 		if (empty && inside) {
759 
760 			ret.push_back(substr(from, i - from));
761 			inside = false;
762 		}
763 
764 		if (i == len)
765 			break;
766 		i++;
767 	}
768 
769 	return ret;
770 }
771 
split(const String & p_splitter,bool p_allow_empty,int p_maxsplit) const772 Vector<String> String::split(const String &p_splitter, bool p_allow_empty, int p_maxsplit) const {
773 
774 	Vector<String> ret;
775 	int from = 0;
776 	int len = length();
777 
778 	while (true) {
779 
780 		int end = find(p_splitter, from);
781 		if (end < 0)
782 			end = len;
783 		if (p_allow_empty || (end > from)) {
784 			if (p_maxsplit <= 0)
785 				ret.push_back(substr(from, end - from));
786 			else {
787 
788 				// Put rest of the string and leave cycle.
789 				if (p_maxsplit == ret.size()) {
790 					ret.push_back(substr(from, len));
791 					break;
792 				}
793 
794 				// Otherwise, push items until positive limit is reached.
795 				ret.push_back(substr(from, end - from));
796 			}
797 		}
798 
799 		if (end == len)
800 			break;
801 
802 		from = end + p_splitter.length();
803 	}
804 
805 	return ret;
806 }
807 
rsplit(const String & p_splitter,bool p_allow_empty,int p_maxsplit) const808 Vector<String> String::rsplit(const String &p_splitter, bool p_allow_empty, int p_maxsplit) const {
809 
810 	Vector<String> ret;
811 	const int len = length();
812 	int remaining_len = len;
813 
814 	while (true) {
815 
816 		if (remaining_len < p_splitter.length() || (p_maxsplit > 0 && p_maxsplit == ret.size())) {
817 			// no room for another splitter or hit max splits, push what's left and we're done
818 			if (p_allow_empty || remaining_len > 0) {
819 				ret.push_back(substr(0, remaining_len));
820 			}
821 			break;
822 		}
823 
824 		int left_edge = rfind(p_splitter, remaining_len - p_splitter.length());
825 
826 		if (left_edge < 0) {
827 			// no more splitters, we're done
828 			ret.push_back(substr(0, remaining_len));
829 			break;
830 		}
831 
832 		int substr_start = left_edge + p_splitter.length();
833 		if (p_allow_empty || substr_start < remaining_len) {
834 			ret.push_back(substr(substr_start, remaining_len - substr_start));
835 		}
836 
837 		remaining_len = left_edge;
838 	}
839 
840 	ret.invert();
841 	return ret;
842 }
843 
split_floats(const String & p_splitter,bool p_allow_empty) const844 Vector<float> String::split_floats(const String &p_splitter, bool p_allow_empty) const {
845 
846 	Vector<float> ret;
847 	int from = 0;
848 	int len = length();
849 
850 	while (true) {
851 
852 		int end = find(p_splitter, from);
853 		if (end < 0)
854 			end = len;
855 		if (p_allow_empty || (end > from))
856 			ret.push_back(String::to_double(&c_str()[from]));
857 
858 		if (end == len)
859 			break;
860 
861 		from = end + p_splitter.length();
862 	}
863 
864 	return ret;
865 }
866 
split_floats_mk(const Vector<String> & p_splitters,bool p_allow_empty) const867 Vector<float> String::split_floats_mk(const Vector<String> &p_splitters, bool p_allow_empty) const {
868 
869 	Vector<float> ret;
870 	int from = 0;
871 	int len = length();
872 
873 	while (true) {
874 
875 		int idx;
876 		int end = findmk(p_splitters, from, &idx);
877 		int spl_len = 1;
878 		if (end < 0) {
879 			end = len;
880 		} else {
881 			spl_len = p_splitters[idx].length();
882 		}
883 
884 		if (p_allow_empty || (end > from)) {
885 			ret.push_back(String::to_double(&c_str()[from]));
886 		}
887 
888 		if (end == len)
889 			break;
890 
891 		from = end + spl_len;
892 	}
893 
894 	return ret;
895 }
896 
split_ints(const String & p_splitter,bool p_allow_empty) const897 Vector<int> String::split_ints(const String &p_splitter, bool p_allow_empty) const {
898 
899 	Vector<int> ret;
900 	int from = 0;
901 	int len = length();
902 
903 	while (true) {
904 
905 		int end = find(p_splitter, from);
906 		if (end < 0)
907 			end = len;
908 		if (p_allow_empty || (end > from))
909 			ret.push_back(String::to_int(&c_str()[from], end - from));
910 
911 		if (end == len)
912 			break;
913 
914 		from = end + p_splitter.length();
915 	}
916 
917 	return ret;
918 }
919 
split_ints_mk(const Vector<String> & p_splitters,bool p_allow_empty) const920 Vector<int> String::split_ints_mk(const Vector<String> &p_splitters, bool p_allow_empty) const {
921 
922 	Vector<int> ret;
923 	int from = 0;
924 	int len = length();
925 
926 	while (true) {
927 
928 		int idx;
929 		int end = findmk(p_splitters, from, &idx);
930 		int spl_len = 1;
931 		if (end < 0) {
932 			end = len;
933 		} else {
934 			spl_len = p_splitters[idx].length();
935 		}
936 
937 		if (p_allow_empty || (end > from))
938 			ret.push_back(String::to_int(&c_str()[from], end - from));
939 
940 		if (end == len)
941 			break;
942 
943 		from = end + spl_len;
944 	}
945 
946 	return ret;
947 }
948 
join(Vector<String> parts)949 String String::join(Vector<String> parts) {
950 	String ret;
951 	for (int i = 0; i < parts.size(); ++i) {
952 		if (i > 0) {
953 			ret += *this;
954 		}
955 		ret += parts[i];
956 	}
957 	return ret;
958 }
959 
char_uppercase(CharType p_char)960 CharType String::char_uppercase(CharType p_char) {
961 
962 	return _find_upper(p_char);
963 }
964 
char_lowercase(CharType p_char)965 CharType String::char_lowercase(CharType p_char) {
966 
967 	return _find_lower(p_char);
968 }
969 
to_upper() const970 String String::to_upper() const {
971 
972 	String upper = *this;
973 
974 	for (int i = 0; i < upper.size(); i++) {
975 
976 		const CharType s = upper[i];
977 		const CharType t = _find_upper(s);
978 		if (s != t) // avoid copy on write
979 			upper[i] = t;
980 	}
981 
982 	return upper;
983 }
984 
to_lower() const985 String String::to_lower() const {
986 
987 	String lower = *this;
988 
989 	for (int i = 0; i < lower.size(); i++) {
990 
991 		const CharType s = lower[i];
992 		const CharType t = _find_lower(s);
993 		if (s != t) // avoid copy on write
994 			lower[i] = t;
995 	}
996 
997 	return lower;
998 }
999 
c_str() const1000 const CharType *String::c_str() const {
1001 
1002 	static const CharType zero = 0;
1003 
1004 	return size() ? &operator[](0) : &zero;
1005 }
1006 
md5(const uint8_t * p_md5)1007 String String::md5(const uint8_t *p_md5) {
1008 	return String::hex_encode_buffer(p_md5, 16);
1009 }
1010 
hex_encode_buffer(const uint8_t * p_buffer,int p_len)1011 String String::hex_encode_buffer(const uint8_t *p_buffer, int p_len) {
1012 	static const char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
1013 
1014 	String ret;
1015 	char v[2] = { 0, 0 };
1016 
1017 	for (int i = 0; i < p_len; i++) {
1018 		v[0] = hex[p_buffer[i] >> 4];
1019 		ret += v;
1020 		v[0] = hex[p_buffer[i] & 0xF];
1021 		ret += v;
1022 	}
1023 
1024 	return ret;
1025 }
1026 
chr(CharType p_char)1027 String String::chr(CharType p_char) {
1028 
1029 	CharType c[2] = { p_char, 0 };
1030 	return String(c);
1031 }
num(double p_num,int p_decimals)1032 String String::num(double p_num, int p_decimals) {
1033 
1034 #ifndef NO_USE_STDLIB
1035 
1036 	if (p_decimals > 16)
1037 		p_decimals = 16;
1038 
1039 	char fmt[7];
1040 	fmt[0] = '%';
1041 	fmt[1] = '.';
1042 
1043 	if (p_decimals < 0) {
1044 
1045 		fmt[1] = 'l';
1046 		fmt[2] = 'f';
1047 		fmt[3] = 0;
1048 
1049 	} else if (p_decimals < 10) {
1050 		fmt[2] = '0' + p_decimals;
1051 		fmt[3] = 'l';
1052 		fmt[4] = 'f';
1053 		fmt[5] = 0;
1054 	} else {
1055 		fmt[2] = '0' + (p_decimals / 10);
1056 		fmt[3] = '0' + (p_decimals % 10);
1057 		fmt[4] = 'l';
1058 		fmt[5] = 'f';
1059 		fmt[6] = 0;
1060 	}
1061 	char buf[256];
1062 
1063 #if defined(__GNUC__) || defined(_MSC_VER)
1064 	snprintf(buf, 256, fmt, p_num);
1065 #else
1066 	sprintf(buf, fmt, p_num);
1067 #endif
1068 
1069 	buf[255] = 0;
1070 	//destroy trailing zeroes
1071 	{
1072 
1073 		bool period = false;
1074 		int z = 0;
1075 		while (buf[z]) {
1076 			if (buf[z] == '.')
1077 				period = true;
1078 			z++;
1079 		}
1080 
1081 		if (period) {
1082 			z--;
1083 			while (z > 0) {
1084 
1085 				if (buf[z] == '0') {
1086 
1087 					buf[z] = 0;
1088 				} else if (buf[z] == '.') {
1089 
1090 					buf[z] = 0;
1091 					break;
1092 				} else {
1093 
1094 					break;
1095 				}
1096 
1097 				z--;
1098 			}
1099 		}
1100 	}
1101 
1102 	return buf;
1103 #else
1104 
1105 	String s;
1106 	String sd;
1107 	/* integer part */
1108 
1109 	bool neg = p_num < 0;
1110 	p_num = ABS(p_num);
1111 	int intn = (int)p_num;
1112 
1113 	/* decimal part */
1114 
1115 	if (p_decimals > 0 || (p_decimals == -1 && (int)p_num != p_num)) {
1116 
1117 		double dec = p_num - (float)((int)p_num);
1118 
1119 		int digit = 0;
1120 		if (p_decimals > MAX_DIGITS)
1121 			p_decimals = MAX_DIGITS;
1122 
1123 		int dec_int = 0;
1124 		int dec_max = 0;
1125 
1126 		while (true) {
1127 
1128 			dec *= 10.0;
1129 			dec_int = dec_int * 10 + (int)dec % 10;
1130 			dec_max = dec_max * 10 + 9;
1131 			digit++;
1132 
1133 			if (p_decimals == -1) {
1134 
1135 				if (digit == MAX_DIGITS) //no point in going to infinite
1136 					break;
1137 
1138 				if ((dec - (float)((int)dec)) < 1e-6)
1139 					break;
1140 			}
1141 
1142 			if (digit == p_decimals)
1143 				break;
1144 		}
1145 		dec *= 10;
1146 		int last = (int)dec % 10;
1147 
1148 		if (last > 5) {
1149 			if (dec_int == dec_max) {
1150 
1151 				dec_int = 0;
1152 				intn++;
1153 			} else {
1154 
1155 				dec_int++;
1156 			}
1157 		}
1158 
1159 		String decimal;
1160 		for (int i = 0; i < digit; i++) {
1161 
1162 			char num[2] = { 0, 0 };
1163 			num[0] = '0' + dec_int % 10;
1164 			decimal = num + decimal;
1165 			dec_int /= 10;
1166 		}
1167 		sd = '.' + decimal;
1168 	}
1169 
1170 	if (intn == 0)
1171 
1172 		s = "0";
1173 	else {
1174 		while (intn) {
1175 
1176 			CharType num = '0' + (intn % 10);
1177 			intn /= 10;
1178 			s = num + s;
1179 		}
1180 	}
1181 
1182 	s = s + sd;
1183 	if (neg)
1184 		s = "-" + s;
1185 	return s;
1186 #endif
1187 }
1188 
num_int64(int64_t p_num,int base,bool capitalize_hex)1189 String String::num_int64(int64_t p_num, int base, bool capitalize_hex) {
1190 
1191 	bool sign = p_num < 0;
1192 
1193 	int64_t n = p_num;
1194 
1195 	int chars = 0;
1196 	do {
1197 		n /= base;
1198 		chars++;
1199 	} while (n);
1200 
1201 	if (sign)
1202 		chars++;
1203 	String s;
1204 	s.resize(chars + 1);
1205 	CharType *c = s.ptrw();
1206 	c[chars] = 0;
1207 	n = p_num;
1208 	do {
1209 		int mod = ABS(n % base);
1210 		if (mod >= 10) {
1211 			char a = (capitalize_hex ? 'A' : 'a');
1212 			c[--chars] = a + (mod - 10);
1213 		} else {
1214 			c[--chars] = '0' + mod;
1215 		}
1216 
1217 		n /= base;
1218 	} while (n);
1219 
1220 	if (sign)
1221 		c[0] = '-';
1222 
1223 	return s;
1224 }
1225 
num_uint64(uint64_t p_num,int base,bool capitalize_hex)1226 String String::num_uint64(uint64_t p_num, int base, bool capitalize_hex) {
1227 
1228 	uint64_t n = p_num;
1229 
1230 	int chars = 0;
1231 	do {
1232 		n /= base;
1233 		chars++;
1234 	} while (n);
1235 
1236 	String s;
1237 	s.resize(chars + 1);
1238 	CharType *c = s.ptrw();
1239 	c[chars] = 0;
1240 	n = p_num;
1241 	do {
1242 		int mod = n % base;
1243 		if (mod >= 10) {
1244 			char a = (capitalize_hex ? 'A' : 'a');
1245 			c[--chars] = a + (mod - 10);
1246 		} else {
1247 			c[--chars] = '0' + mod;
1248 		}
1249 
1250 		n /= base;
1251 	} while (n);
1252 
1253 	return s;
1254 }
1255 
num_real(double p_num)1256 String String::num_real(double p_num) {
1257 
1258 	String s;
1259 	String sd;
1260 	/* integer part */
1261 
1262 	bool neg = p_num < 0;
1263 	p_num = ABS(p_num);
1264 	int intn = (int)p_num;
1265 
1266 	/* decimal part */
1267 
1268 	if ((int)p_num != p_num) {
1269 
1270 		double dec = p_num - (float)((int)p_num);
1271 
1272 		int digit = 0;
1273 		int decimals = MAX_DIGITS;
1274 
1275 		int dec_int = 0;
1276 		int dec_max = 0;
1277 
1278 		while (true) {
1279 
1280 			dec *= 10.0;
1281 			dec_int = dec_int * 10 + (int)dec % 10;
1282 			dec_max = dec_max * 10 + 9;
1283 			digit++;
1284 
1285 			if ((dec - (float)((int)dec)) < 1e-6)
1286 				break;
1287 
1288 			if (digit == decimals)
1289 				break;
1290 		}
1291 
1292 		dec *= 10;
1293 		int last = (int)dec % 10;
1294 
1295 		if (last > 5) {
1296 			if (dec_int == dec_max) {
1297 
1298 				dec_int = 0;
1299 				intn++;
1300 			} else {
1301 
1302 				dec_int++;
1303 			}
1304 		}
1305 
1306 		String decimal;
1307 		for (int i = 0; i < digit; i++) {
1308 
1309 			char num[2] = { 0, 0 };
1310 			num[0] = '0' + dec_int % 10;
1311 			decimal = num + decimal;
1312 			dec_int /= 10;
1313 		}
1314 		sd = '.' + decimal;
1315 	} else {
1316 		sd = ".0";
1317 	}
1318 
1319 	if (intn == 0)
1320 
1321 		s = "0";
1322 	else {
1323 		while (intn) {
1324 
1325 			CharType num = '0' + (intn % 10);
1326 			intn /= 10;
1327 			s = num + s;
1328 		}
1329 	}
1330 
1331 	s = s + sd;
1332 	if (neg)
1333 		s = "-" + s;
1334 	return s;
1335 }
1336 
num_scientific(double p_num)1337 String String::num_scientific(double p_num) {
1338 
1339 #ifndef NO_USE_STDLIB
1340 
1341 	char buf[256];
1342 
1343 #if defined(__GNUC__) || defined(_MSC_VER)
1344 
1345 #if (defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1900)) && defined(_TWO_DIGIT_EXPONENT) && !defined(_UCRT)
1346 	// MinGW and old MSC require _set_output_format() to conform to C99 output for printf
1347 	unsigned int old_exponent_format = _set_output_format(_TWO_DIGIT_EXPONENT);
1348 #endif
1349 	snprintf(buf, 256, "%lg", p_num);
1350 
1351 #if (defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1900)) && defined(_TWO_DIGIT_EXPONENT) && !defined(_UCRT)
1352 	_set_output_format(old_exponent_format);
1353 #endif
1354 
1355 #else
1356 	sprintf(buf, "%.16lg", p_num);
1357 #endif
1358 
1359 	buf[255] = 0;
1360 
1361 	return buf;
1362 #else
1363 
1364 	return String::num(p_num);
1365 #endif
1366 }
1367 
ascii(bool p_allow_extended) const1368 CharString String::ascii(bool p_allow_extended) const {
1369 
1370 	if (!length())
1371 		return CharString();
1372 
1373 	CharString cs;
1374 	cs.resize(size());
1375 
1376 	for (int i = 0; i < size(); i++)
1377 		cs[i] = operator[](i);
1378 
1379 	return cs;
1380 }
1381 
utf8(const char * p_utf8,int p_len)1382 String String::utf8(const char *p_utf8, int p_len) {
1383 
1384 	String ret;
1385 	ret.parse_utf8(p_utf8, p_len);
1386 
1387 	return ret;
1388 };
1389 
parse_utf8(const char * p_utf8,int p_len)1390 bool String::parse_utf8(const char *p_utf8, int p_len) {
1391 
1392 #define _UNICERROR(m_err) print_line("Unicode error: " + String(m_err));
1393 
1394 	if (!p_utf8)
1395 		return true;
1396 
1397 	String aux;
1398 
1399 	int cstr_size = 0;
1400 	int str_size = 0;
1401 
1402 	/* HANDLE BOM (Byte Order Mark) */
1403 	if (p_len < 0 || p_len >= 3) {
1404 
1405 		bool has_bom = uint8_t(p_utf8[0]) == 0xEF && uint8_t(p_utf8[1]) == 0xBB && uint8_t(p_utf8[2]) == 0xBF;
1406 		if (has_bom) {
1407 
1408 			//just skip it
1409 			if (p_len >= 0)
1410 				p_len -= 3;
1411 			p_utf8 += 3;
1412 		}
1413 	}
1414 
1415 	{
1416 		const char *ptrtmp = p_utf8;
1417 		const char *ptrtmp_limit = &p_utf8[p_len];
1418 		int skip = 0;
1419 		while (ptrtmp != ptrtmp_limit && *ptrtmp) {
1420 
1421 			if (skip == 0) {
1422 
1423 				uint8_t c = *ptrtmp >= 0 ? *ptrtmp : uint8_t(256 + *ptrtmp);
1424 
1425 				/* Determine the number of characters in sequence */
1426 				if ((c & 0x80) == 0)
1427 					skip = 0;
1428 				else if ((c & 0xE0) == 0xC0)
1429 					skip = 1;
1430 				else if ((c & 0xF0) == 0xE0)
1431 					skip = 2;
1432 				else if ((c & 0xF8) == 0xF0)
1433 					skip = 3;
1434 				else if ((c & 0xFC) == 0xF8)
1435 					skip = 4;
1436 				else if ((c & 0xFE) == 0xFC)
1437 					skip = 5;
1438 				else {
1439 					_UNICERROR("invalid skip");
1440 					return true; //invalid utf8
1441 				}
1442 
1443 				if (skip == 1 && (c & 0x1E) == 0) {
1444 					//printf("overlong rejected\n");
1445 					_UNICERROR("overlong rejected");
1446 					return true; //reject overlong
1447 				}
1448 
1449 				str_size++;
1450 
1451 			} else {
1452 
1453 				--skip;
1454 			}
1455 
1456 			cstr_size++;
1457 			ptrtmp++;
1458 		}
1459 
1460 		if (skip) {
1461 			_UNICERROR("no space left");
1462 			return true; //not enough spac
1463 		}
1464 	}
1465 
1466 	if (str_size == 0) {
1467 		clear();
1468 		return false;
1469 	}
1470 
1471 	resize(str_size + 1);
1472 	CharType *dst = ptrw();
1473 	dst[str_size] = 0;
1474 
1475 	while (cstr_size) {
1476 
1477 		int len = 0;
1478 
1479 		/* Determine the number of characters in sequence */
1480 		if ((*p_utf8 & 0x80) == 0)
1481 			len = 1;
1482 		else if ((*p_utf8 & 0xE0) == 0xC0)
1483 			len = 2;
1484 		else if ((*p_utf8 & 0xF0) == 0xE0)
1485 			len = 3;
1486 		else if ((*p_utf8 & 0xF8) == 0xF0)
1487 			len = 4;
1488 		else if ((*p_utf8 & 0xFC) == 0xF8)
1489 			len = 5;
1490 		else if ((*p_utf8 & 0xFE) == 0xFC)
1491 			len = 6;
1492 		else {
1493 			_UNICERROR("invalid len");
1494 
1495 			return true; //invalid UTF8
1496 		}
1497 
1498 		if (len > cstr_size) {
1499 			_UNICERROR("no space left");
1500 			return true; //not enough space
1501 		}
1502 
1503 		if (len == 2 && (*p_utf8 & 0x1E) == 0) {
1504 			//printf("overlong rejected\n");
1505 			_UNICERROR("no space left");
1506 			return true; //reject overlong
1507 		}
1508 
1509 		/* Convert the first character */
1510 
1511 		uint32_t unichar = 0;
1512 
1513 		if (len == 1)
1514 			unichar = *p_utf8;
1515 		else {
1516 
1517 			unichar = (0xFF >> (len + 1)) & *p_utf8;
1518 
1519 			for (int i = 1; i < len; i++) {
1520 
1521 				if ((p_utf8[i] & 0xC0) != 0x80) {
1522 					_UNICERROR("invalid utf8");
1523 					return true; //invalid utf8
1524 				}
1525 				if (unichar == 0 && i == 2 && ((p_utf8[i] & 0x7F) >> (7 - len)) == 0) {
1526 					_UNICERROR("invalid utf8 overlong");
1527 					return true; //no overlong
1528 				}
1529 				unichar = (unichar << 6) | (p_utf8[i] & 0x3F);
1530 			}
1531 		}
1532 
1533 		//printf("char %i, len %i\n",unichar,len);
1534 		if (sizeof(wchar_t) == 2 && unichar > 0xFFFF) {
1535 			unichar = ' '; //too long for windows
1536 		}
1537 
1538 		*(dst++) = unichar;
1539 		cstr_size -= len;
1540 		p_utf8 += len;
1541 	}
1542 
1543 	return false;
1544 }
1545 
utf8() const1546 CharString String::utf8() const {
1547 
1548 	int l = length();
1549 	if (!l)
1550 		return CharString();
1551 
1552 	const CharType *d = &operator[](0);
1553 	int fl = 0;
1554 	for (int i = 0; i < l; i++) {
1555 
1556 		uint32_t c = d[i];
1557 		if (c <= 0x7f) // 7 bits.
1558 			fl += 1;
1559 		else if (c <= 0x7ff) { // 11 bits
1560 			fl += 2;
1561 		} else if (c <= 0xffff) { // 16 bits
1562 			fl += 3;
1563 		} else if (c <= 0x001fffff) { // 21 bits
1564 			fl += 4;
1565 
1566 		} else if (c <= 0x03ffffff) { // 26 bits
1567 			fl += 5;
1568 		} else if (c <= 0x7fffffff) { // 31 bits
1569 			fl += 6;
1570 		}
1571 	}
1572 
1573 	CharString utf8s;
1574 	if (fl == 0) {
1575 		return utf8s;
1576 	}
1577 
1578 	utf8s.resize(fl + 1);
1579 	uint8_t *cdst = (uint8_t *)utf8s.get_data();
1580 
1581 #define APPEND_CHAR(m_c) *(cdst++) = m_c
1582 
1583 	for (int i = 0; i < l; i++) {
1584 
1585 		uint32_t c = d[i];
1586 
1587 		if (c <= 0x7f) // 7 bits.
1588 			APPEND_CHAR(c);
1589 		else if (c <= 0x7ff) { // 11 bits
1590 
1591 			APPEND_CHAR(uint32_t(0xc0 | ((c >> 6) & 0x1f))); // Top 5 bits.
1592 			APPEND_CHAR(uint32_t(0x80 | (c & 0x3f))); // Bottom 6 bits.
1593 		} else if (c <= 0xffff) { // 16 bits
1594 
1595 			APPEND_CHAR(uint32_t(0xe0 | ((c >> 12) & 0x0f))); // Top 4 bits.
1596 			APPEND_CHAR(uint32_t(0x80 | ((c >> 6) & 0x3f))); // Middle 6 bits.
1597 			APPEND_CHAR(uint32_t(0x80 | (c & 0x3f))); // Bottom 6 bits.
1598 		} else if (c <= 0x001fffff) { // 21 bits
1599 
1600 			APPEND_CHAR(uint32_t(0xf0 | ((c >> 18) & 0x07))); // Top 3 bits.
1601 			APPEND_CHAR(uint32_t(0x80 | ((c >> 12) & 0x3f))); // Upper middle 6 bits.
1602 			APPEND_CHAR(uint32_t(0x80 | ((c >> 6) & 0x3f))); // Lower middle 6 bits.
1603 			APPEND_CHAR(uint32_t(0x80 | (c & 0x3f))); // Bottom 6 bits.
1604 		} else if (c <= 0x03ffffff) { // 26 bits
1605 
1606 			APPEND_CHAR(uint32_t(0xf8 | ((c >> 24) & 0x03))); // Top 2 bits.
1607 			APPEND_CHAR(uint32_t(0x80 | ((c >> 18) & 0x3f))); // Upper middle 6 bits.
1608 			APPEND_CHAR(uint32_t(0x80 | ((c >> 12) & 0x3f))); // middle 6 bits.
1609 			APPEND_CHAR(uint32_t(0x80 | ((c >> 6) & 0x3f))); // Lower middle 6 bits.
1610 			APPEND_CHAR(uint32_t(0x80 | (c & 0x3f))); // Bottom 6 bits.
1611 		} else if (c <= 0x7fffffff) { // 31 bits
1612 
1613 			APPEND_CHAR(uint32_t(0xfc | ((c >> 30) & 0x01))); // Top 1 bit.
1614 			APPEND_CHAR(uint32_t(0x80 | ((c >> 24) & 0x3f))); // Upper upper middle 6 bits.
1615 			APPEND_CHAR(uint32_t(0x80 | ((c >> 18) & 0x3f))); // Lower upper middle 6 bits.
1616 			APPEND_CHAR(uint32_t(0x80 | ((c >> 12) & 0x3f))); // Upper lower middle 6 bits.
1617 			APPEND_CHAR(uint32_t(0x80 | ((c >> 6) & 0x3f))); // Lower lower middle 6 bits.
1618 			APPEND_CHAR(uint32_t(0x80 | (c & 0x3f))); // Bottom 6 bits.
1619 		}
1620 	}
1621 #undef APPEND_CHAR
1622 	*cdst = 0; //trailing zero
1623 
1624 	return utf8s;
1625 }
1626 
1627 /*
1628 String::String(CharType p_char) {
1629 
1630 	shared=NULL;
1631 	copy_from(p_char);
1632 }
1633 */
1634 
String(const char * p_str)1635 String::String(const char *p_str) {
1636 
1637 	copy_from(p_str);
1638 }
1639 
String(const CharType * p_str,int p_clip_to_len)1640 String::String(const CharType *p_str, int p_clip_to_len) {
1641 
1642 	copy_from(p_str, p_clip_to_len);
1643 }
1644 
String(const StrRange & p_range)1645 String::String(const StrRange &p_range) {
1646 
1647 	if (!p_range.c_str)
1648 		return;
1649 
1650 	copy_from(p_range.c_str, p_range.len);
1651 }
1652 
hex_to_int(bool p_with_prefix) const1653 int String::hex_to_int(bool p_with_prefix) const {
1654 
1655 	if (p_with_prefix && length() < 3)
1656 		return 0;
1657 
1658 	const CharType *s = ptr();
1659 
1660 	int sign = s[0] == '-' ? -1 : 1;
1661 
1662 	if (sign < 0) {
1663 		s++;
1664 	}
1665 
1666 	if (p_with_prefix) {
1667 		if (s[0] != '0' || s[1] != 'x')
1668 			return 0;
1669 		s += 2;
1670 	}
1671 
1672 	int hex = 0;
1673 
1674 	while (*s) {
1675 
1676 		CharType c = LOWERCASE(*s);
1677 		int n;
1678 		if (c >= '0' && c <= '9') {
1679 			n = c - '0';
1680 		} else if (c >= 'a' && c <= 'f') {
1681 			n = (c - 'a') + 10;
1682 		} else {
1683 			return 0;
1684 		}
1685 		// Check for overflow/underflow, with special case to ensure INT32_MIN does not result in error
1686 		bool overflow = ((hex > INT32_MAX / 16) && (sign == 1 || (sign == -1 && hex != (INT32_MAX >> 4) + 1))) || (sign == -1 && hex == (INT32_MAX >> 4) + 1 && c > '0');
1687 		ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT32_MAX : INT32_MIN, "Cannot represent " + *this + " as integer, provided value is " + (sign == 1 ? "too big." : "too small."));
1688 		hex *= 16;
1689 		hex += n;
1690 		s++;
1691 	}
1692 
1693 	return hex * sign;
1694 }
1695 
hex_to_int64(bool p_with_prefix) const1696 int64_t String::hex_to_int64(bool p_with_prefix) const {
1697 
1698 	if (p_with_prefix && length() < 3)
1699 		return 0;
1700 
1701 	const CharType *s = ptr();
1702 
1703 	int64_t sign = s[0] == '-' ? -1 : 1;
1704 
1705 	if (sign < 0) {
1706 		s++;
1707 	}
1708 
1709 	if (p_with_prefix) {
1710 		if (s[0] != '0' || s[1] != 'x')
1711 			return 0;
1712 		s += 2;
1713 	}
1714 
1715 	int64_t hex = 0;
1716 
1717 	while (*s) {
1718 
1719 		CharType c = LOWERCASE(*s);
1720 		int64_t n;
1721 		if (c >= '0' && c <= '9') {
1722 			n = c - '0';
1723 		} else if (c >= 'a' && c <= 'f') {
1724 			n = (c - 'a') + 10;
1725 		} else {
1726 			return 0;
1727 		}
1728 		bool overflow = ((hex > INT64_MAX / 16) && (sign == 1 || (sign == -1 && hex != (INT64_MAX >> 4) + 1))) || (sign == -1 && hex == (INT64_MAX >> 4) + 1 && c > '0');
1729 		ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + *this + " as 64-bit integer, provided value is " + (sign == 1 ? "too big." : "too small."));
1730 		hex *= 16;
1731 		hex += n;
1732 		s++;
1733 	}
1734 
1735 	return hex * sign;
1736 }
1737 
bin_to_int64(bool p_with_prefix) const1738 int64_t String::bin_to_int64(bool p_with_prefix) const {
1739 
1740 	if (p_with_prefix && length() < 3)
1741 		return 0;
1742 
1743 	const CharType *s = ptr();
1744 
1745 	int64_t sign = s[0] == '-' ? -1 : 1;
1746 
1747 	if (sign < 0) {
1748 		s++;
1749 	}
1750 
1751 	if (p_with_prefix) {
1752 		if (s[0] != '0' || s[1] != 'b')
1753 			return 0;
1754 		s += 2;
1755 	}
1756 
1757 	int64_t binary = 0;
1758 
1759 	while (*s) {
1760 
1761 		CharType c = LOWERCASE(*s);
1762 		int64_t n;
1763 		if (c == '0' || c == '1') {
1764 			n = c - '0';
1765 		} else {
1766 			return 0;
1767 		}
1768 		// Check for overflow/underflow, with special case to ensure INT64_MIN does not result in error
1769 		bool overflow = ((binary > INT64_MAX / 2) && (sign == 1 || (sign == -1 && binary != (INT64_MAX >> 1) + 1))) || (sign == -1 && binary == (INT64_MAX >> 1) + 1 && c > '0');
1770 		ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + *this + " as 64-bit integer, provided value is " + (sign == 1 ? "too big." : "too small."));
1771 		binary *= 2;
1772 		binary += n;
1773 		s++;
1774 	}
1775 
1776 	return binary * sign;
1777 }
1778 
to_int() const1779 int String::to_int() const {
1780 
1781 	if (length() == 0)
1782 		return 0;
1783 
1784 	int to = (find(".") >= 0) ? find(".") : length();
1785 
1786 	int integer = 0;
1787 	int sign = 1;
1788 
1789 	for (int i = 0; i < to; i++) {
1790 
1791 		CharType c = operator[](i);
1792 		if (c >= '0' && c <= '9') {
1793 			bool overflow = (integer > INT32_MAX / 10) || (integer == INT32_MAX / 10 && ((sign == 1 && c > '7') || (sign == -1 && c > '8')));
1794 			ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT32_MAX : INT32_MIN, "Cannot represent " + *this + " as integer, provided value is " + (sign == 1 ? "too big." : "too small."));
1795 			integer *= 10;
1796 			integer += c - '0';
1797 
1798 		} else if (integer == 0 && c == '-') {
1799 
1800 			sign = -sign;
1801 		}
1802 	}
1803 
1804 	return integer * sign;
1805 }
1806 
to_int64() const1807 int64_t String::to_int64() const {
1808 
1809 	if (length() == 0)
1810 		return 0;
1811 
1812 	int to = (find(".") >= 0) ? find(".") : length();
1813 
1814 	int64_t integer = 0;
1815 	int64_t sign = 1;
1816 
1817 	for (int i = 0; i < to; i++) {
1818 		CharType c = operator[](i);
1819 		if (c >= '0' && c <= '9') {
1820 			bool overflow = (integer > INT64_MAX / 10) || (integer == INT64_MAX / 10 && ((sign == 1 && c > '7') || (sign == -1 && c > '8')));
1821 			ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + *this + " as 64-bit integer, provided value is " + (sign == 1 ? "too big." : "too small."));
1822 			integer *= 10;
1823 			integer += c - '0';
1824 
1825 		} else if (integer == 0 && c == '-') {
1826 			sign = -sign;
1827 		}
1828 	}
1829 
1830 	return integer * sign;
1831 }
1832 
to_int(const char * p_str,int p_len)1833 int String::to_int(const char *p_str, int p_len) {
1834 
1835 	int to = 0;
1836 	if (p_len >= 0)
1837 		to = p_len;
1838 	else {
1839 		while (p_str[to] != 0 && p_str[to] != '.')
1840 			to++;
1841 	}
1842 
1843 	int integer = 0;
1844 	int sign = 1;
1845 
1846 	for (int i = 0; i < to; i++) {
1847 
1848 		char c = p_str[i];
1849 		if (c >= '0' && c <= '9') {
1850 			bool overflow = (integer > INT32_MAX / 10) || (integer == INT32_MAX / 10 && ((sign == 1 && c > '7') || (sign == -1 && c > '8')));
1851 			ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT32_MAX : INT32_MIN, "Cannot represent " + String(p_str).substr(0, to) + " as integer, provided value is " + (sign == 1 ? "too big." : "too small."));
1852 			integer *= 10;
1853 			integer += c - '0';
1854 
1855 		} else if (c == '-' && integer == 0) {
1856 
1857 			sign = -sign;
1858 		} else if (c != ' ')
1859 			break;
1860 	}
1861 
1862 	return integer * sign;
1863 }
1864 
is_numeric() const1865 bool String::is_numeric() const {
1866 
1867 	if (length() == 0) {
1868 		return false;
1869 	};
1870 
1871 	int s = 0;
1872 	if (operator[](0) == '-') ++s;
1873 	bool dot = false;
1874 	for (int i = s; i < length(); i++) {
1875 
1876 		CharType c = operator[](i);
1877 		if (c == '.') {
1878 			if (dot) {
1879 				return false;
1880 			};
1881 			dot = true;
1882 		}
1883 		if (c < '0' || c > '9') {
1884 			return false;
1885 		};
1886 	};
1887 
1888 	return true; // TODO: Use the parser below for this instead
1889 };
1890 
1891 template <class C>
built_in_strtod(const C * string,C ** endPtr=NULL)1892 static double built_in_strtod(const C *string, /* A decimal ASCII floating-point number,
1893 				 * optionally preceded by white space. Must
1894 				 * have form "-I.FE-X", where I is the integer
1895 				 * part of the mantissa, F is the fractional
1896 				 * part of the mantissa, and X is the
1897 				 * exponent. Either of the signs may be "+",
1898 				 * "-", or omitted. Either I or F may be
1899 				 * omitted, or both. The decimal point isn't
1900 				 * necessary unless F is present. The "E" may
1901 				 * actually be an "e". E and X may both be
1902 				 * omitted (but not just one). */
1903 		C **endPtr = NULL) /* If non-NULL, store terminating Cacter's
1904 				 * address here. */
1905 {
1906 
1907 	static const int maxExponent = 511; /* Largest possible base 10 exponent.  Any
1908 					 * exponent larger than this will already
1909 					 * produce underflow or overflow, so there's
1910 					 * no need to worry about additional digits.
1911 					 */
1912 	static const double powersOf10[] = { /* Table giving binary powers of 10.  Entry */
1913 		10., /* is 10^2^i.  Used to convert decimal */
1914 		100., /* exponents into floating-point numbers. */
1915 		1.0e4,
1916 		1.0e8,
1917 		1.0e16,
1918 		1.0e32,
1919 		1.0e64,
1920 		1.0e128,
1921 		1.0e256
1922 	};
1923 
1924 	bool sign, expSign = false;
1925 	double fraction, dblExp;
1926 	const double *d;
1927 	const C *p;
1928 	int c;
1929 	int exp = 0; /* Exponent read from "EX" field. */
1930 	int fracExp = 0; /* Exponent that derives from the fractional
1931 				 * part. Under normal circumstances, it is
1932 				 * the negative of the number of digits in F.
1933 				 * However, if I is very long, the last digits
1934 				 * of I get dropped (otherwise a long I with a
1935 				 * large negative exponent could cause an
1936 				 * unnecessary overflow on I alone). In this
1937 				 * case, fracExp is incremented one for each
1938 				 * dropped digit. */
1939 	int mantSize; /* Number of digits in mantissa. */
1940 	int decPt; /* Number of mantissa digits BEFORE decimal
1941 				 * point. */
1942 	const C *pExp; /* Temporarily holds location of exponent in
1943 				 * string. */
1944 
1945 	/*
1946      * Strip off leading blanks and check for a sign.
1947      */
1948 
1949 	p = string;
1950 	while (*p == ' ' || *p == '\t' || *p == '\n') {
1951 		p += 1;
1952 	}
1953 	if (*p == '-') {
1954 		sign = true;
1955 		p += 1;
1956 	} else {
1957 		if (*p == '+') {
1958 			p += 1;
1959 		}
1960 		sign = false;
1961 	}
1962 
1963 	/*
1964      * Count the number of digits in the mantissa (including the decimal
1965      * point), and also locate the decimal point.
1966      */
1967 
1968 	decPt = -1;
1969 	for (mantSize = 0;; mantSize += 1) {
1970 		c = *p;
1971 		if (!IS_DIGIT(c)) {
1972 			if ((c != '.') || (decPt >= 0)) {
1973 				break;
1974 			}
1975 			decPt = mantSize;
1976 		}
1977 		p += 1;
1978 	}
1979 
1980 	/*
1981      * Now suck up the digits in the mantissa. Use two integers to collect 9
1982      * digits each (this is faster than using floating-point). If the mantissa
1983      * has more than 18 digits, ignore the extras, since they can't affect the
1984      * value anyway.
1985      */
1986 
1987 	pExp = p;
1988 	p -= mantSize;
1989 	if (decPt < 0) {
1990 		decPt = mantSize;
1991 	} else {
1992 		mantSize -= 1; /* One of the digits was the point. */
1993 	}
1994 	if (mantSize > 18) {
1995 		fracExp = decPt - 18;
1996 		mantSize = 18;
1997 	} else {
1998 		fracExp = decPt - mantSize;
1999 	}
2000 	if (mantSize == 0) {
2001 		fraction = 0.0;
2002 		p = string;
2003 		goto done;
2004 	} else {
2005 		int frac1, frac2;
2006 
2007 		frac1 = 0;
2008 		for (; mantSize > 9; mantSize -= 1) {
2009 			c = *p;
2010 			p += 1;
2011 			if (c == '.') {
2012 				c = *p;
2013 				p += 1;
2014 			}
2015 			frac1 = 10 * frac1 + (c - '0');
2016 		}
2017 		frac2 = 0;
2018 		for (; mantSize > 0; mantSize -= 1) {
2019 			c = *p;
2020 			p += 1;
2021 			if (c == '.') {
2022 				c = *p;
2023 				p += 1;
2024 			}
2025 			frac2 = 10 * frac2 + (c - '0');
2026 		}
2027 		fraction = (1.0e9 * frac1) + frac2;
2028 	}
2029 
2030 	/*
2031      * Skim off the exponent.
2032      */
2033 
2034 	p = pExp;
2035 	if ((*p == 'E') || (*p == 'e')) {
2036 		p += 1;
2037 		if (*p == '-') {
2038 			expSign = true;
2039 			p += 1;
2040 		} else {
2041 			if (*p == '+') {
2042 				p += 1;
2043 			}
2044 			expSign = false;
2045 		}
2046 		if (!IS_DIGIT(CharType(*p))) {
2047 			p = pExp;
2048 			goto done;
2049 		}
2050 		while (IS_DIGIT(CharType(*p))) {
2051 			exp = exp * 10 + (*p - '0');
2052 			p += 1;
2053 		}
2054 	}
2055 	if (expSign) {
2056 		exp = fracExp - exp;
2057 	} else {
2058 		exp = fracExp + exp;
2059 	}
2060 
2061 	/*
2062      * Generate a floating-point number that represents the exponent. Do this
2063      * by processing the exponent one bit at a time to combine many powers of
2064      * 2 of 10. Then combine the exponent with the fraction.
2065      */
2066 
2067 	if (exp < 0) {
2068 		expSign = true;
2069 		exp = -exp;
2070 	} else {
2071 		expSign = false;
2072 	}
2073 
2074 	if (exp > maxExponent) {
2075 		exp = maxExponent;
2076 		WARN_PRINT("Exponent too high");
2077 	}
2078 	dblExp = 1.0;
2079 	for (d = powersOf10; exp != 0; exp >>= 1, ++d) {
2080 		if (exp & 01) {
2081 			dblExp *= *d;
2082 		}
2083 	}
2084 	if (expSign) {
2085 		fraction /= dblExp;
2086 	} else {
2087 		fraction *= dblExp;
2088 	}
2089 
2090 done:
2091 	if (endPtr != NULL) {
2092 		*endPtr = (C *)p;
2093 	}
2094 
2095 	if (sign) {
2096 		return -fraction;
2097 	}
2098 	return fraction;
2099 }
2100 
2101 #define READING_SIGN 0
2102 #define READING_INT 1
2103 #define READING_DEC 2
2104 #define READING_EXP 3
2105 #define READING_DONE 4
2106 
to_double(const char * p_str)2107 double String::to_double(const char *p_str) {
2108 
2109 #ifndef NO_USE_STDLIB
2110 	return built_in_strtod<char>(p_str);
2111 //return atof(p_str); DOES NOT WORK ON ANDROID(??)
2112 #else
2113 	return built_in_strtod<char>(p_str);
2114 #endif
2115 }
2116 
to_float() const2117 float String::to_float() const {
2118 
2119 	return to_double();
2120 }
2121 
to_double(const CharType * p_str,const CharType ** r_end)2122 double String::to_double(const CharType *p_str, const CharType **r_end) {
2123 
2124 	return built_in_strtod<CharType>(p_str, (CharType **)r_end);
2125 }
2126 
to_int(const CharType * p_str,int p_len)2127 int64_t String::to_int(const CharType *p_str, int p_len) {
2128 
2129 	if (p_len == 0 || !p_str[0])
2130 		return 0;
2131 	///@todo make more exact so saving and loading does not lose precision
2132 
2133 	int64_t integer = 0;
2134 	int64_t sign = 1;
2135 	int reading = READING_SIGN;
2136 
2137 	const CharType *str = p_str;
2138 	const CharType *limit = &p_str[p_len];
2139 
2140 	while (*str && reading != READING_DONE && str != limit) {
2141 
2142 		CharType c = *(str++);
2143 		switch (reading) {
2144 			case READING_SIGN: {
2145 				if (c >= '0' && c <= '9') {
2146 					reading = READING_INT;
2147 					// let it fallthrough
2148 				} else if (c == '-') {
2149 					sign = -1;
2150 					reading = READING_INT;
2151 					break;
2152 				} else if (c == '+') {
2153 					sign = 1;
2154 					reading = READING_INT;
2155 					break;
2156 				} else {
2157 					break;
2158 				}
2159 			}
2160 			case READING_INT: {
2161 
2162 				if (c >= '0' && c <= '9') {
2163 
2164 					if (integer > INT64_MAX / 10) {
2165 						String number("");
2166 						str = p_str;
2167 						while (*str && str != limit) {
2168 							number += *(str++);
2169 						}
2170 						ERR_FAIL_V_MSG(sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + number + " as integer, provided value is " + (sign == 1 ? "too big." : "too small."));
2171 					}
2172 					integer *= 10;
2173 					integer += c - '0';
2174 				} else {
2175 					reading = READING_DONE;
2176 				}
2177 
2178 			} break;
2179 		}
2180 	}
2181 
2182 	return sign * integer;
2183 }
2184 
to_double() const2185 double String::to_double() const {
2186 
2187 	if (empty())
2188 		return 0;
2189 #ifndef NO_USE_STDLIB
2190 	return built_in_strtod<CharType>(c_str());
2191 //return wcstod(c_str(),NULL); DOES NOT WORK ON ANDROID :(
2192 #else
2193 	return built_in_strtod<CharType>(c_str());
2194 #endif
2195 }
2196 
operator ==(const char * p_chr,const String & p_str)2197 bool operator==(const char *p_chr, const String &p_str) {
2198 
2199 	return p_str == p_chr;
2200 }
2201 
operator +(const char * p_chr,const String & p_str)2202 String operator+(const char *p_chr, const String &p_str) {
2203 
2204 	String tmp = p_chr;
2205 	tmp += p_str;
2206 	return tmp;
2207 }
operator +(CharType p_chr,const String & p_str)2208 String operator+(CharType p_chr, const String &p_str) {
2209 
2210 	return (String::chr(p_chr) + p_str);
2211 }
2212 
hash(const char * p_cstr)2213 uint32_t String::hash(const char *p_cstr) {
2214 
2215 	uint32_t hashv = 5381;
2216 	uint32_t c;
2217 
2218 	while ((c = *p_cstr++))
2219 		hashv = ((hashv << 5) + hashv) + c; /* hash * 33 + c */
2220 
2221 	return hashv;
2222 }
2223 
hash(const char * p_cstr,int p_len)2224 uint32_t String::hash(const char *p_cstr, int p_len) {
2225 
2226 	uint32_t hashv = 5381;
2227 	for (int i = 0; i < p_len; i++)
2228 		hashv = ((hashv << 5) + hashv) + p_cstr[i]; /* hash * 33 + c */
2229 
2230 	return hashv;
2231 }
2232 
hash(const CharType * p_cstr,int p_len)2233 uint32_t String::hash(const CharType *p_cstr, int p_len) {
2234 
2235 	uint32_t hashv = 5381;
2236 	for (int i = 0; i < p_len; i++)
2237 		hashv = ((hashv << 5) + hashv) + p_cstr[i]; /* hash * 33 + c */
2238 
2239 	return hashv;
2240 }
2241 
hash(const CharType * p_cstr)2242 uint32_t String::hash(const CharType *p_cstr) {
2243 
2244 	uint32_t hashv = 5381;
2245 	uint32_t c;
2246 
2247 	while ((c = *p_cstr++))
2248 		hashv = ((hashv << 5) + hashv) + c; /* hash * 33 + c */
2249 
2250 	return hashv;
2251 }
2252 
hash() const2253 uint32_t String::hash() const {
2254 
2255 	/* simple djb2 hashing */
2256 
2257 	const CharType *chr = c_str();
2258 	uint32_t hashv = 5381;
2259 	uint32_t c;
2260 
2261 	while ((c = *chr++))
2262 		hashv = ((hashv << 5) + hashv) + c; /* hash * 33 + c */
2263 
2264 	return hashv;
2265 }
2266 
hash64() const2267 uint64_t String::hash64() const {
2268 
2269 	/* simple djb2 hashing */
2270 
2271 	const CharType *chr = c_str();
2272 	uint64_t hashv = 5381;
2273 	uint64_t c;
2274 
2275 	while ((c = *chr++))
2276 		hashv = ((hashv << 5) + hashv) + c; /* hash * 33 + c */
2277 
2278 	return hashv;
2279 }
2280 
md5_text() const2281 String String::md5_text() const {
2282 
2283 	CharString cs = utf8();
2284 	unsigned char hash[16];
2285 	CryptoCore::md5((unsigned char *)cs.ptr(), cs.length(), hash);
2286 	return String::hex_encode_buffer(hash, 16);
2287 }
2288 
sha1_text() const2289 String String::sha1_text() const {
2290 	CharString cs = utf8();
2291 	unsigned char hash[20];
2292 	CryptoCore::sha1((unsigned char *)cs.ptr(), cs.length(), hash);
2293 	return String::hex_encode_buffer(hash, 20);
2294 }
2295 
sha256_text() const2296 String String::sha256_text() const {
2297 	CharString cs = utf8();
2298 	unsigned char hash[32];
2299 	CryptoCore::sha256((unsigned char *)cs.ptr(), cs.length(), hash);
2300 	return String::hex_encode_buffer(hash, 32);
2301 }
2302 
md5_buffer() const2303 Vector<uint8_t> String::md5_buffer() const {
2304 
2305 	CharString cs = utf8();
2306 	unsigned char hash[16];
2307 	CryptoCore::md5((unsigned char *)cs.ptr(), cs.length(), hash);
2308 
2309 	Vector<uint8_t> ret;
2310 	ret.resize(16);
2311 	for (int i = 0; i < 16; i++) {
2312 		ret.write[i] = hash[i];
2313 	}
2314 	return ret;
2315 };
2316 
sha1_buffer() const2317 Vector<uint8_t> String::sha1_buffer() const {
2318 	CharString cs = utf8();
2319 	unsigned char hash[20];
2320 	CryptoCore::sha1((unsigned char *)cs.ptr(), cs.length(), hash);
2321 
2322 	Vector<uint8_t> ret;
2323 	ret.resize(20);
2324 	for (int i = 0; i < 20; i++) {
2325 		ret.write[i] = hash[i];
2326 	}
2327 
2328 	return ret;
2329 }
2330 
sha256_buffer() const2331 Vector<uint8_t> String::sha256_buffer() const {
2332 	CharString cs = utf8();
2333 	unsigned char hash[32];
2334 	CryptoCore::sha256((unsigned char *)cs.ptr(), cs.length(), hash);
2335 
2336 	Vector<uint8_t> ret;
2337 	ret.resize(32);
2338 	for (int i = 0; i < 32; i++) {
2339 		ret.write[i] = hash[i];
2340 	}
2341 	return ret;
2342 }
2343 
insert(int p_at_pos,const String & p_string) const2344 String String::insert(int p_at_pos, const String &p_string) const {
2345 
2346 	if (p_at_pos < 0)
2347 		return *this;
2348 
2349 	if (p_at_pos > length())
2350 		p_at_pos = length();
2351 
2352 	String pre;
2353 	if (p_at_pos > 0)
2354 		pre = substr(0, p_at_pos);
2355 
2356 	String post;
2357 	if (p_at_pos < length())
2358 		post = substr(p_at_pos, length() - p_at_pos);
2359 
2360 	return pre + p_string + post;
2361 }
substr(int p_from,int p_chars) const2362 String String::substr(int p_from, int p_chars) const {
2363 
2364 	if (p_chars == -1)
2365 		p_chars = length() - p_from;
2366 
2367 	if (empty() || p_from < 0 || p_from >= length() || p_chars <= 0)
2368 		return "";
2369 
2370 	if ((p_from + p_chars) > length()) {
2371 
2372 		p_chars = length() - p_from;
2373 	}
2374 
2375 	if (p_from == 0 && p_chars >= length()) {
2376 
2377 		return String(*this);
2378 	}
2379 
2380 	String s = String();
2381 	s.copy_from_unchecked(&c_str()[p_from], p_chars);
2382 	return s;
2383 }
2384 
find_last(const String & p_str) const2385 int String::find_last(const String &p_str) const {
2386 
2387 	int pos = -1;
2388 	int findfrom = 0;
2389 	int findres = -1;
2390 	while ((findres = find(p_str, findfrom)) != -1) {
2391 
2392 		pos = findres;
2393 		findfrom = pos + 1;
2394 	}
2395 
2396 	return pos;
2397 }
2398 
find(const String & p_str,int p_from) const2399 int String::find(const String &p_str, int p_from) const {
2400 
2401 	if (p_from < 0)
2402 		return -1;
2403 
2404 	const int src_len = p_str.length();
2405 
2406 	const int len = length();
2407 
2408 	if (src_len == 0 || len == 0)
2409 		return -1; // won't find anything!
2410 
2411 	const CharType *src = c_str();
2412 	const CharType *str = p_str.c_str();
2413 
2414 	for (int i = p_from; i <= (len - src_len); i++) {
2415 
2416 		bool found = true;
2417 		for (int j = 0; j < src_len; j++) {
2418 
2419 			int read_pos = i + j;
2420 
2421 			if (read_pos >= len) {
2422 
2423 				ERR_PRINT("read_pos>=len");
2424 				return -1;
2425 			};
2426 
2427 			if (src[read_pos] != str[j]) {
2428 				found = false;
2429 				break;
2430 			}
2431 		}
2432 
2433 		if (found)
2434 			return i;
2435 	}
2436 
2437 	return -1;
2438 }
2439 
find(const char * p_str,int p_from) const2440 int String::find(const char *p_str, int p_from) const {
2441 
2442 	if (p_from < 0)
2443 		return -1;
2444 
2445 	const int len = length();
2446 
2447 	if (len == 0)
2448 		return -1; // won't find anything!
2449 
2450 	const CharType *src = c_str();
2451 
2452 	int src_len = 0;
2453 	while (p_str[src_len] != '\0')
2454 		src_len++;
2455 
2456 	if (src_len == 1) {
2457 
2458 		const char needle = p_str[0];
2459 
2460 		for (int i = p_from; i < len; i++) {
2461 
2462 			if (src[i] == needle) {
2463 				return i;
2464 			}
2465 		}
2466 
2467 	} else {
2468 
2469 		for (int i = p_from; i <= (len - src_len); i++) {
2470 
2471 			bool found = true;
2472 			for (int j = 0; j < src_len; j++) {
2473 
2474 				int read_pos = i + j;
2475 
2476 				if (read_pos >= len) {
2477 
2478 					ERR_PRINT("read_pos>=len");
2479 					return -1;
2480 				};
2481 
2482 				if (src[read_pos] != p_str[j]) {
2483 					found = false;
2484 					break;
2485 				}
2486 			}
2487 
2488 			if (found)
2489 				return i;
2490 		}
2491 	}
2492 
2493 	return -1;
2494 }
2495 
find_char(const CharType & p_char,int p_from) const2496 int String::find_char(const CharType &p_char, int p_from) const {
2497 	return _cowdata.find(p_char, p_from);
2498 }
2499 
findmk(const Vector<String> & p_keys,int p_from,int * r_key) const2500 int String::findmk(const Vector<String> &p_keys, int p_from, int *r_key) const {
2501 
2502 	if (p_from < 0)
2503 		return -1;
2504 	if (p_keys.size() == 0)
2505 		return -1;
2506 
2507 	//int src_len=p_str.length();
2508 	const String *keys = &p_keys[0];
2509 	int key_count = p_keys.size();
2510 	int len = length();
2511 
2512 	if (len == 0)
2513 		return -1; // won't find anything!
2514 
2515 	const CharType *src = c_str();
2516 
2517 	for (int i = p_from; i < len; i++) {
2518 
2519 		bool found = true;
2520 		for (int k = 0; k < key_count; k++) {
2521 
2522 			found = true;
2523 			if (r_key)
2524 				*r_key = k;
2525 			const CharType *cmp = keys[k].c_str();
2526 			int l = keys[k].length();
2527 
2528 			for (int j = 0; j < l; j++) {
2529 
2530 				int read_pos = i + j;
2531 
2532 				if (read_pos >= len) {
2533 
2534 					found = false;
2535 					break;
2536 				};
2537 
2538 				if (src[read_pos] != cmp[j]) {
2539 					found = false;
2540 					break;
2541 				}
2542 			}
2543 			if (found)
2544 				break;
2545 		}
2546 
2547 		if (found)
2548 			return i;
2549 	}
2550 
2551 	return -1;
2552 }
2553 
findn(const String & p_str,int p_from) const2554 int String::findn(const String &p_str, int p_from) const {
2555 
2556 	if (p_from < 0)
2557 		return -1;
2558 
2559 	int src_len = p_str.length();
2560 
2561 	if (src_len == 0 || length() == 0)
2562 		return -1; // won't find anything!
2563 
2564 	const CharType *srcd = c_str();
2565 
2566 	for (int i = p_from; i <= (length() - src_len); i++) {
2567 
2568 		bool found = true;
2569 		for (int j = 0; j < src_len; j++) {
2570 
2571 			int read_pos = i + j;
2572 
2573 			if (read_pos >= length()) {
2574 
2575 				ERR_PRINT("read_pos>=length()");
2576 				return -1;
2577 			};
2578 
2579 			CharType src = _find_lower(srcd[read_pos]);
2580 			CharType dst = _find_lower(p_str[j]);
2581 
2582 			if (src != dst) {
2583 				found = false;
2584 				break;
2585 			}
2586 		}
2587 
2588 		if (found)
2589 			return i;
2590 	}
2591 
2592 	return -1;
2593 }
2594 
rfind(const String & p_str,int p_from) const2595 int String::rfind(const String &p_str, int p_from) const {
2596 
2597 	// establish a limit
2598 	int limit = length() - p_str.length();
2599 	if (limit < 0)
2600 		return -1;
2601 
2602 	// establish a starting point
2603 	if (p_from < 0)
2604 		p_from = limit;
2605 	else if (p_from > limit)
2606 		p_from = limit;
2607 
2608 	int src_len = p_str.length();
2609 	int len = length();
2610 
2611 	if (src_len == 0 || len == 0)
2612 		return -1; // won't find anything!
2613 
2614 	const CharType *src = c_str();
2615 
2616 	for (int i = p_from; i >= 0; i--) {
2617 
2618 		bool found = true;
2619 		for (int j = 0; j < src_len; j++) {
2620 
2621 			int read_pos = i + j;
2622 
2623 			if (read_pos >= len) {
2624 
2625 				ERR_PRINT("read_pos>=len");
2626 				return -1;
2627 			};
2628 
2629 			if (src[read_pos] != p_str[j]) {
2630 				found = false;
2631 				break;
2632 			}
2633 		}
2634 
2635 		if (found)
2636 			return i;
2637 	}
2638 
2639 	return -1;
2640 }
rfindn(const String & p_str,int p_from) const2641 int String::rfindn(const String &p_str, int p_from) const {
2642 
2643 	// establish a limit
2644 	int limit = length() - p_str.length();
2645 	if (limit < 0)
2646 		return -1;
2647 
2648 	// establish a starting point
2649 	if (p_from < 0)
2650 		p_from = limit;
2651 	else if (p_from > limit)
2652 		p_from = limit;
2653 
2654 	int src_len = p_str.length();
2655 	int len = length();
2656 
2657 	if (src_len == 0 || len == 0)
2658 		return -1; // won't find anything!
2659 
2660 	const CharType *src = c_str();
2661 
2662 	for (int i = p_from; i >= 0; i--) {
2663 
2664 		bool found = true;
2665 		for (int j = 0; j < src_len; j++) {
2666 
2667 			int read_pos = i + j;
2668 
2669 			if (read_pos >= len) {
2670 
2671 				ERR_PRINT("read_pos>=len");
2672 				return -1;
2673 			};
2674 
2675 			CharType srcc = _find_lower(src[read_pos]);
2676 			CharType dstc = _find_lower(p_str[j]);
2677 
2678 			if (srcc != dstc) {
2679 				found = false;
2680 				break;
2681 			}
2682 		}
2683 
2684 		if (found)
2685 			return i;
2686 	}
2687 
2688 	return -1;
2689 }
2690 
ends_with(const String & p_string) const2691 bool String::ends_with(const String &p_string) const {
2692 
2693 	int pos = find_last(p_string);
2694 	if (pos == -1)
2695 		return false;
2696 	return pos + p_string.length() == length();
2697 }
2698 
begins_with(const String & p_string) const2699 bool String::begins_with(const String &p_string) const {
2700 
2701 	if (p_string.length() > length())
2702 		return false;
2703 
2704 	int l = p_string.length();
2705 	if (l == 0)
2706 		return true;
2707 
2708 	const CharType *src = &p_string[0];
2709 	const CharType *str = &operator[](0);
2710 
2711 	int i = 0;
2712 	for (; i < l; i++) {
2713 
2714 		if (src[i] != str[i])
2715 			return false;
2716 	}
2717 
2718 	// only if i == l the p_string matches the beginning
2719 	return i == l;
2720 }
begins_with(const char * p_string) const2721 bool String::begins_with(const char *p_string) const {
2722 
2723 	int l = length();
2724 	if (l == 0 || !p_string)
2725 		return false;
2726 
2727 	const CharType *str = &operator[](0);
2728 	int i = 0;
2729 
2730 	while (*p_string && i < l) {
2731 
2732 		if (*p_string != str[i])
2733 			return false;
2734 		i++;
2735 		p_string++;
2736 	}
2737 
2738 	return *p_string == 0;
2739 }
2740 
is_enclosed_in(const String & p_string) const2741 bool String::is_enclosed_in(const String &p_string) const {
2742 
2743 	return begins_with(p_string) && ends_with(p_string);
2744 }
2745 
is_subsequence_of(const String & p_string) const2746 bool String::is_subsequence_of(const String &p_string) const {
2747 
2748 	return _base_is_subsequence_of(p_string, false);
2749 }
2750 
is_subsequence_ofi(const String & p_string) const2751 bool String::is_subsequence_ofi(const String &p_string) const {
2752 
2753 	return _base_is_subsequence_of(p_string, true);
2754 }
2755 
is_quoted() const2756 bool String::is_quoted() const {
2757 
2758 	return is_enclosed_in("\"") || is_enclosed_in("'");
2759 }
2760 
_count(const String & p_string,int p_from,int p_to,bool p_case_insensitive) const2761 int String::_count(const String &p_string, int p_from, int p_to, bool p_case_insensitive) const {
2762 	if (p_string.empty()) {
2763 		return 0;
2764 	}
2765 	int len = length();
2766 	int slen = p_string.length();
2767 	if (len < slen) {
2768 		return 0;
2769 	}
2770 	String str;
2771 	if (p_from >= 0 && p_to >= 0) {
2772 		if (p_to == 0) {
2773 			p_to = len;
2774 		} else if (p_from >= p_to) {
2775 			return 0;
2776 		}
2777 		if (p_from == 0 && p_to == len) {
2778 			str = String();
2779 			str.copy_from_unchecked(&c_str()[0], len);
2780 		} else {
2781 			str = substr(p_from, p_to - p_from);
2782 		}
2783 	} else {
2784 		return 0;
2785 	}
2786 	int c = 0;
2787 	int idx = -1;
2788 	do {
2789 		idx = p_case_insensitive ? str.findn(p_string) : str.find(p_string);
2790 		if (idx != -1) {
2791 			str = str.substr(idx + slen, str.length() - slen);
2792 			++c;
2793 		}
2794 	} while (idx != -1);
2795 	return c;
2796 }
2797 
count(const String & p_string,int p_from,int p_to) const2798 int String::count(const String &p_string, int p_from, int p_to) const {
2799 	return _count(p_string, p_from, p_to, false);
2800 }
2801 
countn(const String & p_string,int p_from,int p_to) const2802 int String::countn(const String &p_string, int p_from, int p_to) const {
2803 	return _count(p_string, p_from, p_to, true);
2804 }
2805 
_base_is_subsequence_of(const String & p_string,bool case_insensitive) const2806 bool String::_base_is_subsequence_of(const String &p_string, bool case_insensitive) const {
2807 
2808 	int len = length();
2809 	if (len == 0) {
2810 		// Technically an empty string is subsequence of any string
2811 		return true;
2812 	}
2813 
2814 	if (len > p_string.length()) {
2815 		return false;
2816 	}
2817 
2818 	const CharType *src = &operator[](0);
2819 	const CharType *tgt = &p_string[0];
2820 
2821 	for (; *src && *tgt; tgt++) {
2822 		bool match = false;
2823 		if (case_insensitive) {
2824 			CharType srcc = _find_lower(*src);
2825 			CharType tgtc = _find_lower(*tgt);
2826 			match = srcc == tgtc;
2827 		} else {
2828 			match = *src == *tgt;
2829 		}
2830 		if (match) {
2831 			src++;
2832 			if (!*src) {
2833 				return true;
2834 			}
2835 		}
2836 	}
2837 
2838 	return false;
2839 }
2840 
bigrams() const2841 Vector<String> String::bigrams() const {
2842 	int n_pairs = length() - 1;
2843 	Vector<String> b;
2844 	if (n_pairs <= 0) {
2845 		return b;
2846 	}
2847 	b.resize(n_pairs);
2848 	for (int i = 0; i < n_pairs; i++) {
2849 		b.write[i] = substr(i, 2);
2850 	}
2851 	return b;
2852 }
2853 
2854 // Similarity according to Sorensen-Dice coefficient
similarity(const String & p_string) const2855 float String::similarity(const String &p_string) const {
2856 	if (operator==(p_string)) {
2857 		// Equal strings are totally similar
2858 		return 1.0f;
2859 	}
2860 	if (length() < 2 || p_string.length() < 2) {
2861 		// No way to calculate similarity without a single bigram
2862 		return 0.0f;
2863 	}
2864 
2865 	Vector<String> src_bigrams = bigrams();
2866 	Vector<String> tgt_bigrams = p_string.bigrams();
2867 
2868 	int src_size = src_bigrams.size();
2869 	int tgt_size = tgt_bigrams.size();
2870 
2871 	float sum = src_size + tgt_size;
2872 	float inter = 0;
2873 	for (int i = 0; i < src_size; i++) {
2874 		for (int j = 0; j < tgt_size; j++) {
2875 			if (src_bigrams[i] == tgt_bigrams[j]) {
2876 				inter++;
2877 				break;
2878 			}
2879 		}
2880 	}
2881 
2882 	return (2.0f * inter) / sum;
2883 }
2884 
_wildcard_match(const CharType * p_pattern,const CharType * p_string,bool p_case_sensitive)2885 static bool _wildcard_match(const CharType *p_pattern, const CharType *p_string, bool p_case_sensitive) {
2886 	switch (*p_pattern) {
2887 		case '\0':
2888 			return !*p_string;
2889 		case '*':
2890 			return _wildcard_match(p_pattern + 1, p_string, p_case_sensitive) || (*p_string && _wildcard_match(p_pattern, p_string + 1, p_case_sensitive));
2891 		case '?':
2892 			return *p_string && (*p_string != '.') && _wildcard_match(p_pattern + 1, p_string + 1, p_case_sensitive);
2893 		default:
2894 
2895 			return (p_case_sensitive ? (*p_string == *p_pattern) : (_find_upper(*p_string) == _find_upper(*p_pattern))) && _wildcard_match(p_pattern + 1, p_string + 1, p_case_sensitive);
2896 	}
2897 }
2898 
match(const String & p_wildcard) const2899 bool String::match(const String &p_wildcard) const {
2900 
2901 	if (!p_wildcard.length() || !length())
2902 		return false;
2903 
2904 	return _wildcard_match(p_wildcard.c_str(), c_str(), true);
2905 }
2906 
matchn(const String & p_wildcard) const2907 bool String::matchn(const String &p_wildcard) const {
2908 
2909 	if (!p_wildcard.length() || !length())
2910 		return false;
2911 	return _wildcard_match(p_wildcard.c_str(), c_str(), false);
2912 }
2913 
format(const Variant & values,String placeholder) const2914 String String::format(const Variant &values, String placeholder) const {
2915 
2916 	String new_string = String(this->ptr());
2917 
2918 	if (values.get_type() == Variant::ARRAY) {
2919 		Array values_arr = values;
2920 
2921 		for (int i = 0; i < values_arr.size(); i++) {
2922 			String i_as_str = String::num_int64(i);
2923 
2924 			if (values_arr[i].get_type() == Variant::ARRAY) { //Array in Array structure [["name","RobotGuy"],[0,"godot"],["strength",9000.91]]
2925 				Array value_arr = values_arr[i];
2926 
2927 				if (value_arr.size() == 2) {
2928 					Variant v_key = value_arr[0];
2929 					String key = v_key;
2930 					if (key.left(1) == "\"" && key.right(key.length() - 1) == "\"") {
2931 						key = key.substr(1, key.length() - 2);
2932 					}
2933 
2934 					Variant v_val = value_arr[1];
2935 					String val = v_val;
2936 
2937 					if (val.left(1) == "\"" && val.right(val.length() - 1) == "\"") {
2938 						val = val.substr(1, val.length() - 2);
2939 					}
2940 
2941 					new_string = new_string.replace(placeholder.replace("_", key), val);
2942 				} else {
2943 					ERR_PRINT(String("STRING.format Inner Array size != 2 ").ascii().get_data());
2944 				}
2945 			} else { //Array structure ["RobotGuy","Logis","rookie"]
2946 				Variant v_val = values_arr[i];
2947 				String val = v_val;
2948 
2949 				if (val.left(1) == "\"" && val.right(val.length() - 1) == "\"") {
2950 					val = val.substr(1, val.length() - 2);
2951 				}
2952 
2953 				if (placeholder.find("_") > -1) {
2954 					new_string = new_string.replace(placeholder.replace("_", i_as_str), val);
2955 				} else {
2956 					new_string = new_string.replace_first(placeholder, val);
2957 				}
2958 			}
2959 		}
2960 	} else if (values.get_type() == Variant::DICTIONARY) {
2961 		Dictionary d = values;
2962 		List<Variant> keys;
2963 		d.get_key_list(&keys);
2964 
2965 		for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
2966 			String key = E->get();
2967 			String val = d[E->get()];
2968 
2969 			if (key.left(1) == "\"" && key.right(key.length() - 1) == "\"") {
2970 				key = key.substr(1, key.length() - 2);
2971 			}
2972 
2973 			if (val.left(1) == "\"" && val.right(val.length() - 1) == "\"") {
2974 				val = val.substr(1, val.length() - 2);
2975 			}
2976 
2977 			new_string = new_string.replace(placeholder.replace("_", key), val);
2978 		}
2979 	} else {
2980 		ERR_PRINT(String("Invalid type: use Array or Dictionary.").ascii().get_data());
2981 	}
2982 
2983 	return new_string;
2984 }
2985 
replace(const String & p_key,const String & p_with) const2986 String String::replace(const String &p_key, const String &p_with) const {
2987 
2988 	String new_string;
2989 	int search_from = 0;
2990 	int result = 0;
2991 
2992 	while ((result = find(p_key, search_from)) >= 0) {
2993 
2994 		new_string += substr(search_from, result - search_from);
2995 		new_string += p_with;
2996 		search_from = result + p_key.length();
2997 	}
2998 
2999 	if (search_from == 0) {
3000 
3001 		return *this;
3002 	}
3003 
3004 	new_string += substr(search_from, length() - search_from);
3005 
3006 	return new_string;
3007 }
3008 
replace(const char * p_key,const char * p_with) const3009 String String::replace(const char *p_key, const char *p_with) const {
3010 
3011 	String new_string;
3012 	int search_from = 0;
3013 	int result = 0;
3014 
3015 	while ((result = find(p_key, search_from)) >= 0) {
3016 
3017 		new_string += substr(search_from, result - search_from);
3018 		new_string += p_with;
3019 		int k = 0;
3020 		while (p_key[k] != '\0')
3021 			k++;
3022 		search_from = result + k;
3023 	}
3024 
3025 	if (search_from == 0) {
3026 
3027 		return *this;
3028 	}
3029 
3030 	new_string += substr(search_from, length() - search_from);
3031 
3032 	return new_string;
3033 }
3034 
replace_first(const String & p_key,const String & p_with) const3035 String String::replace_first(const String &p_key, const String &p_with) const {
3036 
3037 	int pos = find(p_key);
3038 	if (pos >= 0) {
3039 		return substr(0, pos) + p_with + substr(pos + p_key.length(), length());
3040 	}
3041 
3042 	return *this;
3043 }
replacen(const String & p_key,const String & p_with) const3044 String String::replacen(const String &p_key, const String &p_with) const {
3045 
3046 	String new_string;
3047 	int search_from = 0;
3048 	int result = 0;
3049 
3050 	while ((result = findn(p_key, search_from)) >= 0) {
3051 
3052 		new_string += substr(search_from, result - search_from);
3053 		new_string += p_with;
3054 		search_from = result + p_key.length();
3055 	}
3056 
3057 	if (search_from == 0) {
3058 
3059 		return *this;
3060 	}
3061 
3062 	new_string += substr(search_from, length() - search_from);
3063 	return new_string;
3064 }
3065 
repeat(int p_count) const3066 String String::repeat(int p_count) const {
3067 
3068 	ERR_FAIL_COND_V_MSG(p_count < 0, "", "Parameter count should be a positive number.");
3069 
3070 	String new_string;
3071 	const CharType *src = this->c_str();
3072 
3073 	new_string.resize(length() * p_count + 1);
3074 	new_string[length() * p_count] = 0;
3075 
3076 	for (int i = 0; i < p_count; i++)
3077 		for (int j = 0; j < length(); j++)
3078 			new_string[i * length() + j] = src[j];
3079 
3080 	return new_string;
3081 }
3082 
left(int p_pos) const3083 String String::left(int p_pos) const {
3084 
3085 	if (p_pos <= 0)
3086 		return "";
3087 
3088 	if (p_pos >= length())
3089 		return *this;
3090 
3091 	return substr(0, p_pos);
3092 }
3093 
right(int p_pos) const3094 String String::right(int p_pos) const {
3095 
3096 	if (p_pos >= length())
3097 		return "";
3098 
3099 	if (p_pos <= 0)
3100 		return *this;
3101 
3102 	return substr(p_pos, (length() - p_pos));
3103 }
3104 
ord_at(int p_idx) const3105 CharType String::ord_at(int p_idx) const {
3106 
3107 	ERR_FAIL_INDEX_V(p_idx, length(), 0);
3108 	return operator[](p_idx);
3109 }
3110 
dedent() const3111 String String::dedent() const {
3112 
3113 	String new_string;
3114 	String indent;
3115 	bool has_indent = false;
3116 	bool has_text = false;
3117 	int line_start = 0;
3118 	int indent_stop = -1;
3119 
3120 	for (int i = 0; i < length(); i++) {
3121 
3122 		CharType c = operator[](i);
3123 		if (c == '\n') {
3124 			if (has_text)
3125 				new_string += substr(indent_stop, i - indent_stop);
3126 			new_string += "\n";
3127 			has_text = false;
3128 			line_start = i + 1;
3129 			indent_stop = -1;
3130 		} else if (!has_text) {
3131 			if (c > 32) {
3132 				has_text = true;
3133 				if (!has_indent) {
3134 					has_indent = true;
3135 					indent = substr(line_start, i - line_start);
3136 					indent_stop = i;
3137 				}
3138 			}
3139 			if (has_indent && indent_stop < 0) {
3140 				int j = i - line_start;
3141 				if (j >= indent.length() || c != indent[j])
3142 					indent_stop = i;
3143 			}
3144 		}
3145 	}
3146 
3147 	if (has_text)
3148 		new_string += substr(indent_stop, length() - indent_stop);
3149 
3150 	return new_string;
3151 }
3152 
strip_edges(bool left,bool right) const3153 String String::strip_edges(bool left, bool right) const {
3154 
3155 	int len = length();
3156 	int beg = 0, end = len;
3157 
3158 	if (left) {
3159 		for (int i = 0; i < len; i++) {
3160 
3161 			if (operator[](i) <= 32)
3162 				beg++;
3163 			else
3164 				break;
3165 		}
3166 	}
3167 
3168 	if (right) {
3169 		for (int i = (int)(len - 1); i >= 0; i--) {
3170 
3171 			if (operator[](i) <= 32)
3172 				end--;
3173 			else
3174 				break;
3175 		}
3176 	}
3177 
3178 	if (beg == 0 && end == len)
3179 		return *this;
3180 
3181 	return substr(beg, end - beg);
3182 }
3183 
strip_escapes() const3184 String String::strip_escapes() const {
3185 
3186 	String new_string;
3187 	for (int i = 0; i < length(); i++) {
3188 
3189 		// Escape characters on first page of the ASCII table, before 32 (Space).
3190 		if (operator[](i) < 32)
3191 			continue;
3192 		new_string += operator[](i);
3193 	}
3194 
3195 	return new_string;
3196 }
3197 
lstrip(const String & p_chars) const3198 String String::lstrip(const String &p_chars) const {
3199 
3200 	int len = length();
3201 	int beg;
3202 
3203 	for (beg = 0; beg < len; beg++) {
3204 
3205 		if (p_chars.find_char(get(beg)) == -1)
3206 			break;
3207 	}
3208 
3209 	if (beg == 0)
3210 		return *this;
3211 
3212 	return substr(beg, len - beg);
3213 }
3214 
rstrip(const String & p_chars) const3215 String String::rstrip(const String &p_chars) const {
3216 
3217 	int len = length();
3218 	int end;
3219 
3220 	for (end = len - 1; end >= 0; end--) {
3221 
3222 		if (p_chars.find_char(get(end)) == -1)
3223 			break;
3224 	}
3225 
3226 	if (end == len - 1)
3227 		return *this;
3228 
3229 	return substr(0, end + 1);
3230 }
3231 
simplify_path() const3232 String String::simplify_path() const {
3233 
3234 	String s = *this;
3235 	String drive;
3236 	if (s.begins_with("local://")) {
3237 		drive = "local://";
3238 		s = s.substr(8, s.length());
3239 	} else if (s.begins_with("res://")) {
3240 
3241 		drive = "res://";
3242 		s = s.substr(6, s.length());
3243 	} else if (s.begins_with("user://")) {
3244 
3245 		drive = "user://";
3246 		s = s.substr(7, s.length());
3247 	} else if (s.begins_with("/") || s.begins_with("\\")) {
3248 
3249 		drive = s.substr(0, 1);
3250 		s = s.substr(1, s.length() - 1);
3251 	} else {
3252 
3253 		int p = s.find(":/");
3254 		if (p == -1)
3255 			p = s.find(":\\");
3256 		if (p != -1 && p < s.find("/")) {
3257 
3258 			drive = s.substr(0, p + 2);
3259 			s = s.substr(p + 2, s.length());
3260 		}
3261 	}
3262 
3263 	s = s.replace("\\", "/");
3264 	while (true) { // in case of using 2 or more slash
3265 		String compare = s.replace("//", "/");
3266 		if (s == compare)
3267 			break;
3268 		else
3269 			s = compare;
3270 	}
3271 	Vector<String> dirs = s.split("/", false);
3272 
3273 	for (int i = 0; i < dirs.size(); i++) {
3274 
3275 		String d = dirs[i];
3276 		if (d == ".") {
3277 			dirs.remove(i);
3278 			i--;
3279 		} else if (d == "..") {
3280 
3281 			if (i == 0) {
3282 				dirs.remove(i);
3283 				i--;
3284 			} else {
3285 				dirs.remove(i);
3286 				dirs.remove(i - 1);
3287 				i -= 2;
3288 			}
3289 		}
3290 	}
3291 
3292 	s = "";
3293 
3294 	for (int i = 0; i < dirs.size(); i++) {
3295 
3296 		if (i > 0)
3297 			s += "/";
3298 		s += dirs[i];
3299 	}
3300 
3301 	return drive + s;
3302 }
3303 
_humanize_digits(int p_num)3304 static int _humanize_digits(int p_num) {
3305 
3306 	if (p_num < 100)
3307 		return 2;
3308 	else if (p_num < 1024)
3309 		return 1;
3310 	else
3311 		return 0;
3312 }
3313 
humanize_size(uint64_t p_size)3314 String String::humanize_size(uint64_t p_size) {
3315 
3316 	uint64_t _div = 1;
3317 	Vector<String> prefixes;
3318 	prefixes.push_back(RTR("B"));
3319 	prefixes.push_back(RTR("KiB"));
3320 	prefixes.push_back(RTR("MiB"));
3321 	prefixes.push_back(RTR("GiB"));
3322 	prefixes.push_back(RTR("TiB"));
3323 	prefixes.push_back(RTR("PiB"));
3324 	prefixes.push_back(RTR("EiB"));
3325 
3326 	int prefix_idx = 0;
3327 
3328 	while (prefix_idx < prefixes.size() - 1 && p_size > (_div * 1024)) {
3329 		_div *= 1024;
3330 		prefix_idx++;
3331 	}
3332 
3333 	const int digits = prefix_idx > 0 ? _humanize_digits(p_size / _div) : 0;
3334 	const double divisor = prefix_idx > 0 ? _div : 1;
3335 
3336 	return String::num(p_size / divisor).pad_decimals(digits) + " " + prefixes[prefix_idx];
3337 }
is_abs_path() const3338 bool String::is_abs_path() const {
3339 
3340 	if (length() > 1)
3341 		return (operator[](0) == '/' || operator[](0) == '\\' || find(":/") != -1 || find(":\\") != -1);
3342 	else if ((length()) == 1)
3343 		return (operator[](0) == '/' || operator[](0) == '\\');
3344 	else
3345 		return false;
3346 }
3347 
is_valid_identifier() const3348 bool String::is_valid_identifier() const {
3349 
3350 	int len = length();
3351 
3352 	if (len == 0)
3353 		return false;
3354 
3355 	const wchar_t *str = &operator[](0);
3356 
3357 	for (int i = 0; i < len; i++) {
3358 
3359 		if (i == 0) {
3360 			if (str[0] >= '0' && str[0] <= '9')
3361 				return false; // no start with number plz
3362 		}
3363 
3364 		bool valid_char = (str[i] >= '0' && str[i] <= '9') || (str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z') || str[i] == '_';
3365 
3366 		if (!valid_char)
3367 			return false;
3368 	}
3369 
3370 	return true;
3371 }
3372 
3373 //kind of poor should be rewritten properly
3374 
word_wrap(int p_chars_per_line) const3375 String String::word_wrap(int p_chars_per_line) const {
3376 
3377 	int from = 0;
3378 	int last_space = 0;
3379 	String ret;
3380 	for (int i = 0; i < length(); i++) {
3381 		if (i - from >= p_chars_per_line) {
3382 			if (last_space == -1) {
3383 				ret += substr(from, i - from + 1) + "\n";
3384 			} else {
3385 				ret += substr(from, last_space - from) + "\n";
3386 				i = last_space; //rewind
3387 			}
3388 			from = i + 1;
3389 			last_space = -1;
3390 		} else if (operator[](i) == ' ' || operator[](i) == '\t') {
3391 			last_space = i;
3392 		} else if (operator[](i) == '\n') {
3393 			ret += substr(from, i - from) + "\n";
3394 			from = i + 1;
3395 			last_space = -1;
3396 		}
3397 	}
3398 
3399 	if (from < length()) {
3400 		ret += substr(from, length());
3401 	}
3402 
3403 	return ret;
3404 }
3405 
http_escape() const3406 String String::http_escape() const {
3407 	const CharString temp = utf8();
3408 	String res;
3409 	for (int i = 0; i < temp.length(); ++i) {
3410 		char ord = temp[i];
3411 		if (ord == '.' || ord == '-' || ord == '_' || ord == '~' ||
3412 				(ord >= 'a' && ord <= 'z') ||
3413 				(ord >= 'A' && ord <= 'Z') ||
3414 				(ord >= '0' && ord <= '9')) {
3415 			res += ord;
3416 		} else {
3417 			char h_Val[3];
3418 #if defined(__GNUC__) || defined(_MSC_VER)
3419 			snprintf(h_Val, 3, "%hhX", ord);
3420 #else
3421 			sprintf(h_Val, "%hhX", ord);
3422 #endif
3423 			res += "%";
3424 			res += h_Val;
3425 		}
3426 	}
3427 	return res;
3428 }
3429 
http_unescape() const3430 String String::http_unescape() const {
3431 	String res;
3432 	for (int i = 0; i < length(); ++i) {
3433 		if (ord_at(i) == '%' && i + 2 < length()) {
3434 			CharType ord1 = ord_at(i + 1);
3435 			if ((ord1 >= '0' && ord1 <= '9') || (ord1 >= 'A' && ord1 <= 'Z')) {
3436 				CharType ord2 = ord_at(i + 2);
3437 				if ((ord2 >= '0' && ord2 <= '9') || (ord2 >= 'A' && ord2 <= 'Z')) {
3438 					char bytes[3] = { (char)ord1, (char)ord2, 0 };
3439 					res += (char)strtol(bytes, NULL, 16);
3440 					i += 2;
3441 				}
3442 			} else {
3443 				res += ord_at(i);
3444 			}
3445 		} else {
3446 			res += ord_at(i);
3447 		}
3448 	}
3449 	return String::utf8(res.ascii());
3450 }
3451 
c_unescape() const3452 String String::c_unescape() const {
3453 
3454 	String escaped = *this;
3455 	escaped = escaped.replace("\\a", "\a");
3456 	escaped = escaped.replace("\\b", "\b");
3457 	escaped = escaped.replace("\\f", "\f");
3458 	escaped = escaped.replace("\\n", "\n");
3459 	escaped = escaped.replace("\\r", "\r");
3460 	escaped = escaped.replace("\\t", "\t");
3461 	escaped = escaped.replace("\\v", "\v");
3462 	escaped = escaped.replace("\\'", "\'");
3463 	escaped = escaped.replace("\\\"", "\"");
3464 	escaped = escaped.replace("\\?", "\?");
3465 	escaped = escaped.replace("\\\\", "\\");
3466 
3467 	return escaped;
3468 }
3469 
c_escape() const3470 String String::c_escape() const {
3471 
3472 	String escaped = *this;
3473 	escaped = escaped.replace("\\", "\\\\");
3474 	escaped = escaped.replace("\a", "\\a");
3475 	escaped = escaped.replace("\b", "\\b");
3476 	escaped = escaped.replace("\f", "\\f");
3477 	escaped = escaped.replace("\n", "\\n");
3478 	escaped = escaped.replace("\r", "\\r");
3479 	escaped = escaped.replace("\t", "\\t");
3480 	escaped = escaped.replace("\v", "\\v");
3481 	escaped = escaped.replace("\'", "\\'");
3482 	escaped = escaped.replace("\?", "\\?");
3483 	escaped = escaped.replace("\"", "\\\"");
3484 
3485 	return escaped;
3486 }
3487 
c_escape_multiline() const3488 String String::c_escape_multiline() const {
3489 
3490 	String escaped = *this;
3491 	escaped = escaped.replace("\\", "\\\\");
3492 	escaped = escaped.replace("\"", "\\\"");
3493 
3494 	return escaped;
3495 }
3496 
json_escape() const3497 String String::json_escape() const {
3498 
3499 	String escaped = *this;
3500 	escaped = escaped.replace("\\", "\\\\");
3501 	escaped = escaped.replace("\b", "\\b");
3502 	escaped = escaped.replace("\f", "\\f");
3503 	escaped = escaped.replace("\n", "\\n");
3504 	escaped = escaped.replace("\r", "\\r");
3505 	escaped = escaped.replace("\t", "\\t");
3506 	escaped = escaped.replace("\v", "\\v");
3507 	escaped = escaped.replace("\"", "\\\"");
3508 
3509 	return escaped;
3510 }
3511 
xml_escape(bool p_escape_quotes) const3512 String String::xml_escape(bool p_escape_quotes) const {
3513 
3514 	String str = *this;
3515 	str = str.replace("&", "&amp;");
3516 	str = str.replace("<", "&lt;");
3517 	str = str.replace(">", "&gt;");
3518 	if (p_escape_quotes) {
3519 		str = str.replace("'", "&apos;");
3520 		str = str.replace("\"", "&quot;");
3521 	}
3522 	/*
3523 	for (int i=1;i<32;i++) {
3524 
3525 		char chr[2]={i,0};
3526 		str=str.replace(chr,"&#"+String::num(i)+";");
3527 	}*/
3528 	return str;
3529 }
3530 
_xml_unescape(const CharType * p_src,int p_src_len,CharType * p_dst)3531 static _FORCE_INLINE_ int _xml_unescape(const CharType *p_src, int p_src_len, CharType *p_dst) {
3532 
3533 	int len = 0;
3534 	while (p_src_len) {
3535 
3536 		if (*p_src == '&') {
3537 
3538 			int eat = 0;
3539 
3540 			if (p_src_len >= 4 && p_src[1] == '#') {
3541 
3542 				CharType c = 0;
3543 
3544 				for (int i = 2; i < p_src_len; i++) {
3545 
3546 					eat = i + 1;
3547 					CharType ct = p_src[i];
3548 					if (ct == ';') {
3549 						break;
3550 					} else if (ct >= '0' && ct <= '9') {
3551 						ct = ct - '0';
3552 					} else if (ct >= 'a' && ct <= 'f') {
3553 						ct = (ct - 'a') + 10;
3554 					} else if (ct >= 'A' && ct <= 'F') {
3555 						ct = (ct - 'A') + 10;
3556 					} else {
3557 						continue;
3558 					}
3559 					c <<= 4;
3560 					c |= ct;
3561 				}
3562 
3563 				if (p_dst)
3564 					*p_dst = c;
3565 
3566 			} else if (p_src_len >= 4 && p_src[1] == 'g' && p_src[2] == 't' && p_src[3] == ';') {
3567 
3568 				if (p_dst)
3569 					*p_dst = '>';
3570 				eat = 4;
3571 			} else if (p_src_len >= 4 && p_src[1] == 'l' && p_src[2] == 't' && p_src[3] == ';') {
3572 
3573 				if (p_dst)
3574 					*p_dst = '<';
3575 				eat = 4;
3576 			} else if (p_src_len >= 5 && p_src[1] == 'a' && p_src[2] == 'm' && p_src[3] == 'p' && p_src[4] == ';') {
3577 
3578 				if (p_dst)
3579 					*p_dst = '&';
3580 				eat = 5;
3581 			} else if (p_src_len >= 6 && p_src[1] == 'q' && p_src[2] == 'u' && p_src[3] == 'o' && p_src[4] == 't' && p_src[5] == ';') {
3582 
3583 				if (p_dst)
3584 					*p_dst = '"';
3585 				eat = 6;
3586 			} else if (p_src_len >= 6 && p_src[1] == 'a' && p_src[2] == 'p' && p_src[3] == 'o' && p_src[4] == 's' && p_src[5] == ';') {
3587 
3588 				if (p_dst)
3589 					*p_dst = '\'';
3590 				eat = 6;
3591 			} else {
3592 
3593 				if (p_dst)
3594 					*p_dst = *p_src;
3595 				eat = 1;
3596 			}
3597 
3598 			if (p_dst)
3599 				p_dst++;
3600 
3601 			len++;
3602 			p_src += eat;
3603 			p_src_len -= eat;
3604 		} else {
3605 
3606 			if (p_dst) {
3607 				*p_dst = *p_src;
3608 				p_dst++;
3609 			}
3610 			len++;
3611 			p_src++;
3612 			p_src_len--;
3613 		}
3614 	}
3615 
3616 	return len;
3617 }
3618 
xml_unescape() const3619 String String::xml_unescape() const {
3620 
3621 	String str;
3622 	int l = length();
3623 	int len = _xml_unescape(c_str(), l, NULL);
3624 	if (len == 0)
3625 		return String();
3626 	str.resize(len + 1);
3627 	_xml_unescape(c_str(), l, str.ptrw());
3628 	str[len] = 0;
3629 	return str;
3630 }
3631 
pad_decimals(int p_digits) const3632 String String::pad_decimals(int p_digits) const {
3633 
3634 	String s = *this;
3635 	int c = s.find(".");
3636 
3637 	if (c == -1) {
3638 		if (p_digits <= 0) {
3639 			return s;
3640 		}
3641 		s += ".";
3642 		c = s.length() - 1;
3643 	} else {
3644 		if (p_digits <= 0) {
3645 			return s.substr(0, c);
3646 		}
3647 	}
3648 
3649 	if (s.length() - (c + 1) > p_digits) {
3650 		s = s.substr(0, c + p_digits + 1);
3651 	} else {
3652 		while (s.length() - (c + 1) < p_digits) {
3653 			s += "0";
3654 		}
3655 	}
3656 	return s;
3657 }
3658 
pad_zeros(int p_digits) const3659 String String::pad_zeros(int p_digits) const {
3660 
3661 	String s = *this;
3662 	int end = s.find(".");
3663 
3664 	if (end == -1) {
3665 		end = s.length();
3666 	}
3667 
3668 	if (end == 0)
3669 		return s;
3670 
3671 	int begin = 0;
3672 
3673 	while (begin < end && (s[begin] < '0' || s[begin] > '9')) {
3674 		begin++;
3675 	}
3676 
3677 	if (begin >= end)
3678 		return s;
3679 
3680 	while (end - begin < p_digits) {
3681 
3682 		s = s.insert(begin, "0");
3683 		end++;
3684 	}
3685 
3686 	return s;
3687 }
3688 
trim_prefix(const String & p_prefix) const3689 String String::trim_prefix(const String &p_prefix) const {
3690 
3691 	String s = *this;
3692 	if (s.begins_with(p_prefix)) {
3693 		return s.substr(p_prefix.length(), s.length() - p_prefix.length());
3694 	}
3695 	return s;
3696 }
3697 
trim_suffix(const String & p_suffix) const3698 String String::trim_suffix(const String &p_suffix) const {
3699 
3700 	String s = *this;
3701 	if (s.ends_with(p_suffix)) {
3702 		return s.substr(0, s.length() - p_suffix.length());
3703 	}
3704 	return s;
3705 }
3706 
is_valid_integer() const3707 bool String::is_valid_integer() const {
3708 
3709 	int len = length();
3710 
3711 	if (len == 0)
3712 		return false;
3713 
3714 	int from = 0;
3715 	if (len != 1 && (operator[](0) == '+' || operator[](0) == '-'))
3716 		from++;
3717 
3718 	for (int i = from; i < len; i++) {
3719 
3720 		if (operator[](i) < '0' || operator[](i) > '9')
3721 			return false; // no start with number plz
3722 	}
3723 
3724 	return true;
3725 }
3726 
is_valid_hex_number(bool p_with_prefix) const3727 bool String::is_valid_hex_number(bool p_with_prefix) const {
3728 
3729 	int len = length();
3730 
3731 	if (len == 0)
3732 		return false;
3733 
3734 	int from = 0;
3735 	if (len != 1 && (operator[](0) == '+' || operator[](0) == '-'))
3736 		from++;
3737 
3738 	if (p_with_prefix) {
3739 
3740 		if (len < 3)
3741 			return false;
3742 		if (operator[](from) != '0' || operator[](from + 1) != 'x') {
3743 			return false;
3744 		}
3745 		from += 2;
3746 	}
3747 
3748 	for (int i = from; i < len; i++) {
3749 
3750 		CharType c = operator[](i);
3751 		if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
3752 			continue;
3753 		return false;
3754 	}
3755 
3756 	return true;
3757 };
3758 
is_valid_float() const3759 bool String::is_valid_float() const {
3760 
3761 	int len = length();
3762 
3763 	if (len == 0)
3764 		return false;
3765 
3766 	int from = 0;
3767 	if (operator[](0) == '+' || operator[](0) == '-') {
3768 		from++;
3769 	}
3770 
3771 	bool exponent_found = false;
3772 	bool period_found = false;
3773 	bool sign_found = false;
3774 	bool exponent_values_found = false;
3775 	bool numbers_found = false;
3776 
3777 	for (int i = from; i < len; i++) {
3778 
3779 		if (operator[](i) >= '0' && operator[](i) <= '9') {
3780 
3781 			if (exponent_found)
3782 				exponent_values_found = true;
3783 			else
3784 				numbers_found = true;
3785 		} else if (numbers_found && !exponent_found && operator[](i) == 'e') {
3786 			exponent_found = true;
3787 		} else if (!period_found && !exponent_found && operator[](i) == '.') {
3788 			period_found = true;
3789 		} else if ((operator[](i) == '-' || operator[](i) == '+') && exponent_found && !exponent_values_found && !sign_found) {
3790 			sign_found = true;
3791 		} else
3792 			return false; // no start with number plz
3793 	}
3794 
3795 	return numbers_found;
3796 }
3797 
path_to_file(const String & p_path) const3798 String String::path_to_file(const String &p_path) const {
3799 
3800 	// Don't get base dir for src, this is expected to be a dir already.
3801 	String src = this->replace("\\", "/");
3802 	String dst = p_path.replace("\\", "/").get_base_dir();
3803 	String rel = src.path_to(dst);
3804 	if (rel == dst) // failed
3805 		return p_path;
3806 	else
3807 		return rel + p_path.get_file();
3808 }
3809 
path_to(const String & p_path) const3810 String String::path_to(const String &p_path) const {
3811 
3812 	String src = this->replace("\\", "/");
3813 	String dst = p_path.replace("\\", "/");
3814 	if (!src.ends_with("/"))
3815 		src += "/";
3816 	if (!dst.ends_with("/"))
3817 		dst += "/";
3818 
3819 	String base;
3820 
3821 	if (src.begins_with("res://") && dst.begins_with("res://")) {
3822 
3823 		base = "res:/";
3824 		src = src.replace("res://", "/");
3825 		dst = dst.replace("res://", "/");
3826 
3827 	} else if (src.begins_with("user://") && dst.begins_with("user://")) {
3828 
3829 		base = "user:/";
3830 		src = src.replace("user://", "/");
3831 		dst = dst.replace("user://", "/");
3832 
3833 	} else if (src.begins_with("/") && dst.begins_with("/")) {
3834 
3835 		//nothing
3836 	} else {
3837 		//dos style
3838 		String src_begin = src.get_slicec('/', 0);
3839 		String dst_begin = dst.get_slicec('/', 0);
3840 
3841 		if (src_begin != dst_begin)
3842 			return p_path; //impossible to do this
3843 
3844 		base = src_begin;
3845 		src = src.substr(src_begin.length(), src.length());
3846 		dst = dst.substr(dst_begin.length(), dst.length());
3847 	}
3848 
3849 	//remove leading and trailing slash and split
3850 	Vector<String> src_dirs = src.substr(1, src.length() - 2).split("/");
3851 	Vector<String> dst_dirs = dst.substr(1, dst.length() - 2).split("/");
3852 
3853 	//find common parent
3854 	int common_parent = 0;
3855 
3856 	while (true) {
3857 		if (src_dirs.size() == common_parent)
3858 			break;
3859 		if (dst_dirs.size() == common_parent)
3860 			break;
3861 		if (src_dirs[common_parent] != dst_dirs[common_parent])
3862 			break;
3863 		common_parent++;
3864 	}
3865 
3866 	common_parent--;
3867 
3868 	String dir;
3869 
3870 	for (int i = src_dirs.size() - 1; i > common_parent; i--) {
3871 
3872 		dir += "../";
3873 	}
3874 
3875 	for (int i = common_parent + 1; i < dst_dirs.size(); i++) {
3876 
3877 		dir += dst_dirs[i] + "/";
3878 	}
3879 
3880 	if (dir.length() == 0)
3881 		dir = "./";
3882 	return dir;
3883 }
3884 
is_valid_html_color() const3885 bool String::is_valid_html_color() const {
3886 
3887 	return Color::html_is_valid(*this);
3888 }
3889 
is_valid_filename() const3890 bool String::is_valid_filename() const {
3891 
3892 	String stripped = strip_edges();
3893 	if (*this != stripped) {
3894 		return false;
3895 	}
3896 
3897 	if (stripped == String()) {
3898 		return false;
3899 	}
3900 
3901 	return !(find(":") != -1 || find("/") != -1 || find("\\") != -1 || find("?") != -1 || find("*") != -1 || find("\"") != -1 || find("|") != -1 || find("%") != -1 || find("<") != -1 || find(">") != -1);
3902 }
3903 
is_valid_ip_address() const3904 bool String::is_valid_ip_address() const {
3905 
3906 	if (find(":") >= 0) {
3907 
3908 		Vector<String> ip = split(":");
3909 		for (int i = 0; i < ip.size(); i++) {
3910 
3911 			String n = ip[i];
3912 			if (n.empty())
3913 				continue;
3914 			if (n.is_valid_hex_number(false)) {
3915 				int nint = n.hex_to_int(false);
3916 				if (nint < 0 || nint > 0xffff)
3917 					return false;
3918 				continue;
3919 			};
3920 			if (!n.is_valid_ip_address())
3921 				return false;
3922 		};
3923 
3924 	} else {
3925 		Vector<String> ip = split(".");
3926 		if (ip.size() != 4)
3927 			return false;
3928 		for (int i = 0; i < ip.size(); i++) {
3929 
3930 			String n = ip[i];
3931 			if (!n.is_valid_integer())
3932 				return false;
3933 			int val = n.to_int();
3934 			if (val < 0 || val > 255)
3935 				return false;
3936 		}
3937 	};
3938 
3939 	return true;
3940 }
3941 
is_resource_file() const3942 bool String::is_resource_file() const {
3943 
3944 	return begins_with("res://") && find("::") == -1;
3945 }
3946 
is_rel_path() const3947 bool String::is_rel_path() const {
3948 
3949 	return !is_abs_path();
3950 }
3951 
get_base_dir() const3952 String String::get_base_dir() const {
3953 
3954 	int basepos = find("://");
3955 	String rs;
3956 	String base;
3957 	if (basepos != -1) {
3958 		int end = basepos + 3;
3959 		rs = substr(end, length());
3960 		base = substr(0, end);
3961 	} else {
3962 		if (begins_with("/")) {
3963 			rs = substr(1, length());
3964 			base = "/";
3965 		} else {
3966 
3967 			rs = *this;
3968 		}
3969 	}
3970 
3971 	int sep = MAX(rs.find_last("/"), rs.find_last("\\"));
3972 	if (sep == -1)
3973 		return base;
3974 
3975 	return base + rs.substr(0, sep);
3976 }
3977 
get_file() const3978 String String::get_file() const {
3979 
3980 	int sep = MAX(find_last("/"), find_last("\\"));
3981 	if (sep == -1)
3982 		return *this;
3983 
3984 	return substr(sep + 1, length());
3985 }
3986 
get_extension() const3987 String String::get_extension() const {
3988 
3989 	int pos = find_last(".");
3990 	if (pos < 0 || pos < MAX(find_last("/"), find_last("\\")))
3991 		return "";
3992 
3993 	return substr(pos + 1, length());
3994 }
3995 
plus_file(const String & p_file) const3996 String String::plus_file(const String &p_file) const {
3997 	if (empty())
3998 		return p_file;
3999 	if (operator[](length() - 1) == '/' || (p_file.size() > 0 && p_file.operator[](0) == '/'))
4000 		return *this + p_file;
4001 	return *this + "/" + p_file;
4002 }
4003 
percent_encode() const4004 String String::percent_encode() const {
4005 
4006 	CharString cs = utf8();
4007 	String encoded;
4008 	for (int i = 0; i < cs.length(); i++) {
4009 		uint8_t c = cs[i];
4010 		if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-' || c == '_' || c == '~' || c == '.') {
4011 
4012 			char p[2] = { (char)c, 0 };
4013 			encoded += p;
4014 		} else {
4015 			char p[4] = { '%', 0, 0, 0 };
4016 			static const char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
4017 
4018 			p[1] = hex[c >> 4];
4019 			p[2] = hex[c & 0xF];
4020 			encoded += p;
4021 		}
4022 	}
4023 
4024 	return encoded;
4025 }
percent_decode() const4026 String String::percent_decode() const {
4027 
4028 	CharString pe;
4029 
4030 	CharString cs = utf8();
4031 	for (int i = 0; i < cs.length(); i++) {
4032 
4033 		uint8_t c = cs[i];
4034 		if (c == '%' && i < length() - 2) {
4035 
4036 			uint8_t a = LOWERCASE(cs[i + 1]);
4037 			uint8_t b = LOWERCASE(cs[i + 2]);
4038 
4039 			if (a >= '0' && a <= '9')
4040 				c = (a - '0') << 4;
4041 			else if (a >= 'a' && a <= 'f')
4042 				c = (a - 'a' + 10) << 4;
4043 			else
4044 				continue;
4045 
4046 			uint8_t d = 0;
4047 
4048 			if (b >= '0' && b <= '9')
4049 				d = (b - '0');
4050 			else if (b >= 'a' && b <= 'f')
4051 				d = (b - 'a' + 10);
4052 			else
4053 				continue;
4054 			c += d;
4055 			i += 2;
4056 		}
4057 		pe += c;
4058 	}
4059 
4060 	return String::utf8(pe.ptr());
4061 }
4062 
property_name_encode() const4063 String String::property_name_encode() const {
4064 	// Escape and quote strings with extended ASCII or further Unicode characters
4065 	// as well as '"', '=' or ' ' (32)
4066 	const CharType *cstr = c_str();
4067 	for (int i = 0; cstr[i]; i++) {
4068 		if (cstr[i] == '=' || cstr[i] == '"' || cstr[i] < 33 || cstr[i] > 126) {
4069 			return "\"" + c_escape_multiline() + "\"";
4070 		}
4071 	}
4072 	// Keep as is
4073 	return *this;
4074 }
4075 
get_basename() const4076 String String::get_basename() const {
4077 
4078 	int pos = find_last(".");
4079 	if (pos < 0 || pos < MAX(find_last("/"), find_last("\\")))
4080 		return *this;
4081 
4082 	return substr(0, pos);
4083 }
4084 
itos(int64_t p_val)4085 String itos(int64_t p_val) {
4086 
4087 	return String::num_int64(p_val);
4088 }
4089 
uitos(uint64_t p_val)4090 String uitos(uint64_t p_val) {
4091 
4092 	return String::num_uint64(p_val);
4093 }
4094 
rtos(double p_val)4095 String rtos(double p_val) {
4096 
4097 	return String::num(p_val);
4098 }
4099 
rtoss(double p_val)4100 String rtoss(double p_val) {
4101 
4102 	return String::num_scientific(p_val);
4103 }
4104 
4105 // Right-pad with a character.
rpad(int min_length,const String & character) const4106 String String::rpad(int min_length, const String &character) const {
4107 	String s = *this;
4108 	int padding = min_length - s.length();
4109 	if (padding > 0) {
4110 		for (int i = 0; i < padding; i++)
4111 			s = s + character;
4112 	}
4113 
4114 	return s;
4115 }
4116 // Left-pad with a character.
lpad(int min_length,const String & character) const4117 String String::lpad(int min_length, const String &character) const {
4118 	String s = *this;
4119 	int padding = min_length - s.length();
4120 	if (padding > 0) {
4121 		for (int i = 0; i < padding; i++)
4122 			s = character + s;
4123 	}
4124 
4125 	return s;
4126 }
4127 
4128 // sprintf is implemented in GDScript via:
4129 //   "fish %s pie" % "frog"
4130 //   "fish %s %d pie" % ["frog", 12]
4131 // In case of an error, the string returned is the error description and "error" is true.
sprintf(const Array & values,bool * error) const4132 String String::sprintf(const Array &values, bool *error) const {
4133 	String formatted;
4134 	CharType *self = (CharType *)c_str();
4135 	bool in_format = false;
4136 	int value_index = 0;
4137 	int min_chars = 0;
4138 	int min_decimals = 0;
4139 	bool in_decimals = false;
4140 	bool pad_with_zeroes = false;
4141 	bool left_justified = false;
4142 	bool show_sign = false;
4143 
4144 	*error = true;
4145 
4146 	for (; *self; self++) {
4147 		const CharType c = *self;
4148 
4149 		if (in_format) { // We have % - lets see what else we get.
4150 			switch (c) {
4151 				case '%': { // Replace %% with %
4152 					formatted += chr(c);
4153 					in_format = false;
4154 					break;
4155 				}
4156 				case 'd': // Integer (signed)
4157 				case 'o': // Octal
4158 				case 'x': // Hexadecimal (lowercase)
4159 				case 'X': { // Hexadecimal (uppercase)
4160 					if (value_index >= values.size()) {
4161 						return "not enough arguments for format string";
4162 					}
4163 
4164 					if (!values[value_index].is_num()) {
4165 						return "a number is required";
4166 					}
4167 
4168 					int64_t value = values[value_index];
4169 					int base = 16;
4170 					bool capitalize = false;
4171 					switch (c) {
4172 						case 'd': base = 10; break;
4173 						case 'o': base = 8; break;
4174 						case 'x': break;
4175 						case 'X':
4176 							base = 16;
4177 							capitalize = true;
4178 							break;
4179 					}
4180 					// Get basic number.
4181 					String str = String::num_int64(ABS(value), base, capitalize);
4182 					int number_len = str.length();
4183 
4184 					// Padding.
4185 					String pad_char = pad_with_zeroes ? String("0") : String(" ");
4186 					if (left_justified) {
4187 						str = str.rpad(min_chars, pad_char);
4188 					} else {
4189 						str = str.lpad(min_chars, pad_char);
4190 					}
4191 
4192 					// Sign.
4193 					if (show_sign && value >= 0) {
4194 						str = str.insert(pad_with_zeroes ? 0 : str.length() - number_len, "+");
4195 					} else if (value < 0) {
4196 						str = str.insert(pad_with_zeroes ? 0 : str.length() - number_len, "-");
4197 					}
4198 
4199 					formatted += str;
4200 					++value_index;
4201 					in_format = false;
4202 
4203 					break;
4204 				}
4205 				case 'f': { // Float
4206 					if (value_index >= values.size()) {
4207 						return "not enough arguments for format string";
4208 					}
4209 
4210 					if (!values[value_index].is_num()) {
4211 						return "a number is required";
4212 					}
4213 
4214 					double value = values[value_index];
4215 					bool is_negative = (value < 0);
4216 					String str = String::num(ABS(value), min_decimals);
4217 
4218 					// Pad decimals out.
4219 					str = str.pad_decimals(min_decimals);
4220 
4221 					int initial_len = str.length();
4222 
4223 					// Padding. Leave room for sign later if required.
4224 					int pad_chars_count = (is_negative || show_sign) ? min_chars - 1 : min_chars;
4225 					String pad_char = pad_with_zeroes ? String("0") : String(" ");
4226 					if (left_justified) {
4227 						if (pad_with_zeroes) {
4228 							return "left justification cannot be used with zeros as the padding";
4229 						} else {
4230 							str = str.rpad(pad_chars_count, pad_char);
4231 						}
4232 					} else {
4233 						str = str.lpad(pad_chars_count, pad_char);
4234 					}
4235 
4236 					// Add sign if needed.
4237 					if (show_sign || is_negative) {
4238 						String sign_char = is_negative ? "-" : "+";
4239 						if (left_justified) {
4240 							str = str.insert(0, sign_char);
4241 						} else {
4242 							str = str.insert(pad_with_zeroes ? 0 : str.length() - initial_len, sign_char);
4243 						}
4244 					}
4245 
4246 					formatted += str;
4247 					++value_index;
4248 					in_format = false;
4249 					break;
4250 				}
4251 				case 's': { // String
4252 					if (value_index >= values.size()) {
4253 						return "not enough arguments for format string";
4254 					}
4255 
4256 					String str = values[value_index];
4257 					// Padding.
4258 					if (left_justified) {
4259 						str = str.rpad(min_chars);
4260 					} else {
4261 						str = str.lpad(min_chars);
4262 					}
4263 
4264 					formatted += str;
4265 					++value_index;
4266 					in_format = false;
4267 					break;
4268 				}
4269 				case 'c': {
4270 					if (value_index >= values.size()) {
4271 						return "not enough arguments for format string";
4272 					}
4273 
4274 					// Convert to character.
4275 					String str;
4276 					if (values[value_index].is_num()) {
4277 						int value = values[value_index];
4278 						if (value < 0) {
4279 							return "unsigned byte integer is lower than maximum";
4280 						} else if (value > 255) {
4281 							return "unsigned byte integer is greater than maximum";
4282 						}
4283 						str = chr(values[value_index]);
4284 					} else if (values[value_index].get_type() == Variant::STRING) {
4285 						str = values[value_index];
4286 						if (str.length() != 1) {
4287 							return "%c requires number or single-character string";
4288 						}
4289 					} else {
4290 						return "%c requires number or single-character string";
4291 					}
4292 
4293 					// Padding.
4294 					if (left_justified) {
4295 						str = str.rpad(min_chars);
4296 					} else {
4297 						str = str.lpad(min_chars);
4298 					}
4299 
4300 					formatted += str;
4301 					++value_index;
4302 					in_format = false;
4303 					break;
4304 				}
4305 				case '-': { // Left justify
4306 					left_justified = true;
4307 					break;
4308 				}
4309 				case '+': { // Show + if positive.
4310 					show_sign = true;
4311 					break;
4312 				}
4313 				case '0':
4314 				case '1':
4315 				case '2':
4316 				case '3':
4317 				case '4':
4318 				case '5':
4319 				case '6':
4320 				case '7':
4321 				case '8':
4322 				case '9': {
4323 					int n = c - '0';
4324 					if (in_decimals) {
4325 						min_decimals *= 10;
4326 						min_decimals += n;
4327 					} else {
4328 						if (c == '0' && min_chars == 0) {
4329 							pad_with_zeroes = true;
4330 						} else {
4331 							min_chars *= 10;
4332 							min_chars += n;
4333 						}
4334 					}
4335 					break;
4336 				}
4337 				case '.': { // Float separator.
4338 					if (in_decimals) {
4339 						return "too many decimal points in format";
4340 					}
4341 					in_decimals = true;
4342 					min_decimals = 0; // We want to add the value manually.
4343 					break;
4344 				}
4345 
4346 				case '*': { // Dynamic width, based on value.
4347 					if (value_index >= values.size()) {
4348 						return "not enough arguments for format string";
4349 					}
4350 
4351 					if (!values[value_index].is_num()) {
4352 						return "* wants number";
4353 					}
4354 
4355 					int size = values[value_index];
4356 
4357 					if (in_decimals) {
4358 						min_decimals = size;
4359 					} else {
4360 						min_chars = size;
4361 					}
4362 
4363 					++value_index;
4364 					break;
4365 				}
4366 
4367 				default: {
4368 					return "unsupported format character";
4369 				}
4370 			}
4371 		} else { // Not in format string.
4372 			switch (c) {
4373 				case '%':
4374 					in_format = true;
4375 					// Back to defaults:
4376 					min_chars = 0;
4377 					min_decimals = 6;
4378 					pad_with_zeroes = false;
4379 					left_justified = false;
4380 					show_sign = false;
4381 					in_decimals = false;
4382 					break;
4383 				default:
4384 					formatted += chr(c);
4385 			}
4386 		}
4387 	}
4388 
4389 	if (in_format) {
4390 		return "incomplete format";
4391 	}
4392 
4393 	if (value_index != values.size()) {
4394 		return "not all arguments converted during string formatting";
4395 	}
4396 
4397 	*error = false;
4398 	return formatted;
4399 }
4400 
quote(String quotechar) const4401 String String::quote(String quotechar) const {
4402 	return quotechar + *this + quotechar;
4403 }
4404 
unquote() const4405 String String::unquote() const {
4406 	if (!is_quoted()) {
4407 		return *this;
4408 	}
4409 
4410 	return substr(1, length() - 2);
4411 }
4412 
4413 #ifdef TOOLS_ENABLED
TTR(const String & p_text)4414 String TTR(const String &p_text) {
4415 
4416 	if (TranslationServer::get_singleton()) {
4417 		return TranslationServer::get_singleton()->tool_translate(p_text);
4418 	}
4419 
4420 	return p_text;
4421 }
4422 
4423 #endif
4424 
RTR(const String & p_text)4425 String RTR(const String &p_text) {
4426 
4427 	if (TranslationServer::get_singleton()) {
4428 		String rtr = TranslationServer::get_singleton()->tool_translate(p_text);
4429 		if (rtr == String() || rtr == p_text) {
4430 			return TranslationServer::get_singleton()->translate(p_text);
4431 		} else {
4432 			return rtr;
4433 		}
4434 	}
4435 
4436 	return p_text;
4437 }
4438