소스 검색

Use `append_` instead of `parse_` for `String` methods.

Lukas Tenbrink 4 달 전
부모
커밋
ffa6ef220b
62개의 변경된 파일245개의 추가작업 그리고 274개의 파일을 삭제
  1. 1 1
      core/config/project_settings.cpp
  2. 16 16
      core/extension/gdextension_interface.cpp
  3. 3 3
      core/io/file_access.cpp
  4. 1 1
      core/io/file_access_pack.cpp
  5. 1 1
      core/io/http_client_tcp.cpp
  6. 1 1
      core/io/marshalls.cpp
  7. 1 1
      core/io/plist.cpp
  8. 3 3
      core/io/resource_format_binary.cpp
  9. 1 1
      core/io/stream_peer.cpp
  10. 6 3
      core/io/translation_loader_po.cpp
  11. 2 1
      core/io/xml_parser.cpp
  12. 1 1
      core/io/zip_io.cpp
  13. 4 4
      core/string/optimized_translation.cpp
  14. 31 88
      core/string/ustring.cpp
  15. 32 29
      core/string/ustring.h
  16. 5 5
      core/variant/variant_call.cpp
  17. 6 2
      core/variant/variant_parser.cpp
  18. 2 1
      drivers/d3d12/rendering_device_driver_d3d12.cpp
  19. 5 4
      drivers/unix/dir_access_unix.cpp
  20. 1 1
      drivers/unix/file_access_unix.cpp
  21. 4 4
      drivers/unix/os_unix.cpp
  22. 2 1
      drivers/vulkan/rendering_device_driver_vulkan.cpp
  23. 2 2
      editor/debugger/debug_adapter/debug_adapter_protocol.cpp
  24. 1 1
      editor/engine_update_label.cpp
  25. 2 2
      editor/export/export_template_manager.cpp
  26. 1 1
      editor/plugins/asset_library_editor_plugin.cpp
  27. 1 1
      modules/gdscript/gdscript.cpp
  28. 1 1
      modules/gdscript/gdscript_cache.cpp
  29. 2 2
      modules/gdscript/language_server/gdscript_language_protocol.cpp
  30. 1 1
      modules/gdscript/register_types.cpp
  31. 1 1
      modules/gdscript/tests/test_gdscript.cpp
  32. 2 2
      modules/gltf/gltf_document.cpp
  33. 1 1
      modules/mono/glue/runtime_interop.cpp
  34. 4 4
      modules/mono/utils/path_utils.cpp
  35. 1 1
      modules/mono/utils/string_utils.cpp
  36. 2 2
      modules/multiplayer/scene_cache_interface.cpp
  37. 1 1
      modules/multiplayer/scene_rpc_interface.cpp
  38. 1 1
      modules/svg/image_loader_svg.cpp
  39. 4 2
      modules/text_server_fb/text_server_fb.cpp
  40. 4 2
      modules/webrtc/webrtc_data_channel_js.cpp
  41. 4 2
      modules/websocket/emws_peer.cpp
  42. 2 2
      modules/websocket/wsl_peer.cpp
  43. 1 1
      platform/android/export/export_plugin.cpp
  44. 2 2
      platform/android/file_access_filesystem_jandroid.cpp
  45. 1 1
      platform/android/jni_utils.h
  46. 1 1
      platform/ios/export/export_plugin.cpp
  47. 1 1
      platform/ios/keyboard_input_view.mm
  48. 2 2
      platform/ios/os_ios.mm
  49. 5 3
      platform/linuxbsd/wayland/wayland_thread.cpp
  50. 6 6
      platform/linuxbsd/x11/display_server_x11.cpp
  51. 2 2
      platform/macos/dir_access_macos.mm
  52. 8 8
      platform/macos/display_server_macos.mm
  53. 2 2
      platform/macos/export/export_plugin.cpp
  54. 2 2
      platform/macos/godot_content_view.mm
  55. 7 7
      platform/macos/os_macos.mm
  56. 2 2
      platform/windows/display_server_windows.cpp
  57. 3 2
      platform/windows/windows_utils.cpp
  58. 1 1
      scene/resources/shader.cpp
  59. 1 1
      scene/resources/shader_include.cpp
  60. 1 1
      scene/resources/text_file.cpp
  61. 1 1
      servers/rendering/rendering_device_graph.cpp
  62. 29 24
      tests/core/string/test_string.h

+ 1 - 1
core/config/project_settings.cpp

@@ -771,7 +771,7 @@ Error ProjectSettings::_load_settings_binary(const String &p_path) {
 		cs[slen] = 0;
 		f->get_buffer((uint8_t *)cs.ptr(), slen);
 		String key;
-		key.parse_utf8(cs.ptr(), slen);
+		key.append_utf8(cs.ptr(), slen);
 
 		uint32_t vlen = f->get_32();
 		Vector<uint8_t> d;

+ 16 - 16
core/extension/gdextension_interface.cpp

@@ -873,75 +873,75 @@ static GDExtensionPtrUtilityFunction gdextension_variant_get_ptr_utility_functio
 
 static void gdextension_string_new_with_latin1_chars(GDExtensionUninitializedStringPtr r_dest, const char *p_contents) {
 	String *dest = memnew_placement(r_dest, String);
-	dest->parse_latin1(Span<char>(p_contents, p_contents ? strlen(p_contents) : 0));
+	dest->append_latin1(Span<char>(p_contents, p_contents ? strlen(p_contents) : 0));
 }
 
 static void gdextension_string_new_with_utf8_chars(GDExtensionUninitializedStringPtr r_dest, const char *p_contents) {
 	String *dest = memnew_placement(r_dest, String);
-	dest->parse_utf8(p_contents);
+	dest->append_utf8(p_contents);
 }
 
 static void gdextension_string_new_with_utf16_chars(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents) {
 	String *dest = memnew_placement(r_dest, String);
-	dest->parse_utf16(p_contents);
+	dest->append_utf16(p_contents);
 }
 
 static void gdextension_string_new_with_utf32_chars(GDExtensionUninitializedStringPtr r_dest, const char32_t *p_contents) {
 	String *dest = memnew_placement(r_dest, String);
-	dest->parse_utf32(Span(p_contents, p_contents ? strlen(p_contents) : 0));
+	dest->append_utf32(Span(p_contents, p_contents ? strlen(p_contents) : 0));
 }
 
 static void gdextension_string_new_with_wide_chars(GDExtensionUninitializedStringPtr r_dest, const wchar_t *p_contents) {
 	if constexpr (sizeof(wchar_t) == 2) {
 		// wchar_t is 16 bit (UTF-16).
 		String *dest = memnew_placement(r_dest, String);
-		dest->parse_utf16((const char16_t *)p_contents);
+		dest->append_utf16((const char16_t *)p_contents);
 	} else {
 		// wchar_t is 32 bit (UTF-32).
 		String *string = memnew_placement(r_dest, String);
-		string->parse_utf32(Span((const char32_t *)p_contents, p_contents ? strlen(p_contents) : 0));
+		string->append_utf32(Span((const char32_t *)p_contents, p_contents ? strlen(p_contents) : 0));
 	}
 }
 
 static void gdextension_string_new_with_latin1_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size) {
 	String *dest = memnew_placement(r_dest, String);
-	dest->parse_latin1(Span(p_contents, p_contents ? _strlen_clipped(p_contents, p_size) : 0));
+	dest->append_latin1(Span(p_contents, p_contents ? _strlen_clipped(p_contents, p_size) : 0));
 }
 
 static void gdextension_string_new_with_utf8_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size) {
 	String *dest = memnew_placement(r_dest, String);
-	dest->parse_utf8(p_contents, p_size);
+	dest->append_utf8(p_contents, p_size);
 }
 
 static GDExtensionInt gdextension_string_new_with_utf8_chars_and_len2(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size) {
 	String *dest = memnew_placement(r_dest, String);
-	return (GDExtensionInt)dest->parse_utf8(p_contents, p_size);
+	return (GDExtensionInt)dest->append_utf8(p_contents, p_size);
 }
 
 static void gdextension_string_new_with_utf16_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_char_count) {
 	String *dest = memnew_placement(r_dest, String);
-	dest->parse_utf16(p_contents, p_char_count);
+	dest->append_utf16(p_contents, p_char_count);
 }
 
 static GDExtensionInt gdextension_string_new_with_utf16_chars_and_len2(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_char_count, GDExtensionBool p_default_little_endian) {
 	String *dest = memnew_placement(r_dest, String);
-	return (GDExtensionInt)dest->parse_utf16(p_contents, p_char_count, p_default_little_endian);
+	return (GDExtensionInt)dest->append_utf16(p_contents, p_char_count, p_default_little_endian);
 }
 
 static void gdextension_string_new_with_utf32_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char32_t *p_contents, GDExtensionInt p_char_count) {
 	String *string = memnew_placement(r_dest, String);
-	string->parse_utf32(Span(p_contents, p_contents ? _strlen_clipped(p_contents, p_char_count) : 0));
+	string->append_utf32(Span(p_contents, p_contents ? _strlen_clipped(p_contents, p_char_count) : 0));
 }
 
 static void gdextension_string_new_with_wide_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const wchar_t *p_contents, GDExtensionInt p_char_count) {
 	if constexpr (sizeof(wchar_t) == 2) {
 		// wchar_t is 16 bit (UTF-16).
 		String *dest = memnew_placement(r_dest, String);
-		dest->parse_utf16((const char16_t *)p_contents, p_char_count);
+		dest->append_utf16((const char16_t *)p_contents, p_char_count);
 	} else {
 		// wchar_t is 32 bit (UTF-32).
 		String *string = memnew_placement(r_dest, String);
-		string->parse_utf32(Span((const char32_t *)p_contents, p_contents ? _strlen_clipped((const char32_t *)p_contents, p_char_count) : 0));
+		string->append_utf32(Span((const char32_t *)p_contents, p_contents ? _strlen_clipped((const char32_t *)p_contents, p_char_count) : 0));
 	}
 }
 
