summaryrefslogtreecommitdiffstats
path: root/core/string
diff options
context:
space:
mode:
Diffstat (limited to 'core/string')
-rw-r--r--core/string/node_path.h2
-rw-r--r--core/string/optimized_translation.cpp1
-rw-r--r--core/string/translation.cpp2
-rw-r--r--core/string/translation_po.cpp20
-rw-r--r--core/string/ustring.cpp96
-rw-r--r--core/string/ustring.h1
6 files changed, 94 insertions, 28 deletions
diff --git a/core/string/node_path.h b/core/string/node_path.h
index 26e15636d9..a277ab26fa 100644
--- a/core/string/node_path.h
+++ b/core/string/node_path.h
@@ -66,8 +66,6 @@ public:
void prepend_period();
- NodePath get_parent() const;
-
_FORCE_INLINE_ uint32_t hash() const {
if (!data) {
return 0;
diff --git a/core/string/optimized_translation.cpp b/core/string/optimized_translation.cpp
index 53d0a8924d..268562d971 100644
--- a/core/string/optimized_translation.cpp
+++ b/core/string/optimized_translation.cpp
@@ -46,6 +46,7 @@ void OptimizedTranslation::generate(const Ref<Translation> &p_from) {
// This method compresses a Translation instance.
// Right now, it doesn't handle context or plurals, so Translation subclasses using plurals or context (i.e TranslationPO) shouldn't be compressed.
#ifdef TOOLS_ENABLED
+ ERR_FAIL_COND(p_from.is_null());
List<StringName> keys;
p_from->get_message_list(&keys);
diff --git a/core/string/translation.cpp b/core/string/translation.cpp
index ade5f7b4d8..153f0190fd 100644
--- a/core/string/translation.cpp
+++ b/core/string/translation.cpp
@@ -835,7 +835,7 @@ Vector<String> Translation::_get_message_list() const {
void Translation::_set_messages(const Dictionary &p_messages) {
List<Variant> keys;
p_messages.get_key_list(&keys);
- for (auto E = keys.front(); E; E = E->next()) {
+ for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
translation_map[E->get()] = p_messages[E->get()];
}
}
diff --git a/core/string/translation_po.cpp b/core/string/translation_po.cpp
index 2efadaa9b7..ad768f7140 100644
--- a/core/string/translation_po.cpp
+++ b/core/string/translation_po.cpp
@@ -47,14 +47,14 @@ void TranslationPO::print_translation_map() {
List<StringName> context_l;
translation_map.get_key_list(&context_l);
- for (auto E = context_l.front(); E; E = E->next()) {
+ for (List<StringName>::Element *E = context_l.front(); E; E = E->next()) {
StringName ctx = E->get();
file->store_line(" ===== Context: " + String::utf8(String(ctx).utf8()) + " ===== ");
const HashMap<StringName, Vector<StringName>> &inner_map = translation_map[ctx];
List<StringName> id_l;
inner_map.get_key_list(&id_l);
- for (auto E2 = id_l.front(); E2; E2 = E2->next()) {
+ for (List<StringName>::Element *E2 = id_l.front(); E2; E2 = E2->next()) {
StringName id = E2->get();
file->store_line("msgid: " + String::utf8(String(id).utf8()));
for (int i = 0; i < inner_map[id].size(); i++) {
@@ -74,7 +74,7 @@ Dictionary TranslationPO::_get_messages() const {
List<StringName> context_l;
translation_map.get_key_list(&context_l);
- for (auto E = context_l.front(); E; E = E->next()) {
+ for (List<StringName>::Element *E = context_l.front(); E; E = E->next()) {
StringName ctx = E->get();
const HashMap<StringName, Vector<StringName>> &id_str_map = translation_map[ctx];
@@ -82,7 +82,7 @@ Dictionary TranslationPO::_get_messages() const {
List<StringName> id_l;
id_str_map.get_key_list(&id_l);
// Save list of id and strs associated with a context in a temporary dictionary.
- for (auto E2 = id_l.front(); E2; E2 = E2->next()) {
+ for (List<StringName>::Element *E2 = id_l.front(); E2; E2 = E2->next()) {
StringName id = E2->get();
d2[id] = id_str_map[id];
}
@@ -98,14 +98,14 @@ void TranslationPO::_set_messages(const Dictionary &p_messages) {
List<Variant> context_l;
p_messages.get_key_list(&context_l);
- for (auto E = context_l.front(); E; E = E->next()) {
+ for (List<Variant>::Element *E = context_l.front(); E; E = E->next()) {
StringName ctx = E->get();
const Dictionary &id_str_map = p_messages[ctx];
HashMap<StringName, Vector<StringName>> temp_map;
List<Variant> id_l;
id_str_map.get_key_list(&id_l);
- for (auto E2 = id_l.front(); E2; E2 = E2->next()) {
+ for (List<Variant>::Element *E2 = id_l.front(); E2; E2 = E2->next()) {
StringName id = E2->get();
temp_map[id] = id_str_map[id];
}
@@ -121,7 +121,7 @@ Vector<String> TranslationPO::_get_message_list() const {
get_message_list(&msgs);
Vector<String> v;
- for (auto E = msgs.front(); E; E = E->next()) {
+ for (List<StringName>::Element *E = msgs.front(); E; E = E->next()) {
v.push_back(E->get());
}
@@ -281,7 +281,7 @@ void TranslationPO::get_message_list(List<StringName> *r_messages) const {
List<StringName> context_l;
translation_map.get_key_list(&context_l);
- for (auto E = context_l.front(); E; E = E->next()) {
+ for (List<StringName>::Element *E = context_l.front(); E; E = E->next()) {
if (String(E->get()) != "") {
continue;
}
@@ -289,7 +289,7 @@ void TranslationPO::get_message_list(List<StringName> *r_messages) const {
List<StringName> msgid_l;
translation_map[E->get()].get_key_list(&msgid_l);
- for (auto E2 = msgid_l.front(); E2; E2 = E2->next()) {
+ for (List<StringName>::Element *E2 = msgid_l.front(); E2; E2 = E2->next()) {
r_messages->push_back(E2->get());
}
}
@@ -300,7 +300,7 @@ int TranslationPO::get_message_count() const {
translation_map.get_key_list(&context_l);
int count = 0;
- for (auto E = context_l.front(); E; E = E->next()) {
+ for (List<StringName>::Element *E = context_l.front(); E; E = E->next()) {
count += translation_map[E->get()].size();
}
return count;
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index 05c80296c2..bdb66526a4 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) {
@@ -3772,9 +3837,9 @@ String String::uri_encode() const {
} else {
char h_Val[3];
#if defined(__GNUC__) || defined(_MSC_VER)
- snprintf(h_Val, 3, "%hhX", ord);
+ snprintf(h_Val, 3, "%02hhX", ord);
#else
- sprintf(h_Val, "%hhX", ord);
+ sprintf(h_Val, "%02hhX", ord);
#endif
res += "%";
res += h_Val;
@@ -3784,27 +3849,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 +4831,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 +4847,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 +4863,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 +4878,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;
}
diff --git a/core/string/ustring.h b/core/string/ustring.h
index 1e362d7683..a56845deff 100644
--- a/core/string/ustring.h
+++ b/core/string/ustring.h
@@ -416,6 +416,7 @@ public:
String c_unescape() const;
String json_escape() const;
String word_wrap(int p_chars_per_line) const;
+ Error parse_url(String &r_scheme, String &r_host, int &r_port, String &r_path) const;
String property_name_encode() const;