summaryrefslogtreecommitdiff
path: root/core/string/ustring.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/string/ustring.cpp')
-rw-r--r--core/string/ustring.cpp118
1 files changed, 96 insertions, 22 deletions
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index cf0040353d..49cf171f2b 100644
--- a/core/string/ustring.cpp
+++ b/core/string/ustring.cpp
@@ -240,6 +240,71 @@ String String::word_wrap(int p_chars_per_line) const {
return ret;
}
+Error String::parse_url(String &r_scheme, String &r_host, int &r_port, String &r_path) const {
+ // Splits the URL into scheme, host, port, path. Strip credentials when present.
+ String base = *this;
+ r_scheme = "";
+ r_host = "";
+ r_port = 0;
+ r_path = "";
+ int pos = base.find("://");
+ // Scheme
+ if (pos != -1) {
+ r_scheme = base.substr(0, pos + 3).to_lower();
+ base = base.substr(pos + 3, base.length() - pos - 3);
+ }
+ pos = base.find("/");
+ // Path
+ if (pos != -1) {
+ r_path = base.substr(pos, base.length() - pos);
+ base = base.substr(0, pos);
+ }
+ // Host
+ pos = base.find("@");
+ if (pos != -1) {
+ // Strip credentials
+ base = base.substr(pos + 1, base.length() - pos - 1);
+ }
+ if (base.begins_with("[")) {
+ // Literal IPv6
+ pos = base.rfind("]");
+ if (pos == -1) {
+ return ERR_INVALID_PARAMETER;
+ }
+ r_host = base.substr(1, pos - 1);
+ base = base.substr(pos + 1, base.length() - pos - 1);
+ } else {
+ // Anything else
+ if (base.get_slice_count(":") > 1) {
+ return ERR_INVALID_PARAMETER;
+ }
+ pos = base.rfind(":");
+ if (pos == -1) {
+ r_host = base;
+ base = "";
+ } else {
+ r_host = base.substr(0, pos);
+ base = base.substr(pos, base.length() - pos);
+ }
+ }
+ if (r_host.is_empty()) {
+ return ERR_INVALID_PARAMETER;
+ }
+ r_host = r_host.to_lower();
+ // Port
+ if (base.begins_with(":")) {
+ base = base.substr(1, base.length() - 1);
+ if (!base.is_valid_integer()) {
+ return ERR_INVALID_PARAMETER;
+ }
+ r_port = base.to_int();
+ if (r_port < 1 || r_port > 65535) {
+ return ERR_INVALID_PARAMETER;
+ }
+ }
+ return OK;
+}
+
void String::copy_from(const char *p_cstr) {
// copy Latin-1 encoded c-string directly
if (!p_cstr) {
@@ -874,7 +939,7 @@ const char32_t *String::get_data() const {
}
void String::erase(int p_pos, int p_chars) {
- *this = left(p_pos) + substr(p_pos + p_chars, length() - ((p_pos + p_chars)));
+ *this = left(MAX(p_pos, 0)) + substr(p_pos + p_chars, length() - ((p_pos + p_chars)));
}
String String::capitalize() const {
@@ -3317,14 +3382,14 @@ String String::format(const Variant &values, String placeholder) const {
if (value_arr.size() == 2) {
Variant v_key = value_arr[0];
String key = v_key;
- if (key.left(1) == "\"" && key.right(key.length() - 1) == "\"") {
+ if (key.left(1) == "\"" && key.right(1) == "\"") {
key = key.substr(1, key.length() - 2);
}
Variant v_val = value_arr[1];
String val = v_val;
- if (val.left(1) == "\"" && val.right(val.length() - 1) == "\"") {
+ if (val.left(1) == "\"" && val.right(1) == "\"") {
val = val.substr(1, val.length() - 2);
}
@@ -3336,7 +3401,7 @@ String String::format(const Variant &values, String placeholder) const {
Variant v_val = values_arr[i];
String val = v_val;
- if (val.left(1) == "\"" && val.right(val.length() - 1) == "\"") {
+ if (val.left(1) == "\"" && val.right(1) == "\"") {
val = val.substr(1, val.length() - 2);
}
@@ -3356,11 +3421,11 @@ String String::format(const Variant &values, String placeholder) const {
String key = E->get();
String val = d[E->get()];
- if (key.left(1) == "\"" && key.right(key.length() - 1) == "\"") {
+ if (key.left(1) == "\"" && key.right(1) == "\"") {
key = key.substr(1, key.length() - 2);
}
- if (val.left(1) == "\"" && val.right(val.length() - 1) == "\"") {
+ if (val.left(1) == "\"" && val.right(1) == "\"") {
val = val.substr(1, val.length() - 2);
}
@@ -3464,6 +3529,10 @@ String String::repeat(int p_count) const {
}
String String::left(int p_pos) const {
+ if (p_pos < 0) {
+ p_pos = length() + p_pos;
+ }
+
if (p_pos <= 0) {
return "";
}
@@ -3476,15 +3545,19 @@ String String::left(int p_pos) const {
}
String String::right(int p_pos) const {
- if (p_pos >= length()) {
- return "";
+ if (p_pos < 0) {
+ p_pos = length() + p_pos;
}
if (p_pos <= 0) {
+ return "";
+ }
+
+ if (p_pos >= length()) {
return *this;
}
- return substr(p_pos, (length() - p_pos));
+ return substr(length() - p_pos);
}
char32_t String::unicode_at(int p_idx) const {
@@ -3784,27 +3857,28 @@ String String::uri_encode() const {
}
String String::uri_decode() const {
- String res;
- for (int i = 0; i < length(); ++i) {
- if (unicode_at(i) == '%' && i + 2 < length()) {
- char32_t ord1 = unicode_at(i + 1);
+ CharString src = utf8();
+ CharString res;
+ for (int i = 0; i < src.length(); ++i) {
+ if (src[i] == '%' && i + 2 < src.length()) {
+ char ord1 = src[i + 1];
if ((ord1 >= '0' && ord1 <= '9') || (ord1 >= 'A' && ord1 <= 'Z')) {
- char32_t ord2 = unicode_at(i + 2);
+ char ord2 = src[i + 2];
if ((ord2 >= '0' && ord2 <= '9') || (ord2 >= 'A' && ord2 <= 'Z')) {
char bytes[3] = { (char)ord1, (char)ord2, 0 };
res += (char)strtol(bytes, nullptr, 16);
i += 2;
}
} else {
- res += unicode_at(i);
+ res += src[i];
}
- } else if (unicode_at(i) == '+') {
+ } else if (src[i] == '+') {
res += ' ';
} else {
- res += unicode_at(i);
+ res += src[i];
}
}
- return String::utf8(res.ascii());
+ return String::utf8(res);
}
String String::c_unescape() const {
@@ -4765,7 +4839,7 @@ Vector<uint8_t> String::to_ascii_buffer() const {
size_t len = charstr.length();
retval.resize(len);
uint8_t *w = retval.ptrw();
- copymem(w, charstr.ptr(), len);
+ memcpy(w, charstr.ptr(), len);
return retval;
}
@@ -4781,7 +4855,7 @@ Vector<uint8_t> String::to_utf8_buffer() const {
size_t len = charstr.length();
retval.resize(len);
uint8_t *w = retval.ptrw();
- copymem(w, charstr.ptr(), len);
+ memcpy(w, charstr.ptr(), len);
return retval;
}
@@ -4797,7 +4871,7 @@ Vector<uint8_t> String::to_utf16_buffer() const {
size_t len = charstr.length() * sizeof(char16_t);
retval.resize(len);
uint8_t *w = retval.ptrw();
- copymem(w, (const void *)charstr.ptr(), len);
+ memcpy(w, (const void *)charstr.ptr(), len);
return retval;
}
@@ -4812,7 +4886,7 @@ Vector<uint8_t> String::to_utf32_buffer() const {
size_t len = s->length() * sizeof(char32_t);
retval.resize(len);
uint8_t *w = retval.ptrw();
- copymem(w, (const void *)s->ptr(), len);
+ memcpy(w, (const void *)s->ptr(), len);
return retval;
}