diff options
Diffstat (limited to 'core/string/ustring.cpp')
-rw-r--r-- | core/string/ustring.cpp | 118 |
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; } |