@@ -1053,14 +1053,14 @@ static void gdextension_string_name_new_with_latin1_chars(GDExtensionUninitializ
 
 static void gdextension_string_name_new_with_utf8_chars(GDExtensionUninitializedStringNamePtr r_dest, const char *p_contents) {
 	String tmp;
-	tmp.parse_utf8(p_contents);
+	tmp.append_utf8(p_contents);
 
 	memnew_placement(r_dest, StringName(tmp));
 }
 
 static void gdextension_string_name_new_with_utf8_chars_and_len(GDExtensionUninitializedStringNamePtr r_dest, const char *p_contents, GDExtensionInt p_size) {
 	String tmp;
-	tmp.parse_utf8(p_contents, p_size);
+	tmp.append_utf8(p_contents, p_size);
 
 	memnew_placement(r_dest, StringName(tmp));
 }

+ 3 - 3
core/io/file_access.cpp

@@ -565,7 +565,7 @@ String FileAccess::get_as_utf8_string(bool p_skip_cr) const {
 	w[len] = 0;
 
 	String s;
-	s.parse_utf8((const char *)w, len, p_skip_cr);
+	s.append_utf8((const char *)w, len, p_skip_cr);
 	return s;
 }
 
@@ -745,7 +745,7 @@ String FileAccess::get_pascal_string() {
 	cs[sl] = 0;
 
 	String ret;
-	ret.parse_utf8(cs.ptr(), sl);
+	ret.append_utf8(cs.ptr(), sl);
 	return ret;
 }
 
@@ -838,7 +838,7 @@ String FileAccess::get_file_as_string(const String &p_path, Error *r_error) {
 	}
 
 	String ret;
-	ret.parse_utf8((const char *)array.ptr(), array.size());
+	ret.append_utf8((const char *)array.ptr(), array.size());
 	return ret;
 }
 

+ 1 - 1
core/io/file_access_pack.cpp

@@ -307,7 +307,7 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
 		cs[sl] = 0;
 
 		String path;
-		path.parse_utf8(cs.ptr(), sl);
+		path.append_utf8(cs.ptr(), sl);
 
 		uint64_t ofs = f->get_64();
 		uint64_t size = f->get_64();

+ 1 - 1
core/io/http_client_tcp.cpp

