diff options
Diffstat (limited to 'core/string/ustring.cpp')
-rw-r--r-- | core/string/ustring.cpp | 79 |
1 files changed, 73 insertions, 6 deletions
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 773445edb6..73b5bc2d56 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -2593,6 +2593,23 @@ double String::to_float(const wchar_t *p_str, const wchar_t **r_end) { return built_in_strtod<wchar_t>(p_str, (wchar_t **)r_end); } +uint32_t String::num_characters(int64_t p_int) { + int r = 1; + if (p_int < 0) { + r += 1; + if (p_int == INT64_MIN) { + p_int = INT64_MAX; + } else { + p_int = -p_int; + } + } + while (p_int >= 10) { + p_int /= 10; + r++; + } + return r; +} + int64_t String::to_int(const char32_t *p_str, int p_len, bool p_clamp) { if (p_len == 0 || !p_str[0]) { return 0; @@ -4561,15 +4578,65 @@ String String::property_name_encode() const { } // Changes made to the set of invalid characters must also be reflected in the String documentation. -const String String::invalid_node_name_characters = ". : @ / \" " UNIQUE_NODE_PREFIX; + +static const char32_t invalid_node_name_characters[] = { '.', ':', '@', '/', '\"', UNIQUE_NODE_PREFIX[0], 0 }; + +String String::get_invalid_node_name_characters() { + // Do not use this function for critical validation. + String r; + const char32_t *c = invalid_node_name_characters; + while (*c) { + if (c != invalid_node_name_characters) { + r += " "; + } + r += String::chr(*c); + c++; + } + return r; +} String String::validate_node_name() const { - Vector<String> chars = String::invalid_node_name_characters.split(" "); - String name = this->replace(chars[0], ""); - for (int i = 1; i < chars.size(); i++) { - name = name.replace(chars[i], ""); + // This is a critical validation in node addition, so it must be optimized. + const char32_t *cn = ptr(); + if (cn == nullptr) { + return String(); } - return name; + bool valid = true; + uint32_t idx = 0; + while (cn[idx]) { + const char32_t *c = invalid_node_name_characters; + while (*c) { + if (cn[idx] == *c) { + valid = false; + break; + } + c++; + } + if (!valid) { + break; + } + idx++; + } + + if (valid) { + return *this; + } + + String validated = *this; + char32_t *nn = validated.ptrw(); + while (nn[idx]) { + const char32_t *c = invalid_node_name_characters; + while (*c) { + if (nn[idx] == *c) { + nn[idx] = '_'; + break; + } + c++; + } + idx++; + } + + return validated; } String String::get_basename() const { |