summaryrefslogtreecommitdiff
path: root/core/ustring.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/ustring.cpp')
-rw-r--r--core/ustring.cpp116
1 files changed, 65 insertions, 51 deletions
diff --git a/core/ustring.cpp b/core/ustring.cpp
index 51f05468e2..96e3a3d784 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -102,6 +102,15 @@ bool CharString::operator<(const CharString &p_right) const {
return is_str_less(get_data(), p_right.get_data());
}
+CharString &CharString::operator+=(char p_char) {
+
+ resize(size() ? size() + 1 : 2);
+ set(length(), 0);
+ set(length() - 1, p_char);
+
+ return *this;
+}
+
const char *CharString::get_data() const {
if (size())
@@ -139,7 +148,7 @@ void String::copy_from(const char *p_cstr) {
}
}
-void String::copy_from(const CharType *p_cstr, int p_clip_to) {
+void String::copy_from(const CharType *p_cstr, const int p_clip_to) {
if (!p_cstr) {
@@ -149,26 +158,30 @@ void String::copy_from(const CharType *p_cstr, int p_clip_to) {
int len = 0;
const CharType *ptr = p_cstr;
- while (*(ptr++) != 0)
+ while ((p_clip_to < 0 || len < p_clip_to) && *(ptr++) != 0)
len++;
- if (p_clip_to >= 0 && len > p_clip_to)
- len = p_clip_to;
-
if (len == 0) {
resize(0);
return;
}
- resize(len + 1);
- set(len, 0);
+ copy_from_unchecked(p_cstr, len);
+}
- CharType *dst = &operator[](0);
+// assumes the following have already been validated:
+// p_char != NULL
+// p_length > 0
+// p_length <= p_char strlen
+void String::copy_from_unchecked(const CharType *p_char, const int p_length) {
+ resize(p_length + 1);
+ set(p_length, 0);
- for (int i = 0; i < len; i++) {
+ CharType *dst = &operator[](0);
- dst[i] = p_cstr[i];
+ for (int i = 0; i < p_length; i++) {
+ dst[i] = p_char[i];
}
}
@@ -757,36 +770,32 @@ Vector<String> String::rsplit(const String &p_splitter, bool p_allow_empty, int
Vector<String> ret;
const int len = length();
- int from = len;
+ int remaining_len = len;
while (true) {
- int end = rfind(p_splitter, from);
- if (end < 0)
- end = 0;
-
- if (p_allow_empty || (end < from)) {
- const String str = substr(end > 0 ? end + p_splitter.length() : end, end > 0 ? from - end : from + 2);
-
- if (p_maxsplit <= 0) {
- ret.push_back(str);
- } else if (p_maxsplit > 0) {
-
- // Put rest of the string and leave cycle.
- if (p_maxsplit == ret.size()) {
- ret.push_back(substr(0, from + 2));
- break;
- }
-
- // Otherwise, push items until positive limit is reached.
- ret.push_back(str);
+ if (remaining_len < p_splitter.length() || (p_maxsplit > 0 && p_maxsplit == ret.size())) {
+ // no room for another splitter or hit max splits, push what's left and we're done
+ if (p_allow_empty || remaining_len > 0) {
+ ret.push_back(substr(0, remaining_len));
}
+ break;
}
- if (end == 0)
+ int left_edge = rfind(p_splitter, remaining_len - p_splitter.length());
+
+ if (left_edge < 0) {
+ // no more splitters, we're done
+ ret.push_back(substr(0, remaining_len));
break;
+ }
+
+ int substr_start = left_edge + p_splitter.length();
+ if (p_allow_empty || substr_start < remaining_len) {
+ ret.push_back(substr(substr_start, remaining_len - substr_start));
+ }
- from = end - p_splitter.length();
+ remaining_len = left_edge;
}
ret.invert();
@@ -925,8 +934,8 @@ String String::to_upper() const {
for (int i = 0; i < upper.size(); i++) {
- const char s = upper[i];
- const char t = _find_upper(s);
+ const CharType s = upper[i];
+ const CharType t = _find_upper(s);
if (s != t) // avoid copy on write
upper[i] = t;
}
@@ -940,8 +949,8 @@ String String::to_lower() const {
for (int i = 0; i < lower.size(); i++) {
- const char s = lower[i];
- const char t = _find_lower(s);
+ const CharType s = lower[i];
+ const CharType t = _find_lower(s);
if (s != t) // avoid copy on write
lower[i] = t;
}
@@ -1331,7 +1340,7 @@ String String::utf8(const char *p_utf8, int p_len) {
bool String::parse_utf8(const char *p_utf8, int p_len) {
-#define _UNICERROR(m_err) print_line("unicode error: " + String(m_err));
+#define _UNICERROR(m_err) print_line("Unicode error: " + String(m_err));
String aux;
@@ -1575,6 +1584,7 @@ String::String(const char *p_str) {
copy_from(p_str);
}
+
String::String(const CharType *p_str, int p_clip_to_len) {
copy_from(p_str, p_clip_to_len);
@@ -2194,7 +2204,7 @@ Vector<uint8_t> String::md5_buffer() const {
Vector<uint8_t> ret;
ret.resize(16);
for (int i = 0; i < 16; i++) {
- ret[i] = ctx.digest[i];
+ ret.write[i] = ctx.digest[i];
};
return ret;
@@ -2211,7 +2221,7 @@ Vector<uint8_t> String::sha256_buffer() const {
Vector<uint8_t> ret;
ret.resize(32);
for (int i = 0; i < 32; i++) {
- ret[i] = hash[i];
+ ret.write[i] = hash[i];
}
return ret;
@@ -2250,7 +2260,9 @@ String String::substr(int p_from, int p_chars) const {
return String(*this);
}
- return String(&c_str()[p_from], p_chars);
+ String s = String();
+ s.copy_from_unchecked(&c_str()[p_from], p_chars);
+ return s;
}
int String::find_last(const String &p_str) const {
@@ -2668,7 +2680,7 @@ Vector<String> String::bigrams() const {
}
b.resize(n_pairs);
for (int i = 0; i < n_pairs; i++) {
- b[i] = substr(i, 2);
+ b.write[i] = substr(i, 2);
}
return b;
}
@@ -2763,7 +2775,7 @@ String String::format(const Variant &values, String placeholder) const {
val = val.substr(1, val.length() - 2);
}
- new_string = new_string.replacen(placeholder.replace("_", key), val);
+ new_string = new_string.replace(placeholder.replace("_", key), val);
} else {
ERR_PRINT(String("STRING.format Inner Array size != 2 ").ascii().get_data());
}
@@ -2776,7 +2788,11 @@ String String::format(const Variant &values, String placeholder) const {
val = val.substr(1, val.length() - 2);
}
- new_string = new_string.replacen(placeholder.replace("_", i_as_str), val);
+ if (placeholder.find("_") > -1) {
+ new_string = new_string.replace(placeholder.replace("_", i_as_str), val);
+ } else {
+ new_string = new_string.replace_first(placeholder, val);
+ }
}
}
} else if (values.get_type() == Variant::DICTIONARY) {
@@ -2796,7 +2812,7 @@ String String::format(const Variant &values, String placeholder) const {
val = val.substr(1, val.length() - 2);
}
- new_string = new_string.replacen(placeholder.replace("_", key), val);
+ new_string = new_string.replace(placeholder.replace("_", key), val);
}
} else {
ERR_PRINT(String("Invalid type: use Array or Dictionary.").ascii().get_data());
@@ -3027,14 +3043,14 @@ String String::strip_escapes() const {
return substr(beg, end - beg);
}
-String String::lstrip(const Vector<CharType> &p_chars) const {
+String String::lstrip(const String &p_chars) const {
int len = length();
int beg;
for (beg = 0; beg < len; beg++) {
- if (p_chars.find(operator[](beg)) == -1)
+ if (p_chars.find(&ptr()[beg]) == -1)
break;
}
@@ -3044,14 +3060,14 @@ String String::lstrip(const Vector<CharType> &p_chars) const {
return substr(beg, len - beg);
}
-String String::rstrip(const Vector<CharType> &p_chars) const {
+String String::rstrip(const String &p_chars) const {
int len = length();
int end;
for (end = len - 1; end >= 0; end--) {
- if (p_chars.find(operator[](end)) == -1)
+ if (p_chars.find(&ptr()[end]) == -1)
break;
}
@@ -3863,11 +3879,9 @@ String String::percent_decode() const {
c += d;
i += 2;
}
- pe.push_back(c);
+ pe += c;
}
- pe.push_back(0);
-
return String::utf8(pe.ptr());
}