@@ -484,7 +484,7 @@ Error HTTPClientTCP::poll() {
 					// End of response, parse.
 					response_str.push_back(0);
 					String response;
-					response.parse_utf8((const char *)response_str.ptr(), response_str.size());
+					response.append_utf8((const char *)response_str.ptr(), response_str.size());
 					Vector<String> responses = response.split("\n");
 					body_size = -1;
 					chunked = false;

+ 1 - 1
core/io/marshalls.cpp

@@ -107,7 +107,7 @@ static Error _decode_string(const uint8_t *&buf, int &len, int *r_len, String &r
 	ERR_FAIL_COND_V(strlen < 0 || strlen + pad > len, ERR_FILE_EOF);
 
 	String str;
-	ERR_FAIL_COND_V(str.parse_utf8((const char *)buf, strlen) != OK, ERR_INVALID_DATA);
+	ERR_FAIL_COND_V(str.append_utf8((const char *)buf, strlen) != OK, ERR_INVALID_DATA);
 	r_string = str;
 
 	// Add padding.

+ 1 - 1
core/io/plist.cpp

@@ -648,7 +648,7 @@ bool PList::load_file(const String &p_filename) {
 		ERR_FAIL_COND_V(err != OK, false);
 
 		String ret;
-		ret.parse_utf8((const char *)array.ptr(), array.size());
+		ret.append_utf8((const char *)array.ptr(), array.size());
 		String err_str;
 		bool ok = load_string(ret, err_str);
 		ERR_FAIL_COND_V_MSG(!ok, false, "PList: " + err_str);

+ 3 - 3
core/io/resource_format_binary.cpp

@@ -163,7 +163,7 @@ StringName ResourceLoaderBinary::_get_string() {
 		}
 		f->get_buffer((uint8_t *)&str_buf[0], len);
 		String s;
-		s.parse_utf8(&str_buf[0], len);
+		s.append_utf8(&str_buf[0], len);
 		return s;
 	}
 
@@ -919,7 +919,7 @@ static String get_ustring(Ref<FileAccess> f) {
 	str_buf.resize(len);
 	f->get_buffer((uint8_t *)&str_buf[0], len);
 	String s;
-	s.parse_utf8(&str_buf[0], len);
+	s.append_utf8(&str_buf[0], len);
 	return s;
 }
 
@@ -933,7 +933,7 @@ String ResourceLoaderBinary::get_unicode_string() {
 	}
 	f->get_buffer((uint8_t *)&str_buf[0], len);
 	String s;
-	s.parse_utf8(&str_buf[0], len);
+	s.append_utf8(&str_buf[0], len);
 	return s;
 }
 

+ 1 - 1
core/io/stream_peer.cpp

@@ -384,7 +384,7 @@ String StreamPeer::get_utf8_string(int p_bytes) {
 	ERR_FAIL_COND_V(err != OK, String());
 
 	String ret;
-	ret.parse_utf8((const char *)buf.ptr(), buf.size());
+	ret.append_utf8((const char *)buf.ptr(), buf.size());
 	return ret;
 }
 

+ 6 - 3
core/io/translation_loader_po.cpp

@@ -76,14 +76,17 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_
 				bool is_plural = false;
 				for (uint32_t j = 0; j < str_len + 1; j++) {
 					if (data[j] == 0x04) {
-						msg_context.parse_utf8((const char *)data.ptr(), j);
+						msg_context.clear();
+						msg_context.append_utf8((const char *)data.ptr(), j);
 						str_start = j + 1;
 					}
 					if (data[j] == 0x00) {
 						if (is_plural) {
-							msg_id_plural.parse_utf8((const char *)(data.ptr() + str_start), j - str_start);
+							msg_id_plural.clear();
+							msg_id_plural.append_utf8((const char *)(data.ptr() + str_start), j - str_start);
 						} else {
-							msg_id.parse_utf8((const char *)(data.ptr() + str_start), j - str_start);
+							msg_id.clear();
+							msg_id.append_utf8((const char *)(data.ptr() + str_start), j - str_start);
 							is_plural = true;
 						}
 						str_start = j + 1;

+ 2 - 1
core/io/xml_parser.cpp

@@ -95,7 +95,8 @@ void XMLParser::_ignore_definition() {
 	while (*P && *P != '>') {
 		next_char();
 	}
-	node_name.parse_utf8(F, P - F);
+	node_name.clear();
+	node_name.append_utf8(F, P - F);
 
 	if (*P) {
 		next_char();

+ 1 - 1
core/io/zip_io.cpp

@@ -77,7 +77,7 @@ void *zipio_open(voidpf opaque, const char *p_fname, int mode) {
 	ERR_FAIL_NULL_V(fa, nullptr);
 
 	String fname;
-	fname.parse_utf8(p_fname);
+	fname.append_utf8(p_fname);
 
 	int file_access_mode = 0;
 	if (mode & ZLIB_FILEFUNC_MODE_READ) {

+ 4 - 4
core/string/optimized_translation.cpp

@@ -254,7 +254,7 @@ StringName OptimizedTranslation::get_message(const StringName &p_src_text, const
 
 	if (bucket.elem[idx].comp_size == bucket.elem[idx].uncomp_size) {
 		String rstr;
-		rstr.parse_utf8(&sptr[bucket.elem[idx].str_offset], bucket.elem[idx].uncomp_size);
+		rstr.append_utf8(&sptr[bucket.elem[idx].str_offset], bucket.elem[idx].uncomp_size);
 
 		return rstr;
 	} else {
@@ -262,7 +262,7 @@ StringName OptimizedTranslation::get_message(const StringName &p_src_text, const
 		uncomp.resize(bucket.elem[idx].uncomp_size + 1);
 		smaz_decompress(&sptr[bucket.elem[idx].str_offset], bucket.elem[idx].comp_size, uncomp.ptrw(), bucket.elem[idx].uncomp_size);
 		String rstr;
-		rstr.parse_utf8(uncomp.get_data());
+		rstr.append_utf8(uncomp.get_data());
 		return rstr;
 	}
 }
@@ -284,14 +284,14 @@ Vector<String> OptimizedTranslation::get_translated_message_list() const {
 			for (int j = 0; j < bucket.size; j++) {
 				if (bucket.elem[j].comp_size == bucket.elem[j].uncomp_size) {
 					String rstr;
-					rstr.parse_utf8(&sptr[bucket.elem[j].str_offset], bucket.elem[j].uncomp_size);
+					rstr.append_utf8(&sptr[bucket.elem[j].str_offset], bucket.elem[j].uncomp_size);
 					msgs.push_back(rstr);
 				} else {
 					CharString uncomp;
 					uncomp.resize(bucket.elem[j].uncomp_size + 1);
 					smaz_decompress(&sptr[bucket.elem[j].str_offset], bucket.elem[j].comp_size, uncomp.ptrw(), bucket.elem[j].uncomp_size);
 					String rstr;
-					rstr.parse_utf8(uncomp.get_data());
+					rstr.append_utf8(uncomp.get_data());
 					msgs.push_back(rstr);
 				}
 			}

+ 31 - 88
core/string/ustring.cpp

@@ -299,17 +299,17 @@ Error String::parse_url(String &r_scheme, String &r_host, int &r_port, String &r
 	return OK;
 }
 
-void String::parse_latin1(const Span<char> &p_cstr) {
-	if (p_cstr.size() == 0) {
-		resize(0);
+void String::append_latin1(const Span<char> &p_cstr) {
+	if (p_cstr.is_empty()) {
 		return;
 	}
 
-	resize(p_cstr.size() + 1); // include 0
+	const int prev_length = length();
+	resize(prev_length + p_cstr.size() + 1); // include 0
 
 	const char *src = p_cstr.ptr();
 	const char *end = src + p_cstr.size();
-	char32_t *dst = ptrw();
+	char32_t *dst = ptrw() + prev_length;
 
 	for (; src < end; ++src, ++dst) {
 		// If char is int8_t, a set sign bit will be reinterpreted as 256 - val implicitly.
@@ -318,16 +318,16 @@ void String::parse_latin1(const Span<char> &p_cstr) {
 	*dst = 0;
 }
 
-void String::parse_utf32(const Span<char32_t> &p_cstr) {
-	if (p_cstr.size() == 0) {
-		resize(0);
+void String::append_utf32(const Span<char32_t> &p_cstr) {
+	if (p_cstr.is_empty()) {
 		return;
 	}
 
-	resize(p_cstr.size() + 1);
+	const int prev_length = length();
+	resize(prev_length + p_cstr.size() + 1);
 	const char32_t *src = p_cstr.ptr();
 	const char32_t *end = p_cstr.ptr() + p_cstr.size();
-	char32_t *dst = ptrw();
+	char32_t *dst = ptrw() + prev_length;
 
 	// Copy the string, and check for UTF-32 problems.
 	for (; src < end; ++src, ++dst) {
@@ -412,55 +412,16 @@ String operator+(char32_t p_chr, const String &p_str) {
 }
 
 String &String::operator+=(const String &p_str) {
-	const int lhs_len = length();
-	if (lhs_len == 0) {
+	if (is_empty()) {
 		*this = p_str;
 		return *this;
 	}
-
-	const int rhs_len = p_str.length();
-	if (rhs_len == 0) {
-		return *this;
-	}
-
-	resize(lhs_len + rhs_len + 1);
-
-	const char32_t *src = p_str.ptr();
-	char32_t *dst = ptrw() + lhs_len;
-
-	// Don't copy the terminating null with `memcpy` to avoid undefined behavior when string is being added to itself (it would overlap the destination).
-	memcpy(dst, src, rhs_len * sizeof(char32_t));
-	*(dst + rhs_len) = _null;
-
+	append_utf32(p_str);
 	return *this;
 }
 
 String &String::operator+=(const char *p_str) {
-	if (!p_str || p_str[0] == 0) {
-		return *this;
-	}
-
-	const int lhs_len = length();
-	const size_t rhs_len = strlen(p_str);
-
-	resize(lhs_len + rhs_len + 1);
-
-	char32_t *dst = ptrw() + lhs_len;
-
-	for (size_t i = 0; i <= rhs_len; i++) {
-#if CHAR_MIN == 0
-		uint8_t c = p_str[i];
-#else
-		uint8_t c = p_str[i] >= 0 ? p_str[i] : uint8_t(256 + p_str[i]);
-#endif
-		if (c == 0 && i < rhs_len) {
-			print_unicode_error("NUL character", true);
-			dst[i] = _replacement_char;
-		} else {
-			dst[i] = c;
-		}
-	}
-
+	append_latin1(p_str);
 	return *this;
 }
 
@@ -476,32 +437,12 @@ String &String::operator+=(const wchar_t *p_str) {
 }
 
 String &String::operator+=(const char32_t *p_str) {
-	*this += String(p_str);
+	append_utf32(Span(p_str, strlen(p_str)));
 	return *this;
 }
 
 String &String::operator+=(char32_t p_char) {
-	if (p_char == 0) {
-		print_unicode_error("NUL character", true);
-		return *this;
-	}
-
-	const int lhs_len = length();
-	resize(lhs_len + 2);
-	char32_t *dst = ptrw();
-
-	if ((p_char & 0xfffff800) == 0xd800) {
-		print_unicode_error(vformat("Unpaired surrogate (%x)", (uint32_t)p_char));
-		dst[lhs_len] = _replacement_char;
-	} else if (p_char > 0x10ffff) {
-		print_unicode_error(vformat("Invalid unicode codepoint (%x)", (uint32_t)p_char));
-		dst[lhs_len] = _replacement_char;
-	} else {
-		dst[lhs_len] = p_char;
-	}
-
-	dst[lhs_len + 1] = 0;
-
+	append_utf32(Span(&p_char, 1));
 	return *this;
 }
 
@@ -1921,17 +1862,17 @@ CharString String::ascii(bool p_allow_extended) const {
 	return cs;
 }
 
-Error String::parse_ascii(const Span<char> &p_range) {
-	if (p_range.size() == 0) {
-		resize(0);
+Error String::append_ascii(const Span<char> &p_range) {
+	if (p_range.is_empty()) {
 		return OK;
 	}
 
-	resize(p_range.size() + 1); // Include \0
+	const int prev_length = length();
+	resize(prev_length + p_range.size() + 1); // Include \0
 
 	const char *src = p_range.ptr();
 	const char *end = src + p_range.size();
-	char32_t *dst = ptrw();
+	char32_t *dst = ptrw() + prev_length;
 	bool decode_failed = false;
 
 	for (; src < end; ++src, ++dst) {
@@ -1951,12 +1892,12 @@ Error String::parse_ascii(const Span<char> &p_range) {
 
 String String::utf8(const char *p_utf8, int p_len) {
 	String ret;
-	ret.parse_utf8(p_utf8, p_len);
+	ret.append_utf8(p_utf8, p_len);
 
 	return ret;
 }
 
-Error String::parse_utf8(const char *p_utf8, int p_len, bool p_skip_cr) {
+Error String::append_utf8(const char *p_utf8, int p_len, bool p_skip_cr) {
 	if (!p_utf8) {
 		return ERR_INVALID_DATA;
 	}
@@ -1977,9 +1918,10 @@ Error String::parse_utf8(const char *p_utf8, int p_len, bool p_skip_cr) {
 		p_len = strlen(p_utf8);
 	}
 
+	const int prev_length = length();
 	// If all utf8 characters maps to ASCII, then the max size will be p_len, and we add +1 for the null termination.
-	resize(p_len + 1);
-	char32_t *dst = ptrw();
+	resize(prev_length + p_len + 1);
+	char32_t *dst = ptrw() + prev_length;
 
 	Error result = Error::OK;
 
@@ -2124,7 +2066,7 @@ Error String::parse_utf8(const char *p_utf8, int p_len, bool p_skip_cr) {
 	}
 
 	(*dst++) = 0;
-	resize(dst - ptr());
+	resize(prev_length + dst - ptr());
 
 	return result;
 }
@@ -2215,12 +2157,12 @@ CharString String::utf8() const {
 
 String String::utf16(const char16_t *p_utf16, int p_len) {
 	String ret;
-	ret.parse_utf16(p_utf16, p_len, true);
+	ret.append_utf16(p_utf16, p_len, true);
 
 	return ret;
 }
 
-Error String::parse_utf16(const char16_t *p_utf16, int p_len, bool p_default_little_endian) {
+Error String::append_utf16(const char16_t *p_utf16, int p_len, bool p_default_little_endian) {
 	if (!p_utf16) {
 		return ERR_INVALID_DATA;
 	}
@@ -2297,8 +2239,9 @@ Error String::parse_utf16(const char16_t *p_utf16, int p_len, bool p_default_lit
 		return OK; // empty string
 	}
 
-	resize(str_size + 1);
-	char32_t *dst = ptrw();
+	const int prev_length = length();
+	resize(prev_length + str_size + 1);
+	char32_t *dst = ptrw() + prev_length;
 	dst[str_size] = 0;
 
 	bool skip = false;

+ 32 - 29
core/string/ustring.h

@@ -249,30 +249,30 @@ class String {
 	void copy_from_unchecked(const char32_t *p_char, int p_length);
 
 	// NULL-terminated c string copy - automatically parse the string to find the length.
-	void parse_latin1(const char *p_cstr) {
-		parse_latin1(Span(p_cstr, p_cstr ? strlen(p_cstr) : 0));
+	void append_latin1(const char *p_cstr) {
+		append_latin1(Span(p_cstr, p_cstr ? strlen(p_cstr) : 0));
 	}
-	void parse_utf32(const char32_t *p_cstr) {
-		parse_utf32(Span(p_cstr, p_cstr ? strlen(p_cstr) : 0));
+	void append_utf32(const char32_t *p_cstr) {
+		append_utf32(Span(p_cstr, p_cstr ? strlen(p_cstr) : 0));
 	}
 
 	// wchar_t copy_from depends on the platform.
-	void parse_wstring(const Span<wchar_t> &p_cstr) {
+	void append_wstring(const Span<wchar_t> &p_cstr) {
 #ifdef WINDOWS_ENABLED
 		// wchar_t is 16-bit, parse as UTF-16
-		parse_utf16((const char16_t *)p_cstr.ptr(), p_cstr.size());
+		append_utf16((const char16_t *)p_cstr.ptr(), p_cstr.size());
 #else
 		// wchar_t is 32-bit, copy directly
-		parse_utf32((Span<char32_t> &)p_cstr);
+		append_utf32((Span<char32_t> &)p_cstr);
 #endif
 	}
-	void parse_wstring(const wchar_t *p_cstr) {
+	void append_wstring(const wchar_t *p_cstr) {
 #ifdef WINDOWS_ENABLED
 		// wchar_t is 16-bit, parse as UTF-16
-		parse_utf16((const char16_t *)p_cstr);
+		append_utf16((const char16_t *)p_cstr);
 #else
 		// wchar_t is 32-bit, copy directly
-		parse_utf32((const char32_t *)p_cstr);
+		append_utf32((const char32_t *)p_cstr);
 #endif
 	}
 
@@ -424,7 +424,7 @@ public:
 	static String num_uint64(uint64_t p_num, int base = 10, bool capitalize_hex = false);
 	static String chr(char32_t p_char) {
 		String string;
-		string.parse_utf32(Span(&p_char, 1));
+		string.append_utf32(Span(&p_char, 1));
 		return string;
 	}
 	static String md5(const uint8_t *p_md5);
@@ -497,40 +497,40 @@ public:
 	CharString ascii(bool p_allow_extended = false) const;
 	// Parse an ascii string.
 	// If any character is > 127, an error will be logged, and 0xfffd will be inserted.
-	Error parse_ascii(const Span<char> &p_range);
+	Error append_ascii(const Span<char> &p_range);
 	static String ascii(const Span<char> &p_range) {
 		String s;
-		s.parse_ascii(p_range);
+		s.append_ascii(p_range);
 		return s;
 	}
 	CharString latin1() const { return ascii(true); }
-	void parse_latin1(const Span<char> &p_cstr);
+	void append_latin1(const Span<char> &p_cstr);
 	static String latin1(const Span<char> &p_string) {
 		String string;
-		string.parse_latin1(p_string);
+		string.append_latin1(p_string);
 		return string;
 	}
 
 	CharString utf8() const;
-	Error parse_utf8(const char *p_utf8, int p_len = -1, bool p_skip_cr = false);
-	Error parse_utf8(const Span<char> &p_range, bool p_skip_cr = false) {
-		return parse_utf8(p_range.ptr(), p_range.size(), p_skip_cr);
+	Error append_utf8(const char *p_utf8, int p_len = -1, bool p_skip_cr = false);
+	Error append_utf8(const Span<char> &p_range, bool p_skip_cr = false) {
+		return append_utf8(p_range.ptr(), p_range.size(), p_skip_cr);
 	}
 	static String utf8(const char *p_utf8, int p_len = -1);
 	static String utf8(const Span<char> &p_range) { return utf8(p_range.ptr(), p_range.size()); }
 
 	Char16String utf16() const;
-	Error parse_utf16(const char16_t *p_utf16, int p_len = -1, bool p_default_little_endian = true);
-	Error parse_utf16(const Span<char16_t> p_range, bool p_skip_cr = false) {
-		return parse_utf16(p_range.ptr(), p_range.size(), p_skip_cr);
+	Error append_utf16(const char16_t *p_utf16, int p_len = -1, bool p_default_little_endian = true);
+	Error append_utf16(const Span<char16_t> p_range, bool p_skip_cr = false) {
+		return append_utf16(p_range.ptr(), p_range.size(), p_skip_cr);
 	}
 	static String utf16(const char16_t *p_utf16, int p_len = -1);
 	static String utf16(const Span<char16_t> &p_range) { return utf16(p_range.ptr(), p_range.size()); }
 
-	void parse_utf32(const Span<char32_t> &p_cstr);
+	void append_utf32(const Span<char32_t> &p_cstr);
 	static String utf32(const Span<char32_t> &p_span) {
 		String string;
-		string.parse_utf32(p_span);
+		string.append_utf32(p_span);
 		return string;
 	}
 
@@ -621,24 +621,27 @@ public:
 
 	// Constructors for NULL terminated C strings.
 	String(const char *p_cstr) {
-		parse_latin1(p_cstr);
+		append_latin1(p_cstr);
 	}
 	String(const wchar_t *p_cstr) {
-		parse_wstring(p_cstr);
+		append_wstring(p_cstr);
 	}
 	String(const char32_t *p_cstr) {
-		parse_utf32(p_cstr);
+		append_utf32(p_cstr);
 	}
 
 	// Copy assignment for NULL terminated C strings.
 	void operator=(const char *p_cstr) {
-		parse_latin1(p_cstr);
+		clear();
+		append_latin1(p_cstr);
 	}
 	void operator=(const wchar_t *p_cstr) {
-		parse_wstring(p_cstr);
+		clear();
+		append_wstring(p_cstr);
 	}
 	void operator=(const char32_t *p_cstr) {
-		parse_utf32(p_cstr);
+		clear();
+		append_utf32(p_cstr);
 	}
 };
 

+ 5 - 5
core/variant/variant_call.cpp

@@ -698,7 +698,7 @@ struct _VariantCall {
 		String s;
 		if (p_instance->size() > 0) {
 			const uint8_t *r = p_instance->ptr();
-			s.parse_utf8((const char *)r, p_instance->size());
+			s.append_utf8((const char *)r, p_instance->size());
 		}
 		return s;
 	}
@@ -707,7 +707,7 @@ struct _VariantCall {
 		String s;
 		if (p_instance->size() > 0) {
 			const uint8_t *r = p_instance->ptr();
-			s.parse_utf16((const char16_t *)r, floor((double)p_instance->size() / (double)sizeof(char16_t)));
+			s.append_utf16((const char16_t *)r, floor((double)p_instance->size() / (double)sizeof(char16_t)));
 		}
 		return s;
 	}
@@ -716,7 +716,7 @@ struct _VariantCall {
 		String s;
 		if (p_instance->size() > 0) {
 			const uint8_t *r = p_instance->ptr();
-			s.parse_utf32(Span((const char32_t *)r, floor((double)p_instance->size() / (double)sizeof(char32_t))));
+			s.append_utf32(Span((const char32_t *)r, floor((double)p_instance->size() / (double)sizeof(char32_t))));
 		}
 		return s;
 	}
@@ -726,9 +726,9 @@ struct _VariantCall {
 		if (p_instance->size() > 0) {
 			const uint8_t *r = p_instance->ptr();
 #ifdef WINDOWS_ENABLED
-			s.parse_utf16((const char16_t *)r, floor((double)p_instance->size() / (double)sizeof(char16_t)));
+			s.append_utf16((const char16_t *)r, floor((double)p_instance->size() / (double)sizeof(char16_t)));
 #else
-			s.parse_utf32(Span((const char32_t *)r, floor((double)p_instance->size() / (double)sizeof(char32_t))));
+			s.append_utf32(Span((const char32_t *)r, floor((double)p_instance->size() / (double)sizeof(char32_t))));
 #endif
 		}
 		return s;

+ 6 - 2
core/variant/variant_parser.cpp

@@ -396,7 +396,10 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
 				}
 
 				if (p_stream->is_utf8()) {
-					str.parse_utf8(str.ascii(true).get_data());
+					// Re-interpret the string we built as ascii.
+					CharString string_as_ascii = str.ascii(true);
+					str.clear();
+					str.append_utf8(string_as_ascii);
 				}
 				if (string_name) {
 					r_token.type = TK_STRING_NAME;
@@ -1734,7 +1737,8 @@ Error VariantParser::_parse_tag(Token &token, Stream *p_stream, int &line, Strin
 				}
 				cs += c;
 			}
-			r_tag.name.parse_utf8(cs.get_data(), cs.length());
+			r_tag.name.clear();
+			r_tag.name.append_utf8(cs.get_data(), cs.length());
 		} else {
 			while (true) {
 				char32_t c = p_stream->get_char();

+ 2 - 1
drivers/d3d12/rendering_device_driver_d3d12.cpp

@@ -3691,7 +3691,8 @@ RDD::ShaderID RenderingDeviceDriverD3D12::shader_create_from_bytecode(const Vect
 	read_offset += sizeof(uint32_t) * 3 + bin_data_size;
 
 	if (binary_data.shader_name_len) {
-		r_name.parse_utf8((const char *)(binptr + read_offset), binary_data.shader_name_len);
+		r_name.clear();
+		r_name.append_utf8((const char *)(binptr + read_offset), binary_data.shader_name_len);
 		read_offset += STEPIFY(binary_data.shader_name_len, 4);
 	}
 

+ 5 - 4
drivers/unix/dir_access_unix.cpp

@@ -342,7 +342,7 @@ Error DirAccessUnix::change_dir(String p_dir) {
 	String prev_dir;
 	char real_current_dir_name[2048];
 	ERR_FAIL_NULL_V(getcwd(real_current_dir_name, 2048), ERR_BUG);
-	if (prev_dir.parse_utf8(real_current_dir_name) != OK) {
+	if (prev_dir.append_utf8(real_current_dir_name) != OK) {
 		prev_dir = real_current_dir_name; //no utf8, maybe latin?
 	}
 
@@ -365,7 +365,7 @@ Error DirAccessUnix::change_dir(String p_dir) {
 	if (!base.is_empty() && !try_dir.begins_with(base)) {
 		ERR_FAIL_NULL_V(getcwd(real_current_dir_name, 2048), ERR_BUG);
 		String new_dir;
-		new_dir.parse_utf8(real_current_dir_name);
+		new_dir.append_utf8(real_current_dir_name);
 
 		if (!new_dir.begins_with(base)) {
 			try_dir = current_dir; //revert
@@ -486,7 +486,7 @@ String DirAccessUnix::read_link(String p_file) {
 	ssize_t len = readlink(p_file.utf8().get_data(), buf, sizeof(buf));
 	String link;
 	if (len > 0) {
-		link.parse_utf8(buf, len);
+		link.append_utf8(buf, len);
 	}
 	return link;
 }
@@ -553,7 +553,8 @@ DirAccessUnix::DirAccessUnix() {
 	// set current directory to an absolute path of the current directory
 	char real_current_dir_name[2048];
 	ERR_FAIL_NULL(getcwd(real_current_dir_name, 2048));
-	if (current_dir.parse_utf8(real_current_dir_name) != OK) {
+	current_dir.clear();
+	if (current_dir.append_utf8(real_current_dir_name) != OK) {
 		current_dir = real_current_dir_name;
 	}
 

+ 1 - 1
drivers/unix/file_access_unix.cpp

@@ -211,7 +211,7 @@ String FileAccessUnix::get_real_path() const {
 	}
 
 	String result;
-	Error parse_ok = result.parse_utf8(resolved_path);
+	Error parse_ok = result.append_utf8(resolved_path);
 	::free(resolved_path);
 
 	if (parse_ok != OK) {

+ 4 - 4
drivers/unix/os_unix.cpp

@@ -710,7 +710,7 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, St
 				p_pipe_mutex->lock();
 			}
 			String pipe_out;
-			if (pipe_out.parse_utf8(buf) == OK) {
+			if (pipe_out.append_utf8(buf) == OK) {
 				(*r_pipe) += pipe_out;
 			} else {
 				(*r_pipe) += String(buf); // If not valid UTF-8 try decode as Latin-1
@@ -942,7 +942,7 @@ String OS_Unix::get_environment(const String &p_var) const {
 		return "";
 	}
 	String s;
-	if (s.parse_utf8(val) == OK) {
+	if (s.append_utf8(val) == OK) {
 		return s;
 	}
 	return String(val); // Not valid UTF-8, so return as-is
@@ -971,7 +971,7 @@ String OS_Unix::get_executable_path() const {
 	ssize_t len = readlink("/proc/self/exe", buf, sizeof(buf));
 	String b;
 	if (len > 0) {
-		b.parse_utf8(buf, len);
+		b.append_utf8(buf, len);
 	}
 	if (b.is_empty()) {
 		WARN_PRINT("Couldn't get executable path from /proc/self/exe, using argv[0]");
@@ -1008,7 +1008,7 @@ String OS_Unix::get_executable_path() const {
 		return OS::get_executable_path();
 	}
 	String b;
-	b.parse_utf8(buf);
+	b.append_utf8(buf);
 	return b;
 #elif defined(__APPLE__)
 	char temp_path[1];

+ 2 - 1
drivers/vulkan/rendering_device_driver_vulkan.cpp

@@ -3649,7 +3649,8 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_bytecode(const Vec
 	read_offset += sizeof(uint32_t) * 4 + bin_data_size;
 
 	if (binary_data.shader_name_len) {
-		r_name.parse_utf8((const char *)(binptr + read_offset), binary_data.shader_name_len);
+		r_name.clear();
+		r_name.append_utf8((const char *)(binptr + read_offset), binary_data.shader_name_len);
 		read_offset += STEPIFY(binary_data.shader_name_len, 4);
 	}
 

+ 2 - 2
editor/debugger/debug_adapter/debug_adapter_protocol.cpp

@@ -67,7 +67,7 @@ Error DAPeer::handle_data() {
 			if (l > 3 && r[l] == '\n' && r[l - 1] == '\r' && r[l - 2] == '\n' && r[l - 3] == '\r') {
 				r[l - 3] = '\0'; // Null terminate to read string
 				String header;
-				header.parse_utf8(r);
+				header.append_utf8(r);
 				content_length = header.substr(16).to_int();
 				has_header = true;
 				req_pos = 0;
@@ -94,7 +94,7 @@ Error DAPeer::handle_data() {
 
 		// Parse data
 		String msg;
-		msg.parse_utf8((const char *)req_buf, req_pos);
+		msg.append_utf8((const char *)req_buf, req_pos);
 
 		// Apply a timestamp if it there's none yet
 		if (!timestamp) {

+ 1 - 1
editor/engine_update_label.cpp

@@ -63,7 +63,7 @@ void EngineUpdateLabel::_http_request_completed(int p_result, int p_response_cod
 	{
 		String s;
 		const uint8_t *r = p_body.ptr();
-		s.parse_utf8((const char *)r, p_body.size());
+		s.append_utf8((const char *)r, p_body.size());
 
 		Variant result = JSON::parse_string(s);
 		if (result == Variant()) {

+ 2 - 2
editor/export/export_template_manager.cpp

@@ -284,7 +284,7 @@ void ExportTemplateManager::_refresh_mirrors_completed(int p_status, int p_code,
 	String response_json;
 	{
 		const uint8_t *r = p_data.ptr();
-		response_json.parse_utf8((const char *)r, p_data.size());
+		response_json.append_utf8((const char *)r, p_data.size());
 	}
 
 	JSON json;
@@ -465,7 +465,7 @@ bool ExportTemplateManager::_install_file_selected(const String &p_file, bool p_
 			unzCloseCurrentFile(pkg);
 
 			String data_str;
-			data_str.parse_utf8((const char *)uncomp_data.ptr(), uncomp_data.size());
+			data_str.append_utf8((const char *)uncomp_data.ptr(), uncomp_data.size());
 			data_str = data_str.strip_edges();
 
 			// Version number should be of the form major.minor[.patch].status[.module_config]

+ 1 - 1
editor/plugins/asset_library_editor_plugin.cpp

@@ -1219,7 +1219,7 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
 	{
 		int datalen = p_data.size();
 		const uint8_t *r = p_data.ptr();
-		str.parse_utf8((const char *)r, datalen);
+		str.append_utf8((const char *)r, datalen);
 	}
 
 	bool error_abort = true;

+ 1 - 1
modules/gdscript/gdscript.cpp

@@ -1121,7 +1121,7 @@ Error GDScript::load_source_code(const String &p_path) {
 	w[len] = 0;
 
 	String s;
-	if (s.parse_utf8((const char *)w, len) != OK) {
+	if (s.append_utf8((const char *)w, len) != OK) {
 		ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode.");
 	}
 

+ 1 - 1
modules/gdscript/gdscript_cache.cpp

@@ -275,7 +275,7 @@ String GDScriptCache::get_source_code(const String &p_path) {
 	source_file.write[len] = 0;
 
 	String source;
-	if (source.parse_utf8((const char *)source_file.ptr(), len) != OK) {
+	if (source.append_utf8((const char *)source_file.ptr(), len) != OK) {
 		ERR_FAIL_V_MSG("", "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode.");
 	}
 	return source;

+ 2 - 2
modules/gdscript/language_server/gdscript_language_protocol.cpp

@@ -61,7 +61,7 @@ Error GDScriptLanguageProtocol::LSPeer::handle_data() {
 			if (l > 3 && r[l] == '\n' && r[l - 1] == '\r' && r[l - 2] == '\n' && r[l - 3] == '\r') {
 				r[l - 3] = '\0'; // Null terminate to read string
 				String header;
-				header.parse_utf8(r);
+				header.append_utf8(r);
 				content_length = header.substr(16).to_int();
 				has_header = true;
 				req_pos = 0;
@@ -88,7 +88,7 @@ Error GDScriptLanguageProtocol::LSPeer::handle_data() {
 
 		// Parse data
 		String msg;
-		msg.parse_utf8((const char *)req_buf, req_pos);
+		msg.append_utf8((const char *)req_buf, req_pos);
 
 		// Reset to read again
 		req_pos = 0;

+ 1 - 1
modules/gdscript/register_types.cpp

@@ -102,7 +102,7 @@ protected:
 		}
 
 		String source;
-		source.parse_utf8(reinterpret_cast<const char *>(file.ptr()), file.size());
+		source.append_utf8(reinterpret_cast<const char *>(file.ptr()), file.size());
 		GDScriptTokenizerBuffer::CompressMode compress_mode = script_mode == EditorExportPreset::MODE_SCRIPT_BINARY_TOKENS_COMPRESSED ? GDScriptTokenizerBuffer::COMPRESS_ZSTD : GDScriptTokenizerBuffer::COMPRESS_NONE;
 		file = GDScriptTokenizerBuffer::parse_code_string(source, compress_mode);
 		if (file.is_empty()) {

+ 1 - 1
modules/gdscript/tests/test_gdscript.cpp

@@ -310,7 +310,7 @@ void test(TestType p_type) {
 	buf.write[flen] = 0;
 
 	String code;
-	code.parse_utf8((const char *)&buf[0]);
+	code.append_utf8((const char *)&buf[0]);
 
 	Vector<String> lines;
 	int last = 0;

+ 2 - 2
modules/gltf/gltf_document.cpp

@@ -300,7 +300,7 @@ Error GLTFDocument::_parse_json(const String &p_path, Ref<GLTFState> p_state) {
 	array.resize(file->get_length());
 	file->get_buffer(array.ptrw(), array.size());
 	String text;
-	text.parse_utf8((const char *)array.ptr(), array.size());
+	text.append_utf8((const char *)array.ptr(), array.size());
 
 	JSON json;
 	err = json.parse(text);
@@ -331,7 +331,7 @@ Error GLTFDocument::_parse_glb(Ref<FileAccess> p_file, Ref<GLTFState> p_state) {
 	ERR_FAIL_COND_V(len != chunk_length, ERR_FILE_CORRUPT);
 
 	String text;
-	text.parse_utf8((const char *)json_data.ptr(), json_data.size());
+	text.append_utf8((const char *)json_data.ptr(), json_data.size());
 
 	JSON json;
 	Error err = json.parse(text);

+ 1 - 1
modules/mono/glue/runtime_interop.cpp

@@ -934,7 +934,7 @@ bool godotsharp_variant_equals(const godot_variant *p_a, const godot_variant *p_
 
 void godotsharp_string_new_with_utf16_chars(String *r_dest, const char16_t *p_contents) {
 	memnew_placement(r_dest, String());
-	r_dest->parse_utf16(p_contents);
+	r_dest->append_utf16(p_contents);
 }
 
 // string_name.h

+ 4 - 4
modules/mono/utils/path_utils.cpp

@@ -93,7 +93,7 @@ String cwd() {
 	}
 
 	String result;
-	result.parse_utf16(buffer.ptr());
+	result.append_utf16(buffer.ptr());
 	if (result.is_empty()) {
 		return ".";
 	}
@@ -105,7 +105,7 @@ String cwd() {
 	}
 
 	String result;
-	if (result.parse_utf8(buffer) != OK) {
+	if (result.append_utf8(buffer) != OK) {
 		return ".";
 	}
 
@@ -146,7 +146,7 @@ String realpath(const String &p_path) {
 	::CloseHandle(hFile);
 
 	String result;
-	result.parse_utf16(buffer.ptr());
+	result.append_utf16(buffer.ptr());
 	if (result.is_empty()) {
 		return p_path;
 	}
@@ -160,7 +160,7 @@ String realpath(const String &p_path) {
 	}
 
 	String result;
-	Error parse_ok = result.parse_utf8(resolved_path);
+	Error parse_ok = result.append_utf8(resolved_path);
 	::free(resolved_path);
 
 	if (parse_ok != OK) {

+ 1 - 1
modules/mono/utils/string_utils.cpp

@@ -159,7 +159,7 @@ Error read_all_file_utf8(const String &p_path, String &r_content) {
 	w[len] = 0;
 
 	String source;
-	if (source.parse_utf8((const char *)w, len) != OK) {
+	if (source.append_utf8((const char *)w, len) != OK) {
 		ERR_FAIL_V(ERR_INVALID_DATA);
 	}
 

+ 2 - 2
modules/multiplayer/scene_cache_interface.cpp

@@ -101,7 +101,7 @@ void SceneCacheInterface::process_simplify_path(int p_from, const uint8_t *p_pac
 	int ofs = 1;
 
 	String methods_md5;
-	methods_md5.parse_utf8((const char *)(p_packet + ofs), 32);
+	methods_md5.append_utf8((const char *)(p_packet + ofs), 32);
 	ofs += 33;
 
 	int id = decode_uint32(&p_packet[ofs]);
@@ -110,7 +110,7 @@ void SceneCacheInterface::process_simplify_path(int p_from, const uint8_t *p_pac
 	ERR_FAIL_COND_MSG(peers_info[p_from].recv_nodes.has(id), vformat("Duplicate remote cache ID %d for peer %d", id, p_from));
 
 	String paths;
-	paths.parse_utf8((const char *)(p_packet + ofs), p_packet_len - ofs);
+	paths.append_utf8((const char *)(p_packet + ofs), p_packet_len - ofs);
 
 	const NodePath path = paths;
 

+ 1 - 1
modules/multiplayer/scene_rpc_interface.cpp

@@ -139,7 +139,7 @@ Node *SceneRPCInterface::_process_get_node(int p_from, const uint8_t *p_packet,
 		ERR_FAIL_COND_V_MSG(ofs >= p_packet_len, nullptr, "Invalid packet received. Size smaller than declared.");
 
 		String paths;
-		paths.parse_utf8((const char *)&p_packet[ofs], p_packet_len - ofs);
+		paths.append_utf8((const char *)&p_packet[ofs], p_packet_len - ofs);
 
 		NodePath np = paths;
 

+ 1 - 1
modules/svg/image_loader_svg.cpp

@@ -161,7 +161,7 @@ Error ImageLoaderSVG::load_image(Ref<Image> p_image, Ref<FileAccess> p_fileacces
 	p_fileaccess->get_buffer(buffer.ptrw(), buffer.size());
 
 	String svg;
-	Error err = svg.parse_utf8((const char *)buffer.ptr(), buffer.size());
+	Error err = svg.append_utf8((const char *)buffer.ptr(), buffer.size());
 	if (err != OK) {
 		return err;
 	}

+ 4 - 2
modules/text_server_fb/text_server_fb.cpp

@@ -920,12 +920,14 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontFallback *p_f
 
 					switch (sfnt_name.platform_id) {
 						case TT_PLATFORM_APPLE_UNICODE: {
-							p_font_data->font_name.parse_utf16((const char16_t *)sfnt_name.string, sfnt_name.string_len / 2, false);
+							p_font_data->font_name.clear();
+							p_font_data->font_name.append_utf16((const char16_t *)sfnt_name.string, sfnt_name.string_len / 2, false);
 						} break;
 
 						case TT_PLATFORM_MICROSOFT: {
 							if (sfnt_name.encoding_id == TT_MS_ID_UNICODE_CS || sfnt_name.encoding_id == TT_MS_ID_UCS_4) {
-								p_font_data->font_name.parse_utf16((const char16_t *)sfnt_name.string, sfnt_name.string_len / 2, false);
+								p_font_data->font_name.clear();
+								p_font_data->font_name.append_utf16((const char16_t *)sfnt_name.string, sfnt_name.string_len / 2, false);
 							}
 						} break;
 					}

+ 4 - 2
modules/webrtc/webrtc_data_channel_js.cpp

@@ -198,12 +198,14 @@ WebRTCDataChannelJS::WebRTCDataChannelJS(int js_id) {
 	// Parse label
 	char *label = godot_js_rtc_datachannel_label_get(js_id);
 	if (label) {
-		_label.parse_utf8(label);
+		_label.clear();
+		_label.append_utf8(label);
 		free(label);
 	}
 	char *protocol = godot_js_rtc_datachannel_protocol_get(js_id);
 	if (protocol) {
-		_protocol.parse_utf8(protocol);
+		_protocol.clear();
+		_protocol.append_utf8(protocol);
 		free(protocol);
 	}
 }

+ 4 - 2
modules/websocket/emws_peer.cpp

@@ -37,7 +37,8 @@
 void EMWSPeer::_esws_on_connect(void *p_obj, char *p_proto) {
 	EMWSPeer *peer = static_cast<EMWSPeer *>(p_obj);
 	peer->ready_state = STATE_OPEN;
-	peer->selected_protocol.parse_utf8(p_proto);
+	peer->selected_protocol.clear();
+	peer->selected_protocol.append_utf8(p_proto);
 }
 
 void EMWSPeer::_esws_on_message(void *p_obj, const uint8_t *p_data, int p_data_size, int p_is_string) {
@@ -54,7 +55,8 @@ void EMWSPeer::_esws_on_error(void *p_obj) {
 void EMWSPeer::_esws_on_close(void *p_obj, int p_code, const char *p_reason, int p_was_clean) {
 	EMWSPeer *peer = static_cast<EMWSPeer *>(p_obj);
 	peer->close_code = p_code;
-	peer->close_reason.parse_utf8(p_reason);
+	peer->close_reason.clear();
+	peer->close_reason.append_utf8(p_reason);
 	peer->ready_state = STATE_CLOSED;
 }
 

+ 2 - 2
modules/websocket/wsl_peer.cpp

@@ -646,9 +646,9 @@ void WSLPeer::_wsl_msg_recv_callback(wslay_event_context_ptr ctx, const struct w
 		// Close request or confirmation.
 		peer->close_code = arg->status_code;
 		size_t len = arg->msg_length;
-		peer->close_reason = "";
+		peer->close_reason.clear();
 		if (len > 2 /* first 2 bytes = close code */) {
-			peer->close_reason.parse_utf8((char *)arg->msg + 2, len - 2);
+			peer->close_reason.append_utf8((char *)arg->msg + 2, len - 2);
 		}
 		if (peer->ready_state == STATE_OPEN) {
 			peer->ready_state = STATE_CLOSING;

+ 1 - 1
platform/android/export/export_plugin.cpp

@@ -1593,7 +1593,7 @@ String EditorExportPlatformAndroid::_parse_string(const uint8_t *p_bytes, bool p
 		}
 		str8.write[len] = 0;
 		String str;
-		str.parse_utf8((const char *)str8.ptr(), len);
+		str.append_utf8((const char *)str8.ptr(), len);
 		return str;
 	} else {
 		String str;

+ 2 - 2
platform/android/file_access_filesystem_jandroid.cpp

@@ -203,7 +203,7 @@ String FileAccessFilesystemJAndroid::get_line() const {
 			if (elem == '\n' || elem == '\0') {
 				// Found the end of the line
 				const_cast<FileAccessFilesystemJAndroid *>(this)->seek(start_position + line_buffer_position + 1);
-				if (result.parse_utf8((const char *)line_buffer.ptr(), line_buffer_position, true)) {
+				if (result.append_utf8((const char *)line_buffer.ptr(), line_buffer_position, true)) {
 					return String();
 				}
 				return result;
@@ -211,7 +211,7 @@ String FileAccessFilesystemJAndroid::get_line() const {
 		}
 	}
 
-	if (result.parse_utf8((const char *)line_buffer.ptr(), line_buffer_position, true)) {
+	if (result.append_utf8((const char *)line_buffer.ptr(), line_buffer_position, true)) {
 		return String();
 	}
 	return result;

+ 1 - 1
platform/android/jni_utils.h

@@ -90,7 +90,7 @@ static inline String jstring_to_string(jstring source, JNIEnv *env = nullptr) {
 		}
 		const char *const source_utf8 = env->GetStringUTFChars(source, nullptr);
 		if (source_utf8) {
-			result.parse_utf8(source_utf8);
+			result.append_utf8(source_utf8);
 			env->ReleaseStringUTFChars(source, source_utf8);
 		}
 	}

+ 1 - 1
platform/ios/export/export_plugin.cpp

@@ -452,7 +452,7 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_
 
 	String str;
 	String strnew;
-	str.parse_utf8((const char *)pfile.ptr(), pfile.size());
+	str.append_utf8((const char *)pfile.ptr(), pfile.size());
 	Vector<String> lines = str.split("\n");
 	for (int i = 0; i < lines.size(); i++) {
 		if (lines[i].contains("$binary")) {

+ 1 - 1
platform/ios/keyboard_input_view.mm

@@ -123,7 +123,7 @@
 
 - (void)enterText:(NSString *)substring {
 	String characters;
-	characters.parse_utf8([substring UTF8String]);
+	characters.append_utf8([substring UTF8String]);
 
 	for (int i = 0; i < characters.size(); i++) {
 		int character = characters[i];

+ 2 - 2
platform/ios/os_ios.mm

@@ -359,7 +359,7 @@ String OS_IOS::get_user_data_dir(const String &p_user_dir) const {
 	if (ret.is_empty()) {
 		NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
 		if (paths && [paths count] >= 1) {
-			ret.parse_utf8([[paths firstObject] UTF8String]);
+			ret.append_utf8([[paths firstObject] UTF8String]);
 		}
 	}
 	return ret;
@@ -370,7 +370,7 @@ String OS_IOS::get_cache_path() const {
 	if (ret.is_empty()) {
 		NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
 		if (paths && [paths count] >= 1) {
-			ret.parse_utf8([[paths firstObject] UTF8String]);
+			ret.append_utf8([[paths firstObject] UTF8String]);
 		}
 	}
 	return ret;

+ 5 - 3
platform/linuxbsd/wayland/wayland_thread.cpp

@@ -1110,8 +1110,10 @@ void WaylandThread::_wl_output_on_geometry(void *data, struct wl_output *wl_outp
 	ss->pending_data.physical_size.width = physical_width;
 	ss->pending_data.physical_size.height = physical_height;
 
-	ss->pending_data.make.parse_utf8(make);
-	ss->pending_data.model.parse_utf8(model);
+	ss->pending_data.make.clear();
+	ss->pending_data.make.append_utf8(make);
+	ss->pending_data.model.clear();
+	ss->pending_data.model.append_utf8(model);
 
 	// `wl_output::done` is a version 2 addition. We'll directly update the data
 	// for compatibility.
@@ -4139,7 +4141,7 @@ String WaylandThread::keyboard_get_layout_name(int p_index) const {
 
 	if (ss && ss->xkb_keymap) {
 		String ret;
-		ret.parse_utf8(xkb_keymap_layout_get_name(ss->xkb_keymap, p_index));
+		ret.append_utf8(xkb_keymap_layout_get_name(ss->xkb_keymap, p_index));
 
 		return ret;
 	}

+ 6 - 6
platform/linuxbsd/x11/display_server_x11.cpp

@@ -112,7 +112,7 @@ static String get_atom_name(Display *p_disp, Atom p_atom) {
 	char *name = XGetAtomName(p_disp, p_atom);
 	ERR_FAIL_NULL_V_MSG(name, String(), "Atom is invalid.");
 	String ret;
-	ret.parse_utf8(name);
+	ret.append_utf8(name);
 	XFree(name);
 	return ret;
 }
@@ -766,7 +766,7 @@ String DisplayServerX11::_clipboard_get_impl(Atom p_source, Window x11_window, A
 			}
 
 			if (success && (data_size > 0)) {
-				ret.parse_utf8((const char *)incr_data.ptr(), data_size);
+				ret.append_utf8((const char *)incr_data.ptr(), data_size);
 			}
 		} else if (bytes_left > 0) {
 			// Data is ready and can be processed all at once.
@@ -776,7 +776,7 @@ String DisplayServerX11::_clipboard_get_impl(Atom p_source, Window x11_window, A
 					&len, &dummy, &data);
 
 			if (result == Success) {
-				ret.parse_utf8((const char *)data);
+				ret.append_utf8((const char *)data);
 			} else {
 				print_verbose("Failed to get selection data.");
 			}
@@ -3685,7 +3685,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
 			}
 
 			String tmp;
-			tmp.parse_utf8(utf8string, utf8bytes);
+			tmp.append_utf8(utf8string, utf8bytes);
 			for (int i = 0; i < tmp.length(); i++) {
 				Ref<InputEventKey> k;
 				k.instantiate();
@@ -3766,7 +3766,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
 				int str_xkb_size = xkb_compose_state_get_utf8(wd.xkb_state, str_xkb, 255);
 
 				String tmp;
-				tmp.parse_utf8(str_xkb, str_xkb_size);
+				tmp.append_utf8(str_xkb, str_xkb_size);
 				for (int i = 0; i < tmp.length(); i++) {
 					Ref<InputEventKey> k;
 					k.instantiate();
@@ -4121,7 +4121,7 @@ void DisplayServerX11::_xim_preedit_draw_callback(::XIM xim, ::XPointer client_d
 			if (xim_text->encoding_is_wchar) {
 				changed_text = String(xim_text->string.wide_char);
 			} else {
-				changed_text.parse_utf8(xim_text->string.multi_byte);
+				changed_text.append_utf8(xim_text->string.multi_byte);
 			}
 
 			if (call_data->chg_length < 0) {

+ 2 - 2
platform/macos/dir_access_macos.mm

@@ -43,7 +43,7 @@ String DirAccessMacOS::fix_unicode_name(const char *p_name) const {
 	String fname;
 	if (p_name != nullptr) {
 		NSString *nsstr = [[NSString stringWithUTF8String:p_name] precomposedStringWithCanonicalMapping];
-		fname.parse_utf8([nsstr UTF8String]);
+		fname.append_utf8([nsstr UTF8String]);
 	}
 
 	return fname;
@@ -66,7 +66,7 @@ String DirAccessMacOS::get_drive(int p_drive) {
 	String volname;
 	NSString *path = [vols[p_drive] path];
 
-	volname.parse_utf8([path UTF8String]);
+	volname.append_utf8([path UTF8String]);
 
 	return volname;
 }

+ 8 - 8
platform/macos/display_server_macos.mm

@@ -513,10 +513,10 @@ void DisplayServerMacOS::_update_keyboard_layouts() const {
 	for (NSUInteger i = 0; i < [list_ime count]; i++) {
 		LayoutInfo ly;
 		NSString *name = (__bridge NSString *)TISGetInputSourceProperty((__bridge TISInputSourceRef)[list_ime objectAtIndex:i], kTISPropertyLocalizedName);
-		ly.name.parse_utf8([name UTF8String]);
+		ly.name.append_utf8([name UTF8String]);
 
 		NSArray *langs = (__bridge NSArray *)TISGetInputSourceProperty((__bridge TISInputSourceRef)[list_ime objectAtIndex:i], kTISPropertyInputSourceLanguages);
-		ly.code.parse_utf8([(NSString *)[langs objectAtIndex:0] UTF8String]);
+		ly.code.append_utf8([(NSString *)[langs objectAtIndex:0] UTF8String]);
 		kbd_layouts.push_back(ly);
 
 		if ([name isEqualToString:cur_name]) {
@@ -530,10 +530,10 @@ void DisplayServerMacOS::_update_keyboard_layouts() const {
 	for (NSUInteger i = 0; i < [list_kbd count]; i++) {
 		LayoutInfo ly;
 		NSString *name = (__bridge NSString *)TISGetInputSourceProperty((__bridge TISInputSourceRef)[list_kbd objectAtIndex:i], kTISPropertyLocalizedName);
-		ly.name.parse_utf8([name UTF8String]);
+		ly.name.append_utf8([name UTF8String]);
 
 		NSArray *langs = (__bridge NSArray *)TISGetInputSourceProperty((__bridge TISInputSourceRef)[list_kbd objectAtIndex:i], kTISPropertyInputSourceLanguages);
-		ly.code.parse_utf8([(NSString *)[langs objectAtIndex:0] UTF8String]);
+		ly.code.append_utf8([(NSString *)[langs objectAtIndex:0] UTF8String]);
 		kbd_layouts.push_back(ly);
 
 		if ([name isEqualToString:cur_name]) {
@@ -1054,7 +1054,7 @@ Error DisplayServerMacOS::_file_dialog_with_options_show(const String &p_title,
 				// Callback.
 				Vector<String> files;
 				String url;
-				url.parse_utf8([[[panel URL] path] UTF8String]);
+				url.append_utf8([[[panel URL] path] UTF8String]);
 				files.push_back(url);
 				if (callback.is_valid()) {
 					if (p_options_in_cb) {
@@ -1173,7 +1173,7 @@ Error DisplayServerMacOS::_file_dialog_with_options_show(const String &p_title,
 				Vector<String> files;
 				for (NSUInteger i = 0; i != [urls count]; ++i) {
 					String url;
-					url.parse_utf8([[[urls objectAtIndex:i] path] UTF8String]);
+					url.append_utf8([[[urls objectAtIndex:i] path] UTF8String]);
 					files.push_back(url);
 				}
 				if (callback.is_valid()) {
@@ -1271,7 +1271,7 @@ Error DisplayServerMacOS::dialog_input_text(String p_title, String p_description
 	[window runModal];
 
 	String ret;
-	ret.parse_utf8([[input stringValue] UTF8String]);
+	ret.append_utf8([[input stringValue] UTF8String]);
 
 	if (p_callback.is_valid()) {
 		Variant v_result = ret;
@@ -1555,7 +1555,7 @@ String DisplayServerMacOS::clipboard_get() const {
 	NSString *string = [objectsToPaste objectAtIndex:0];
 
 	String ret;
-	ret.parse_utf8([string UTF8String]);
+	ret.append_utf8([string UTF8String]);
 	return ret;
 }
 

+ 2 - 2
platform/macos/export/export_plugin.cpp

@@ -738,7 +738,7 @@ void EditorExportPlatformMacOS::_make_icon(const Ref<EditorExportPreset> &p_pres
 void EditorExportPlatformMacOS::_fix_privacy_manifest(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &plist) {
 	String str;
 	String strnew;
-	str.parse_utf8((const char *)plist.ptr(), plist.size());
+	str.append_utf8((const char *)plist.ptr(), plist.size());
 	Vector<String> lines = str.split("\n");
 	for (int i = 0; i < lines.size(); i++) {
 		if (lines[i].find("$priv_collection") != -1) {
@@ -817,7 +817,7 @@ void EditorExportPlatformMacOS::_fix_privacy_manifest(const Ref<EditorExportPres
 void EditorExportPlatformMacOS::_fix_plist(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &plist, const String &p_binary) {
 	String str;
 	String strnew;
-	str.parse_utf8((const char *)plist.ptr(), plist.size());
+	str.append_utf8((const char *)plist.ptr(), plist.size());
 	Vector<String> lines = str.split("\n");
 	for (int i = 0; i < lines.size(); i++) {
 		if (lines[i].contains("$binary")) {

+ 2 - 2
platform/macos/godot_content_view.mm

@@ -271,7 +271,7 @@
 	[characters getCharacters:(unichar *)text.ptrw() range:NSMakeRange(0, [characters length])];
 
 	String u32text;
-	u32text.parse_utf16(text.ptr(), text.length());
+	u32text.append_utf16(text.ptr(), text.length());
 
 	for (int i = 0; i < u32text.length(); i++) {
 		const char32_t codepoint = u32text[i];
@@ -653,7 +653,7 @@
 			[characters getCharacters:(unichar *)text.ptrw() range:NSMakeRange(0, [characters length])];
 
 			String u32text;
-			u32text.parse_utf16(text.ptr(), text.length());
+			u32text.append_utf16(text.ptr(), text.length());
 
 			DisplayServerMacOS::KeyEvent ke;
 			ke.window_id = window_id;

+ 7 - 7
platform/macos/os_macos.mm

@@ -106,7 +106,7 @@ Vector<String> OS_MacOS::get_granted_permissions() const {
 			NSURL *url = [NSURL URLByResolvingBookmarkData:bookmark options:NSURLBookmarkResolutionWithSecurityScope relativeToURL:nil bookmarkDataIsStale:&isStale error:&error];
 			if (!error && !isStale) {
 				String url_string;
-				url_string.parse_utf8([[url path] UTF8String]);
+				url_string.append_utf8([[url path] UTF8String]);
 				ret.push_back(url_string);
 			}
 		}
@@ -328,7 +328,7 @@ String OS_MacOS::get_bundle_resource_dir() const {
 	NSBundle *main = [NSBundle mainBundle];
 	if (main) {
 		NSString *resource_path = [main resourcePath];
-		ret.parse_utf8([resource_path UTF8String]);
+		ret.append_utf8([resource_path UTF8String]);
 	}
 	return ret;
 }
@@ -340,7 +340,7 @@ String OS_MacOS::get_bundle_icon_path() const {
 	if (main) {
 		NSString *icon_path = [[main infoDictionary] objectForKey:@"CFBundleIconFile"];
 		if (icon_path) {
-			ret.parse_utf8([icon_path UTF8String]);
+			ret.append_utf8([icon_path UTF8String]);
 		}
 	}
 	return ret;
@@ -383,7 +383,7 @@ String OS_MacOS::get_system_dir(SystemDir p_dir, bool p_shared_storage) const {
 	if (found) {
 		NSArray *paths = NSSearchPathForDirectoriesInDomains(id, NSUserDomainMask, YES);
 		if (paths && [paths count] >= 1) {
-			ret.parse_utf8([[paths firstObject] UTF8String]);
+			ret.append_utf8([[paths firstObject] UTF8String]);
 		}
 	}
 
@@ -647,7 +647,7 @@ String OS_MacOS::get_executable_path() const {
 		return OS::get_executable_path();
 	} else {
 		String path;
-		path.parse_utf8(pathbuf);
+		path.append_utf8(pathbuf);
 
 		return path;
 	}
@@ -720,7 +720,7 @@ Error OS_MacOS::create_instance(const List<String> &p_arguments, ProcessID *r_ch
 	NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
 	if (nsappname != nil) {
 		String path;
-		path.parse_utf8([[[NSBundle mainBundle] bundlePath] UTF8String]);
+		path.append_utf8([[[NSBundle mainBundle] bundlePath] UTF8String]);
 		return create_process(path, p_arguments, r_child_id, false);
 	} else {
 		return create_process(get_executable_path(), p_arguments, r_child_id, false);
@@ -754,7 +754,7 @@ String OS_MacOS::get_unique_id() const {
 		}
 
 		if (serial_number_ns_string) {
-			serial_number.parse_utf8([serial_number_ns_string UTF8String]);
+			serial_number.append_utf8([serial_number_ns_string UTF8String]);
 		}
 	}
 

+ 2 - 2
platform/windows/display_server_windows.cpp

@@ -981,7 +981,7 @@ String DisplayServerWindows::clipboard_get() const {
 		if (mem != nullptr) {
 			LPTSTR ptr = (LPTSTR)GlobalLock(mem);
 			if (ptr != nullptr) {
-				ret.parse_utf8((const char *)ptr);
+				ret.append_utf8((const char *)ptr);
 				GlobalUnlock(mem);
 			}
 		}
@@ -2761,7 +2761,7 @@ String DisplayServerWindows::ime_get_text() const {
 	int32_t length = ImmGetCompositionStringW(wd.im_himc, GCS_COMPSTR, nullptr, 0);
 	wchar_t *string = reinterpret_cast<wchar_t *>(memalloc(length));
 	ImmGetCompositionStringW(wd.im_himc, GCS_COMPSTR, string, length);
-	ret.parse_utf16((char16_t *)string, length / sizeof(wchar_t));
+	ret.append_utf16((char16_t *)string, length / sizeof(wchar_t));
 
 	memdelete(string);
 

+ 3 - 2
platform/windows/windows_utils.cpp

@@ -136,7 +136,7 @@ Error WindowsUtils::copy_and_rename_pdb(const String &p_dll_path) {
 		}
 
 		String utf_path;
-		Error err = utf_path.parse_utf8(raw_pdb_path);
+		Error err = utf_path.append_utf8(raw_pdb_path);
 		ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Failed to read PDB path from '%s'.", p_dll_path));
 
 		pdb_info.path = utf_path;
@@ -179,7 +179,8 @@ Error WindowsUtils::copy_and_rename_pdb(const String &p_dll_path) {
 		if (new_expected_buffer_size > original_path_size) {
 			ERR_FAIL_COND_V_MSG(original_path_size < min_base_size + suffix_size, FAILED, vformat("The original PDB path size in bytes is too small: '%s'. Expected size: %d or more bytes, but available %d.", pdb_info.path, min_base_size + suffix_size, original_path_size));
 
-			new_pdb_base_name.parse_utf8(utf8_name, original_path_size - suffix_size);
+			new_pdb_base_name.clear();
+			new_pdb_base_name.append_utf8(utf8_name, original_path_size - suffix_size);
 			new_pdb_base_name[new_pdb_base_name.length() - 1] = '_'; // Restore the last '_'
 			WARN_PRINT(vformat("The original path size of '%s' in bytes was too small to fit the new name, so it was shortened to '%s%d.pdb'.", pdb_info.path, new_pdb_base_name, max_pdb_names - 1));
 		}

+ 1 - 1
scene/resources/shader.cpp

@@ -312,7 +312,7 @@ Ref<Resource> ResourceFormatLoaderShader::load(const String &p_path, const Strin
 
 	String str;
 	if (buffer.size() > 0) {
-		error = str.parse_utf8((const char *)buffer.ptr(), buffer.size());
+		error = str.append_utf8((const char *)buffer.ptr(), buffer.size());
 		ERR_FAIL_COND_V_MSG(error, nullptr, "Cannot parse shader: " + p_path);
 	}
 

+ 1 - 1
scene/resources/shader_include.cpp

@@ -94,7 +94,7 @@ Ref<Resource> ResourceFormatLoaderShaderInclude::load(const String &p_path, cons
 
 	String str;
 	if (buffer.size() > 0) {
-		error = str.parse_utf8((const char *)buffer.ptr(), buffer.size());
+		error = str.append_utf8((const char *)buffer.ptr(), buffer.size());
 		ERR_FAIL_COND_V_MSG(error, nullptr, "Cannot parse shader include: " + p_path);
 	}
 

+ 1 - 1
scene/resources/text_file.cpp

@@ -64,7 +64,7 @@ Error TextFile::load_text(const String &p_path) {
 	w[len] = 0;
 
 	String s;
-	ERR_FAIL_COND_V_MSG(s.parse_utf8((const char *)w) != OK, ERR_INVALID_DATA, "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode.");
+	ERR_FAIL_COND_V_MSG(s.append_utf8((const char *)w) != OK, ERR_INVALID_DATA, "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode.");
 	text = s;
 	path = p_path;
 #ifdef TOOLS_ENABLED

+ 1 - 1
servers/rendering/rendering_device_graph.cpp

@@ -1119,7 +1119,7 @@ void RenderingDeviceGraph::_run_label_command_change(RDD::CommandBufferID p_comm
 		Color label_color;
 		if (p_new_label_index >= 0) {
 			const char *label_chars = &command_label_chars[command_label_offsets[p_new_label_index]];
-			label_name.parse_utf8(label_chars);
+			label_name.append_utf8(label_chars);
 			label_color = command_label_colors[p_new_label_index];
 		} else if (p_use_label_for_empty) {
 			label_name = "Command graph";

+ 29 - 24
tests/core/string/test_string.h

@@ -87,34 +87,38 @@ TEST_CASE("[String] UTF8") {
 	/* how can i embed UTF in here? */
 	static const char32_t u32str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 };
 	static const uint8_t u8str[] = { 0x45, 0x20, 0xE3, 0x81, 0x8A, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0 };
-	String s = u32str;
-	Error err = s.parse_utf8(s.utf8().get_data());
+	String expected = u32str;
+	String parsed;
+	Error err = parsed.append_utf8(expected.utf8().get_data());
 	CHECK(err == OK);
-	CHECK(s == u32str);
+	CHECK(parsed == u32str);
 
-	err = s.parse_utf8((const char *)u8str);
+	parsed.clear();
+	err = parsed.append_utf8((const char *)u8str);
 	CHECK(err == OK);
-	CHECK(s == u32str);
+	CHECK(parsed == u32str);
 
 	CharString cs = (const char *)u8str;
-	CHECK(String::utf8(cs) == s);
+	CHECK(String::utf8(cs) == parsed);
 }
 
 TEST_CASE("[String] UTF16") {
 	/* how can i embed UTF in here? */
 	static const char32_t u32str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 };
 	static const char16_t u16str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0xD83C, 0xDFA4, 0 };
-	String s = u32str;
-	Error err = s.parse_utf16(s.utf16().get_data());
+	String expected = u32str;
+	String parsed;
+	Error err = parsed.append_utf16(expected.utf16().get_data());
 	CHECK(err == OK);
-	CHECK(s == u32str);
+	CHECK(parsed == u32str);
 
-	err = s.parse_utf16(u16str);
+	parsed.clear();
+	err = parsed.append_utf16(u16str);
 	CHECK(err == OK);
-	CHECK(s == u32str);
+	CHECK(parsed == u32str);
 
 	Char16String cs = u16str;
-	CHECK(String::utf16(cs) == s);
+	CHECK(String::utf16(cs) == parsed);
 }
 
 TEST_CASE("[String] UTF8 with BOM") {
@@ -122,7 +126,7 @@ TEST_CASE("[String] UTF8 with BOM") {
 	static const char32_t u32str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 };
 	static const uint8_t u8str[] = { 0xEF, 0xBB, 0xBF, 0x45, 0x20, 0xE3, 0x81, 0x8A, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0 };
 	String s;
-	Error err = s.parse_utf8((const char *)u8str);
+	Error err = s.append_utf8((const char *)u8str);
 	CHECK(err == OK);
 	CHECK(s == u32str);
 
@@ -136,11 +140,12 @@ TEST_CASE("[String] UTF16 with BOM") {
 	static const char16_t u16str[] = { 0xFEFF, 0x0020, 0x0045, 0x304A, 0x360F, 0x3088, 0x3046, 0xD83C, 0xDFA4, 0 };
 	static const char16_t u16str_swap[] = { 0xFFFE, 0x2000, 0x4500, 0x4A30, 0x0F36, 0x8830, 0x4630, 0x3CD8, 0xA4DF, 0 };
 	String s;
-	Error err = s.parse_utf16(u16str);
+	Error err = s.append_utf16(u16str);
 	CHECK(err == OK);
 	CHECK(s == u32str);
 
-	err = s.parse_utf16(u16str_swap);
+	s.clear();
+	err = s.append_utf16(u16str_swap);
 	CHECK(err == OK);
 	CHECK(s == u32str);
 
@@ -155,12 +160,12 @@ TEST_CASE("[String] UTF8 with CR") {
 	const String base = U"Hello darkness\r\nMy old friend\nI've come to talk\rWith you again";
 
 	String keep_cr;
-	Error err = keep_cr.parse_utf8(base.utf8().get_data());
+	Error err = keep_cr.append_utf8(base.utf8().get_data());
 	CHECK(err == OK);
 	CHECK(keep_cr == base);
 
 	String no_cr;
-	err = no_cr.parse_utf8(base.utf8().get_data(), -1, true); // Skip CR.
+	err = no_cr.append_utf8(base.utf8().get_data(), -1, true); // Skip CR.
 	CHECK(err == OK);
 	CHECK(no_cr == base.replace("\r", ""));
 }
@@ -171,7 +176,7 @@ TEST_CASE("[String] Invalid UTF8 (non shortest form sequence)") {
 	static const uint8_t u8str[] = { 0xC0, 0xAF, 0xE0, 0x80, 0xBF, 0xF0, 0x81, 0x82, 0x41, 0 };
 	static const char32_t u32str[] = { 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x41, 0 };
 	String s;
-	Error err = s.parse_utf8((const char *)u8str);
+	Error err = s.append_utf8((const char *)u8str);
 	CHECK(err == ERR_INVALID_DATA);
 	CHECK(s == u32str);
 
@@ -186,7 +191,7 @@ TEST_CASE("[String] Invalid UTF8 (ill formed sequences for surrogates)") {
 	static const uint8_t u8str[] = { 0xED, 0xA0, 0x80, 0xED, 0xBF, 0xBF, 0xED, 0xAF, 0x41, 0 };
 	static const char32_t u32str[] = { 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x41, 0 };
 	String s;
-	Error err = s.parse_utf8((const char *)u8str);
+	Error err = s.append_utf8((const char *)u8str);
 	CHECK(err == ERR_INVALID_DATA);
 	CHECK(s == u32str);
 
@@ -201,7 +206,7 @@ TEST_CASE("[String] Invalid UTF8 (other ill formed sequences)") {
 	static const uint8_t u8str[] = { 0xF4, 0x91, 0x92, 0x93, 0xFF, 0x41, 0x80, 0xBF, 0x42, 0 };
 	static const char32_t u32str[] = { 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x41, 0xFFFD, 0xFFFD, 0x42, 0 };
 	String s;
-	Error err = s.parse_utf8((const char *)u8str);
+	Error err = s.append_utf8((const char *)u8str);
 	CHECK(err == ERR_INVALID_DATA);
 	CHECK(s == u32str);
 
@@ -216,7 +221,7 @@ TEST_CASE("[String] Invalid UTF8 (truncated sequences)") {
 	static const uint8_t u8str[] = { 0xE1, 0x80, 0xE2, 0xF0, 0x91, 0x92, 0xF1, 0xBF, 0x41, 0 };
 	static const char32_t u32str[] = { 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x41, 0 };
 	String s;
-	Error err = s.parse_utf8((const char *)u8str);
+	Error err = s.append_utf8((const char *)u8str);
 	CHECK(err == ERR_INVALID_DATA);
 	CHECK(s == u32str);
 
@@ -231,7 +236,7 @@ TEST_CASE("[String] Invalid UTF16 (non-standard)") {
 	//                                 +       +       +       +       unpaired
 	static const char32_t u32str[] = { 0x0045, 0x304A, 0x3088, 0x3046, 0xDFA4, 0 };
 	String s;
-	Error err = s.parse_utf16(u16str);
+	Error err = s.append_utf16(u16str);
 	CHECK(err == ERR_PARSE_ERROR);
 	CHECK(s == u32str);
 
@@ -1604,9 +1609,9 @@ TEST_CASE("[String] lstrip and rstrip") {
 #undef STRIP_TEST
 }
 
-TEST_CASE("[String] Ensuring empty string into parse_utf8 passes empty string") {
+TEST_CASE("[String] Ensuring empty string into extend_utf8 passes empty string") {
 	String empty;
-	CHECK(empty.parse_utf8(nullptr, -1) == ERR_INVALID_DATA);
+	CHECK(empty.append_utf8(nullptr, -1) == ERR_INVALID_DATA);
 }
 
 TEST_CASE("[String] Cyrillic to_lower()") {