diff options
Diffstat (limited to 'core/io')
80 files changed, 635 insertions, 442 deletions
diff --git a/core/io/compression.cpp b/core/io/compression.cpp index 790b6febc0..ae5ccf8354 100644 --- a/core/io/compression.cpp +++ b/core/io/compression.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -212,7 +212,7 @@ int Compression::decompress_dynamic(Vector<uint8_t> *p_dst_vect, int p_max_dst_s strm.avail_in = p_src_size; // Ensure the destination buffer is empty - p_dst_vect->resize(0); + p_dst_vect->clear(); // decompress until deflate stream ends or end of file do { @@ -244,7 +244,7 @@ int Compression::decompress_dynamic(Vector<uint8_t> *p_dst_vect, int p_max_dst_s WARN_PRINT(strm.msg); } (void)inflateEnd(&strm); - p_dst_vect->resize(0); + p_dst_vect->clear(); return ret; } } while (strm.avail_out > 0 && strm.avail_in > 0); @@ -254,7 +254,7 @@ int Compression::decompress_dynamic(Vector<uint8_t> *p_dst_vect, int p_max_dst_s // Enforce max output size if (p_max_dst_size > -1 && strm.total_out > (uint64_t)p_max_dst_size) { (void)inflateEnd(&strm); - p_dst_vect->resize(0); + p_dst_vect->clear(); return Z_BUF_ERROR; } } while (ret != Z_STREAM_END); diff --git a/core/io/compression.h b/core/io/compression.h index 06f26876e5..2e66970a6c 100644 --- a/core/io/compression.h +++ b/core/io/compression.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp index 33f992e153..c942b417e4 100644 --- a/core/io/config_file.cpp +++ b/core/io/config_file.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -183,7 +183,7 @@ Error ConfigFile::_internal_save(FileAccess *file) { if (E != values.front()) { file->store_string("\n"); } - if (E.key() != "") { + if (!E.key().is_empty()) { file->store_string("[" + E.key() + "]\n\n"); } @@ -287,9 +287,9 @@ Error ConfigFile::_parse(const String &p_path, VariantParser::Stream *p_stream) return err; } - if (assign != String()) { + if (!assign.is_empty()) { set_value(section, assign, value); - } else if (next_tag.name != String()) { + } else if (!next_tag.name.is_empty()) { section = next_tag.name; } } diff --git a/core/io/config_file.h b/core/io/config_file.h index dbba43ace5..71e9080fb7 100644 --- a/core/io/config_file.h +++ b/core/io/config_file.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/dir_access.cpp b/core/io/dir_access.cpp index 3bff0a3fd5..86d8dea3d9 100644 --- a/core/io/dir_access.cpp +++ b/core/io/dir_access.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -79,7 +79,7 @@ static Error _erase_recursive(DirAccess *da) { da->list_dir_begin(); String n = da->get_next(); - while (n != String()) { + while (!n.is_empty()) { if (n != "." && n != "..") { if (da->current_is_dir()) { dirs.push_back(n); @@ -145,17 +145,21 @@ Error DirAccess::make_dir_recursive(String p_dir) { full_dir = full_dir.replace("\\", "/"); - //int slices = full_dir.get_slice_count("/"); - String base; if (full_dir.begins_with("res://")) { base = "res://"; } else if (full_dir.begins_with("user://")) { base = "user://"; + } else if (full_dir.is_network_share_path()) { + int pos = full_dir.find("/", 2); + ERR_FAIL_COND_V(pos < 0, ERR_INVALID_PARAMETER); + pos = full_dir.find("/", pos + 1); + ERR_FAIL_COND_V(pos < 0, ERR_INVALID_PARAMETER); + base = full_dir.substr(0, pos + 1); } else if (full_dir.begins_with("/")) { base = "/"; - } else if (full_dir.find(":/") != -1) { + } else if (full_dir.contains(":/")) { base = full_dir.substr(0, full_dir.find(":/") + 2); } else { ERR_FAIL_V(ERR_INVALID_PARAMETER); @@ -183,7 +187,7 @@ String DirAccess::fix_path(String p_path) const { if (ProjectSettings::get_singleton()) { if (p_path.begins_with("res://")) { String resource_path = ProjectSettings::get_singleton()->get_resource_path(); - if (resource_path != "") { + if (!resource_path.is_empty()) { return p_path.replace_first("res:/", resource_path); } return p_path.replace_first("res://", ""); @@ -194,7 +198,7 @@ String DirAccess::fix_path(String p_path) const { case ACCESS_USERDATA: { if (p_path.begins_with("user://")) { String data_dir = OS::get_singleton()->get_user_data_dir(); - if (data_dir != "") { + if (!data_dir.is_empty()) { return p_path.replace_first("user:/", data_dir); } return p_path.replace_first("user://", ""); @@ -337,7 +341,7 @@ Error DirAccess::_copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flag String curdir = get_current_dir(); list_dir_begin(); String n = get_next(); - while (n != String()) { + while (!n.is_empty()) { if (n != "." && n != "..") { if (p_copy_links && is_link(get_current_dir().plus_file(n))) { create_link(read_link(get_current_dir().plus_file(n)), p_to + n); diff --git a/core/io/dir_access.h b/core/io/dir_access.h index 16154a4850..8154f5366c 100644 --- a/core/io/dir_access.h +++ b/core/io/dir_access.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/dtls_server.cpp b/core/io/dtls_server.cpp index 655fb18535..b5c44e1b64 100644 --- a/core/io/dtls_server.cpp +++ b/core/io/dtls_server.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/dtls_server.h b/core/io/dtls_server.h index 02a32533e1..0c9b0149b0 100644 --- a/core/io/dtls_server.h +++ b/core/io/dtls_server.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/file_access.cpp b/core/io/file_access.cpp index e6e79dff8a..86836454c5 100644 --- a/core/io/file_access.cpp +++ b/core/io/file_access.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -127,7 +127,7 @@ String FileAccess::fix_path(const String &p_path) const { if (ProjectSettings::get_singleton()) { if (r_path.begins_with("res://")) { String resource_path = ProjectSettings::get_singleton()->get_resource_path(); - if (resource_path != "") { + if (!resource_path.is_empty()) { return r_path.replace("res:/", resource_path); } return r_path.replace("res://", ""); @@ -138,7 +138,7 @@ String FileAccess::fix_path(const String &p_path) const { case ACCESS_USERDATA: { if (r_path.begins_with("user://")) { String data_dir = OS::get_singleton()->get_user_data_dir(); - if (data_dir != "") { + if (!data_dir.is_empty()) { return r_path.replace("user:/", data_dir); } return r_path.replace("user://", ""); @@ -538,7 +538,7 @@ void FileAccess::store_csv_line(const Vector<String> &p_values, const String &p_ for (int i = 0; i < size; ++i) { String value = p_values[i]; - if (value.find("\"") != -1 || value.find(p_delim) != -1 || value.find("\n") != -1) { + if (value.contains("\"") || value.contains(p_delim) || value.contains("\n")) { value = "\"" + value.replace("\"", "\"\"") + "\""; } if (i < size - 1) { diff --git a/core/io/file_access.h b/core/io/file_access.h index 5804aa2c47..5413665440 100644 --- a/core/io/file_access.h +++ b/core/io/file_access.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp index df631053b8..526952b14f 100644 --- a/core/io/file_access_compressed.cpp +++ b/core/io/file_access_compressed.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -312,10 +312,10 @@ uint64_t FileAccessCompressed::get_buffer(uint8_t *p_dst, uint64_t p_length) con } else { read_block--; at_end = true; - if (i < p_length - 1) { + if (i + 1 < p_length) { read_eof = true; } - return i; + return i + 1; } } } diff --git a/core/io/file_access_compressed.h b/core/io/file_access_compressed.h index 3389e020e3..97ef3fbdeb 100644 --- a/core/io/file_access_compressed.h +++ b/core/io/file_access_compressed.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index 9e316291e8..8ee19d3d06 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h index decffae696..be5904c894 100644 --- a/core/io/file_access_encrypted.h +++ b/core/io/file_access_encrypted.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp index 627fd2bf9c..4aca26b007 100644 --- a/core/io/file_access_memory.cpp +++ b/core/io/file_access_memory.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/file_access_memory.h b/core/io/file_access_memory.h index 14135bd68c..50b23e1f32 100644 --- a/core/io/file_access_memory.h +++ b/core/io/file_access_memory.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp index 9ee3876c2f..cb38ac0928 100644 --- a/core/io/file_access_network.cpp +++ b/core/io/file_access_network.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -487,7 +487,6 @@ FileAccessNetwork::~FileAccessNetwork() { FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton; nc->lock_mutex(); - id = nc->last_id++; nc->accesses.erase(id); nc->unlock_mutex(); } diff --git a/core/io/file_access_network.h b/core/io/file_access_network.h index 1d9d761fbb..6cae49b540 100644 --- a/core/io/file_access_network.h +++ b/core/io/file_access_network.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index b2832b2a75..7dbea96c3d 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -70,7 +70,7 @@ void PackedData::add_path(const String &p_pkg_path, const String &p_path, uint64 String p = p_path.replace_first("res://", ""); PackedDir *cd = root; - if (p.find("/") != -1) { //in a subdir + if (p.contains("/")) { //in a subdir Vector<String> ds = p.get_base_dir().split("/"); @@ -459,7 +459,7 @@ PackedData::PackedDir *DirAccessPack::_find_dir(String p_dir) { nd = nd.simplify_path(); - if (nd == "") { + if (nd.is_empty()) { nd = "."; } diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h index 2f0ee62723..6eee2f593d 100644 --- a/core/io/file_access_pack.h +++ b/core/io/file_access_pack.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp index 53bf7456e6..6347862775 100644 --- a/core/io/file_access_zip.cpp +++ b/core/io/file_access_zip.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -189,7 +189,7 @@ bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files, uint6 f.package = pkg_num; unzGetFilePos(zfile, &f.file_pos); - String fname = String("res://") + filename_inzip; + String fname = String("res://") + String::utf8(filename_inzip); files[fname] = f; uint8_t md5[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h index cca14ded62..7cd5893101 100644 --- a/core/io/file_access_zip.h +++ b/core/io/file_access_zip.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index 800ac779e5..52b1120b2a 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -49,6 +49,14 @@ HTTPClient *HTTPClient::create() { return nullptr; } +void HTTPClient::set_http_proxy(const String &p_host, int p_port) { + WARN_PRINT("HTTP proxy feature is not available"); +} + +void HTTPClient::set_https_proxy(const String &p_host, int p_port) { + WARN_PRINT("HTTPS proxy feature is not available"); +} + Error HTTPClient::_request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const Vector<uint8_t> &p_body) { int size = p_body.size(); return request(p_method, p_url, p_headers, size > 0 ? p_body.ptr() : nullptr, size); @@ -88,6 +96,17 @@ String HTTPClient::query_string_from_dict(const Dictionary &p_dict) { return query.substr(1); } +Error HTTPClient::verify_headers(const Vector<String> &p_headers) { + for (int i = 0; i < p_headers.size(); i++) { + String sanitized = p_headers[i].strip_edges(); + ERR_FAIL_COND_V_MSG(sanitized.is_empty(), ERR_INVALID_PARAMETER, "Invalid HTTP header at index " + itos(i) + ": empty."); + ERR_FAIL_COND_V_MSG(sanitized.find(":") < 1, ERR_INVALID_PARAMETER, + "Invalid HTTP header at index " + itos(i) + ": String must contain header-value pair, delimited by ':', but was: " + p_headers[i]); + } + + return OK; +} + Dictionary HTTPClient::_get_response_headers_as_dictionary() { List<String> rh; get_response_headers(&rh); @@ -142,6 +161,9 @@ void HTTPClient::_bind_methods() { ClassDB::bind_method(D_METHOD("get_status"), &HTTPClient::get_status); ClassDB::bind_method(D_METHOD("poll"), &HTTPClient::poll); + ClassDB::bind_method(D_METHOD("set_http_proxy", "host", "port"), &HTTPClient::set_http_proxy); + ClassDB::bind_method(D_METHOD("set_https_proxy", "host", "port"), &HTTPClient::set_https_proxy); + ClassDB::bind_method(D_METHOD("query_string_from_dict", "fields"), &HTTPClient::query_string_from_dict); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "blocking_mode_enabled"), "set_blocking_mode", "is_blocking_mode_enabled"); diff --git a/core/io/http_client.h b/core/io/http_client.h index 718c3a905e..de6045f647 100644 --- a/core/io/http_client.h +++ b/core/io/http_client.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -165,6 +165,7 @@ public: static HTTPClient *create(); String query_string_from_dict(const Dictionary &p_dict); + Error verify_headers(const Vector<String> &p_headers); virtual Error request(Method p_method, const String &p_url, const Vector<String> &p_headers, const uint8_t *p_body, int p_body_size) = 0; virtual Error connect_to_host(const String &p_host, int p_port = -1, bool p_ssl = false, bool p_verify_host = true) = 0; @@ -180,7 +181,7 @@ public: virtual bool is_response_chunked() const = 0; virtual int get_response_code() const = 0; virtual Error get_response_headers(List<String> *r_response) = 0; - virtual int get_response_body_length() const = 0; + virtual int64_t get_response_body_length() const = 0; virtual PackedByteArray read_response_body_chunk() = 0; // Can't get body as partial text because of most encodings UTF8, gzip, etc. @@ -192,6 +193,10 @@ public: virtual Error poll() = 0; + // Use empty string or -1 to unset + virtual void set_http_proxy(const String &p_host, int p_port); + virtual void set_https_proxy(const String &p_host, int p_port); + HTTPClient() {} virtual ~HTTPClient() {} }; diff --git a/core/io/http_client_tcp.cpp b/core/io/http_client_tcp.cpp index b3d35b3603..f920799677 100644 --- a/core/io/http_client_tcp.cpp +++ b/core/io/http_client_tcp.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -70,9 +70,21 @@ Error HTTPClientTCP::connect_to_host(const String &p_host, int p_port, bool p_ss connection = tcp_connection; - if (conn_host.is_valid_ip_address()) { - // Host contains valid IP - Error err = tcp_connection->connect_to_host(IPAddress(conn_host), p_port); + if (ssl && https_proxy_port != -1) { + proxy_client.instantiate(); // Needs proxy negotiation. + server_host = https_proxy_host; + server_port = https_proxy_port; + } else if (!ssl && http_proxy_port != -1) { + server_host = http_proxy_host; + server_port = http_proxy_port; + } else { + server_host = conn_host; + server_port = conn_port; + } + + if (server_host.is_valid_ip_address()) { + // Host contains valid IP. + Error err = tcp_connection->connect_to_host(IPAddress(server_host), server_port); if (err) { status = STATUS_CANT_CONNECT; return err; @@ -80,8 +92,8 @@ Error HTTPClientTCP::connect_to_host(const String &p_host, int p_port, bool p_ss status = STATUS_CONNECTING; } else { - // Host contains hostname and needs to be resolved to IP - resolving = IP::get_singleton()->resolve_hostname_queue_item(conn_host); + // Host contains hostname and needs to be resolved to IP. + resolving = IP::get_singleton()->resolve_hostname_queue_item(server_host); status = STATUS_RESOLVING; } @@ -112,7 +124,7 @@ Ref<StreamPeer> HTTPClientTCP::get_connection() const { static bool _check_request_url(HTTPClientTCP::Method p_method, const String &p_url) { switch (p_method) { case HTTPClientTCP::METHOD_CONNECT: { - // Authority in host:port format, as in RFC7231 + // Authority in host:port format, as in RFC7231. int pos = p_url.find_char(':'); return 0 < pos && pos < p_url.length() - 1; } @@ -123,7 +135,7 @@ static bool _check_request_url(HTTPClientTCP::Method p_method, const String &p_u [[fallthrough]]; } default: - // Absolute path or absolute URL + // Absolute path or absolute URL. return p_url.begins_with("/") || p_url.begins_with("http://") || p_url.begins_with("https://"); } } @@ -134,7 +146,17 @@ Error HTTPClientTCP::request(Method p_method, const String &p_url, const Vector< ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(connection.is_null(), ERR_INVALID_DATA); - String request = String(_methods[p_method]) + " " + p_url + " HTTP/1.1\r\n"; + Error err = verify_headers(p_headers); + if (err) { + return err; + } + + String uri = p_url; + if (!ssl && http_proxy_port != -1) { + uri = vformat("http://%s:%d%s", conn_host, conn_port, p_url); + } + + String request = String(_methods[p_method]) + " " + uri + " HTTP/1.1\r\n"; bool add_host = true; bool add_clen = p_body_size > 0; bool add_uagent = true; @@ -156,7 +178,7 @@ Error HTTPClientTCP::request(Method p_method, const String &p_url, const Vector< } if (add_host) { if ((ssl && conn_port == PORT_HTTPS) || (!ssl && conn_port == PORT_HTTP)) { - // Don't append the standard ports + // Don't append the standard ports. request += "Host: " + conn_host + "\r\n"; } else { request += "Host: " + conn_host + ":" + itos(conn_port) + "\r\n"; @@ -175,21 +197,12 @@ Error HTTPClientTCP::request(Method p_method, const String &p_url, const Vector< request += "\r\n"; CharString cs = request.utf8(); - Vector<uint8_t> data; - data.resize(cs.length() + p_body_size); - memcpy(data.ptrw(), cs.get_data(), cs.length()); + request_buffer->clear(); + request_buffer->put_data((const uint8_t *)cs.get_data(), cs.length()); if (p_body_size > 0) { - memcpy(data.ptrw() + cs.length(), p_body, p_body_size); - } - - // TODO Implement non-blocking requests. - Error err = connection->put_data(data.ptr(), data.size()); - - if (err) { - close(); - status = STATUS_CONNECTION_ERROR; - return err; + request_buffer->put_data(p_body, p_body_size); } + request_buffer->seek(0); status = STATUS_REQUESTING; head_request = p_method == METHOD_HEAD; @@ -229,6 +242,7 @@ void HTTPClientTCP::close() { } connection.unref(); + proxy_client.unref(); status = STATUS_DISCONNECTED; head_request = false; if (resolving != IP::RESOLVER_INVALID_ID) { @@ -239,6 +253,7 @@ void HTTPClientTCP::close() { ip_candidates.clear(); response_headers.clear(); response_str.clear(); + request_buffer->clear(); body_size = -1; body_left = 0; chunk_left = 0; @@ -256,7 +271,7 @@ Error HTTPClientTCP::poll() { IP::ResolverStatus rstatus = IP::get_singleton()->get_resolve_item_status(resolving); switch (rstatus) { case IP::RESOLVER_STATUS_WAITING: - return OK; // Still resolving + return OK; // Still resolving. case IP::RESOLVER_STATUS_DONE: { ip_candidates = IP::get_singleton()->get_resolve_item_addresses(resolving); @@ -265,7 +280,7 @@ Error HTTPClientTCP::poll() { Error err = ERR_BUG; // Should be at least one entry. while (ip_candidates.size() > 0) { - err = tcp_connection->connect_to_host(ip_candidates.front(), conn_port); + err = tcp_connection->connect_to_host(ip_candidates.pop_front(), server_port); if (err == OK) { break; } @@ -294,10 +309,51 @@ Error HTTPClientTCP::poll() { return OK; } break; case StreamPeerTCP::STATUS_CONNECTED: { - if (ssl) { + if (ssl && proxy_client.is_valid()) { + Error err = proxy_client->poll(); + if (err == ERR_UNCONFIGURED) { + proxy_client->set_connection(tcp_connection); + const Vector<String> headers; + err = proxy_client->request(METHOD_CONNECT, vformat("%s:%d", conn_host, conn_port), headers, nullptr, 0); + if (err != OK) { + status = STATUS_CANT_CONNECT; + return err; + } + } else if (err != OK) { + status = STATUS_CANT_CONNECT; + return err; + } + switch (proxy_client->get_status()) { + case STATUS_REQUESTING: { + return OK; + } break; + case STATUS_BODY: { + proxy_client->read_response_body_chunk(); + return OK; + } break; + case STATUS_CONNECTED: { + if (proxy_client->get_response_code() != RESPONSE_OK) { + status = STATUS_CANT_CONNECT; + return ERR_CANT_CONNECT; + } + proxy_client.unref(); + return OK; + } + case STATUS_DISCONNECTED: + case STATUS_RESOLVING: + case STATUS_CONNECTING: { + status = STATUS_CANT_CONNECT; + ERR_FAIL_V(ERR_BUG); + } break; + default: { + status = STATUS_CANT_CONNECT; + return ERR_CANT_CONNECT; + } break; + } + } else if (ssl) { Ref<StreamPeerSSL> ssl; if (!handshaking) { - // Connect the StreamPeerSSL and start handshaking + // Connect the StreamPeerSSL and start handshaking. ssl = Ref<StreamPeerSSL>(StreamPeerSSL::create()); ssl->set_blocking_handshake_enabled(false); Error err = ssl->connect_to_stream(tcp_connection, ssl_verify_host, conn_host); @@ -309,7 +365,7 @@ Error HTTPClientTCP::poll() { connection = ssl; handshaking = true; } else { - // We are already handshaking, which means we can use your already active SSL connection + // We are already handshaking, which means we can use your already active SSL connection. ssl = static_cast<Ref<StreamPeerSSL>>(connection); if (ssl.is_null()) { close(); @@ -317,22 +373,22 @@ Error HTTPClientTCP::poll() { return ERR_CANT_CONNECT; } - ssl->poll(); // Try to finish the handshake + ssl->poll(); // Try to finish the handshake. } if (ssl->get_status() == StreamPeerSSL::STATUS_CONNECTED) { - // Handshake has been successful + // Handshake has been successful. handshaking = false; ip_candidates.clear(); status = STATUS_CONNECTED; return OK; } else if (ssl->get_status() != StreamPeerSSL::STATUS_HANDSHAKING) { - // Handshake has failed + // Handshake has failed. close(); status = STATUS_SSL_HANDSHAKE_ERROR; return ERR_CANT_CONNECT; } - // ... we will need to poll more for handshake to finish + // ... we will need to poll more for handshake to finish. } else { ip_candidates.clear(); status = STATUS_CONNECTED; @@ -344,7 +400,7 @@ Error HTTPClientTCP::poll() { Error err = ERR_CANT_CONNECT; while (ip_candidates.size() > 0) { tcp_connection->disconnect_from_host(); - err = tcp_connection->connect_to_host(ip_candidates.pop_front(), conn_port); + err = tcp_connection->connect_to_host(ip_candidates.pop_front(), server_port); if (err == OK) { return OK; } @@ -357,7 +413,7 @@ Error HTTPClientTCP::poll() { } break; case STATUS_BODY: case STATUS_CONNECTED: { - // Check if we are still connected + // Check if we are still connected. if (ssl) { Ref<StreamPeerSSL> tmp = connection; tmp->poll(); @@ -369,10 +425,34 @@ Error HTTPClientTCP::poll() { status = STATUS_CONNECTION_ERROR; return ERR_CONNECTION_ERROR; } - // Connection established, requests can now be made + // Connection established, requests can now be made. return OK; } break; case STATUS_REQUESTING: { + if (request_buffer->get_available_bytes()) { + int avail = request_buffer->get_available_bytes(); + int pos = request_buffer->get_position(); + const Vector<uint8_t> data = request_buffer->get_data_array(); + int wrote = 0; + Error err; + if (blocking) { + err = connection->put_data(data.ptr() + pos, avail); + wrote += avail; + } else { + err = connection->put_partial_data(data.ptr() + pos, avail, wrote); + } + if (err != OK) { + close(); + status = STATUS_CONNECTION_ERROR; + return ERR_CONNECTION_ERROR; + } + pos += wrote; + request_buffer->seek(pos); + if (avail - wrote > 0) { + return OK; + } + request_buffer->clear(); + } while (true) { uint8_t byte; int rec = 0; @@ -475,7 +555,7 @@ Error HTTPClientTCP::poll() { return OK; } -int HTTPClientTCP::get_response_body_length() const { +int64_t HTTPClientTCP::get_response_body_length() const { return body_size; } @@ -488,7 +568,7 @@ PackedByteArray HTTPClientTCP::read_response_body_chunk() { if (chunked) { while (true) { if (chunk_trailer_part) { - // We need to consume the trailer part too or keep-alive will break + // We need to consume the trailer part too or keep-alive will break. uint8_t b; int rec = 0; err = _get_http_data(&b, 1, rec); @@ -501,18 +581,18 @@ PackedByteArray HTTPClientTCP::read_response_body_chunk() { int cs = chunk.size(); if ((cs >= 2 && chunk[cs - 2] == '\r' && chunk[cs - 1] == '\n')) { if (cs == 2) { - // Finally over + // Finally over. chunk_trailer_part = false; status = STATUS_CONNECTED; chunk.clear(); break; } else { - // We do not process nor return the trailer data + // We do not process nor return the trailer data. chunk.clear(); } } } else if (chunk_left == 0) { - // Reading length + // Reading length. uint8_t b; int rec = 0; err = _get_http_data(&b, 1, rec); @@ -534,7 +614,7 @@ PackedByteArray HTTPClientTCP::read_response_body_chunk() { for (int i = 0; i < chunk.size() - 2; i++) { char c = chunk[i]; int v = 0; - if (c >= '0' && c <= '9') { + if (is_digit(c)) { v = c - '0'; } else if (c >= 'a' && c <= 'f') { v = c - 'a' + 10; @@ -599,7 +679,7 @@ PackedByteArray HTTPClientTCP::read_response_body_chunk() { uint8_t *w = ret.ptrw(); err = _get_http_data(w + _offset, to_read, rec); } - if (rec <= 0) { // Ended up reading less + if (rec <= 0) { // Ended up reading less. ret.resize(_offset); break; } else { @@ -620,7 +700,7 @@ PackedByteArray HTTPClientTCP::read_response_body_chunk() { close(); if (err == ERR_FILE_EOF) { - status = STATUS_DISCONNECTED; // Server disconnected + status = STATUS_DISCONNECTED; // Server disconnected. } else { status = STATUS_CONNECTION_ERROR; } @@ -678,8 +758,29 @@ int HTTPClientTCP::get_read_chunk_size() const { return read_chunk_size; } +void HTTPClientTCP::set_http_proxy(const String &p_host, int p_port) { + if (p_host.is_empty() || p_port == -1) { + http_proxy_host = ""; + http_proxy_port = -1; + } else { + http_proxy_host = p_host; + http_proxy_port = p_port; + } +} + +void HTTPClientTCP::set_https_proxy(const String &p_host, int p_port) { + if (p_host.is_empty() || p_port == -1) { + https_proxy_host = ""; + https_proxy_port = -1; + } else { + https_proxy_host = p_host; + https_proxy_port = p_port; + } +} + HTTPClientTCP::HTTPClientTCP() { tcp_connection.instantiate(); + request_buffer.instantiate(); } HTTPClient *(*HTTPClient::_create)() = HTTPClientTCP::_create_func; diff --git a/core/io/http_client_tcp.h b/core/io/http_client_tcp.h index 170afb551c..c10e0b1eca 100644 --- a/core/io/http_client_tcp.h +++ b/core/io/http_client_tcp.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -38,8 +38,14 @@ private: Status status = STATUS_DISCONNECTED; IP::ResolverID resolving = IP::RESOLVER_INVALID_ID; Array ip_candidates; - int conn_port = -1; + int conn_port = -1; // Server to make requests to. String conn_host; + int server_port = -1; // Server to connect to (might be a proxy server). + String server_host; + int http_proxy_port = -1; // Proxy server for http requests. + String http_proxy_host; + int https_proxy_port = -1; // Proxy server for https requests. + String https_proxy_host; bool ssl = false; bool ssl_verify_host = false; bool blocking = false; @@ -52,12 +58,14 @@ private: Vector<uint8_t> chunk; int chunk_left = 0; bool chunk_trailer_part = false; - int body_size = -1; - int body_left = 0; + int64_t body_size = -1; + int64_t body_left = 0; bool read_until_eof = false; + Ref<StreamPeerBuffer> request_buffer; Ref<StreamPeerTCP> tcp_connection; Ref<StreamPeer> connection; + Ref<HTTPClientTCP> proxy_client; // Negotiate with proxy server. int response_num = 0; Vector<String> response_headers; @@ -80,13 +88,15 @@ public: bool is_response_chunked() const override; int get_response_code() const override; Error get_response_headers(List<String> *r_response) override; - int get_response_body_length() const override; + int64_t get_response_body_length() const override; PackedByteArray read_response_body_chunk() override; void set_blocking_mode(bool p_enable) override; bool is_blocking_mode_enabled() const override; void set_read_chunk_size(int p_size) override; int get_read_chunk_size() const override; Error poll() override; + void set_http_proxy(const String &p_host, int p_port) override; + void set_https_proxy(const String &p_host, int p_port) override; HTTPClientTCP(); }; diff --git a/core/io/image.cpp b/core/io/image.cpp index 3f34de132f..577fc59807 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,14 +30,17 @@ #include "image.h" +#include "core/error/error_list.h" #include "core/error/error_macros.h" #include "core/io/image_loader.h" #include "core/io/resource_loader.h" #include "core/math/math_funcs.h" #include "core/string/print_string.h" #include "core/templates/hash_map.h" +#include "core/variant/dictionary.h" #include <stdio.h> +#include <cmath> const char *Image::format_names[Image::FORMAT_MAX] = { "Lum8", //luminance @@ -65,10 +68,6 @@ const char *Image::format_names[Image::FORMAT_MAX] = { "BPTC_RGBA", "BPTC_RGBF", "BPTC_RGBFU", - "PVRTC1_2", //pvrtc - "PVRTC1_2A", - "PVRTC1_4", - "PVRTC1_4A", "ETC", //etc1 "ETC2_R11", //etc2 "ETC2_R11S", //signed", NOT srgb. @@ -148,14 +147,6 @@ int Image::get_format_pixel_size(Format p_format) { return 1; //float / case FORMAT_BPTC_RGBFU: return 1; //unsigned float - case FORMAT_PVRTC1_2: - return 1; //pvrtc - case FORMAT_PVRTC1_2A: - return 1; - case FORMAT_PVRTC1_4: - return 1; - case FORMAT_PVRTC1_4A: - return 1; case FORMAT_ETC: return 1; //etc1 case FORMAT_ETC2_R11: @@ -193,16 +184,6 @@ void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) { r_w = 4; r_h = 4; } break; - case FORMAT_PVRTC1_2: - case FORMAT_PVRTC1_2A: { - r_w = 16; - r_h = 8; - } break; - case FORMAT_PVRTC1_4A: - case FORMAT_PVRTC1_4: { - r_w = 8; - r_h = 8; - } break; case FORMAT_ETC: { r_w = 4; r_h = 4; @@ -235,10 +216,8 @@ void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) { } int Image::get_format_pixel_rshift(Format p_format) { - if (p_format == FORMAT_DXT1 || p_format == FORMAT_RGTC_R || p_format == FORMAT_PVRTC1_4 || p_format == FORMAT_PVRTC1_4A || p_format == FORMAT_ETC || p_format == FORMAT_ETC2_R11 || p_format == FORMAT_ETC2_R11S || p_format == FORMAT_ETC2_RGB8 || p_format == FORMAT_ETC2_RGB8A1) { + if (p_format == FORMAT_DXT1 || p_format == FORMAT_RGTC_R || p_format == FORMAT_ETC || p_format == FORMAT_ETC2_R11 || p_format == FORMAT_ETC2_R11S || p_format == FORMAT_ETC2_RGB8 || p_format == FORMAT_ETC2_RGB8A1) { return 1; - } else if (p_format == FORMAT_PVRTC1_2 || p_format == FORMAT_PVRTC1_2A) { - return 2; } else { return 0; } @@ -254,14 +233,6 @@ int Image::get_format_block_size(Format p_format) { return 4; } - case FORMAT_PVRTC1_2: - case FORMAT_PVRTC1_2A: { - return 4; - } - case FORMAT_PVRTC1_4A: - case FORMAT_PVRTC1_4: { - return 4; - } case FORMAT_ETC: { return 4; } @@ -1466,12 +1437,11 @@ int Image::_get_dst_image_size(int p_width, int p_height, Format p_format, int & } // Set mipmap size. - // It might be necessary to put this after the minimum mipmap size check because of the possible occurrence of "1 >> 1". if (r_mm_width) { - *r_mm_width = bw >> 1; + *r_mm_width = w; } if (r_mm_height) { - *r_mm_height = bh >> 1; + *r_mm_height = h; } // Reach target mipmap. @@ -2089,7 +2059,7 @@ void Image::create(const char **p_xpm) { for (int i = 0; i < 6; i++) { char v = line_ptr[i]; - if (v >= '0' && v <= '9') { + if (is_digit(v)) { v -= '0'; } else if (v >= 'A' && v <= 'F') { v = (v - 'A') + 10; @@ -2222,8 +2192,6 @@ bool Image::is_invisible() const { } break; - case FORMAT_PVRTC1_2A: - case FORMAT_PVRTC1_4A: case FORMAT_DXT3: case FORMAT_DXT5: { detected = true; @@ -2264,8 +2232,6 @@ Image::AlphaMode Image::detect_alpha() const { } } break; - case FORMAT_PVRTC1_2A: - case FORMAT_PVRTC1_4A: case FORMAT_DXT3: case FORMAT_DXT5: { detected = true; @@ -2361,8 +2327,6 @@ Error Image::decompress() { _image_decompress_bc(this); } else if (format >= FORMAT_BPTC_RGBA && format <= FORMAT_BPTC_RGBFU && _image_decompress_bptc) { _image_decompress_bptc(this); - } else if (format >= FORMAT_PVRTC1_2 && format <= FORMAT_PVRTC1_4A && _image_decompress_pvrtc) { - _image_decompress_pvrtc(this); } else if (format == FORMAT_ETC && _image_decompress_etc1) { _image_decompress_etc1(this); } else if (format >= FORMAT_ETC2_R11 && format <= FORMAT_ETC2_RA_AS_RG && _image_decompress_etc2) { @@ -2385,10 +2349,6 @@ Error Image::compress_from_channels(CompressMode p_mode, UsedChannels p_channels ERR_FAIL_COND_V(!_image_compress_bc_func, ERR_UNAVAILABLE); _image_compress_bc_func(this, p_lossy_quality, p_channels); } break; - case COMPRESS_PVRTC1_4: { - ERR_FAIL_COND_V(!_image_compress_pvrtc1_4bpp_func, ERR_UNAVAILABLE); - _image_compress_pvrtc1_4bpp_func(this); - } break; case COMPRESS_ETC: { ERR_FAIL_COND_V(!_image_compress_etc1_func, ERR_UNAVAILABLE); _image_compress_etc1_func(this, p_lossy_quality); @@ -2752,10 +2712,8 @@ ImageMemLoadFunc Image::_bmp_mem_loader_func = nullptr; void (*Image::_image_compress_bc_func)(Image *, float, Image::UsedChannels) = nullptr; void (*Image::_image_compress_bptc_func)(Image *, float, Image::UsedChannels) = nullptr; -void (*Image::_image_compress_pvrtc1_4bpp_func)(Image *) = nullptr; void (*Image::_image_compress_etc1_func)(Image *, float) = nullptr; void (*Image::_image_compress_etc2_func)(Image *, float, Image::UsedChannels) = nullptr; -void (*Image::_image_decompress_pvrtc)(Image *) = nullptr; void (*Image::_image_decompress_bc)(Image *) = nullptr; void (*Image::_image_decompress_bptc)(Image *) = nullptr; void (*Image::_image_decompress_etc1)(Image *) = nullptr; @@ -3180,6 +3138,8 @@ void Image::_bind_methods() { ClassDB::bind_method(D_METHOD("rgbe_to_srgb"), &Image::rgbe_to_srgb); ClassDB::bind_method(D_METHOD("bump_map_to_normal_map", "bump_scale"), &Image::bump_map_to_normal_map, DEFVAL(1.0)); + ClassDB::bind_method(D_METHOD("compute_image_metrics", "compared_image", "use_luma"), &Image::compute_image_metrics); + ClassDB::bind_method(D_METHOD("blit_rect", "src", "src_rect", "dst"), &Image::blit_rect); ClassDB::bind_method(D_METHOD("blit_rect_mask", "src", "mask", "src_rect", "dst"), &Image::blit_rect_mask); ClassDB::bind_method(D_METHOD("blend_rect", "src", "src_rect", "dst"), &Image::blend_rect); @@ -3238,10 +3198,6 @@ void Image::_bind_methods() { BIND_ENUM_CONSTANT(FORMAT_BPTC_RGBA); //btpc bc6h BIND_ENUM_CONSTANT(FORMAT_BPTC_RGBF); //float / BIND_ENUM_CONSTANT(FORMAT_BPTC_RGBFU); //unsigned float - BIND_ENUM_CONSTANT(FORMAT_PVRTC1_2); //pvrtc - BIND_ENUM_CONSTANT(FORMAT_PVRTC1_2A); - BIND_ENUM_CONSTANT(FORMAT_PVRTC1_4); - BIND_ENUM_CONSTANT(FORMAT_PVRTC1_4A); BIND_ENUM_CONSTANT(FORMAT_ETC); //etc1 BIND_ENUM_CONSTANT(FORMAT_ETC2_R11); //etc2 BIND_ENUM_CONSTANT(FORMAT_ETC2_R11S); //signed ); NOT srgb. @@ -3265,7 +3221,6 @@ void Image::_bind_methods() { BIND_ENUM_CONSTANT(ALPHA_BLEND); BIND_ENUM_CONSTANT(COMPRESS_S3TC); - BIND_ENUM_CONSTANT(COMPRESS_PVRTC1_4); BIND_ENUM_CONSTANT(COMPRESS_ETC); BIND_ENUM_CONSTANT(COMPRESS_ETC2); BIND_ENUM_CONSTANT(COMPRESS_BPTC); @@ -3670,3 +3625,128 @@ Ref<Resource> Image::duplicate(bool p_subresources) const { void Image::set_as_black() { memset(data.ptrw(), 0, data.size()); } + +Dictionary Image::compute_image_metrics(const Ref<Image> p_compared_image, bool p_luma_metric) { + // https://github.com/richgel999/bc7enc_rdo/blob/master/LICENSE + // + // This is free and unencumbered software released into the public domain. + // Anyone is free to copy, modify, publish, use, compile, sell, or distribute this + // software, either in source code form or as a compiled binary, for any purpose, + // commercial or non - commercial, and by any means. + // In jurisdictions that recognize copyright laws, the author or authors of this + // software dedicate any and all copyright interest in the software to the public + // domain. We make this dedication for the benefit of the public at large and to + // the detriment of our heirs and successors. We intend this dedication to be an + // overt act of relinquishment in perpetuity of all present and future rights to + // this software under copyright law. + // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE + // AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Dictionary result; + result["max"] = INFINITY; + result["mean"] = INFINITY; + result["mean_squared"] = INFINITY; + result["root_mean_squared"] = INFINITY; + result["peak_snr"] = 0.0f; + + ERR_FAIL_NULL_V(p_compared_image, result); + Error err = OK; + Ref<Image> compared_image = duplicate(true); + if (compared_image->is_compressed()) { + err = compared_image->decompress(); + } + ERR_FAIL_COND_V(err != OK, result); + Ref<Image> source_image = p_compared_image->duplicate(true); + if (source_image->is_compressed()) { + err = source_image->decompress(); + } + ERR_FAIL_COND_V(err != OK, result); + + ERR_FAIL_COND_V(err != OK, result); + + ERR_FAIL_COND_V_MSG((compared_image->get_format() >= Image::FORMAT_RH) && (compared_image->get_format() <= Image::FORMAT_RGBE9995), result, "Metrics on HDR images are not supported."); + ERR_FAIL_COND_V_MSG((source_image->get_format() >= Image::FORMAT_RH) && (source_image->get_format() <= Image::FORMAT_RGBE9995), result, "Metrics on HDR images are not supported."); + + double image_metric_max, image_metric_mean, image_metric_mean_squared, image_metric_root_mean_squared, image_metric_peak_snr = 0.0; + const bool average_component_error = true; + + const uint32_t width = MIN(compared_image->get_width(), source_image->get_width()); + const uint32_t height = MIN(compared_image->get_height(), source_image->get_height()); + + // Histogram approach originally due to Charles Bloom. + double hist[256]; + memset(hist, 0, sizeof(hist)); + + for (uint32_t y = 0; y < height; y++) { + for (uint32_t x = 0; x < width; x++) { + const Color color_a = compared_image->get_pixel(x, y); + + const Color color_b = source_image->get_pixel(x, y); + + if (!p_luma_metric) { + ERR_FAIL_COND_V_MSG(color_a.r > 1.0f, Dictionary(), "Can't compare HDR colors."); + ERR_FAIL_COND_V_MSG(color_b.r > 1.0f, Dictionary(), "Can't compare HDR colors."); + hist[Math::abs(color_a.get_r8() - color_b.get_r8())]++; + ERR_FAIL_COND_V_MSG(color_a.g > 1.0f, Dictionary(), "Can't compare HDR colors."); + ERR_FAIL_COND_V_MSG(color_b.g > 1.0f, Dictionary(), "Can't compare HDR colors."); + hist[Math::abs(color_a.get_g8() - color_b.get_g8())]++; + ERR_FAIL_COND_V_MSG(color_a.b > 1.0f, Dictionary(), "Can't compare HDR colors."); + ERR_FAIL_COND_V_MSG(color_b.b > 1.0f, Dictionary(), "Can't compare HDR colors."); + hist[Math::abs(color_a.get_b8() - color_b.get_b8())]++; + ERR_FAIL_COND_V_MSG(color_a.a > 1.0f, Dictionary(), "Can't compare HDR colors."); + ERR_FAIL_COND_V_MSG(color_b.a > 1.0f, Dictionary(), "Can't compare HDR colors."); + hist[Math::abs(color_a.get_a8() - color_b.get_a8())]++; + } else { + ERR_FAIL_COND_V_MSG(color_a.r > 1.0f, Dictionary(), "Can't compare HDR colors."); + ERR_FAIL_COND_V_MSG(color_b.r > 1.0f, Dictionary(), "Can't compare HDR colors."); + // REC709 weightings + int luma_a = (13938U * color_a.get_r8() + 46869U * color_a.get_g8() + 4729U * color_a.get_b8() + 32768U) >> 16U; + int luma_b = (13938U * color_b.get_r8() + 46869U * color_b.get_g8() + 4729U * color_b.get_b8() + 32768U) >> 16U; + hist[Math::abs(luma_a - luma_b)]++; + } + } + } + + image_metric_max = 0; + double sum = 0.0f, sum2 = 0.0f; + for (uint32_t i = 0; i < 256; i++) { + if (!hist[i]) { + continue; + } + + image_metric_max = MAX(image_metric_max, i); + + double x = i * hist[i]; + + sum += x; + sum2 += i * x; + } + + // See http://richg42.blogspot.com/2016/09/how-to-compute-psnr-from-old-berkeley.html + double total_values = width * height; + + if (average_component_error) { + total_values *= 4; + } + + image_metric_mean = CLAMP(sum / total_values, 0.0f, 255.0f); + image_metric_mean_squared = CLAMP(sum2 / total_values, 0.0f, 255.0f * 255.0f); + + image_metric_root_mean_squared = sqrt(image_metric_mean_squared); + + if (!image_metric_root_mean_squared) { + image_metric_peak_snr = 1e+10f; + } else { + image_metric_peak_snr = CLAMP(log10(255.0f / image_metric_root_mean_squared) * 20.0f, 0.0f, 500.0f); + } + result["max"] = image_metric_max; + result["mean"] = image_metric_mean; + result["mean_squared"] = image_metric_mean_squared; + result["root_mean_squared"] = image_metric_root_mean_squared; + result["peak_snr"] = image_metric_peak_snr; + return result; +} diff --git a/core/io/image.h b/core/io/image.h index 9023463b08..53bfa0881f 100644 --- a/core/io/image.h +++ b/core/io/image.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -36,8 +36,6 @@ #include "core/math/rect2.h" /** - * @author Juan Linietsky <reduzio@gmail.com> - * * Image storage class. This is used to store an image in user memory, as well as * providing some basic methods for image manipulation. * Images can be loaded from a file, or registered into the Render object as textures. @@ -91,10 +89,6 @@ public: FORMAT_BPTC_RGBA, //btpc bc7 FORMAT_BPTC_RGBF, //float bc6h FORMAT_BPTC_RGBFU, //unsigned float bc6hu - FORMAT_PVRTC1_2, //pvrtc1 - FORMAT_PVRTC1_2A, - FORMAT_PVRTC1_4, - FORMAT_PVRTC1_4A, FORMAT_ETC, //etc1 FORMAT_ETC2_R11, //etc2 FORMAT_ETC2_R11S, //signed, NOT srgb. @@ -138,11 +132,9 @@ public: static void (*_image_compress_bc_func)(Image *, float, UsedChannels p_channels); static void (*_image_compress_bptc_func)(Image *, float p_lossy_quality, UsedChannels p_channels); - static void (*_image_compress_pvrtc1_4bpp_func)(Image *); static void (*_image_compress_etc1_func)(Image *, float); static void (*_image_compress_etc2_func)(Image *, float, UsedChannels p_channels); - static void (*_image_decompress_pvrtc)(Image *); static void (*_image_decompress_bc)(Image *); static void (*_image_decompress_bptc)(Image *); static void (*_image_decompress_etc1)(Image *); @@ -334,7 +326,6 @@ public: enum CompressMode { COMPRESS_S3TC, - COMPRESS_PVRTC1_4, COMPRESS_ETC, COMPRESS_ETC2, COMPRESS_BPTC, @@ -408,6 +399,8 @@ public: mipmaps = p_image->mipmaps; data = p_image->data; } + + Dictionary compute_image_metrics(const Ref<Image> p_compared_image, bool p_luma_metric = true); }; VARIANT_ENUM_CAST(Image::Format) diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp index b9fc416f65..5518ec8ceb 100644 --- a/core/io/image_loader.cpp +++ b/core/io/image_loader.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/image_loader.h b/core/io/image_loader.h index 6d1b1e3646..37d7620f96 100644 --- a/core/io/image_loader.h +++ b/core/io/image_loader.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/ip.cpp b/core/io/ip.cpp index 68b4e4b354..8e0d47e762 100644 --- a/core/io/ip.cpp +++ b/core/io/ip.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -98,6 +98,11 @@ struct _IP_ResolverPrivate { if (queue[i].status.get() != IP::RESOLVER_STATUS_WAITING) { continue; } + // We might be overriding another result, but we don't care as long as the result is valid. + if (response.size()) { + String key = get_cache_key(hostname, type); + cache[key] = response; + } queue[i].response = response; queue[i].status.set(response.is_empty() ? IP::RESOLVER_STATUS_ERROR : IP::RESOLVER_STATUS_DONE); } @@ -120,30 +125,8 @@ struct _IP_ResolverPrivate { }; IPAddress IP::resolve_hostname(const String &p_hostname, IP::Type p_type) { - List<IPAddress> res; - String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type); - - resolver->mutex.lock(); - if (resolver->cache.has(key)) { - res = resolver->cache[key]; - } else { - // This should be run unlocked so the resolver thread can keep - // resolving other requests. - resolver->mutex.unlock(); - _resolve_hostname(res, p_hostname, p_type); - resolver->mutex.lock(); - // We might be overriding another result, but we don't care (they are the - // same hostname). - resolver->cache[key] = res; - } - resolver->mutex.unlock(); - - for (int i = 0; i < res.size(); ++i) { - if (res[i].is_valid()) { - return res[i]; - } - } - return IPAddress(); + const Array addresses = resolve_hostname_addresses(p_hostname, p_type); + return addresses.size() ? addresses[0].operator IPAddress() : IPAddress(); } Array IP::resolve_hostname_addresses(const String &p_hostname, Type p_type) { @@ -159,17 +142,16 @@ Array IP::resolve_hostname_addresses(const String &p_hostname, Type p_type) { resolver->mutex.unlock(); _resolve_hostname(res, p_hostname, p_type); resolver->mutex.lock(); - // We might be overriding another result, but we don't care (they are the - // same hostname). - resolver->cache[key] = res; + // We might be overriding another result, but we don't care as long as the result is valid. + if (res.size()) { + resolver->cache[key] = res; + } } resolver->mutex.unlock(); Array result; for (int i = 0; i < res.size(); ++i) { - if (res[i].is_valid()) { - result.push_back(String(res[i])); - } + result.push_back(String(res[i])); } return result; } diff --git a/core/io/ip.h b/core/io/ip.h index 3c6040a1f0..5602710550 100644 --- a/core/io/ip.h +++ b/core/io/ip.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/ip_address.cpp b/core/io/ip_address.cpp index 1c1ac8a88f..d183c60798 100644 --- a/core/io/ip_address.cpp +++ b/core/io/ip_address.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -71,7 +71,7 @@ static void _parse_hex(const String &p_string, int p_start, uint8_t *p_dst) { int n = 0; char32_t c = p_string[i]; - if (c >= '0' && c <= '9') { + if (is_digit(c)) { n = c - '0'; } else if (c >= 'a' && c <= 'f') { n = 10 + (c - 'a'); @@ -113,7 +113,7 @@ void IPAddress::_parse_ipv6(const String &p_string) { } else if (c == '.') { part_ipv4 = true; - } else if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { + } else if (is_hex_digit(c)) { if (!part_found) { parts[parts_idx++] = i; part_found = true; diff --git a/core/io/ip_address.h b/core/io/ip_address.h index 05da675704..dc0c19bf48 100644 --- a/core/io/ip_address.h +++ b/core/io/ip_address.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/json.cpp b/core/io/json.cpp index 5823afbdcd..4b745dff44 100644 --- a/core/io/json.cpp +++ b/core/io/json.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -229,12 +229,12 @@ Error JSON::_get_token(const char32_t *p_str, int &index, int p_len, Token &r_to r_err_str = "Unterminated String"; return ERR_PARSE_ERROR; } - if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) { + if (!is_hex_digit(c)) { r_err_str = "Malformed hex constant in string"; return ERR_PARSE_ERROR; } char32_t v; - if (c >= '0' && c <= '9') { + if (is_digit(c)) { v = c - '0'; } else if (c >= 'a' && c <= 'f') { v = c - 'a'; @@ -265,12 +265,12 @@ Error JSON::_get_token(const char32_t *p_str, int &index, int p_len, Token &r_to r_err_str = "Unterminated String"; return ERR_PARSE_ERROR; } - if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) { + if (!is_hex_digit(c)) { r_err_str = "Malformed hex constant in string"; return ERR_PARSE_ERROR; } char32_t v; - if (c >= '0' && c <= '9') { + if (is_digit(c)) { v = c - '0'; } else if (c >= 'a' && c <= 'f') { v = c - 'a'; @@ -326,7 +326,7 @@ Error JSON::_get_token(const char32_t *p_str, int &index, int p_len, Token &r_to break; } - if (p_str[index] == '-' || (p_str[index] >= '0' && p_str[index] <= '9')) { + if (p_str[index] == '-' || is_digit(p_str[index])) { //a number const char32_t *rptr; double number = String::to_float(&p_str[index], &rptr); @@ -335,10 +335,10 @@ Error JSON::_get_token(const char32_t *p_str, int &index, int p_len, Token &r_to r_token.value = number; return OK; - } else if ((p_str[index] >= 'A' && p_str[index] <= 'Z') || (p_str[index] >= 'a' && p_str[index] <= 'z')) { + } else if (is_ascii_char(p_str[index])) { String id; - while ((p_str[index] >= 'A' && p_str[index] <= 'Z') || (p_str[index] >= 'a' && p_str[index] <= 'z')) { + while (is_ascii_char(p_str[index])) { id += p_str[index]; index++; } diff --git a/core/io/json.h b/core/io/json.h index f20c97f540..ed251938ec 100644 --- a/core/io/json.h +++ b/core/io/json.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/logger.cpp b/core/io/logger.cpp index 8a8bdf07d3..cb6369ae3d 100644 --- a/core/io/logger.cpp +++ b/core/io/logger.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -136,7 +136,7 @@ void RotatedFileLogger::clear_old_backups() { da->list_dir_begin(); String f = da->get_next(); Set<String> backups; - while (f != String()) { + while (!f.is_empty()) { if (!da->current_is_dir() && f.begins_with(basename) && f.get_extension() == extension && f != base_path.get_file()) { backups.insert(f); } @@ -163,7 +163,7 @@ void RotatedFileLogger::rotate_file() { if (max_files > 1) { String timestamp = Time::get_singleton()->get_datetime_string_from_system().replace(":", "."); String backup_name = base_path.get_basename() + timestamp; - if (base_path.get_extension() != String()) { + if (!base_path.get_extension().is_empty()) { backup_name += "." + base_path.get_extension(); } diff --git a/core/io/logger.h b/core/io/logger.h index 48b073aa45..047ee3d0f1 100644 --- a/core/io/logger.h +++ b/core/io/logger.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index e7d5b78d14..a363cc3694 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -52,9 +52,8 @@ ObjectID EncodedObjectAsID::get_object_id() const { return id; } -#define _S(a) ((int32_t)a) -#define ERR_FAIL_ADD_OF(a, b, err) ERR_FAIL_COND_V(_S(b) < 0 || _S(a) < 0 || _S(a) > INT_MAX - _S(b), err) -#define ERR_FAIL_MUL_OF(a, b, err) ERR_FAIL_COND_V(_S(a) < 0 || _S(b) <= 0 || _S(a) > INT_MAX / _S(b), err) +#define ERR_FAIL_ADD_OF(a, b, err) ERR_FAIL_COND_V(((int32_t)(b)) < 0 || ((int32_t)(a)) < 0 || ((int32_t)(a)) > INT_MAX - ((int32_t)(b)), err) +#define ERR_FAIL_MUL_OF(a, b, err) ERR_FAIL_COND_V(((int32_t)(a)) < 0 || ((int32_t)(b)) <= 0 || ((int32_t)(a)) > INT_MAX / ((int32_t)(b)), err) #define ENCODE_MASK 0xFF #define ENCODE_FLAG_64 1 << 16 @@ -562,7 +561,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int return err; } - if (str == String()) { + if (str.is_empty()) { r_variant = (Object *)nullptr; } else { Object *obj = ClassDB::instantiate(str); @@ -1031,7 +1030,7 @@ static void _encode_string(const String &p_string, uint8_t *&buf, int &r_len) { } Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_full_objects, int p_depth) { - ERR_FAIL_COND_V_MSG(p_depth > Variant::MAX_RECURSION_DEPTH, ERR_OUT_OF_MEMORY, "Potential inifite recursion detected. Bailing."); + ERR_FAIL_COND_V_MSG(p_depth > Variant::MAX_RECURSION_DEPTH, ERR_OUT_OF_MEMORY, "Potential infinite recursion detected. Bailing."); uint8_t *buf = r_buffer; r_len = 0; diff --git a/core/io/marshalls.h b/core/io/marshalls.h index 9ea060e48c..4d7b98b749 100644 --- a/core/io/marshalls.h +++ b/core/io/marshalls.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/net_socket.cpp b/core/io/net_socket.cpp index b51d26ba83..3e5246a134 100644 --- a/core/io/net_socket.cpp +++ b/core/io/net_socket.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/net_socket.h b/core/io/net_socket.h index fd7d50c704..23eff17a61 100644 --- a/core/io/net_socket.h +++ b/core/io/net_socket.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/packed_data_container.cpp b/core/io/packed_data_container.cpp index d34b5b6fe3..14183b472b 100644 --- a/core/io/packed_data_container.cpp +++ b/core/io/packed_data_container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/packed_data_container.h b/core/io/packed_data_container.h index 40772bb2bf..f042b364ee 100644 --- a/core/io/packed_data_container.h +++ b/core/io/packed_data_container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp index 87d2b66e5b..0af236f766 100644 --- a/core/io/packet_peer.cpp +++ b/core/io/packet_peer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -39,7 +39,7 @@ void PacketPeer::set_encode_buffer_max_size(int p_max_size) { ERR_FAIL_COND_MSG(p_max_size < 1024, "Max encode buffer must be at least 1024 bytes"); ERR_FAIL_COND_MSG(p_max_size > 256 * 1024 * 1024, "Max encode buffer cannot exceed 256 MiB"); encode_buffer_max_size = next_power_of_2(p_max_size); - encode_buffer.resize(0); + encode_buffer.clear(); } int PacketPeer::get_encode_buffer_max_size() const { diff --git a/core/io/packet_peer.h b/core/io/packet_peer.h index bc1f4aaabf..0b12640627 100644 --- a/core/io/packet_peer.h +++ b/core/io/packet_peer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/packet_peer_dtls.cpp b/core/io/packet_peer_dtls.cpp index a6d220622b..3c7ab28e12 100644 --- a/core/io/packet_peer_dtls.cpp +++ b/core/io/packet_peer_dtls.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/packet_peer_dtls.h b/core/io/packet_peer_dtls.h index 31c52f539f..c5443d043e 100644 --- a/core/io/packet_peer_dtls.h +++ b/core/io/packet_peer_dtls.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/packet_peer_udp.cpp b/core/io/packet_peer_udp.cpp index f951a5158c..503eb17cae 100644 --- a/core/io/packet_peer_udp.cpp +++ b/core/io/packet_peer_udp.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/packet_peer_udp.h b/core/io/packet_peer_udp.h index 40d3c44e40..444a6dd5ba 100644 --- a/core/io/packet_peer_udp.h +++ b/core/io/packet_peer_udp.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp index 8d75581342..272ace3438 100644 --- a/core/io/pck_packer.cpp +++ b/core/io/pck_packer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -62,7 +62,7 @@ Error PCKPacker::pck_start(const String &p_file, int p_alignment, const String & int v = 0; if (i * 2 < _key.length()) { char32_t ct = _key[i * 2]; - if (ct >= '0' && ct <= '9') { + if (is_digit(ct)) { ct = ct - '0'; } else if (ct >= 'a' && ct <= 'f') { ct = 10 + ct - 'a'; @@ -72,7 +72,7 @@ Error PCKPacker::pck_start(const String &p_file, int p_alignment, const String & if (i * 2 + 1 < _key.length()) { char32_t ct = _key[i * 2 + 1]; - if (ct >= '0' && ct <= '9') { + if (is_digit(ct)) { ct = ct - '0'; } else if (ct >= 'a' && ct <= 'f') { ct = 10 + ct - 'a'; diff --git a/core/io/pck_packer.h b/core/io/pck_packer.h index bd8902a01d..583171a70b 100644 --- a/core/io/pck_packer.h +++ b/core/io/pck_packer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/resource.cpp b/core/io/resource.cpp index 972076e397..66d5c54b53 100644 --- a/core/io/resource.cpp +++ b/core/io/resource.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -52,7 +52,7 @@ void Resource::set_path(const String &p_path, bool p_take_over) { return; } - if (path_cache != "") { + if (!path_cache.is_empty()) { ResourceCache::lock.write_lock(); ResourceCache::resources.erase(path_cache); ResourceCache::lock.write_unlock(); @@ -82,7 +82,7 @@ void Resource::set_path(const String &p_path, bool p_take_over) { } path_cache = p_path; - if (path_cache != "") { + if (!path_cache.is_empty()) { ResourceCache::lock.write_lock(); ResourceCache::resources[path_cache] = this; ResourceCache::lock.write_unlock(); @@ -383,7 +383,7 @@ bool Resource::is_translation_remapped() const { #ifdef TOOLS_ENABLED //helps keep IDs same number when loading/saving scenes. -1 clears ID and it Returns -1 when no id stored void Resource::set_id_for_path(const String &p_path, const String &p_id) { - if (p_id == "") { + if (p_id.is_empty()) { ResourceCache::path_cache_lock.write_lock(); ResourceCache::resource_path_cache[p_path].erase(get_path()); ResourceCache::path_cache_lock.write_unlock(); @@ -434,7 +434,7 @@ Resource::Resource() : remapped_list(this) {} Resource::~Resource() { - if (path_cache != "") { + if (!path_cache.is_empty()) { ResourceCache::lock.write_lock(); ResourceCache::resources.erase(path_cache); ResourceCache::lock.write_unlock(); @@ -520,8 +520,8 @@ void ResourceCache::dump(const char *p_file, bool p_short) { FileAccess *f = nullptr; if (p_file) { - f = FileAccess::open(p_file, FileAccess::WRITE); - ERR_FAIL_COND_MSG(!f, "Cannot create file at path '" + String(p_file) + "'."); + f = FileAccess::open(String::utf8(p_file), FileAccess::WRITE); + ERR_FAIL_COND_MSG(!f, "Cannot create file at path '" + String::utf8(p_file) + "'."); } const String *K = nullptr; diff --git a/core/io/resource.h b/core/io/resource.h index 109c0f6611..b1e1c15541 100644 --- a/core/io/resource.h +++ b/core/io/resource.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -37,6 +37,8 @@ #include "core/templates/safe_refcount.h" #include "core/templates/self_list.h" +class Node; + #define RES_BASE_EXTENSION(m_ext) \ public: \ static void register_custom_data_to_otdb() { ClassDB::add_resource_base_extension(m_ext, get_class_static()); } \ @@ -103,7 +105,7 @@ public: virtual void set_path(const String &p_path, bool p_take_over = false); String get_path() const; - _FORCE_INLINE_ bool is_built_in() const { return path_cache.is_empty() || path_cache.find("::") != -1 || path_cache.begins_with("local://"); } + _FORCE_INLINE_ bool is_built_in() const { return path_cache.is_empty() || path_cache.contains("::") || path_cache.begins_with("local://"); } static String generate_scene_unique_id(); void set_scene_unique_id(const String &p_id); diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index a5a195f859..8588bab0be 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -53,9 +53,9 @@ enum { VARIANT_PLANE = 13, VARIANT_QUATERNION = 14, VARIANT_AABB = 15, - VARIANT_MATRIX3 = 16, - VARIANT_TRANSFORM = 17, - VARIANT_MATRIX32 = 18, + VARIANT_BASIS = 16, + VARIANT_TRANSFORM3D = 17, + VARIANT_TRANSFORM2D = 18, VARIANT_COLOR = 20, VARIANT_NODE_PATH = 22, VARIANT_RID = 23, @@ -63,13 +63,13 @@ enum { VARIANT_INPUT_EVENT = 25, VARIANT_DICTIONARY = 26, VARIANT_ARRAY = 30, - VARIANT_RAW_ARRAY = 31, - VARIANT_INT32_ARRAY = 32, - VARIANT_FLOAT32_ARRAY = 33, - VARIANT_STRING_ARRAY = 34, - VARIANT_VECTOR3_ARRAY = 35, - VARIANT_COLOR_ARRAY = 36, - VARIANT_VECTOR2_ARRAY = 37, + VARIANT_PACKED_BYTE_ARRAY = 31, + VARIANT_PACKED_INT32_ARRAY = 32, + VARIANT_PACKED_FLOAT32_ARRAY = 33, + VARIANT_PACKED_STRING_ARRAY = 34, + VARIANT_PACKED_VECTOR3_ARRAY = 35, + VARIANT_PACKED_COLOR_ARRAY = 36, + VARIANT_PACKED_VECTOR2_ARRAY = 37, VARIANT_INT64 = 40, VARIANT_DOUBLE = 41, VARIANT_CALLABLE = 42, @@ -78,8 +78,8 @@ enum { VARIANT_VECTOR2I = 45, VARIANT_RECT2I = 46, VARIANT_VECTOR3I = 47, - VARIANT_INT64_ARRAY = 48, - VARIANT_FLOAT64_ARRAY = 49, + VARIANT_PACKED_INT64_ARRAY = 48, + VARIANT_PACKED_FLOAT64_ARRAY = 49, OBJECT_EMPTY = 0, OBJECT_EXTERNAL_RESOURCE = 1, OBJECT_INTERNAL_RESOURCE = 2, @@ -220,7 +220,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = v; } break; - case VARIANT_MATRIX32: { + case VARIANT_TRANSFORM2D: { Transform2D v; v.elements[0].x = f->get_real(); v.elements[0].y = f->get_real(); @@ -231,7 +231,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = v; } break; - case VARIANT_MATRIX3: { + case VARIANT_BASIS: { Basis v; v.elements[0].x = f->get_real(); v.elements[0].y = f->get_real(); @@ -245,7 +245,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = v; } break; - case VARIANT_TRANSFORM: { + case VARIANT_TRANSFORM3D: { Transform3D v; v.basis.elements[0].x = f->get_real(); v.basis.elements[0].y = f->get_real(); @@ -335,7 +335,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { String exttype = get_unicode_string(); String path = get_unicode_string(); - if (path.find("://") == -1 && path.is_relative_path()) { + if (!path.contains("://") && path.is_relative_path()) { // path is relative to file being loaded, so convert to a resource path path = ProjectSettings::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path)); } @@ -422,7 +422,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = a; } break; - case VARIANT_RAW_ARRAY: { + case VARIANT_PACKED_BYTE_ARRAY: { uint32_t len = f->get_32(); Vector<uint8_t> array; @@ -434,7 +434,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_INT32_ARRAY: { + case VARIANT_PACKED_INT32_ARRAY: { uint32_t len = f->get_32(); Vector<int32_t> array; @@ -453,7 +453,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_INT64_ARRAY: { + case VARIANT_PACKED_INT64_ARRAY: { uint32_t len = f->get_32(); Vector<int64_t> array; @@ -472,7 +472,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_FLOAT32_ARRAY: { + case VARIANT_PACKED_FLOAT32_ARRAY: { uint32_t len = f->get_32(); Vector<float> array; @@ -491,7 +491,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_FLOAT64_ARRAY: { + case VARIANT_PACKED_FLOAT64_ARRAY: { uint32_t len = f->get_32(); Vector<double> array; @@ -510,7 +510,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_STRING_ARRAY: { + case VARIANT_PACKED_STRING_ARRAY: { uint32_t len = f->get_32(); Vector<String> array; array.resize(len); @@ -522,7 +522,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_VECTOR2_ARRAY: { + case VARIANT_PACKED_VECTOR2_ARRAY: { uint32_t len = f->get_32(); Vector<Vector2> array; @@ -547,7 +547,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_VECTOR3_ARRAY: { + case VARIANT_PACKED_VECTOR3_ARRAY: { uint32_t len = f->get_32(); Vector<Vector3> array; @@ -572,7 +572,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = array; } break; - case VARIANT_COLOR_ARRAY: { + case VARIANT_PACKED_COLOR_ARRAY: { uint32_t len = f->get_32(); Vector<Color> array; @@ -626,7 +626,7 @@ Error ResourceLoaderBinary::load() { path = remaps[path]; } - if (path.find("://") == -1 && path.is_relative_path()) { + if (!path.contains("://") && path.is_relative_path()) { // path is relative to file being loaded, so convert to a resource path path = ProjectSettings::get_singleton()->localize_path(path.get_base_dir().plus_file(external_resources[i].path)); } @@ -727,7 +727,7 @@ Error ResourceLoaderBinary::load() { } res = RES(r); - if (path != String() && cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) { + if (!path.is_empty() && cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) { r->set_path(path, cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE); //if got here because the resource with same path has different type, replace it } r->set_scene_unique_id(id); @@ -829,7 +829,7 @@ void ResourceLoaderBinary::get_dependencies(FileAccess *p_f, List<String> *p_dep dep = external_resources[i].path; } - if (p_add_types && external_resources[i].type != String()) { + if (p_add_types && !external_resources[i].type.is_empty()) { dep += "::" + external_resources[i].type; } @@ -1026,7 +1026,7 @@ RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_origi loader.cache_mode = p_cache_mode; loader.use_sub_threads = p_use_sub_threads; loader.progress = r_progress; - String path = p_original_path != "" ? p_original_path : p_path; + String path = !p_original_path.is_empty() ? p_original_path : p_path; loader.local_path = ProjectSettings::get_singleton()->localize_path(path); loader.res_path = loader.local_path; //loader.set_local_path( Globals::get_singleton()->localize_path(p_path) ); @@ -1045,7 +1045,7 @@ RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_origi } void ResourceFormatLoaderBinary::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const { - if (p_type == "") { + if (p_type.is_empty()) { get_recognized_extensions(p_extensions); return; } @@ -1476,7 +1476,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::TRANSFORM2D: { - f->store_32(VARIANT_MATRIX32); + f->store_32(VARIANT_TRANSFORM2D); Transform2D val = p_property; f->store_real(val.elements[0].x); f->store_real(val.elements[0].y); @@ -1487,7 +1487,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::BASIS: { - f->store_32(VARIANT_MATRIX3); + f->store_32(VARIANT_BASIS); Basis val = p_property; f->store_real(val.elements[0].x); f->store_real(val.elements[0].y); @@ -1501,7 +1501,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::TRANSFORM3D: { - f->store_32(VARIANT_TRANSFORM); + f->store_32(VARIANT_TRANSFORM3D); Transform3D val = p_property; f->store_real(val.basis.elements[0].x); f->store_real(val.basis.elements[0].y); @@ -1625,7 +1625,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_BYTE_ARRAY: { - f->store_32(VARIANT_RAW_ARRAY); + f->store_32(VARIANT_PACKED_BYTE_ARRAY); Vector<uint8_t> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1635,7 +1635,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_INT32_ARRAY: { - f->store_32(VARIANT_INT32_ARRAY); + f->store_32(VARIANT_PACKED_INT32_ARRAY); Vector<int32_t> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1646,7 +1646,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_INT64_ARRAY: { - f->store_32(VARIANT_INT64_ARRAY); + f->store_32(VARIANT_PACKED_INT64_ARRAY); Vector<int64_t> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1657,7 +1657,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_FLOAT32_ARRAY: { - f->store_32(VARIANT_FLOAT32_ARRAY); + f->store_32(VARIANT_PACKED_FLOAT32_ARRAY); Vector<float> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1668,7 +1668,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_FLOAT64_ARRAY: { - f->store_32(VARIANT_FLOAT64_ARRAY); + f->store_32(VARIANT_PACKED_FLOAT64_ARRAY); Vector<double> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1679,7 +1679,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_STRING_ARRAY: { - f->store_32(VARIANT_STRING_ARRAY); + f->store_32(VARIANT_PACKED_STRING_ARRAY); Vector<String> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1690,7 +1690,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_VECTOR3_ARRAY: { - f->store_32(VARIANT_VECTOR3_ARRAY); + f->store_32(VARIANT_PACKED_VECTOR3_ARRAY); Vector<Vector3> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1703,7 +1703,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_VECTOR2_ARRAY: { - f->store_32(VARIANT_VECTOR2_ARRAY); + f->store_32(VARIANT_PACKED_VECTOR2_ARRAY); Vector<Vector2> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1715,7 +1715,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia } break; case Variant::PACKED_COLOR_ARRAY: { - f->store_32(VARIANT_COLOR_ARRAY); + f->store_32(VARIANT_PACKED_COLOR_ARRAY); Vector<Color> arr = p_property; int len = arr.size(); f->store_32(len); @@ -1979,7 +1979,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p for (RES &r : saved_resources) { if (r->is_built_in()) { - if (r->get_scene_unique_id() != "") { + if (!r->get_scene_unique_id().is_empty()) { if (used_unique_ids.has(r->get_scene_unique_id())) { r->set_scene_unique_id(""); } else { @@ -1993,7 +1993,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p int res_index = 0; for (RES &r : saved_resources) { if (r->is_built_in()) { - if (r->get_scene_unique_id() == "") { + if (r->get_scene_unique_id().is_empty()) { String new_id; while (true) { diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index a6e6d1848e..ecc3e95f6b 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index cd44c537a8..9b6440e2a2 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -78,8 +78,8 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy return err; } - if (assign != String()) { - if (!path_found && assign.begins_with("path.") && r_path_and_type.path == String()) { + if (!assign.is_empty()) { + if (!path_found && assign.begins_with("path.") && r_path_and_type.path.is_empty()) { String feature = assign.get_slicec('.', 1); if (OS::get_singleton()->has_feature(feature)) { r_path_and_type.path = value; @@ -112,7 +112,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy memdelete(f); - if (r_path_and_type.path == String() || r_path_and_type.type == String()) { + if (r_path_and_type.path.is_empty() || r_path_and_type.type.is_empty()) { return ERR_FILE_CORRUPT; } return OK; @@ -158,7 +158,7 @@ void ResourceFormatImporter::get_recognized_extensions(List<String> *p_extension } void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const { - if (p_type == "") { + if (p_type.is_empty()) { get_recognized_extensions(p_extensions); return; } @@ -167,7 +167,7 @@ void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_ for (int i = 0; i < importers.size(); i++) { String res_type = importers[i]->get_resource_type(); - if (res_type == String()) { + if (res_type.is_empty()) { continue; } @@ -246,7 +246,7 @@ int ResourceFormatImporter::get_import_order(const String &p_path) const { bool ResourceFormatImporter::handles_type(const String &p_type) const { for (int i = 0; i < importers.size(); i++) { String res_type = importers[i]->get_resource_type(); - if (res_type == String()) { + if (res_type.is_empty()) { continue; } if (ClassDB::is_parent_class(res_type, p_type)) { @@ -300,7 +300,7 @@ void ResourceFormatImporter::get_internal_resource_path_list(const String &p_pat return; } - if (assign != String()) { + if (!assign.is_empty()) { if (assign.begins_with("path.")) { r_paths->push_back(value); } else if (assign == "path") { @@ -463,3 +463,12 @@ void ResourceImporter::_bind_methods() { BIND_ENUM_CONSTANT(IMPORT_ORDER_DEFAULT); BIND_ENUM_CONSTANT(IMPORT_ORDER_SCENE); } + +void ResourceFormatImporter::add_importer(const Ref<ResourceImporter> &p_importer, bool p_first_priority) { + ERR_FAIL_COND(p_importer.is_null()); + if (p_first_priority) { + importers.insert(0, p_importer); + } else { + importers.push_back(p_importer); + } +} diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index cd583e2533..2fffc16ad8 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -80,9 +80,8 @@ public: String get_internal_resource_path(const String &p_path) const; void get_internal_resource_path_list(const String &p_path, List<String> *r_paths); - void add_importer(const Ref<ResourceImporter> &p_importer) { - importers.push_back(p_importer); - } + void add_importer(const Ref<ResourceImporter> &p_importer, bool p_first_priority = false); + void remove_importer(const Ref<ResourceImporter> &p_importer) { importers.erase(p_importer); } Ref<ResourceImporter> get_importer_by_name(const String &p_name) const; Ref<ResourceImporter> get_importer_by_extension(const String &p_extension) const; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 2198761c2a..21bf566b1b 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -52,7 +52,7 @@ bool ResourceFormatLoader::recognize_path(const String &p_path, const String &p_ String extension = p_path.get_extension(); List<String> extensions; - if (p_for_type == String()) { + if (p_for_type.is_empty()) { get_recognized_extensions(&extensions); } else { get_recognized_extensions_for_type(p_for_type, &extensions); @@ -96,7 +96,7 @@ ResourceUID::ID ResourceFormatLoader::get_resource_uid(const String &p_path) con } void ResourceFormatLoader::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const { - if (p_type == "" || handles_type(p_type)) { + if (p_type.is_empty() || handles_type(p_type)) { get_recognized_extensions(p_extensions); } } @@ -194,7 +194,7 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c continue; } found = true; - RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress, p_cache_mode); + RES res = loader[i]->load(p_path, !p_original_path.is_empty() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress, p_cache_mode); if (res.is_null()) { continue; } @@ -289,7 +289,7 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String & thread_load_mutex->lock(); - if (p_source_resource != String()) { + if (!p_source_resource.is_empty()) { //must be loading from this resource if (!thread_load_tasks.has(p_source_resource)) { thread_load_mutex->unlock(); @@ -310,7 +310,7 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String & if (thread_load_tasks.has(local_path)) { thread_load_tasks[local_path].requests++; - if (p_source_resource != String()) { + if (!p_source_resource.is_empty()) { thread_load_tasks[p_source_resource].sub_tasks.insert(local_path); } thread_load_mutex->unlock(); @@ -354,7 +354,7 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String & ResourceCache::lock.read_unlock(); } - if (p_source_resource != String()) { + if (!p_source_resource.is_empty()) { thread_load_tasks[p_source_resource].sub_tasks.insert(local_path); } @@ -574,7 +574,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, Resour bool xl_remapped = false; String path = _path_remap(local_path, &xl_remapped); - if (path == "") { + if (path.is_empty()) { ERR_FAIL_V_MSG(RES(), "Remapping '" + local_path + "' failed."); } @@ -776,7 +776,7 @@ String ResourceLoader::get_resource_type(const String &p_path) { for (int i = 0; i < loader_count; i++) { String result = loader[i]->get_resource_type(local_path); - if (result != "") { + if (!result.is_empty()) { return result; } } @@ -806,38 +806,26 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem // To find the path of the remapped resource, we extract the locale name after // the last ':' to match the project locale. - // We also fall back in case of regional locales as done in TranslationServer::translate - // (e.g. 'ru_RU' -> 'ru' if the former has no specific mapping). String locale = TranslationServer::get_singleton()->get_locale(); ERR_FAIL_COND_V_MSG(locale.length() < 2, p_path, "Could not remap path '" + p_path + "' for translation as configured locale '" + locale + "' is invalid."); - String lang = TranslationServer::get_language_code(locale); Vector<String> &res_remaps = *translation_remaps.getptr(new_path); - bool near_match = false; + int best_score = 0; for (int i = 0; i < res_remaps.size(); i++) { int split = res_remaps[i].rfind(":"); if (split == -1) { continue; } - String l = res_remaps[i].substr(split + 1).strip_edges(); - if (l == locale) { // Exact match. - new_path = res_remaps[i].left(split); - break; - } else if (near_match) { - continue; // Already found near match, keep going for potential exact match. - } - - // No exact match (e.g. locale 'ru_RU' but remap is 'ru'), let's look further - // for a near match (same language code, i.e. first 2 or 3 letters before - // regional code, if included). - if (TranslationServer::get_language_code(l) == lang) { - // Language code matches, that's a near match. Keep looking for exact match. - near_match = true; + int score = TranslationServer::get_singleton()->compare_locales(locale, l); + if (score > 0 && score >= best_score) { new_path = res_remaps[i].left(split); - continue; + best_score = score; + if (score == 10) { + break; // Exact match, skip the rest. + } } } diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index f1d9815635..a3fdefa0f1 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp index 823b5f75b1..c883e8502f 100644 --- a/core/io/resource_saver.cpp +++ b/core/io/resource_saver.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h index fcde835dab..2919a4cec0 100644 --- a/core/io/resource_saver.h +++ b/core/io/resource_saver.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/resource_uid.cpp b/core/io/resource_uid.cpp index b7d01712ff..776756e64e 100644 --- a/core/io/resource_uid.cpp +++ b/core/io/resource_uid.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -71,9 +71,9 @@ ResourceUID::ID ResourceUID::text_to_id(const String &p_text) const { for (uint32_t i = 6; i < l; i++) { uid *= base; uint32_t c = p_text[i]; - if (c >= 'a' && c <= 'z') { + if (is_ascii_lower_case(c)) { uid += c - 'a'; - } else if (c >= '0' && c <= '9') { + } else if (is_digit(c)) { uid += c - '0' + char_count; } else { return INVALID_ID; diff --git a/core/io/resource_uid.h b/core/io/resource_uid.h index 2f1bfdf243..9f2ab5245b 100644 --- a/core/io/resource_uid.h +++ b/core/io/resource_uid.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp index 8ab025dda1..c65968ef03 100644 --- a/core/io/stream_peer.cpp +++ b/core/io/stream_peer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -98,7 +98,7 @@ Array StreamPeer::_get_partial_data(int p_bytes) { Error err = get_partial_data(&w[0], p_bytes, received); if (err != OK) { - data.resize(0); + data.clear(); } else if (received != data.size()) { data.resize(received); } @@ -563,7 +563,7 @@ Vector<uint8_t> StreamPeerBuffer::get_data_array() const { } void StreamPeerBuffer::clear() { - data.resize(0); + data.clear(); pointer = 0; } diff --git a/core/io/stream_peer.h b/core/io/stream_peer.h index 89432951c5..e71941b7e1 100644 --- a/core/io/stream_peer.h +++ b/core/io/stream_peer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/stream_peer_ssl.cpp b/core/io/stream_peer_ssl.cpp index 6f5a06474c..ea8435e587 100644 --- a/core/io/stream_peer_ssl.cpp +++ b/core/io/stream_peer_ssl.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/stream_peer_ssl.h b/core/io/stream_peer_ssl.h index 1df9ced08c..15f646d897 100644 --- a/core/io/stream_peer_ssl.h +++ b/core/io/stream_peer_ssl.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/stream_peer_tcp.cpp b/core/io/stream_peer_tcp.cpp index 5b794274ca..6d5784a8ab 100644 --- a/core/io/stream_peer_tcp.cpp +++ b/core/io/stream_peer_tcp.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/stream_peer_tcp.h b/core/io/stream_peer_tcp.h index a2a7f447d8..f2c47b25cf 100644 --- a/core/io/stream_peer_tcp.h +++ b/core/io/stream_peer_tcp.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/tcp_server.cpp b/core/io/tcp_server.cpp index 5e0c0390f9..f1e745cf36 100644 --- a/core/io/tcp_server.cpp +++ b/core/io/tcp_server.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/tcp_server.h b/core/io/tcp_server.h index 10985a04d5..2d427818a0 100644 --- a/core/io/tcp_server.h +++ b/core/io/tcp_server.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp index 83d575cee8..8d3e58cad1 100644 --- a/core/io/translation_loader_po.cpp +++ b/core/io/translation_loader_po.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -87,7 +87,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) { // In PO file, "msgctxt" appears before "msgid". If we encounter a "msgctxt", we add what we have read // and set "entered_context" to true to prevent adding twice. - if (!skip_this && msg_id != "") { + if (!skip_this && !msg_id.is_empty()) { if (status == STATUS_READING_STRING) { translation->add_message(msg_id, msg_str, msg_context); } else if (status == STATUS_READING_PLURAL) { @@ -125,7 +125,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) { ERR_FAIL_V_MSG(RES(), "Unexpected 'msgid', was expecting 'msgstr' while parsing: " + path + ":" + itos(line)); } - if (msg_id != "") { + if (!msg_id.is_empty()) { if (!skip_this && !entered_context) { if (status == STATUS_READING_STRING) { translation->add_message(msg_id, msg_str, msg_context); @@ -137,7 +137,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) { translation->add_plural_message(msg_id, msgs_plural, msg_context); } } - } else if (config == "") { + } else if (config.is_empty()) { config = msg_str; // Record plural rule. int p_start = config.find("Plural-Forms"); @@ -178,8 +178,8 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) { status = STATUS_READING_STRING; } - if (l == "" || l.begins_with("#")) { - if (l.find("fuzzy") != -1) { + if (l.is_empty() || l.begins_with("#")) { + if (l.contains("fuzzy")) { skip_next = true; } line++; @@ -236,15 +236,15 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) { // Add the last set of data from last iteration. if (status == STATUS_READING_STRING) { - if (msg_id != "") { + if (!msg_id.is_empty()) { if (!skip_this) { translation->add_message(msg_id, msg_str, msg_context); } - } else if (config == "") { + } else if (config.is_empty()) { config = msg_str; } } else if (status == STATUS_READING_PLURAL) { - if (!skip_this && msg_id != "") { + if (!skip_this && !msg_id.is_empty()) { if (plural_index != plural_forms - 1) { memdelete(f); ERR_FAIL_V_MSG(RES(), "Number of 'msgstr[]' doesn't match with number of plural forms: " + path + ":" + itos(line)); @@ -253,7 +253,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) { } } - ERR_FAIL_COND_V_MSG(config == "", RES(), "No config found in file: " + path + "."); + ERR_FAIL_COND_V_MSG(config.is_empty(), RES(), "No config found in file: " + path + "."); Vector<String> configs = config.split("\n"); for (int i = 0; i < configs.size(); i++) { diff --git a/core/io/translation_loader_po.h b/core/io/translation_loader_po.h index c52820e60d..1c58896a00 100644 --- a/core/io/translation_loader_po.h +++ b/core/io/translation_loader_po.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/udp_server.cpp b/core/io/udp_server.cpp index 27a1cab721..4934e3a7b6 100644 --- a/core/io/udp_server.cpp +++ b/core/io/udp_server.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/udp_server.h b/core/io/udp_server.h index e49a559c51..4a7546fddf 100644 --- a/core/io/udp_server.h +++ b/core/io/udp_server.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp index 938d93a01b..360da46f96 100644 --- a/core/io/xml_parser.cpp +++ b/core/io/xml_parser.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/xml_parser.h b/core/io/xml_parser.h index 1113cce715..da14ee8eae 100644 --- a/core/io/xml_parser.h +++ b/core/io/xml_parser.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/zip_io.cpp b/core/io/zip_io.cpp index 24808cc8d6..2c4f8346ab 100644 --- a/core/io/zip_io.cpp +++ b/core/io/zip_io.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/zip_io.h b/core/io/zip_io.h index 776473bfa1..6a29703449 100644 --- a/core/io/zip_io.h +++ b/core/io/zip_io.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ |