summaryrefslogtreecommitdiff
path: root/core/io
diff options
context:
space:
mode:
Diffstat (limited to 'core/io')
-rw-r--r--core/io/config_file.cpp45
-rw-r--r--core/io/config_file.h4
-rw-r--r--core/io/dir_access.cpp88
-rw-r--r--core/io/dir_access.h37
-rw-r--r--core/io/file_access.cpp58
-rw-r--r--core/io/file_access.h33
-rw-r--r--core/io/file_access_compressed.cpp58
-rw-r--r--core/io/file_access_compressed.h7
-rw-r--r--core/io/file_access_encrypted.cpp42
-rw-r--r--core/io/file_access_encrypted.h10
-rw-r--r--core/io/file_access_memory.cpp6
-rw-r--r--core/io/file_access_memory.h3
-rw-r--r--core/io/file_access_network.cpp11
-rw-r--r--core/io/file_access_network.h2
-rw-r--r--core/io/file_access_pack.cpp145
-rw-r--r--core/io/file_access_pack.h37
-rw-r--r--core/io/file_access_zip.cpp52
-rw-r--r--core/io/file_access_zip.h7
-rw-r--r--core/io/http_client_tcp.cpp3
-rw-r--r--core/io/image.cpp140
-rw-r--r--core/io/image.h5
-rw-r--r--core/io/image_loader.cpp27
-rw-r--r--core/io/image_loader.h4
-rw-r--r--core/io/ip.cpp10
-rw-r--r--core/io/ip.h5
-rw-r--r--core/io/logger.cpp28
-rw-r--r--core/io/logger.h17
-rw-r--r--core/io/packed_data_container.cpp2
-rw-r--r--core/io/packet_peer_udp.cpp4
-rw-r--r--core/io/packet_peer_udp.h2
-rw-r--r--core/io/pck_packer.cpp56
-rw-r--r--core/io/pck_packer.h3
-rw-r--r--core/io/resource.cpp14
-rw-r--r--core/io/resource.h1
-rw-r--r--core/io/resource_format_binary.cpp225
-rw-r--r--core/io/resource_format_binary.h16
-rw-r--r--core/io/resource_importer.cpp15
-rw-r--r--core/io/resource_loader.cpp9
-rw-r--r--core/io/resource_uid.cpp20
-rw-r--r--core/io/resource_uid.h2
-rw-r--r--core/io/stream_peer.h1
-rw-r--r--core/io/stream_peer_tcp.cpp85
-rw-r--r--core/io/stream_peer_tcp.h12
-rw-r--r--core/io/translation_loader_po.cpp69
-rw-r--r--core/io/translation_loader_po.h2
-rw-r--r--core/io/udp_server.h2
-rw-r--r--core/io/xml_parser.cpp4
-rw-r--r--core/io/zip_io.cpp50
-rw-r--r--core/io/zip_io.h10
49 files changed, 619 insertions, 869 deletions
diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp
index c942b417e4..bc24cac955 100644
--- a/core/io/config_file.cpp
+++ b/core/io/config_file.cpp
@@ -129,12 +129,9 @@ void ConfigFile::erase_section_key(const String &p_section, const String &p_key)
Error ConfigFile::save(const String &p_path) {
Error err;
- FileAccess *file = FileAccess::open(p_path, FileAccess::WRITE, &err);
+ Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::WRITE, &err);
if (err) {
- if (file) {
- memdelete(file);
- }
return err;
}
@@ -143,17 +140,16 @@ Error ConfigFile::save(const String &p_path) {
Error ConfigFile::save_encrypted(const String &p_path, const Vector<uint8_t> &p_key) {
Error err;
- FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE, &err);
+ Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE, &err);
if (err) {
return err;
}
- FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
+ Ref<FileAccessEncrypted> fae;
+ fae.instantiate();
err = fae->open_and_parse(f, p_key, FileAccessEncrypted::MODE_WRITE_AES256);
if (err) {
- memdelete(fae);
- memdelete(f);
return err;
}
return _internal_save(fae);
@@ -161,24 +157,23 @@ Error ConfigFile::save_encrypted(const String &p_path, const Vector<uint8_t> &p_
Error ConfigFile::save_encrypted_pass(const String &p_path, const String &p_pass) {
Error err;
- FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE, &err);
+ Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE, &err);
if (err) {
return err;
}
- FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
+ Ref<FileAccessEncrypted> fae;
+ fae.instantiate();
err = fae->open_and_parse_password(f, p_pass, FileAccessEncrypted::MODE_WRITE_AES256);
if (err) {
- memdelete(fae);
- memdelete(f);
return err;
}
return _internal_save(fae);
}
-Error ConfigFile::_internal_save(FileAccess *file) {
+Error ConfigFile::_internal_save(Ref<FileAccess> file) {
for (OrderedHashMap<String, OrderedHashMap<String, Variant>>::Element E = values.front(); E; E = E.next()) {
if (E != values.front()) {
file->store_string("\n");
@@ -194,16 +189,14 @@ Error ConfigFile::_internal_save(FileAccess *file) {
}
}
- memdelete(file);
-
return OK;
}
Error ConfigFile::load(const String &p_path) {
Error err;
- FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
+ Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ, &err);
- if (!f) {
+ if (f.is_null()) {
return err;
}
@@ -212,17 +205,16 @@ Error ConfigFile::load(const String &p_path) {
Error ConfigFile::load_encrypted(const String &p_path, const Vector<uint8_t> &p_key) {
Error err;
- FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
+ Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ, &err);
if (err) {
return err;
}
- FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
+ Ref<FileAccessEncrypted> fae;
+ fae.instantiate();
err = fae->open_and_parse(f, p_key, FileAccessEncrypted::MODE_READ);
if (err) {
- memdelete(fae);
- memdelete(f);
return err;
}
return _internal_load(p_path, fae);
@@ -230,31 +222,28 @@ Error ConfigFile::load_encrypted(const String &p_path, const Vector<uint8_t> &p_
Error ConfigFile::load_encrypted_pass(const String &p_path, const String &p_pass) {
Error err;
- FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
+ Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ, &err);
if (err) {
return err;
}
- FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
+ Ref<FileAccessEncrypted> fae;
+ fae.instantiate();
err = fae->open_and_parse_password(f, p_pass, FileAccessEncrypted::MODE_READ);
if (err) {
- memdelete(fae);
- memdelete(f);
return err;
}
return _internal_load(p_path, fae);
}
-Error ConfigFile::_internal_load(const String &p_path, FileAccess *f) {
+Error ConfigFile::_internal_load(const String &p_path, Ref<FileAccess> f) {
VariantParser::StreamFile stream;
stream.f = f;
Error err = _parse(p_path, &stream);
- memdelete(f);
-
return err;
}
diff --git a/core/io/config_file.h b/core/io/config_file.h
index 71e9080fb7..7a52b0e16a 100644
--- a/core/io/config_file.h
+++ b/core/io/config_file.h
@@ -43,8 +43,8 @@ class ConfigFile : public RefCounted {
PackedStringArray _get_sections() const;
PackedStringArray _get_section_keys(const String &p_section) const;
- Error _internal_load(const String &p_path, FileAccess *f);
- Error _internal_save(FileAccess *file);
+ Error _internal_load(const String &p_path, Ref<FileAccess> f);
+ Error _internal_save(Ref<FileAccess> file);
Error _parse(const String &p_path, VariantParser::Stream *p_stream);
diff --git a/core/io/dir_access.cpp b/core/io/dir_access.cpp
index 73efdeb38e..433a7efb21 100644
--- a/core/io/dir_access.cpp
+++ b/core/io/dir_access.cpp
@@ -217,8 +217,8 @@ String DirAccess::fix_path(String p_path) const {
DirAccess::CreateFunc DirAccess::create_func[ACCESS_MAX] = { nullptr, nullptr, nullptr };
-DirAccess *DirAccess::create_for_path(const String &p_path) {
- DirAccess *da = nullptr;
+Ref<DirAccess> DirAccess::create_for_path(const String &p_path) {
+ Ref<DirAccess> da;
if (p_path.begins_with("res://")) {
da = create(ACCESS_RESOURCES);
} else if (p_path.begins_with("user://")) {
@@ -230,25 +230,23 @@ DirAccess *DirAccess::create_for_path(const String &p_path) {
return da;
}
-DirAccess *DirAccess::open(const String &p_path, Error *r_error) {
- DirAccess *da = create_for_path(p_path);
-
- ERR_FAIL_COND_V_MSG(!da, nullptr, "Cannot create DirAccess for path '" + p_path + "'.");
+Ref<DirAccess> DirAccess::open(const String &p_path, Error *r_error) {
+ Ref<DirAccess> da = create_for_path(p_path);
+ ERR_FAIL_COND_V_MSG(da.is_null(), nullptr, "Cannot create DirAccess for path '" + p_path + "'.");
Error err = da->change_dir(p_path);
if (r_error) {
*r_error = err;
}
if (err != OK) {
- memdelete(da);
return nullptr;
}
return da;
}
-DirAccess *DirAccess::create(AccessType p_access) {
- DirAccess *da = create_func[p_access] ? create_func[p_access]() : nullptr;
- if (da) {
+Ref<DirAccess> DirAccess::create(AccessType p_access) {
+ Ref<DirAccess> da = create_func[p_access] ? create_func[p_access]() : nullptr;
+ if (da.is_valid()) {
da->_access_type = p_access;
// for ACCESS_RESOURCES and ACCESS_FILESYSTEM, current_dir already defaults to where game was started
@@ -264,54 +262,45 @@ DirAccess *DirAccess::create(AccessType p_access) {
}
String DirAccess::get_full_path(const String &p_path, AccessType p_access) {
- DirAccess *d = DirAccess::create(p_access);
- if (!d) {
+ Ref<DirAccess> d = DirAccess::create(p_access);
+ if (d.is_null()) {
return p_path;
}
d->change_dir(p_path);
String full = d->get_current_dir();
- memdelete(d);
return full;
}
Error DirAccess::copy(String p_from, String p_to, int p_chmod_flags) {
//printf("copy %s -> %s\n",p_from.ascii().get_data(),p_to.ascii().get_data());
Error err;
- FileAccess *fsrc = FileAccess::open(p_from, FileAccess::READ, &err);
-
- if (err) {
- ERR_PRINT("Failed to open " + p_from);
- return err;
- }
-
- FileAccess *fdst = FileAccess::open(p_to, FileAccess::WRITE, &err);
- if (err) {
- fsrc->close();
- memdelete(fsrc);
- ERR_PRINT("Failed to open " + p_to);
- return err;
- }
+ {
+ Ref<FileAccess> fsrc = FileAccess::open(p_from, FileAccess::READ, &err);
+ ERR_FAIL_COND_V_MSG(err != OK, err, "Failed to open " + p_from);
+
+ Ref<FileAccess> fdst = FileAccess::open(p_to, FileAccess::WRITE, &err);
+ ERR_FAIL_COND_V_MSG(err != OK, err, "Failed to open " + p_to);
+
+ fsrc->seek_end(0);
+ int size = fsrc->get_position();
+ fsrc->seek(0);
+ err = OK;
+ while (size--) {
+ if (fsrc->get_error() != OK) {
+ err = fsrc->get_error();
+ break;
+ }
+ if (fdst->get_error() != OK) {
+ err = fdst->get_error();
+ break;
+ }
- fsrc->seek_end(0);
- int size = fsrc->get_position();
- fsrc->seek(0);
- err = OK;
- while (size--) {
- if (fsrc->get_error() != OK) {
- err = fsrc->get_error();
- break;
- }
- if (fdst->get_error() != OK) {
- err = fdst->get_error();
- break;
+ fdst->store_8(fsrc->get_8());
}
-
- fdst->store_8(fsrc->get_8());
}
if (err == OK && p_chmod_flags != -1) {
- fdst->close();
err = FileAccess::set_unix_permissions(p_to, p_chmod_flags);
// If running on a platform with no chmod support (i.e., Windows), don't fail
if (err == ERR_UNAVAILABLE) {
@@ -319,9 +308,6 @@ Error DirAccess::copy(String p_from, String p_to, int p_chmod_flags) {
}
}
- memdelete(fsrc);
- memdelete(fdst);
-
return err;
}
@@ -343,7 +329,7 @@ public:
}
};
-Error DirAccess::_copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flags, bool p_copy_links) {
+Error DirAccess::_copy_dir(Ref<DirAccess> &p_target_da, String p_to, int p_chmod_flags, bool p_copy_links) {
List<String> dirs;
String curdir = get_current_dir();
@@ -399,14 +385,11 @@ Error DirAccess::_copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flag
Error DirAccess::copy_dir(String p_from, String p_to, int p_chmod_flags, bool p_copy_links) {
ERR_FAIL_COND_V_MSG(!dir_exists(p_from), ERR_FILE_NOT_FOUND, "Source directory doesn't exist.");
- DirAccess *target_da = DirAccess::create_for_path(p_to);
- ERR_FAIL_COND_V_MSG(!target_da, ERR_CANT_CREATE, "Cannot create DirAccess for path '" + p_to + "'.");
+ Ref<DirAccess> target_da = DirAccess::create_for_path(p_to);
+ ERR_FAIL_COND_V_MSG(target_da.is_null(), ERR_CANT_CREATE, "Cannot create DirAccess for path '" + p_to + "'.");
if (!target_da->dir_exists(p_to)) {
Error err = target_da->make_dir_recursive(p_to);
- if (err) {
- memdelete(target_da);
- }
ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot create directory '" + p_to + "'.");
}
@@ -416,12 +399,11 @@ Error DirAccess::copy_dir(String p_from, String p_to, int p_chmod_flags, bool p_
DirChanger dir_changer(this, p_from);
Error err = _copy_dir(target_da, p_to, p_chmod_flags, p_copy_links);
- memdelete(target_da);
return err;
}
bool DirAccess::exists(String p_dir) {
- DirAccessRef da = DirAccess::create_for_path(p_dir);
+ Ref<DirAccess> da = DirAccess::create_for_path(p_dir);
return da->change_dir(p_dir) == OK;
}
diff --git a/core/io/dir_access.h b/core/io/dir_access.h
index d63453e947..0125f011b5 100644
--- a/core/io/dir_access.h
+++ b/core/io/dir_access.h
@@ -31,11 +31,12 @@
#ifndef DIR_ACCESS_H
#define DIR_ACCESS_H
+#include "core/object/ref_counted.h"
#include "core/string/ustring.h"
#include "core/typedefs.h"
//@ TODO, excellent candidate for THREAD_SAFE MACRO, should go through all these and add THREAD_SAFE where it applies
-class DirAccess {
+class DirAccess : public RefCounted {
public:
enum AccessType {
ACCESS_RESOURCES,
@@ -44,13 +45,13 @@ public:
ACCESS_MAX
};
- typedef DirAccess *(*CreateFunc)();
+ typedef Ref<DirAccess> (*CreateFunc)();
private:
AccessType _access_type = ACCESS_FILESYSTEM;
static CreateFunc create_func[ACCESS_MAX]; ///< set this to instance a filesystem object
- Error _copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flags, bool p_copy_links);
+ Error _copy_dir(Ref<DirAccess> &p_target_da, String p_to, int p_chmod_flags, bool p_copy_links);
protected:
String _get_root_path() const;
@@ -59,7 +60,7 @@ protected:
String fix_path(String p_path) const;
template <class T>
- static DirAccess *_create_builtin() {
+ static Ref<DirAccess> _create_builtin() {
return memnew(T);
}
@@ -77,7 +78,7 @@ public:
virtual bool drives_are_shortcuts();
virtual Error change_dir(String p_dir) = 0; ///< can be relative or absolute, return false on success
- virtual String get_current_dir(bool p_include_drive = true) = 0; ///< return current dir location
+ virtual String get_current_dir(bool p_include_drive = true) const = 0; ///< return current dir location
virtual Error make_dir(String p_dir) = 0;
virtual Error make_dir_recursive(String p_dir);
virtual Error erase_contents_recursive(); //super dangerous, use with care!
@@ -101,47 +102,29 @@ public:
// Meant for editor code when we want to quickly remove a file without custom
// handling (e.g. removing a cache file).
static void remove_file_or_error(String p_path) {
- DirAccess *da = create(ACCESS_FILESYSTEM);
+ Ref<DirAccess> da = create(ACCESS_FILESYSTEM);
if (da->file_exists(p_path)) {
if (da->remove(p_path) != OK) {
ERR_FAIL_MSG("Cannot remove file or directory: " + p_path);
}
}
- memdelete(da);
}
virtual String get_filesystem_type() const = 0;
static String get_full_path(const String &p_path, AccessType p_access);
- static DirAccess *create_for_path(const String &p_path);
+ static Ref<DirAccess> create_for_path(const String &p_path);
- static DirAccess *create(AccessType p_access);
+ static Ref<DirAccess> create(AccessType p_access);
template <class T>
static void make_default(AccessType p_access) {
create_func[p_access] = _create_builtin<T>;
}
- static DirAccess *open(const String &p_path, Error *r_error = nullptr);
+ static Ref<DirAccess> open(const String &p_path, Error *r_error = nullptr);
DirAccess() {}
virtual ~DirAccess() {}
};
-struct DirAccessRef {
- _FORCE_INLINE_ DirAccess *operator->() {
- return f;
- }
-
- operator bool() const { return f != nullptr; }
-
- DirAccess *f = nullptr;
-
- DirAccessRef(DirAccess *fa) { f = fa; }
- ~DirAccessRef() {
- if (f) {
- memdelete(f);
- }
- }
-};
-
#endif // DIR_ACCESS_H
diff --git a/core/io/file_access.cpp b/core/io/file_access.cpp
index 86836454c5..7d8da1b11c 100644
--- a/core/io/file_access.cpp
+++ b/core/io/file_access.cpp
@@ -42,10 +42,10 @@ FileAccess::FileCloseFailNotify FileAccess::close_fail_notify = nullptr;
bool FileAccess::backup_save = false;
-FileAccess *FileAccess::create(AccessType p_access) {
+Ref<FileAccess> FileAccess::create(AccessType p_access) {
ERR_FAIL_INDEX_V(p_access, ACCESS_MAX, nullptr);
- FileAccess *ret = create_func[p_access]();
+ Ref<FileAccess> ret = create_func[p_access]();
ret->_set_access_type(p_access);
return ret;
}
@@ -55,11 +55,10 @@ bool FileAccess::exists(const String &p_name) {
return true;
}
- FileAccess *f = open(p_name, READ);
- if (!f) {
+ Ref<FileAccess> f = open(p_name, READ);
+ if (f.is_null()) {
return false;
}
- memdelete(f);
return true;
}
@@ -67,8 +66,8 @@ void FileAccess::_set_access_type(AccessType p_access) {
_access_type = p_access;
}
-FileAccess *FileAccess::create_for_path(const String &p_path) {
- FileAccess *ret = nullptr;
+Ref<FileAccess> FileAccess::create_for_path(const String &p_path) {
+ Ref<FileAccess> ret;
if (p_path.begins_with("res://")) {
ret = create(ACCESS_RESOURCES);
} else if (p_path.begins_with("user://")) {
@@ -85,13 +84,13 @@ Error FileAccess::reopen(const String &p_path, int p_mode_flags) {
return _open(p_path, p_mode_flags);
}
-FileAccess *FileAccess::open(const String &p_path, int p_mode_flags, Error *r_error) {
+Ref<FileAccess> FileAccess::open(const String &p_path, int p_mode_flags, Error *r_error) {
//try packed data first
- FileAccess *ret = nullptr;
+ Ref<FileAccess> ret;
if (!(p_mode_flags & WRITE) && PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled()) {
ret = PackedData::get_singleton()->try_open_path(p_path);
- if (ret) {
+ if (ret.is_valid()) {
if (r_error) {
*r_error = OK;
}
@@ -106,8 +105,7 @@ FileAccess *FileAccess::open(const String &p_path, int p_mode_flags, Error *r_er
*r_error = err;
}
if (err != OK) {
- memdelete(ret);
- ret = nullptr;
+ ret.unref();
}
return ret;
@@ -463,11 +461,10 @@ uint64_t FileAccess::get_modified_time(const String &p_file) {
return 0;
}
- FileAccess *fa = create_for_path(p_file);
- ERR_FAIL_COND_V_MSG(!fa, 0, "Cannot create FileAccess for path '" + p_file + "'.");
+ Ref<FileAccess> fa = create_for_path(p_file);
+ ERR_FAIL_COND_V_MSG(fa.is_null(), 0, "Cannot create FileAccess for path '" + p_file + "'.");
uint64_t mt = fa->_get_modified_time(p_file);
- memdelete(fa);
return mt;
}
@@ -476,11 +473,10 @@ uint32_t FileAccess::get_unix_permissions(const String &p_file) {
return 0;
}
- FileAccess *fa = create_for_path(p_file);
- ERR_FAIL_COND_V_MSG(!fa, 0, "Cannot create FileAccess for path '" + p_file + "'.");
+ Ref<FileAccess> fa = create_for_path(p_file);
+ ERR_FAIL_COND_V_MSG(fa.is_null(), 0, "Cannot create FileAccess for path '" + p_file + "'.");
uint32_t mt = fa->_get_unix_permissions(p_file);
- memdelete(fa);
return mt;
}
@@ -489,11 +485,10 @@ Error FileAccess::set_unix_permissions(const String &p_file, uint32_t p_permissi
return ERR_UNAVAILABLE;
}
- FileAccess *fa = create_for_path(p_file);
- ERR_FAIL_COND_V_MSG(!fa, ERR_CANT_CREATE, "Cannot create FileAccess for path '" + p_file + "'.");
+ Ref<FileAccess> fa = create_for_path(p_file);
+ ERR_FAIL_COND_V_MSG(fa.is_null(), ERR_CANT_CREATE, "Cannot create FileAccess for path '" + p_file + "'.");
Error err = fa->_set_unix_permissions(p_file, p_permissions);
- memdelete(fa);
return err;
}
@@ -559,8 +554,8 @@ void FileAccess::store_buffer(const uint8_t *p_src, uint64_t p_length) {
}
Vector<uint8_t> FileAccess::get_file_as_array(const String &p_path, Error *r_error) {
- FileAccess *f = FileAccess::open(p_path, READ, r_error);
- if (!f) {
+ Ref<FileAccess> f = FileAccess::open(p_path, READ, r_error);
+ if (f.is_null()) {
if (r_error) { // if error requested, do not throw error
return Vector<uint8_t>();
}
@@ -569,7 +564,6 @@ Vector<uint8_t> FileAccess::get_file_as_array(const String &p_path, Error *r_err
Vector<uint8_t> data;
data.resize(f->get_length());
f->get_buffer(data.ptrw(), data.size());
- memdelete(f);
return data;
}
@@ -592,8 +586,8 @@ String FileAccess::get_file_as_string(const String &p_path, Error *r_error) {
}
String FileAccess::get_md5(const String &p_file) {
- FileAccess *f = FileAccess::open(p_file, READ);
- if (!f) {
+ Ref<FileAccess> f = FileAccess::open(p_file, READ);
+ if (f.is_null()) {
return String();
}
@@ -615,8 +609,6 @@ String FileAccess::get_md5(const String &p_file) {
unsigned char hash[16];
ctx.finish(hash);
- memdelete(f);
-
return String::md5(hash);
}
@@ -625,8 +617,8 @@ String FileAccess::get_multiple_md5(const Vector<String> &p_file) {
ctx.start();
for (int i = 0; i < p_file.size(); i++) {
- FileAccess *f = FileAccess::open(p_file[i], READ);
- ERR_CONTINUE(!f);
+ Ref<FileAccess> f = FileAccess::open(p_file[i], READ);
+ ERR_CONTINUE(f.is_null());
unsigned char step[32768];
@@ -639,7 +631,6 @@ String FileAccess::get_multiple_md5(const Vector<String> &p_file) {
break;
}
}
- memdelete(f);
}
unsigned char hash[16];
@@ -649,8 +640,8 @@ String FileAccess::get_multiple_md5(const Vector<String> &p_file) {
}
String FileAccess::get_sha256(const String &p_file) {
- FileAccess *f = FileAccess::open(p_file, READ);
- if (!f) {
+ Ref<FileAccess> f = FileAccess::open(p_file, READ);
+ if (f.is_null()) {
return String();
}
@@ -672,6 +663,5 @@ String FileAccess::get_sha256(const String &p_file) {
unsigned char hash[32];
ctx.finish(hash);
- memdelete(f);
return String::hex_encode_buffer(hash, 32);
}
diff --git a/core/io/file_access.h b/core/io/file_access.h
index 5413665440..e2c11142d7 100644
--- a/core/io/file_access.h
+++ b/core/io/file_access.h
@@ -32,6 +32,7 @@
#define FILE_ACCESS_H
#include "core/math/math_defs.h"
+#include "core/object/ref_counted.h"
#include "core/os/memory.h"
#include "core/string/ustring.h"
#include "core/typedefs.h"
@@ -40,7 +41,7 @@
* Multi-Platform abstraction for accessing to files.
*/
-class FileAccess {
+class FileAccess : public RefCounted {
public:
enum AccessType {
ACCESS_RESOURCES,
@@ -51,7 +52,7 @@ public:
typedef void (*FileCloseFailNotify)(const String &);
- typedef FileAccess *(*CreateFunc)();
+ typedef Ref<FileAccess> (*CreateFunc)();
bool big_endian = false;
bool real_is_double = false;
@@ -71,7 +72,7 @@ private:
AccessType _access_type = ACCESS_FILESYSTEM;
static CreateFunc create_func[ACCESS_MAX]; /** default file access creation function for a platform */
template <class T>
- static FileAccess *_create_builtin() {
+ static Ref<FileAccess> _create_builtin() {
return memnew(T);
}
@@ -87,7 +88,6 @@ public:
WRITE_READ = 7,
};
- virtual void close() = 0; ///< close a file
virtual bool is_open() const = 0; ///< true when file is open
virtual String get_path() const { return ""; } /// returns the path for the current open file
@@ -148,9 +148,9 @@ public:
virtual Error reopen(const String &p_path, int p_mode_flags); ///< does not change the AccessType
- static FileAccess *create(AccessType p_access); /// Create a file access (for the current platform) this is the only portable way of accessing files.
- static FileAccess *create_for_path(const String &p_path);
- static FileAccess *open(const String &p_path, int p_mode_flags, Error *r_error = nullptr); /// Create a file access (for the current platform) this is the only portable way of accessing files.
+ static Ref<FileAccess> create(AccessType p_access); /// Create a file access (for the current platform) this is the only portable way of accessing files.
+ static Ref<FileAccess> create_for_path(const String &p_path);
+ static Ref<FileAccess> open(const String &p_path, int p_mode_flags, Error *r_error = nullptr); /// Create a file access (for the current platform) this is the only portable way of accessing files.
static CreateFunc get_create_func(AccessType p_access);
static bool exists(const String &p_name); ///< return true if a file exists
static uint64_t get_modified_time(const String &p_file);
@@ -176,23 +176,4 @@ public:
virtual ~FileAccess() {}
};
-struct FileAccessRef {
- _FORCE_INLINE_ FileAccess *operator->() {
- return f;
- }
-
- operator bool() const { return f != nullptr; }
-
- FileAccess *f;
-
- operator FileAccess *() { return f; }
-
- FileAccessRef(FileAccess *fa) { f = fa; }
- ~FileAccessRef() {
- if (f) {
- memdelete(f);
- }
- }
-};
-
#endif // FILE_ACCESS_H
diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp
index 85faf04315..1d0a718166 100644
--- a/core/io/file_access_compressed.cpp
+++ b/core/io/file_access_compressed.cpp
@@ -58,12 +58,12 @@ void FileAccessCompressed::configure(const String &p_magic, Compression::Mode p_
} \
}
-Error FileAccessCompressed::open_after_magic(FileAccess *p_base) {
+Error FileAccessCompressed::open_after_magic(Ref<FileAccess> p_base) {
f = p_base;
cmode = (Compression::Mode)f->get_32();
block_size = f->get_32();
if (block_size == 0) {
- f = nullptr; // Let the caller to handle the FileAccess object if failed to open as compressed file.
+ f.unref();
ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Can't open compressed file '" + p_base->get_path() + "' with block size 0, it is corrupted.");
}
read_total = f->get_32();
@@ -97,17 +97,13 @@ Error FileAccessCompressed::open_after_magic(FileAccess *p_base) {
Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) {
ERR_FAIL_COND_V(p_mode_flags == READ_WRITE, ERR_UNAVAILABLE);
-
- if (f) {
- close();
- }
+ _close();
Error err;
f = FileAccess::open(p_path, p_mode_flags, &err);
if (err != OK) {
//not openable
-
- f = nullptr;
+ f.unref();
return err;
}
@@ -127,8 +123,7 @@ Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) {
rmagic[4] = 0;
err = ERR_FILE_UNRECOGNIZED;
if (magic != rmagic || (err = open_after_magic(f)) != OK) {
- memdelete(f);
- f = nullptr;
+ f.unref();
return err;
}
}
@@ -136,8 +131,8 @@ Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) {
return OK;
}
-void FileAccessCompressed::close() {
- if (!f) {
+void FileAccessCompressed::_close() {
+ if (f.is_null()) {
return;
}
@@ -182,17 +177,15 @@ void FileAccessCompressed::close() {
buffer.clear();
read_blocks.clear();
}
-
- memdelete(f);
- f = nullptr;
+ f.unref();
}
bool FileAccessCompressed::is_open() const {
- return f != nullptr;
+ return f.is_valid();
}
void FileAccessCompressed::seek(uint64_t p_position) {
- ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
+ ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before use.");
if (writing) {
ERR_FAIL_COND(p_position > write_max);
@@ -222,7 +215,7 @@ void FileAccessCompressed::seek(uint64_t p_position) {
}
void FileAccessCompressed::seek_end(int64_t p_position) {
- ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
+ ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before use.");
if (writing) {
seek(write_max + p_position);
} else {
@@ -231,7 +224,7 @@ void FileAccessCompressed::seek_end(int64_t p_position) {
}
uint64_t FileAccessCompressed::get_position() const {
- ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
+ ERR_FAIL_COND_V_MSG(f.is_null(), 0, "File must be opened before use.");
if (writing) {
return write_pos;
} else {
@@ -240,7 +233,7 @@ uint64_t FileAccessCompressed::get_position() const {
}
uint64_t FileAccessCompressed::get_length() const {
- ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
+ ERR_FAIL_COND_V_MSG(f.is_null(), 0, "File must be opened before use.");
if (writing) {
return write_max;
} else {
@@ -249,7 +242,7 @@ uint64_t FileAccessCompressed::get_length() const {
}
bool FileAccessCompressed::eof_reached() const {
- ERR_FAIL_COND_V_MSG(!f, false, "File must be opened before use.");
+ ERR_FAIL_COND_V_MSG(f.is_null(), false, "File must be opened before use.");
if (writing) {
return false;
} else {
@@ -258,7 +251,7 @@ bool FileAccessCompressed::eof_reached() const {
}
uint8_t FileAccessCompressed::get_8() const {
- ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
+ ERR_FAIL_COND_V_MSG(f.is_null(), 0, "File must be opened before use.");
ERR_FAIL_COND_V_MSG(writing, 0, "File has not been opened in read mode.");
if (at_end) {
@@ -291,7 +284,7 @@ uint8_t FileAccessCompressed::get_8() const {
uint64_t FileAccessCompressed::get_buffer(uint8_t *p_dst, uint64_t p_length) const {
ERR_FAIL_COND_V(!p_dst && p_length > 0, -1);
- ERR_FAIL_COND_V_MSG(!f, -1, "File must be opened before use.");
+ ERR_FAIL_COND_V_MSG(f.is_null(), -1, "File must be opened before use.");
ERR_FAIL_COND_V_MSG(writing, -1, "File has not been opened in read mode.");
if (at_end) {
@@ -332,14 +325,14 @@ Error FileAccessCompressed::get_error() const {
}
void FileAccessCompressed::flush() {
- ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
+ ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before use.");
ERR_FAIL_COND_MSG(!writing, "File has not been opened in write mode.");
// compressed files keep data in memory till close()
}
void FileAccessCompressed::store_8(uint8_t p_dest) {
- ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
+ ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before use.");
ERR_FAIL_COND_MSG(!writing, "File has not been opened in write mode.");
WRITE_FIT(1);
@@ -347,16 +340,15 @@ void FileAccessCompressed::store_8(uint8_t p_dest) {
}
bool FileAccessCompressed::file_exists(const String &p_name) {
- FileAccess *fa = FileAccess::open(p_name, FileAccess::READ);
- if (!fa) {
+ Ref<FileAccess> fa = FileAccess::open(p_name, FileAccess::READ);
+ if (fa.is_null()) {
return false;
}
- memdelete(fa);
return true;
}
uint64_t FileAccessCompressed::_get_modified_time(const String &p_file) {
- if (f) {
+ if (f.is_valid()) {
return f->get_modified_time(p_file);
} else {
return 0;
@@ -364,21 +356,19 @@ uint64_t FileAccessCompressed::_get_modified_time(const String &p_file) {
}
uint32_t FileAccessCompressed::_get_unix_permissions(const String &p_file) {
- if (f) {
+ if (f.is_valid()) {
return f->_get_unix_permissions(p_file);
}
return 0;
}
Error FileAccessCompressed::_set_unix_permissions(const String &p_file, uint32_t p_permissions) {
- if (f) {
+ if (f.is_valid()) {
return f->_set_unix_permissions(p_file, p_permissions);
}
return FAILED;
}
FileAccessCompressed::~FileAccessCompressed() {
- if (f) {
- close();
- }
+ _close();
}
diff --git a/core/io/file_access_compressed.h b/core/io/file_access_compressed.h
index 97ef3fbdeb..b8382e61d9 100644
--- a/core/io/file_access_compressed.h
+++ b/core/io/file_access_compressed.h
@@ -61,15 +61,16 @@ class FileAccessCompressed : public FileAccess {
String magic = "GCMP";
mutable Vector<uint8_t> buffer;
- FileAccess *f = nullptr;
+ Ref<FileAccess> f;
+
+ void _close();
public:
void configure(const String &p_magic, Compression::Mode p_mode = Compression::MODE_ZSTD, uint32_t p_block_size = 4096);
- Error open_after_magic(FileAccess *p_base);
+ Error open_after_magic(Ref<FileAccess> p_base);
virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
- virtual void close(); ///< close a file
virtual bool is_open() const; ///< true when file is open
virtual void seek(uint64_t p_position); ///< seek to a given position
diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp
index 8ee19d3d06..d1b014a0be 100644
--- a/core/io/file_access_encrypted.cpp
+++ b/core/io/file_access_encrypted.cpp
@@ -36,7 +36,7 @@
#include <stdio.h>
-Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic) {
+Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic) {
ERR_FAIL_COND_V_MSG(file != nullptr, ERR_ALREADY_IN_USE, "Can't open file while another file from path '" + file->get_path_absolute() + "' is open.");
ERR_FAIL_COND_V(p_key.size() != 32, ERR_INVALID_PARAMETER);
@@ -99,7 +99,7 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8
return OK;
}
-Error FileAccessEncrypted::open_and_parse_password(FileAccess *p_base, const String &p_key, Mode p_mode) {
+Error FileAccessEncrypted::open_and_parse_password(Ref<FileAccess> p_base, const String &p_key, Mode p_mode) {
String cs = p_key.md5_text();
ERR_FAIL_COND_V(cs.length() != 32, ERR_INVALID_PARAMETER);
Vector<uint8_t> key;
@@ -115,30 +115,11 @@ Error FileAccessEncrypted::_open(const String &p_path, int p_mode_flags) {
return OK;
}
-void FileAccessEncrypted::close() {
- if (!file) {
+void FileAccessEncrypted::_close() {
+ if (file.is_null()) {
return;
}
- _release();
-
- file->close();
- memdelete(file);
-
- file = nullptr;
-}
-
-void FileAccessEncrypted::release() {
- if (!file) {
- return;
- }
-
- _release();
-
- file = nullptr;
-}
-
-void FileAccessEncrypted::_release() {
if (writing) {
Vector<uint8_t> compressed;
uint64_t len = data.size();
@@ -176,6 +157,8 @@ void FileAccessEncrypted::_release() {
file->store_buffer(compressed.ptr(), compressed.size());
data.clear();
}
+
+ file.unref();
}
bool FileAccessEncrypted::is_open() const {
@@ -183,7 +166,7 @@ bool FileAccessEncrypted::is_open() const {
}
String FileAccessEncrypted::get_path() const {
- if (file) {
+ if (file.is_valid()) {
return file->get_path();
} else {
return "";
@@ -191,7 +174,7 @@ String FileAccessEncrypted::get_path() const {
}
String FileAccessEncrypted::get_path_absolute() const {
- if (file) {
+ if (file.is_valid()) {
return file->get_path_absolute();
} else {
return "";
@@ -291,11 +274,10 @@ void FileAccessEncrypted::store_8(uint8_t p_dest) {
}
bool FileAccessEncrypted::file_exists(const String &p_name) {
- FileAccess *fa = FileAccess::open(p_name, FileAccess::READ);
- if (!fa) {
+ Ref<FileAccess> fa = FileAccess::open(p_name, FileAccess::READ);
+ if (fa.is_null()) {
return false;
}
- memdelete(fa);
return true;
}
@@ -313,7 +295,5 @@ Error FileAccessEncrypted::_set_unix_permissions(const String &p_file, uint32_t
}
FileAccessEncrypted::~FileAccessEncrypted() {
- if (file) {
- close();
- }
+ _close();
}
diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h
index be5904c894..0d1ee6a4d8 100644
--- a/core/io/file_access_encrypted.h
+++ b/core/io/file_access_encrypted.h
@@ -46,7 +46,7 @@ public:
private:
Vector<uint8_t> key;
bool writing = false;
- FileAccess *file = nullptr;
+ Ref<FileAccess> file;
uint64_t base = 0;
uint64_t length = 0;
Vector<uint8_t> data;
@@ -54,15 +54,13 @@ private:
mutable bool eofed = false;
bool use_magic = true;
- void _release();
+ void _close();
public:
- Error open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic = true);
- Error open_and_parse_password(FileAccess *p_base, const String &p_key, Mode p_mode);
+ Error open_and_parse(Ref<FileAccess> p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic = true);
+ Error open_and_parse_password(Ref<FileAccess> p_base, const String &p_key, Mode p_mode);
virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
- virtual void close(); ///< close a file
- virtual void release(); ///< finish and keep base file open
virtual bool is_open() const; ///< true when file is open
virtual String get_path() const; /// returns the path for the current open file
diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp
index 4aca26b007..943dc72307 100644
--- a/core/io/file_access_memory.cpp
+++ b/core/io/file_access_memory.cpp
@@ -60,7 +60,7 @@ void FileAccessMemory::cleanup() {
memdelete(files);
}
-FileAccess *FileAccessMemory::create() {
+Ref<FileAccess> FileAccessMemory::create() {
return memnew(FileAccessMemory);
}
@@ -94,10 +94,6 @@ Error FileAccessMemory::_open(const String &p_path, int p_mode_flags) {
return OK;
}
-void FileAccessMemory::close() {
- data = nullptr;
-}
-
bool FileAccessMemory::is_open() const {
return data != nullptr;
}
diff --git a/core/io/file_access_memory.h b/core/io/file_access_memory.h
index 50b23e1f32..868b8ed481 100644
--- a/core/io/file_access_memory.h
+++ b/core/io/file_access_memory.h
@@ -38,7 +38,7 @@ class FileAccessMemory : public FileAccess {
uint64_t length = 0;
mutable uint64_t pos = 0;
- static FileAccess *create();
+ static Ref<FileAccess> create();
public:
static void register_file(String p_name, Vector<uint8_t> p_data);
@@ -46,7 +46,6 @@ public:
virtual Error open_custom(const uint8_t *p_data, uint64_t p_len); ///< open a file
virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
- virtual void close(); ///< close a file
virtual bool is_open() const; ///< true when file is open
virtual void seek(uint64_t p_position); ///< seek to a given position
diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp
index cb38ac0928..1365b4b593 100644
--- a/core/io/file_access_network.cpp
+++ b/core/io/file_access_network.cpp
@@ -165,7 +165,7 @@ void FileAccessNetworkClient::_thread_func() {
}
void FileAccessNetworkClient::_thread_func(void *s) {
- FileAccessNetworkClient *self = (FileAccessNetworkClient *)s;
+ FileAccessNetworkClient *self = static_cast<FileAccessNetworkClient *>(s);
self->_thread_func();
}
@@ -254,9 +254,8 @@ void FileAccessNetwork::_respond(uint64_t p_len, Error p_status) {
Error FileAccessNetwork::_open(const String &p_path, int p_mode_flags) {
ERR_FAIL_COND_V(p_mode_flags != READ, ERR_UNAVAILABLE);
- if (opened) {
- close();
- }
+ _close();
+
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
DEBUG_PRINT("open: " + p_path);
@@ -287,7 +286,7 @@ Error FileAccessNetwork::_open(const String &p_path, int p_mode_flags) {
return response;
}
-void FileAccessNetwork::close() {
+void FileAccessNetwork::_close() {
if (!opened) {
return;
}
@@ -483,7 +482,7 @@ FileAccessNetwork::FileAccessNetwork() {
}
FileAccessNetwork::~FileAccessNetwork() {
- close();
+ _close();
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
nc->lock_mutex();
diff --git a/core/io/file_access_network.h b/core/io/file_access_network.h
index 6cae49b540..6afbf6adf5 100644
--- a/core/io/file_access_network.h
+++ b/core/io/file_access_network.h
@@ -113,6 +113,7 @@ class FileAccessNetwork : public FileAccess {
void _queue_page(int32_t p_page) const;
void _respond(uint64_t p_len, Error p_status);
void _set_block(uint64_t p_offset, const Vector<uint8_t> &p_block);
+ void _close();
public:
enum Command {
@@ -131,7 +132,6 @@ public:
};
virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
- virtual void close(); ///< close a file
virtual bool is_open() const; ///< true when file is open
virtual void seek(uint64_t p_position); ///< seek to a given position
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index 7dbea96c3d..ba120de68b 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -32,6 +32,7 @@
#include "core/io/file_access_encrypted.h"
#include "core/object/script_language.h"
+#include "core/os/os.h"
#include "core/version.h"
#include <stdio.h>
@@ -126,60 +127,81 @@ PackedData::~PackedData() {
//////////////////////////////////////////////////////////////////
bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, uint64_t p_offset) {
- FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
- if (!f) {
+ Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
+ if (f.is_null()) {
return false;
}
- f->seek(p_offset);
+ bool pck_header_found = false;
+ // Search for the header at the start offset - standalone PCK file.
+ f->seek(p_offset);
uint32_t magic = f->get_32();
+ if (magic == PACK_HEADER_MAGIC) {
+ pck_header_found = true;
+ }
- if (magic != PACK_HEADER_MAGIC) {
- // loading with offset feature not supported for self contained exe files
+ // Search for the header in the executable "pck" section - self contained executable.
+ if (!pck_header_found) {
+ // Loading with offset feature not supported for self contained exe files.
if (p_offset != 0) {
- f->close();
- memdelete(f);
ERR_FAIL_V_MSG(false, "Loading self-contained executable with offset not supported.");
}
- //maybe at the end.... self contained exe
- f->seek_end();
- f->seek(f->get_position() - 4);
- magic = f->get_32();
- if (magic != PACK_HEADER_MAGIC) {
- f->close();
- memdelete(f);
- return false;
+ int64_t pck_off = OS::get_singleton()->get_embedded_pck_offset();
+ if (pck_off != 0) {
+ // Search for the header, in case PCK start and section have different alignment.
+ for (int i = 0; i < 8; i++) {
+ f->seek(pck_off);
+ magic = f->get_32();
+ if (magic == PACK_HEADER_MAGIC) {
+#ifdef DEBUG_ENABLED
+ print_verbose("PCK header found in executable pck section, loading from offset 0x" + String::num_int64(pck_off - 4, 16));
+#endif
+ pck_header_found = true;
+ break;
+ }
+ pck_off++;
+ }
}
- f->seek(f->get_position() - 12);
+ }
- uint64_t ds = f->get_64();
- f->seek(f->get_position() - ds - 8);
+ // Search for the header at the end of file - self contained executable.
+ if (!pck_header_found) {
+ // Loading with offset feature not supported for self contained exe files.
+ if (p_offset != 0) {
+ ERR_FAIL_V_MSG(false, "Loading self-contained executable with offset not supported.");
+ }
+ f->seek_end();
+ f->seek(f->get_position() - 4);
magic = f->get_32();
- if (magic != PACK_HEADER_MAGIC) {
- f->close();
- memdelete(f);
- return false;
+
+ if (magic == PACK_HEADER_MAGIC) {
+ f->seek(f->get_position() - 12);
+ uint64_t ds = f->get_64();
+ f->seek(f->get_position() - ds - 8);
+ magic = f->get_32();
+ if (magic == PACK_HEADER_MAGIC) {
+#ifdef DEBUG_ENABLED
+ print_verbose("PCK header found at the end of executable, loading from offset 0x" + String::num_int64(f->get_position() - 4, 16));
+#endif
+ pck_header_found = true;
+ }
}
}
+ if (!pck_header_found) {
+ return false;
+ }
+
uint32_t version = f->get_32();
uint32_t ver_major = f->get_32();
uint32_t ver_minor = f->get_32();
f->get_32(); // patch number, not used for validation.
- if (version != PACK_FORMAT_VERSION) {
- f->close();
- memdelete(f);
- ERR_FAIL_V_MSG(false, "Pack version unsupported: " + itos(version) + ".");
- }
- if (ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR)) {
- f->close();
- memdelete(f);
- ERR_FAIL_V_MSG(false, "Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor) + ".");
- }
+ ERR_FAIL_COND_V_MSG(version != PACK_FORMAT_VERSION, false, "Pack version unsupported: " + itos(version) + ".");
+ ERR_FAIL_COND_V_MSG(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), false, "Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor) + ".");
uint32_t pack_flags = f->get_32();
uint64_t file_base = f->get_64();
@@ -194,12 +216,9 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
int file_count = f->get_32();
if (enc_directory) {
- FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
- if (!fae) {
- f->close();
- memdelete(f);
- ERR_FAIL_V_MSG(false, "Can't open encrypted pack directory.");
- }
+ Ref<FileAccessEncrypted> fae;
+ fae.instantiate();
+ ERR_FAIL_COND_V_MSG(fae.is_null(), false, "Can't open encrypted pack directory.");
Vector<uint8_t> key;
key.resize(32);
@@ -208,12 +227,7 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
}
Error err = fae->open_and_parse(f, key, FileAccessEncrypted::MODE_READ, false);
- if (err) {
- f->close();
- memdelete(f);
- memdelete(fae);
- ERR_FAIL_V_MSG(false, "Can't open encrypted pack directory.");
- }
+ ERR_FAIL_COND_V_MSG(err, false, "Can't open encrypted pack directory.");
f = fae;
}
@@ -236,12 +250,10 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
PackedData::get_singleton()->add_path(p_path, path, ofs + p_offset, size, md5, this, p_replace_files, (flags & PACK_FILE_ENCRYPTED));
}
- f->close();
- memdelete(f);
return true;
}
-FileAccess *PackedSourcePCK::get_file(const String &p_path, PackedData::PackedFile *p_file) {
+Ref<FileAccess> PackedSourcePCK::get_file(const String &p_path, PackedData::PackedFile *p_file) {
return memnew(FileAccessPack(p_path, *p_file));
}
@@ -252,15 +264,17 @@ Error FileAccessPack::_open(const String &p_path, int p_mode_flags) {
return ERR_UNAVAILABLE;
}
-void FileAccessPack::close() {
- f->close();
-}
-
bool FileAccessPack::is_open() const {
- return f->is_open();
+ if (f.is_valid()) {
+ return f->is_open();
+ } else {
+ return false;
+ }
}
void FileAccessPack::seek(uint64_t p_position) {
+ ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before use.");
+
if (p_position > pf.size) {
eof = true;
} else {
@@ -288,6 +302,7 @@ bool FileAccessPack::eof_reached() const {
}
uint8_t FileAccessPack::get_8() const {
+ ERR_FAIL_COND_V_MSG(f.is_null(), 0, "File must be opened before use.");
if (pos >= pf.size) {
eof = true;
return 0;
@@ -298,6 +313,7 @@ uint8_t FileAccessPack::get_8() const {
}
uint64_t FileAccessPack::get_buffer(uint8_t *p_dst, uint64_t p_length) const {
+ ERR_FAIL_COND_V_MSG(f.is_null(), -1, "File must be opened before use.");
ERR_FAIL_COND_V(!p_dst && p_length > 0, -1);
if (eof) {
@@ -321,6 +337,8 @@ uint64_t FileAccessPack::get_buffer(uint8_t *p_dst, uint64_t p_length) const {
}
void FileAccessPack::set_big_endian(bool p_big_endian) {
+ ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before use.");
+
FileAccess::set_big_endian(p_big_endian);
f->set_big_endian(p_big_endian);
}
@@ -351,16 +369,15 @@ bool FileAccessPack::file_exists(const String &p_name) {
FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFile &p_file) :
pf(p_file),
f(FileAccess::open(pf.pack, FileAccess::READ)) {
- ERR_FAIL_COND_MSG(!f, "Can't open pack-referenced file '" + String(pf.pack) + "'.");
+ ERR_FAIL_COND_MSG(f.is_null(), "Can't open pack-referenced file '" + String(pf.pack) + "'.");
f->seek(pf.offset);
off = pf.offset;
if (pf.encrypted) {
- FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
- if (!fae) {
- ERR_FAIL_MSG("Can't open encrypted pack-referenced file '" + String(pf.pack) + "'.");
- }
+ Ref<FileAccessEncrypted> fae;
+ fae.instantiate();
+ ERR_FAIL_COND_MSG(fae.is_null(), "Can't open encrypted pack-referenced file '" + String(pf.pack) + "'.");
Vector<uint8_t> key;
key.resize(32);
@@ -369,10 +386,7 @@ FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFil
}
Error err = fae->open_and_parse(f, key, FileAccessEncrypted::MODE_READ, false);
- if (err) {
- memdelete(fae);
- ERR_FAIL_MSG("Can't open encrypted pack-referenced file '" + String(pf.pack) + "'.");
- }
+ ERR_FAIL_COND_MSG(err, "Can't open encrypted pack-referenced file '" + String(pf.pack) + "'.");
f = fae;
off = 0;
}
@@ -380,13 +394,6 @@ FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFil
eof = false;
}
-FileAccessPack::~FileAccessPack() {
- if (f) {
- f->close();
- memdelete(f);
- }
-}
-
//////////////////////////////////////////////////////////////////////////////////
// DIR ACCESS
//////////////////////////////////////////////////////////////////////////////////
@@ -507,7 +514,7 @@ Error DirAccessPack::change_dir(String p_dir) {
}
}
-String DirAccessPack::get_current_dir(bool p_include_drive) {
+String DirAccessPack::get_current_dir(bool p_include_drive) const {
PackedData::PackedDir *pd = current;
String p = current->name;
diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h
index 6eee2f593d..17e87c835a 100644
--- a/core/io/file_access_pack.h
+++ b/core/io/file_access_pack.h
@@ -64,7 +64,7 @@ public:
uint64_t offset; //if offset is ZERO, the file was ERASED
uint64_t size;
uint8_t md5[16];
- PackSource *src;
+ PackSource *src = nullptr;
bool encrypted;
};
@@ -93,7 +93,7 @@ private:
PathMD5() {}
- PathMD5(const Vector<uint8_t> &p_buf) {
+ explicit PathMD5(const Vector<uint8_t> &p_buf) {
a = *((uint64_t *)&p_buf[0]);
b = *((uint64_t *)&p_buf[8]);
}
@@ -103,7 +103,7 @@ private:
Vector<PackSource *> sources;
- PackedDir *root;
+ PackedDir *root = nullptr;
static PackedData *singleton;
bool disabled = false;
@@ -120,10 +120,10 @@ public:
static PackedData *get_singleton() { return singleton; }
Error add_pack(const String &p_path, bool p_replace_files, uint64_t p_offset);
- _FORCE_INLINE_ FileAccess *try_open_path(const String &p_path);
+ _FORCE_INLINE_ Ref<FileAccess> try_open_path(const String &p_path);
_FORCE_INLINE_ bool has_path(const String &p_path);
- _FORCE_INLINE_ DirAccess *try_open_directory(const String &p_path);
+ _FORCE_INLINE_ Ref<DirAccess> try_open_directory(const String &p_path);
_FORCE_INLINE_ bool has_directory(const String &p_path);
PackedData();
@@ -133,14 +133,14 @@ public:
class PackSource {
public:
virtual bool try_open_pack(const String &p_path, bool p_replace_files, uint64_t p_offset) = 0;
- virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file) = 0;
+ virtual Ref<FileAccess> get_file(const String &p_path, PackedData::PackedFile *p_file) = 0;
virtual ~PackSource() {}
};
class PackedSourcePCK : public PackSource {
public:
- virtual bool try_open_pack(const String &p_path, bool p_replace_files, uint64_t p_offset);
- virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file);
+ virtual bool try_open_pack(const String &p_path, bool p_replace_files, uint64_t p_offset) override;
+ virtual Ref<FileAccess> get_file(const String &p_path, PackedData::PackedFile *p_file) override;
};
class FileAccessPack : public FileAccess {
@@ -150,14 +150,13 @@ class FileAccessPack : public FileAccess {
mutable bool eof;
uint64_t off;
- FileAccess *f;
+ Ref<FileAccess> f;
virtual Error _open(const String &p_path, int p_mode_flags);
virtual uint64_t _get_modified_time(const String &p_file) { return 0; }
virtual uint32_t _get_unix_permissions(const String &p_file) { return 0; }
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) { return FAILED; }
public:
- virtual void close();
virtual bool is_open() const;
virtual void seek(uint64_t p_position);
@@ -183,10 +182,9 @@ public:
virtual bool file_exists(const String &p_name);
FileAccessPack(const String &p_path, const PackedData::PackedFile &p_file);
- ~FileAccessPack();
};
-FileAccess *PackedData::try_open_path(const String &p_path) {
+Ref<FileAccess> PackedData::try_open_path(const String &p_path) {
PathMD5 pmd5(p_path.md5_buffer());
Map<PathMD5, PackedFile>::Element *E = files.find(pmd5);
if (!E) {
@@ -204,9 +202,8 @@ bool PackedData::has_path(const String &p_path) {
}
bool PackedData::has_directory(const String &p_path) {
- DirAccess *da = try_open_directory(p_path);
- if (da) {
- memdelete(da);
+ Ref<DirAccess> da = try_open_directory(p_path);
+ if (da.is_valid()) {
return true;
} else {
return false;
@@ -233,7 +230,7 @@ public:
virtual String get_drive(int p_drive);
virtual Error change_dir(String p_dir);
- virtual String get_current_dir(bool p_include_drive = true);
+ virtual String get_current_dir(bool p_include_drive = true) const;
virtual bool file_exists(String p_file);
virtual bool dir_exists(String p_dir);
@@ -252,14 +249,12 @@ public:
virtual String get_filesystem_type() const;
DirAccessPack();
- ~DirAccessPack() {}
};
-DirAccess *PackedData::try_open_directory(const String &p_path) {
- DirAccess *da = memnew(DirAccessPack());
+Ref<DirAccess> PackedData::try_open_directory(const String &p_path) {
+ Ref<DirAccess> da = memnew(DirAccessPack());
if (da->change_dir(p_path) != OK) {
- memdelete(da);
- da = nullptr;
+ da = Ref<DirAccess>();
}
return da;
}
diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp
index 6347862775..17f2335a8e 100644
--- a/core/io/file_access_zip.cpp
+++ b/core/io/file_access_zip.cpp
@@ -38,20 +38,26 @@ ZipArchive *ZipArchive::instance = nullptr;
extern "C" {
-static void *godot_open(void *data, const char *p_fname, int mode) {
+struct ZipData {
+ Ref<FileAccess> f;
+};
+
+static void *godot_open(voidpf opaque, const char *p_fname, int mode) {
if (mode & ZLIB_FILEFUNC_MODE_WRITE) {
return nullptr;
}
- FileAccess *f = FileAccess::open(p_fname, FileAccess::READ);
- ERR_FAIL_COND_V(!f, nullptr);
+ Ref<FileAccess> f = FileAccess::open(p_fname, FileAccess::READ);
+ ERR_FAIL_COND_V(f.is_null(), nullptr);
- return f;
+ ZipData *zd = memnew(ZipData);
+ zd->f = f;
+ return zd;
}
-static uLong godot_read(void *data, void *fdata, void *buf, uLong size) {
- FileAccess *f = (FileAccess *)fdata;
- f->get_buffer((uint8_t *)buf, size);
+static uLong godot_read(voidpf opaque, voidpf stream, void *buf, uLong size) {
+ ZipData *zd = (ZipData *)stream;
+ zd->f->get_buffer((uint8_t *)buf, size);
return size;
}
@@ -60,42 +66,38 @@ static uLong godot_write(voidpf opaque, voidpf stream, const void *buf, uLong si
}
static long godot_tell(voidpf opaque, voidpf stream) {
- FileAccess *f = (FileAccess *)stream;
- return f->get_position();
+ ZipData *zd = (ZipData *)stream;
+ return zd->f->get_position();
}
static long godot_seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
- FileAccess *f = (FileAccess *)stream;
+ ZipData *zd = (ZipData *)stream;
uint64_t pos = offset;
switch (origin) {
case ZLIB_FILEFUNC_SEEK_CUR:
- pos = f->get_position() + offset;
+ pos = zd->f->get_position() + offset;
break;
case ZLIB_FILEFUNC_SEEK_END:
- pos = f->get_length() + offset;
+ pos = zd->f->get_length() + offset;
break;
default:
break;
}
- f->seek(pos);
+ zd->f->seek(pos);
return 0;
}
static int godot_close(voidpf opaque, voidpf stream) {
- FileAccess *f = (FileAccess *)stream;
- if (f) {
- f->close();
- memdelete(f);
- f = nullptr;
- }
+ ZipData *zd = (ZipData *)stream;
+ memdelete(zd);
return 0;
}
static int godot_testerror(voidpf opaque, voidpf stream) {
- FileAccess *f = (FileAccess *)stream;
- return f->get_error() != OK ? 1 : 0;
+ ZipData *zd = (ZipData *)stream;
+ return zd->f->get_error() != OK ? 1 : 0;
}
static voidpf godot_alloc(voidpf opaque, uInt items, uInt size) {
@@ -208,7 +210,7 @@ bool ZipArchive::file_exists(String p_name) const {
return files.has(p_name);
}
-FileAccess *ZipArchive::get_file(const String &p_path, PackedData::PackedFile *p_file) {
+Ref<FileAccess> ZipArchive::get_file(const String &p_path, PackedData::PackedFile *p_file) {
return memnew(FileAccessZip(p_path, *p_file));
}
@@ -233,7 +235,7 @@ ZipArchive::~ZipArchive() {
}
Error FileAccessZip::_open(const String &p_path, int p_mode_flags) {
- close();
+ _close();
ERR_FAIL_COND_V(p_mode_flags & FileAccess::WRITE, FAILED);
ZipArchive *arch = ZipArchive::get_singleton();
@@ -247,7 +249,7 @@ Error FileAccessZip::_open(const String &p_path, int p_mode_flags) {
return OK;
}
-void FileAccessZip::close() {
+void FileAccessZip::_close() {
if (!zfile) {
return;
}
@@ -339,7 +341,7 @@ FileAccessZip::FileAccessZip(const String &p_path, const PackedData::PackedFile
}
FileAccessZip::~FileAccessZip() {
- close();
+ _close();
}
#endif // MINIZIP_ENABLED
diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h
index 7cd5893101..2504aeedc4 100644
--- a/core/io/file_access_zip.h
+++ b/core/io/file_access_zip.h
@@ -67,8 +67,8 @@ public:
bool file_exists(String p_name) const;
- virtual bool try_open_pack(const String &p_path, bool p_replace_files, uint64_t p_offset);
- FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file);
+ virtual bool try_open_pack(const String &p_path, bool p_replace_files, uint64_t p_offset) override;
+ Ref<FileAccess> get_file(const String &p_path, PackedData::PackedFile *p_file) override;
static ZipArchive *get_singleton();
@@ -82,9 +82,10 @@ class FileAccessZip : public FileAccess {
mutable bool at_eof;
+ void _close();
+
public:
virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
- virtual void close(); ///< close a file
virtual bool is_open() const; ///< true when file is open
virtual void seek(uint64_t p_position); ///< seek to a given position
diff --git a/core/io/http_client_tcp.cpp b/core/io/http_client_tcp.cpp
index f920799677..d983d86b99 100644
--- a/core/io/http_client_tcp.cpp
+++ b/core/io/http_client_tcp.cpp
@@ -264,6 +264,9 @@ void HTTPClientTCP::close() {
}
Error HTTPClientTCP::poll() {
+ if (tcp_connection.is_valid()) {
+ tcp_connection->poll();
+ }
switch (status) {
case STATUS_RESOLVING: {
ERR_FAIL_COND_V(resolving == IP::RESOLVER_INVALID_ID, ERR_BUG);
diff --git a/core/io/image.cpp b/core/io/image.cpp
index 5376b78a89..661a9f7177 100644
--- a/core/io/image.cpp
+++ b/core/io/image.cpp
@@ -378,25 +378,25 @@ Image::Image3DValidateError Image::validate_3d_image(Image::Format p_format, int
String Image::get_3d_image_validation_error_text(Image3DValidateError p_error) {
switch (p_error) {
case VALIDATE_3D_OK: {
- return TTR("Ok");
+ return "Ok";
} break;
case VALIDATE_3D_ERR_IMAGE_EMPTY: {
- return TTR("Empty Image found");
+ return "Empty Image found";
} break;
case VALIDATE_3D_ERR_MISSING_IMAGES: {
- return TTR("Missing Images");
+ return "Missing Images";
} break;
case VALIDATE_3D_ERR_EXTRA_IMAGES: {
- return TTR("Too many Images");
+ return "Too many Images";
} break;
case VALIDATE_3D_ERR_IMAGE_SIZE_MISMATCH: {
- return TTR("Image size mismatch");
+ return "Image size mismatch";
} break;
case VALIDATE_3D_ERR_IMAGE_FORMAT_MISMATCH: {
- return TTR("Image format mismatch");
+ return "Image format mismatch";
} break;
case VALIDATE_3D_ERR_IMAGE_HAS_MIPMAPS: {
- return TTR("Image has included mipmaps");
+ return "Image has included mipmaps";
} break;
}
return String();
@@ -2442,6 +2442,39 @@ Ref<Image> Image::get_rect(const Rect2 &p_area) const {
return img;
}
+void Image::_get_clipped_src_and_dest_rects(const Ref<Image> &p_src, const Rect2i &p_src_rect, const Point2i &p_dest, Rect2i &r_clipped_src_rect, Rect2i &r_clipped_dest_rect) const {
+ r_clipped_dest_rect.position = p_dest;
+ r_clipped_src_rect = p_src_rect;
+
+ if (r_clipped_src_rect.position.x < 0) {
+ r_clipped_dest_rect.position.x -= r_clipped_src_rect.position.x;
+ r_clipped_src_rect.size.x += r_clipped_src_rect.position.x;
+ r_clipped_src_rect.position.x = 0;
+ }
+ if (r_clipped_src_rect.position.y < 0) {
+ r_clipped_dest_rect.position.y -= r_clipped_src_rect.position.y;
+ r_clipped_src_rect.size.y += r_clipped_src_rect.position.y;
+ r_clipped_src_rect.position.y = 0;
+ }
+
+ if (r_clipped_dest_rect.position.x < 0) {
+ r_clipped_src_rect.position.x -= r_clipped_dest_rect.position.x;
+ r_clipped_src_rect.size.x += r_clipped_dest_rect.position.x;
+ r_clipped_dest_rect.position.x = 0;
+ }
+ if (r_clipped_dest_rect.position.y < 0) {
+ r_clipped_src_rect.position.y -= r_clipped_dest_rect.position.y;
+ r_clipped_src_rect.size.y += r_clipped_dest_rect.position.y;
+ r_clipped_dest_rect.position.y = 0;
+ }
+
+ r_clipped_src_rect.size.x = MAX(0, MIN(r_clipped_src_rect.size.x, MIN(p_src->width - r_clipped_src_rect.position.x, width - r_clipped_dest_rect.position.x)));
+ r_clipped_src_rect.size.y = MAX(0, MIN(r_clipped_src_rect.size.y, MIN(p_src->height - r_clipped_src_rect.position.y, height - r_clipped_dest_rect.position.y)));
+
+ r_clipped_dest_rect.size.x = r_clipped_src_rect.size.x;
+ r_clipped_dest_rect.size.y = r_clipped_src_rect.size.y;
+}
+
void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest) {
ERR_FAIL_COND_MSG(p_src.is_null(), "It's not a reference to a valid Image object.");
int dsize = data.size();
@@ -2451,22 +2484,13 @@ void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Po
ERR_FAIL_COND(format != p_src->format);
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot blit_rect in compressed or custom image formats.");
- Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).intersection(p_src_rect);
-
- if (p_dest.x < 0) {
- clipped_src_rect.position.x = ABS(p_dest.x);
- }
- if (p_dest.y < 0) {
- clipped_src_rect.position.y = ABS(p_dest.y);
- }
-
- if (clipped_src_rect.has_no_area()) {
+ Rect2i src_rect;
+ Rect2i dest_rect;
+ _get_clipped_src_and_dest_rects(p_src, p_src_rect, p_dest, src_rect, dest_rect);
+ if (src_rect.has_no_area() || dest_rect.has_no_area()) {
return;
}
- Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
- Rect2i dest_rect = Rect2i(0, 0, width, height).intersection(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
-
uint8_t *wp = data.ptrw();
uint8_t *dst_data_ptr = wp;
@@ -2477,8 +2501,8 @@ void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Po
for (int i = 0; i < dest_rect.size.y; i++) {
for (int j = 0; j < dest_rect.size.x; j++) {
- int src_x = clipped_src_rect.position.x + j;
- int src_y = clipped_src_rect.position.y + i;
+ int src_x = src_rect.position.x + j;
+ int src_y = src_rect.position.y + i;
int dst_x = dest_rect.position.x + j;
int dst_y = dest_rect.position.y + i;
@@ -2506,22 +2530,13 @@ void Image::blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, co
ERR_FAIL_COND_MSG(p_src->height != p_mask->height, "Source image height is different from mask height.");
ERR_FAIL_COND(format != p_src->format);
- Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).intersection(p_src_rect);
-
- if (p_dest.x < 0) {
- clipped_src_rect.position.x = ABS(p_dest.x);
- }
- if (p_dest.y < 0) {
- clipped_src_rect.position.y = ABS(p_dest.y);
- }
-
- if (clipped_src_rect.has_no_area()) {
+ Rect2i src_rect;
+ Rect2i dest_rect;
+ _get_clipped_src_and_dest_rects(p_src, p_src_rect, p_dest, src_rect, dest_rect);
+ if (src_rect.has_no_area() || dest_rect.has_no_area()) {
return;
}
- Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
- Rect2i dest_rect = Rect2i(0, 0, width, height).intersection(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
-
uint8_t *wp = data.ptrw();
uint8_t *dst_data_ptr = wp;
@@ -2534,8 +2549,8 @@ void Image::blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, co
for (int i = 0; i < dest_rect.size.y; i++) {
for (int j = 0; j < dest_rect.size.x; j++) {
- int src_x = clipped_src_rect.position.x + j;
- int src_y = clipped_src_rect.position.y + i;
+ int src_x = src_rect.position.x + j;
+ int src_y = src_rect.position.y + i;
if (msk->get_pixel(src_x, src_y).a != 0) {
int dst_x = dest_rect.position.x + j;
@@ -2560,28 +2575,19 @@ void Image::blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const P
ERR_FAIL_COND(srcdsize == 0);
ERR_FAIL_COND(format != p_src->format);
- Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).intersection(p_src_rect);
-
- if (p_dest.x < 0) {
- clipped_src_rect.position.x = ABS(p_dest.x);
- }
- if (p_dest.y < 0) {
- clipped_src_rect.position.y = ABS(p_dest.y);
- }
-
- if (clipped_src_rect.has_no_area()) {
+ Rect2i src_rect;
+ Rect2i dest_rect;
+ _get_clipped_src_and_dest_rects(p_src, p_src_rect, p_dest, src_rect, dest_rect);
+ if (src_rect.has_no_area() || dest_rect.has_no_area()) {
return;
}
- Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
- Rect2i dest_rect = Rect2i(0, 0, width, height).intersection(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
-
Ref<Image> img = p_src;
for (int i = 0; i < dest_rect.size.y; i++) {
for (int j = 0; j < dest_rect.size.x; j++) {
- int src_x = clipped_src_rect.position.x + j;
- int src_y = clipped_src_rect.position.y + i;
+ int src_x = src_rect.position.x + j;
+ int src_y = src_rect.position.y + i;
int dst_x = dest_rect.position.x + j;
int dst_y = dest_rect.position.y + i;
@@ -2609,29 +2615,20 @@ void Image::blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, c
ERR_FAIL_COND_MSG(p_src->height != p_mask->height, "Source image height is different from mask height.");
ERR_FAIL_COND(format != p_src->format);
- Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).intersection(p_src_rect);
-
- if (p_dest.x < 0) {
- clipped_src_rect.position.x = ABS(p_dest.x);
- }
- if (p_dest.y < 0) {
- clipped_src_rect.position.y = ABS(p_dest.y);
- }
-
- if (clipped_src_rect.has_no_area()) {
+ Rect2i src_rect;
+ Rect2i dest_rect;
+ _get_clipped_src_and_dest_rects(p_src, p_src_rect, p_dest, src_rect, dest_rect);
+ if (src_rect.has_no_area() || dest_rect.has_no_area()) {
return;
}
- Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
- Rect2i dest_rect = Rect2i(0, 0, width, height).intersection(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
-
Ref<Image> img = p_src;
Ref<Image> msk = p_mask;
for (int i = 0; i < dest_rect.size.y; i++) {
for (int j = 0; j < dest_rect.size.x; j++) {
- int src_x = clipped_src_rect.position.x + j;
- int src_y = clipped_src_rect.position.y + i;
+ int src_x = src_rect.position.x + j;
+ int src_y = src_rect.position.y + i;
// If the mask's pixel is transparent then we skip it
//Color c = msk->get_pixel(src_x, src_y);
@@ -2726,6 +2723,7 @@ Vector<uint8_t> (*Image::png_packer)(const Ref<Image> &) = nullptr;
Ref<Image> (*Image::png_unpacker)(const Vector<uint8_t> &) = nullptr;
Vector<uint8_t> (*Image::basis_universal_packer)(const Ref<Image> &, Image::UsedChannels) = nullptr;
Ref<Image> (*Image::basis_universal_unpacker)(const Vector<uint8_t> &) = nullptr;
+Ref<Image> (*Image::basis_universal_unpacker_ptr)(const uint8_t *, int) = nullptr;
void Image::_set_data(const Dictionary &p_data) {
ERR_FAIL_COND(!p_data.has("width"));
@@ -3008,7 +3006,7 @@ void Image::adjust_bcs(float p_brightness, float p_contrast, float p_saturation)
}
}
-Image::UsedChannels Image::detect_used_channels(CompressSource p_source) {
+Image::UsedChannels Image::detect_used_channels(CompressSource p_source) const {
ERR_FAIL_COND_V(data.size() == 0, USED_CHANNELS_RGBA);
ERR_FAIL_COND_V(is_compressed(), USED_CHANNELS_RGBA);
bool r = false, g = false, b = false, a = false, c = false;
@@ -3275,7 +3273,7 @@ Ref<Image> Image::rgbe_to_srgb() {
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
- new_image->set_pixel(col, row, get_pixel(col, row).to_srgb());
+ new_image->set_pixel(col, row, get_pixel(col, row).linear_to_srgb());
}
}
@@ -3613,6 +3611,10 @@ Image::Image(const uint8_t *p_mem_png_jpg, int p_len) {
if (is_empty() && _jpg_mem_loader_func) {
copy_internals_from(_jpg_mem_loader_func(p_mem_png_jpg, p_len));
}
+
+ if (is_empty() && _webp_mem_loader_func) {
+ copy_internals_from(_webp_mem_loader_func(p_mem_png_jpg, p_len));
+ }
}
Ref<Resource> Image::duplicate(bool p_subresources) const {
diff --git a/core/io/image.h b/core/io/image.h
index 39c700565b..1025554d51 100644
--- a/core/io/image.h
+++ b/core/io/image.h
@@ -147,6 +147,7 @@ public:
static Ref<Image> (*png_unpacker)(const Vector<uint8_t> &p_buffer);
static Vector<uint8_t> (*basis_universal_packer)(const Ref<Image> &p_image, UsedChannels p_channels);
static Ref<Image> (*basis_universal_unpacker)(const Vector<uint8_t> &p_buffer);
+ static Ref<Image> (*basis_universal_unpacker_ptr)(const uint8_t *p_data, int p_size);
_FORCE_INLINE_ Color _get_color_at_ofs(const uint8_t *ptr, uint32_t ofs) const;
_FORCE_INLINE_ void _set_color_at_ofs(uint8_t *ptr, uint32_t ofs, const Color &p_color);
@@ -174,6 +175,8 @@ private:
static int _get_dst_image_size(int p_width, int p_height, Format p_format, int &r_mipmaps, int p_mipmaps = -1, int *r_mm_width = nullptr, int *r_mm_height = nullptr);
bool _can_modify(Format p_format) const;
+ _FORCE_INLINE_ void _get_clipped_src_and_dest_rects(const Ref<Image> &p_src, const Rect2i &p_src_rect, const Point2i &p_dest, Rect2i &r_clipped_src_rect, Rect2i &r_clipped_dest_rect) const;
+
_FORCE_INLINE_ void _put_pixelb(int p_x, int p_y, uint32_t p_pixel_size, uint8_t *p_data, const uint8_t *p_pixel);
_FORCE_INLINE_ void _get_pixelb(int p_x, int p_y, uint32_t p_pixel_size, const uint8_t *p_data, uint8_t *p_pixel);
@@ -379,7 +382,7 @@ public:
virtual Ref<Resource> duplicate(bool p_subresources = false) const override;
- UsedChannels detect_used_channels(CompressSource p_source = COMPRESS_SOURCE_GENERIC);
+ UsedChannels detect_used_channels(CompressSource p_source = COMPRESS_SOURCE_GENERIC) const;
void optimize_channels();
Color get_pixelv(const Point2i &p_point) const;
diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp
index 5518ec8ceb..2ccc95f0de 100644
--- a/core/io/image_loader.cpp
+++ b/core/io/image_loader.cpp
@@ -44,17 +44,14 @@ bool ImageFormatLoader::recognize(const String &p_extension) const {
return false;
}
-Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom, bool p_force_linear, float p_scale) {
+Error ImageLoader::load_image(String p_file, Ref<Image> p_image, Ref<FileAccess> p_custom, bool p_force_linear, float p_scale) {
ERR_FAIL_COND_V_MSG(p_image.is_null(), ERR_INVALID_PARAMETER, "It's not a reference to a valid Image object.");
- FileAccess *f = p_custom;
- if (!f) {
+ Ref<FileAccess> f = p_custom;
+ if (f.is_null()) {
Error err;
f = FileAccess::open(p_file, FileAccess::READ, &err);
- if (!f) {
- ERR_PRINT("Error opening file '" + p_file + "'.");
- return err;
- }
+ ERR_FAIL_COND_V_MSG(f.is_null(), err, "Error opening file '" + p_file + "'.");
}
String extension = p_file.get_extension();
@@ -69,18 +66,10 @@ Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_c
}
if (err != ERR_FILE_UNRECOGNIZED) {
- if (!p_custom) {
- memdelete(f);
- }
-
return err;
}
}
- if (!p_custom) {
- memdelete(f);
- }
-
return ERR_FILE_UNRECOGNIZED;
}
@@ -123,8 +112,8 @@ void ImageLoader::cleanup() {
/////////////////
RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
- FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
- if (!f) {
+ Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
+ if (f.is_null()) {
if (r_error) {
*r_error = ERR_CANT_OPEN;
}
@@ -136,7 +125,6 @@ RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_origin
bool unrecognized = header[0] != 'G' || header[1] != 'D' || header[2] != 'I' || header[3] != 'M';
if (unrecognized) {
- memdelete(f);
if (r_error) {
*r_error = ERR_FILE_UNRECOGNIZED;
}
@@ -155,7 +143,6 @@ RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_origin
}
if (idx == -1) {
- memdelete(f);
if (r_error) {
*r_error = ERR_FILE_UNRECOGNIZED;
}
@@ -167,8 +154,6 @@ RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_origin
Error err = ImageLoader::loader[idx]->load_image(image, f, false, 1.0);
- memdelete(f);
-
if (err != OK) {
if (r_error) {
*r_error = err;
diff --git a/core/io/image_loader.h b/core/io/image_loader.h
index 37d7620f96..9409617268 100644
--- a/core/io/image_loader.h
+++ b/core/io/image_loader.h
@@ -44,7 +44,7 @@ class ImageFormatLoader {
friend class ResourceFormatLoaderImage;
protected:
- virtual Error load_image(Ref<Image> p_image, FileAccess *p_fileaccess, bool p_force_linear, float p_scale) = 0;
+ virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> p_fileaccess, bool p_force_linear, float p_scale) = 0;
virtual void get_recognized_extensions(List<String> *p_extensions) const = 0;
bool recognize(const String &p_extension) const;
@@ -58,7 +58,7 @@ class ImageLoader {
protected:
public:
- static Error load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom = nullptr, bool p_force_linear = false, float p_scale = 1.0);
+ static Error load_image(String p_file, Ref<Image> p_image, Ref<FileAccess> p_custom = Ref<FileAccess>(), bool p_force_linear = false, float p_scale = 1.0);
static void get_recognized_extensions(List<String> *p_extensions);
static ImageFormatLoader *recognize(const String &p_extension);
diff --git a/core/io/ip.cpp b/core/io/ip.cpp
index 8e0d47e762..52674150bb 100644
--- a/core/io/ip.cpp
+++ b/core/io/ip.cpp
@@ -109,7 +109,7 @@ struct _IP_ResolverPrivate {
}
static void _thread_function(void *self) {
- _IP_ResolverPrivate *ipr = (_IP_ResolverPrivate *)self;
+ _IP_ResolverPrivate *ipr = static_cast<_IP_ResolverPrivate *>(self);
while (!ipr->thread_abort) {
ipr->sem.wait();
@@ -186,7 +186,7 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Typ
}
IP::ResolverStatus IP::get_resolve_item_status(ResolverID p_id) const {
- ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, IP::RESOLVER_STATUS_NONE);
+ ERR_FAIL_INDEX_V_MSG(p_id, IP::RESOLVER_MAX_QUERIES, IP::RESOLVER_STATUS_NONE, vformat("Too many concurrent DNS resolver queries (%d, but should be %d at most). Try performing less network requests at once.", p_id, IP::RESOLVER_MAX_QUERIES));
IP::ResolverStatus res = resolver->queue[p_id].status.get();
if (res == IP::RESOLVER_STATUS_NONE) {
@@ -197,7 +197,7 @@ IP::ResolverStatus IP::get_resolve_item_status(ResolverID p_id) const {
}
IPAddress IP::get_resolve_item_address(ResolverID p_id) const {
- ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, IPAddress());
+ ERR_FAIL_INDEX_V_MSG(p_id, IP::RESOLVER_MAX_QUERIES, IPAddress(), vformat("Too many concurrent DNS resolver queries (%d, but should be %d at most). Try performing less network requests at once.", p_id, IP::RESOLVER_MAX_QUERIES));
MutexLock lock(resolver->mutex);
@@ -217,7 +217,7 @@ IPAddress IP::get_resolve_item_address(ResolverID p_id) const {
}
Array IP::get_resolve_item_addresses(ResolverID p_id) const {
- ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, Array());
+ ERR_FAIL_INDEX_V_MSG(p_id, IP::RESOLVER_MAX_QUERIES, Array(), vformat("Too many concurrent DNS resolver queries (%d, but should be %d at most). Try performing less network requests at once.", p_id, IP::RESOLVER_MAX_QUERIES));
MutexLock lock(resolver->mutex);
if (resolver->queue[p_id].status.get() != IP::RESOLVER_STATUS_DONE) {
@@ -237,7 +237,7 @@ Array IP::get_resolve_item_addresses(ResolverID p_id) const {
}
void IP::erase_resolve_item(ResolverID p_id) {
- ERR_FAIL_INDEX(p_id, IP::RESOLVER_MAX_QUERIES);
+ ERR_FAIL_INDEX_MSG(p_id, IP::RESOLVER_MAX_QUERIES, vformat("Too many concurrent DNS resolver queries (%d, but should be %d at most). Try performing less network requests at once.", p_id, IP::RESOLVER_MAX_QUERIES));
resolver->queue[p_id].status.set(IP::RESOLVER_STATUS_NONE);
}
diff --git a/core/io/ip.h b/core/io/ip.h
index 5602710550..06ff8a4d70 100644
--- a/core/io/ip.h
+++ b/core/io/ip.h
@@ -38,7 +38,6 @@ struct _IP_ResolverPrivate;
class IP : public Object {
GDCLASS(IP, Object);
- OBJ_CATEGORY("Networking");
public:
enum ResolverStatus {
@@ -56,14 +55,14 @@ public:
};
enum {
- RESOLVER_MAX_QUERIES = 32,
+ RESOLVER_MAX_QUERIES = 256,
RESOLVER_INVALID_ID = -1
};
typedef int ResolverID;
private:
- _IP_ResolverPrivate *resolver;
+ _IP_ResolverPrivate *resolver = nullptr;
protected:
static IP *singleton;
diff --git a/core/io/logger.cpp b/core/io/logger.cpp
index 2b6f230434..c19fc2820b 100644
--- a/core/io/logger.cpp
+++ b/core/io/logger.cpp
@@ -115,21 +115,14 @@ void Logger::logf_error(const char *p_format, ...) {
va_end(argp);
}
-void RotatedFileLogger::close_file() {
- if (file) {
- memdelete(file);
- file = nullptr;
- }
-}
-
void RotatedFileLogger::clear_old_backups() {
int max_backups = max_files - 1; // -1 for the current file
String basename = base_path.get_file().get_basename();
String extension = base_path.get_extension();
- DirAccessRef da = DirAccess::open(base_path.get_base_dir());
- if (!da) {
+ Ref<DirAccess> da = DirAccess::open(base_path.get_base_dir());
+ if (da.is_null()) {
return;
}
@@ -155,7 +148,7 @@ void RotatedFileLogger::clear_old_backups() {
}
void RotatedFileLogger::rotate_file() {
- close_file();
+ file.unref();
if (FileAccess::exists(base_path)) {
if (max_files > 1) {
@@ -165,20 +158,21 @@ void RotatedFileLogger::rotate_file() {
backup_name += "." + base_path.get_extension();
}
- DirAccessRef da = DirAccess::open(base_path.get_base_dir());
- if (da) {
+ Ref<DirAccess> da = DirAccess::open(base_path.get_base_dir());
+ if (da.is_valid()) {
da->copy(base_path, backup_name);
}
clear_old_backups();
}
} else {
- DirAccessRef da = DirAccess::create(DirAccess::ACCESS_USERDATA);
- if (da) {
+ Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_USERDATA);
+ if (da.is_valid()) {
da->make_dir_recursive(base_path.get_base_dir());
}
}
file = FileAccess::open(base_path, FileAccess::WRITE);
+ file->detach_from_objectdb(); // Note: This FileAccess instance will exist longer than ObjectDB, therefor can't be registered in ObjectDB.
}
RotatedFileLogger::RotatedFileLogger(const String &p_base_path, int p_max_files) :
@@ -192,7 +186,7 @@ void RotatedFileLogger::logv(const char *p_format, va_list p_list, bool p_err) {
return;
}
- if (file) {
+ if (file.is_valid()) {
const int static_buf_size = 512;
char static_buf[static_buf_size];
char *buf = static_buf;
@@ -218,10 +212,6 @@ void RotatedFileLogger::logv(const char *p_format, va_list p_list, bool p_err) {
}
}
-RotatedFileLogger::~RotatedFileLogger() {
- close_file();
-}
-
void StdLogger::logv(const char *p_format, va_list p_list, bool p_err) {
if (!should_log(p_err)) {
return;
diff --git a/core/io/logger.h b/core/io/logger.h
index 047ee3d0f1..8ac086e376 100644
--- a/core/io/logger.h
+++ b/core/io/logger.h
@@ -67,7 +67,7 @@ public:
*/
class StdLogger : public Logger {
public:
- virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0;
+ virtual void logv(const char *p_format, va_list p_list, bool p_err) override _PRINTF_FORMAT_ATTRIBUTE_2_0;
virtual ~StdLogger() {}
};
@@ -81,28 +81,25 @@ class RotatedFileLogger : public Logger {
String base_path;
int max_files;
- FileAccess *file = nullptr;
+ Ref<FileAccess> file;
- void close_file();
void clear_old_backups();
void rotate_file();
public:
- RotatedFileLogger(const String &p_base_path, int p_max_files = 10);
+ explicit RotatedFileLogger(const String &p_base_path, int p_max_files = 10);
- virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0;
-
- virtual ~RotatedFileLogger();
+ virtual void logv(const char *p_format, va_list p_list, bool p_err) override _PRINTF_FORMAT_ATTRIBUTE_2_0;
};
class CompositeLogger : public Logger {
Vector<Logger *> loggers;
public:
- CompositeLogger(Vector<Logger *> p_loggers);
+ explicit CompositeLogger(Vector<Logger *> p_loggers);
- virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0;
- virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type = ERR_ERROR);
+ virtual void logv(const char *p_format, va_list p_list, bool p_err) override _PRINTF_FORMAT_ATTRIBUTE_2_0;
+ virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type = ERR_ERROR) override;
void add_logger(Logger *p_logger);
diff --git a/core/io/packed_data_container.cpp b/core/io/packed_data_container.cpp
index 14183b472b..027fdd51aa 100644
--- a/core/io/packed_data_container.cpp
+++ b/core/io/packed_data_container.cpp
@@ -105,7 +105,7 @@ Variant PackedDataContainer::_get_at_ofs(uint32_t p_ofs, const uint8_t *p_buf, b
if (type == TYPE_ARRAY || type == TYPE_DICT) {
Ref<PackedDataContainerRef> pdcr = memnew(PackedDataContainerRef);
- Ref<PackedDataContainer> pdc = Ref<PackedDataContainer>((PackedDataContainer *)this);
+ Ref<PackedDataContainer> pdc = Ref<PackedDataContainer>(const_cast<PackedDataContainer *>(this));
pdcr->from = pdc;
pdcr->offset = p_ofs;
diff --git a/core/io/packet_peer_udp.cpp b/core/io/packet_peer_udp.cpp
index 503eb17cae..84d1f3ebd4 100644
--- a/core/io/packet_peer_udp.cpp
+++ b/core/io/packet_peer_udp.cpp
@@ -242,7 +242,7 @@ Error PacketPeerUDP::connect_to_host(const IPAddress &p_host, int p_port) {
return OK;
}
-bool PacketPeerUDP::is_connected_to_host() const {
+bool PacketPeerUDP::is_socket_connected() const {
return connected;
}
@@ -348,7 +348,7 @@ void PacketPeerUDP::_bind_methods() {
ClassDB::bind_method(D_METHOD("wait"), &PacketPeerUDP::wait);
ClassDB::bind_method(D_METHOD("is_bound"), &PacketPeerUDP::is_bound);
ClassDB::bind_method(D_METHOD("connect_to_host", "host", "port"), &PacketPeerUDP::connect_to_host);
- ClassDB::bind_method(D_METHOD("is_connected_to_host"), &PacketPeerUDP::is_connected_to_host);
+ ClassDB::bind_method(D_METHOD("is_socket_connected"), &PacketPeerUDP::is_socket_connected);
ClassDB::bind_method(D_METHOD("get_packet_ip"), &PacketPeerUDP::_get_packet_ip);
ClassDB::bind_method(D_METHOD("get_packet_port"), &PacketPeerUDP::get_packet_port);
ClassDB::bind_method(D_METHOD("get_local_port"), &PacketPeerUDP::get_local_port);
diff --git a/core/io/packet_peer_udp.h b/core/io/packet_peer_udp.h
index 444a6dd5ba..a174cf5347 100644
--- a/core/io/packet_peer_udp.h
+++ b/core/io/packet_peer_udp.h
@@ -79,7 +79,7 @@ public:
void disconnect_shared_socket(); // Used by UDPServer
Error store_packet(IPAddress p_ip, uint32_t p_port, uint8_t *p_buf, int p_buf_size); // Used internally and by UDPServer
Error connect_to_host(const IPAddress &p_host, int p_port);
- bool is_connected_to_host() const;
+ bool is_socket_connected() const;
IPAddress get_packet_address() const;
int get_packet_port() const;
diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp
index b3bf0cff2d..aa1b323db2 100644
--- a/core/io/pck_packer.cpp
+++ b/core/io/pck_packer.cpp
@@ -83,13 +83,8 @@ Error PCKPacker::pck_start(const String &p_file, int p_alignment, const String &
}
enc_dir = p_encrypt_directory;
- if (file != nullptr) {
- memdelete(file);
- }
-
file = FileAccess::open(p_file, FileAccess::WRITE);
-
- ERR_FAIL_COND_V_MSG(!file, ERR_CANT_CREATE, "Can't open file to write: " + String(p_file) + ".");
+ ERR_FAIL_COND_V_MSG(file.is_null(), ERR_CANT_CREATE, "Can't open file to write: " + String(p_file) + ".");
alignment = p_alignment;
@@ -112,8 +107,8 @@ Error PCKPacker::pck_start(const String &p_file, int p_alignment, const String &
}
Error PCKPacker::add_file(const String &p_file, const String &p_src, bool p_encrypt) {
- FileAccess *f = FileAccess::open(p_src, FileAccess::READ);
- if (!f) {
+ Ref<FileAccess> f = FileAccess::open(p_src, FileAccess::READ);
+ if (f.is_null()) {
return ERR_FILE_CANT_OPEN;
}
@@ -149,14 +144,11 @@ Error PCKPacker::add_file(const String &p_file, const String &p_src, bool p_encr
files.push_back(pf);
- f->close();
- memdelete(f);
-
return OK;
}
Error PCKPacker::flush(bool p_verbose) {
- ERR_FAIL_COND_V_MSG(!file, ERR_INVALID_PARAMETER, "File must be opened before use.");
+ ERR_FAIL_COND_V_MSG(file.is_null(), ERR_INVALID_PARAMETER, "File must be opened before use.");
int64_t file_base_ofs = file->get_position();
file->store_64(0); // files base
@@ -168,12 +160,12 @@ Error PCKPacker::flush(bool p_verbose) {
// write the index
file->store_32(files.size());
- FileAccessEncrypted *fae = nullptr;
- FileAccess *fhead = file;
+ Ref<FileAccessEncrypted> fae;
+ Ref<FileAccess> fhead = file;
if (enc_dir) {
- fae = memnew(FileAccessEncrypted);
- ERR_FAIL_COND_V(!fae, ERR_CANT_CREATE);
+ fae.instantiate();
+ ERR_FAIL_COND_V(fae.is_null(), ERR_CANT_CREATE);
Error err = fae->open_and_parse(file, key, FileAccessEncrypted::MODE_WRITE_AES256, false);
ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE);
@@ -202,9 +194,9 @@ Error PCKPacker::flush(bool p_verbose) {
fhead->store_32(flags);
}
- if (fae) {
- fae->release();
- memdelete(fae);
+ if (fae.is_valid()) {
+ fhead.unref();
+ fae.unref();
}
int header_padding = _get_pad(alignment, file->get_position());
@@ -222,14 +214,13 @@ Error PCKPacker::flush(bool p_verbose) {
int count = 0;
for (int i = 0; i < files.size(); i++) {
- FileAccess *src = FileAccess::open(files[i].src_path, FileAccess::READ);
+ Ref<FileAccess> src = FileAccess::open(files[i].src_path, FileAccess::READ);
uint64_t to_write = files[i].size;
- fae = nullptr;
- FileAccess *ftmp = file;
+ Ref<FileAccess> ftmp = file;
if (files[i].encrypted) {
- fae = memnew(FileAccessEncrypted);
- ERR_FAIL_COND_V(!fae, ERR_CANT_CREATE);
+ fae.instantiate();
+ ERR_FAIL_COND_V(fae.is_null(), ERR_CANT_CREATE);
Error err = fae->open_and_parse(file, key, FileAccessEncrypted::MODE_WRITE_AES256, false);
ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE);
@@ -242,9 +233,9 @@ Error PCKPacker::flush(bool p_verbose) {
to_write -= read;
}
- if (fae) {
- fae->release();
- memdelete(fae);
+ if (fae.is_valid()) {
+ ftmp.unref();
+ fae.unref();
}
int pad = _get_pad(alignment, file->get_position());
@@ -252,8 +243,6 @@ Error PCKPacker::flush(bool p_verbose) {
file->store_8(Math::rand() % 256);
}
- src->close();
- memdelete(src);
count += 1;
const int file_num = files.size();
if (p_verbose && (file_num > 0)) {
@@ -265,15 +254,8 @@ Error PCKPacker::flush(bool p_verbose) {
printf("\n");
}
- file->close();
+ file.unref();
memdelete_arr(buf);
return OK;
}
-
-PCKPacker::~PCKPacker() {
- if (file != nullptr) {
- memdelete(file);
- }
- file = nullptr;
-}
diff --git a/core/io/pck_packer.h b/core/io/pck_packer.h
index 583171a70b..77ec293fb2 100644
--- a/core/io/pck_packer.h
+++ b/core/io/pck_packer.h
@@ -38,7 +38,7 @@ class FileAccess;
class PCKPacker : public RefCounted {
GDCLASS(PCKPacker, RefCounted);
- FileAccess *file = nullptr;
+ Ref<FileAccess> file;
int alignment = 0;
uint64_t ofs = 0;
@@ -63,7 +63,6 @@ public:
Error flush(bool p_verbose = false);
PCKPacker() {}
- ~PCKPacker();
};
#endif // PCK_PACKER_H
diff --git a/core/io/resource.cpp b/core/io/resource.cpp
index f90a6e9304..96efffd49b 100644
--- a/core/io/resource.cpp
+++ b/core/io/resource.cpp
@@ -257,7 +257,7 @@ Ref<Resource> Resource::duplicate(bool p_subresources) const {
List<PropertyInfo> plist;
get_property_list(&plist);
- Ref<Resource> r = (Resource *)ClassDB::instantiate(get_class());
+ Ref<Resource> r = static_cast<Resource *>(ClassDB::instantiate(get_class()));
ERR_FAIL_COND_V(r.is_null(), Ref<Resource>());
for (const PropertyInfo &E : plist) {
@@ -538,10 +538,10 @@ void ResourceCache::dump(const char *p_file, bool p_short) {
Map<String, int> type_count;
- FileAccess *f = nullptr;
+ Ref<FileAccess> f;
if (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) + "'.");
+ ERR_FAIL_COND_MSG(f.is_null(), "Cannot create file at path '" + String::utf8(p_file) + "'.");
}
const String *K = nullptr;
@@ -555,21 +555,17 @@ void ResourceCache::dump(const char *p_file, bool p_short) {
type_count[r->get_class()]++;
if (!p_short) {
- if (f) {
+ if (f.is_valid()) {
f->store_line(r->get_class() + ": " + r->get_path());
}
}
}
for (const KeyValue<String, int> &E : type_count) {
- if (f) {
+ if (f.is_valid()) {
f->store_line(E.key + " count: " + itos(E.value));
}
}
- if (f) {
- f->close();
- memdelete(f);
- }
lock.read_unlock();
#else
diff --git a/core/io/resource.h b/core/io/resource.h
index b1e1c15541..8068000f32 100644
--- a/core/io/resource.h
+++ b/core/io/resource.h
@@ -48,7 +48,6 @@ private:
class Resource : public RefCounted {
GDCLASS(Resource, RefCounted);
- OBJ_CATEGORY("Resources");
public:
static void register_custom_data_to_otdb() { ClassDB::add_resource_base_extension("res", get_class_static()); }
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index b65993e3dd..b6988109c5 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -101,6 +101,50 @@ void ResourceLoaderBinary::_advance_padding(uint32_t p_len) {
}
}
+static Error read_reals(real_t *dst, Ref<FileAccess> &f, size_t count) {
+ if (f->real_is_double) {
+ if (sizeof(real_t) == 8) {
+ // Ideal case with double-precision
+ f->get_buffer((uint8_t *)dst, count * sizeof(double));
+#ifdef BIG_ENDIAN_ENABLED
+ {
+ uint64_t *dst = (uint64_t *)dst;
+ for (size_t i = 0; i < count; i++) {
+ dst[i] = BSWAP64(dst[i]);
+ }
+ }
+#endif
+ } else if (sizeof(real_t) == 4) {
+ // May be slower, but this is for compatibility. Eventually the data should be converted.
+ for (size_t i = 0; i < count; ++i) {
+ dst[i] = f->get_double();
+ }
+ } else {
+ ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "real_t size is neither 4 nor 8!");
+ }
+ } else {
+ if (sizeof(real_t) == 4) {
+ // Ideal case with float-precision
+ f->get_buffer((uint8_t *)dst, count * sizeof(float));
+#ifdef BIG_ENDIAN_ENABLED
+ {
+ uint32_t *dst = (uint32_t *)dst;
+ for (size_t i = 0; i < count; i++) {
+ dst[i] = BSWAP32(dst[i]);
+ }
+ }
+#endif
+ } else if (sizeof(real_t) == 8) {
+ for (size_t i = 0; i < count; ++i) {
+ dst[i] = f->get_float();
+ }
+ } else {
+ ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "real_t size is neither 4 nor 8!");
+ }
+ }
+ return OK;
+}
+
StringName ResourceLoaderBinary::_get_string() {
uint32_t id = f->get_32();
if (id & 0x80000000) {
@@ -528,21 +572,9 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
Vector<Vector2> array;
array.resize(len);
Vector2 *w = array.ptrw();
- if (sizeof(Vector2) == 8) {
- f->get_buffer((uint8_t *)w, len * sizeof(real_t) * 2);
-#ifdef BIG_ENDIAN_ENABLED
- {
- uint32_t *ptr = (uint32_t *)w.ptr();
- for (int i = 0; i < len * 2; i++) {
- ptr[i] = BSWAP32(ptr[i]);
- }
- }
-
-#endif
-
- } else {
- ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Vector2 size is NOT 8!");
- }
+ static_assert(sizeof(Vector2) == 2 * sizeof(real_t));
+ const Error err = read_reals(reinterpret_cast<real_t *>(w), f, len * 2);
+ ERR_FAIL_COND_V(err != OK, err);
r_v = array;
@@ -553,21 +585,9 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
Vector<Vector3> array;
array.resize(len);
Vector3 *w = array.ptrw();
- if (sizeof(Vector3) == 12) {
- f->get_buffer((uint8_t *)w, len * sizeof(real_t) * 3);
-#ifdef BIG_ENDIAN_ENABLED
- {
- uint32_t *ptr = (uint32_t *)w.ptr();
- for (int i = 0; i < len * 3; i++) {
- ptr[i] = BSWAP32(ptr[i]);
- }
- }
-
-#endif
-
- } else {
- ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Vector3 size is NOT 12!");
- }
+ static_assert(sizeof(Vector3) == 3 * sizeof(real_t));
+ const Error err = read_reals(reinterpret_cast<real_t *>(w), f, len * 3);
+ ERR_FAIL_COND_V(err != OK, err);
r_v = array;
@@ -578,22 +598,19 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
Vector<Color> array;
array.resize(len);
Color *w = array.ptrw();
- if (sizeof(Color) == 16) {
- f->get_buffer((uint8_t *)w, len * sizeof(real_t) * 4);
+ // Colors always use `float` even with double-precision support enabled
+ static_assert(sizeof(Color) == 4 * sizeof(float));
+ f->get_buffer((uint8_t *)w, len * sizeof(float) * 4);
#ifdef BIG_ENDIAN_ENABLED
- {
- uint32_t *ptr = (uint32_t *)w.ptr();
- for (int i = 0; i < len * 4; i++) {
- ptr[i] = BSWAP32(ptr[i]);
- }
+ {
+ uint32_t *ptr = (uint32_t *)w.ptr();
+ for (int i = 0; i < len * 4; i++) {
+ ptr[i] = BSWAP32(ptr[i]);
}
+ }
#endif
- } else {
- ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Color size is NOT 16!");
- }
-
r_v = array;
} break;
default: {
@@ -772,7 +789,7 @@ Error ResourceLoaderBinary::load() {
resource_cache.push_back(res);
if (main) {
- f->close();
+ f.unref();
resource = res;
resource->set_as_translation_remapped(translation_remapped);
error = OK;
@@ -787,13 +804,13 @@ void ResourceLoaderBinary::set_translation_remapped(bool p_remapped) {
translation_remapped = p_remapped;
}
-static void save_ustring(FileAccess *f, const String &p_string) {
+static void save_ustring(Ref<FileAccess> f, const String &p_string) {
CharString utf8 = p_string.utf8();
f->store_32(utf8.length() + 1);
f->store_buffer((const uint8_t *)utf8.get_data(), utf8.length() + 1);
}
-static String get_ustring(FileAccess *f) {
+static String get_ustring(Ref<FileAccess> f) {
int len = f->get_32();
Vector<char> str_buf;
str_buf.resize(len);
@@ -817,7 +834,7 @@ String ResourceLoaderBinary::get_unicode_string() {
return s;
}
-void ResourceLoaderBinary::get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types) {
+void ResourceLoaderBinary::get_dependencies(Ref<FileAccess> p_f, List<String> *p_dependencies, bool p_add_types) {
open(p_f, false, true);
if (error) {
return;
@@ -839,7 +856,7 @@ void ResourceLoaderBinary::get_dependencies(FileAccess *p_f, List<String> *p_dep
}
}
-void ResourceLoaderBinary::open(FileAccess *p_f, bool p_no_resources, bool p_keep_uuid_paths) {
+void ResourceLoaderBinary::open(Ref<FileAccess> p_f, bool p_no_resources, bool p_keep_uuid_paths) {
error = OK;
f = p_f;
@@ -847,11 +864,11 @@ void ResourceLoaderBinary::open(FileAccess *p_f, bool p_no_resources, bool p_kee
f->get_buffer(header, 4);
if (header[0] == 'R' && header[1] == 'S' && header[2] == 'C' && header[3] == 'C') {
// Compressed.
- FileAccessCompressed *fac = memnew(FileAccessCompressed);
+ Ref<FileAccessCompressed> fac;
+ fac.instantiate();
error = fac->open_after_magic(f);
if (error != OK) {
- memdelete(fac);
- f->close();
+ f.unref();
ERR_FAIL_MSG("Failed to open binary resource file: " + local_path + ".");
}
f = fac;
@@ -859,7 +876,7 @@ void ResourceLoaderBinary::open(FileAccess *p_f, bool p_no_resources, bool p_kee
} else if (header[0] != 'R' || header[1] != 'S' || header[2] != 'R' || header[3] != 'C') {
// Not normal.
error = ERR_FILE_UNRECOGNIZED;
- f->close();
+ f.unref();
ERR_FAIL_MSG("Unrecognized binary resource file: " + local_path + ".");
}
@@ -884,7 +901,7 @@ void ResourceLoaderBinary::open(FileAccess *p_f, bool p_no_resources, bool p_kee
print_bl("format: " + itos(ver_format));
if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) {
- f->close();
+ f.unref();
ERR_FAIL_MSG(vformat("File '%s' can't be loaded, as it uses a format version (%d) or engine version (%d.%d) which are not supported by your engine version (%s).",
local_path, ver_format, ver_major, ver_minor, VERSION_BRANCH));
}
@@ -961,12 +978,12 @@ void ResourceLoaderBinary::open(FileAccess *p_f, bool p_no_resources, bool p_kee
if (f->eof_reached()) {
error = ERR_FILE_CORRUPT;
- f->close();
+ f.unref();
ERR_FAIL_MSG("Premature end of file (EOF): " + local_path + ".");
}
}
-String ResourceLoaderBinary::recognize(FileAccess *p_f) {
+String ResourceLoaderBinary::recognize(Ref<FileAccess> p_f) {
error = OK;
f = p_f;
@@ -974,11 +991,11 @@ String ResourceLoaderBinary::recognize(FileAccess *p_f) {
f->get_buffer(header, 4);
if (header[0] == 'R' && header[1] == 'S' && header[2] == 'C' && header[3] == 'C') {
// Compressed.
- FileAccessCompressed *fac = memnew(FileAccessCompressed);
+ Ref<FileAccessCompressed> fac;
+ fac.instantiate();
error = fac->open_after_magic(f);
if (error != OK) {
- memdelete(fac);
- f->close();
+ f.unref();
return "";
}
f = fac;
@@ -986,7 +1003,7 @@ String ResourceLoaderBinary::recognize(FileAccess *p_f) {
} else if (header[0] != 'R' || header[1] != 'S' || header[2] != 'R' || header[3] != 'C') {
// Not normal.
error = ERR_FILE_UNRECOGNIZED;
- f->close();
+ f.unref();
return "";
}
@@ -1000,7 +1017,7 @@ String ResourceLoaderBinary::recognize(FileAccess *p_f) {
uint32_t ver_format = f->get_32();
if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) {
- f->close();
+ f.unref();
return "";
}
@@ -1009,19 +1026,13 @@ String ResourceLoaderBinary::recognize(FileAccess *p_f) {
return type;
}
-ResourceLoaderBinary::~ResourceLoaderBinary() {
- if (f) {
- memdelete(f);
- }
-}
-
RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
if (r_error) {
*r_error = ERR_FILE_CANT_OPEN;
}
Error err;
- FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
+ Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ, &err);
ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot open file '" + p_path + "'.");
@@ -1079,8 +1090,8 @@ bool ResourceFormatLoaderBinary::handles_type(const String &p_type) const {
}
void ResourceFormatLoaderBinary::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
- FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
- ERR_FAIL_COND_MSG(!f, "Cannot open file '" + p_path + "'.");
+ Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
+ ERR_FAIL_COND_MSG(f.is_null(), "Cannot open file '" + p_path + "'.");
ResourceLoaderBinary loader;
loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path);
@@ -1089,10 +1100,10 @@ void ResourceFormatLoaderBinary::get_dependencies(const String &p_path, List<Str
}
Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, const Map<String, String> &p_map) {
- FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
- ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, "Cannot open file '" + p_path + "'.");
+ Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
+ ERR_FAIL_COND_V_MSG(f.is_null(), ERR_CANT_OPEN, "Cannot open file '" + p_path + "'.");
- FileAccess *fw = nullptr;
+ Ref<FileAccess> fw;
String local_path = p_path.get_base_dir();
@@ -1100,36 +1111,26 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
f->get_buffer(header, 4);
if (header[0] == 'R' && header[1] == 'S' && header[2] == 'C' && header[3] == 'C') {
// Compressed.
- FileAccessCompressed *fac = memnew(FileAccessCompressed);
+ Ref<FileAccessCompressed> fac;
+ fac.instantiate();
Error err = fac->open_after_magic(f);
- if (err != OK) {
- memdelete(fac);
- memdelete(f);
- ERR_FAIL_V_MSG(err, "Cannot open file '" + p_path + "'.");
- }
+ ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot open file '" + p_path + "'.");
f = fac;
- FileAccessCompressed *facw = memnew(FileAccessCompressed);
+ Ref<FileAccessCompressed> facw;
+ facw.instantiate();
facw->configure("RSCC");
err = facw->_open(p_path + ".depren", FileAccess::WRITE);
- if (err) {
- memdelete(fac);
- memdelete(facw);
- ERR_FAIL_COND_V_MSG(err, ERR_FILE_CORRUPT, "Cannot create file '" + p_path + ".depren'.");
- }
+ ERR_FAIL_COND_V_MSG(err, ERR_FILE_CORRUPT, "Cannot create file '" + p_path + ".depren'.");
fw = facw;
} else if (header[0] != 'R' || header[1] != 'S' || header[2] != 'R' || header[3] != 'C') {
// Not normal.
- memdelete(f);
ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, "Unrecognized binary resource file '" + local_path + "'.");
} else {
fw = FileAccess::open(p_path + ".depren", FileAccess::WRITE);
- if (!fw) {
- memdelete(f);
- }
- ERR_FAIL_COND_V_MSG(!fw, ERR_CANT_CREATE, "Cannot create file '" + p_path + ".depren'.");
+ ERR_FAIL_COND_V_MSG(fw.is_null(), ERR_CANT_CREATE, "Cannot create file '" + p_path + ".depren'.");
uint8_t magic[4] = { 'R', 'S', 'R', 'C' };
fw->store_buffer(magic, 4);
@@ -1152,10 +1153,10 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
uint32_t ver_format = f->get_32();
if (ver_format < FORMAT_VERSION_CAN_RENAME_DEPS) {
- memdelete(f);
- memdelete(fw);
+ fw.unref();
+
{
- DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
da->remove(p_path + ".depren");
}
@@ -1184,8 +1185,6 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
}
if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) {
- memdelete(f);
- memdelete(fw);
ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED,
vformat("File '%s' can't be loaded, as it uses a format version (%d) or engine version (%d.%d) which are not supported by your engine version (%s).",
local_path, ver_format, ver_major, ver_minor, VERSION_BRANCH));
@@ -1294,22 +1293,21 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
fw->seek(md_ofs);
fw->store_64(importmd_ofs + size_diff);
- memdelete(f);
- memdelete(fw);
-
if (!all_ok) {
return ERR_CANT_CREATE;
}
- DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ fw.unref();
+
+ Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
da->remove(p_path);
da->rename(p_path + ".depren", p_path);
return OK;
}
String ResourceFormatLoaderBinary::get_resource_type(const String &p_path) const {
- FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
- if (!f) {
+ Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
+ if (f.is_null()) {
return ""; //could not read
}
@@ -1326,8 +1324,8 @@ ResourceUID::ID ResourceFormatLoaderBinary::get_resource_uid(const String &p_pat
return ResourceUID::INVALID_ID;
}
- FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
- if (!f) {
+ Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
+ if (f.is_null()) {
return ResourceUID::INVALID_ID; //could not read
}
@@ -1345,7 +1343,7 @@ ResourceUID::ID ResourceFormatLoaderBinary::get_resource_uid(const String &p_pat
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
-void ResourceFormatSaverBinaryInstance::_pad_buffer(FileAccess *f, int p_bytes) {
+void ResourceFormatSaverBinaryInstance::_pad_buffer(Ref<FileAccess> f, int p_bytes) {
int extra = 4 - (p_bytes % 4);
if (extra < 4) {
for (int i = 0; i < extra; i++) {
@@ -1354,7 +1352,7 @@ void ResourceFormatSaverBinaryInstance::_pad_buffer(FileAccess *f, int p_bytes)
}
}
-void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Variant &p_property, Map<RES, int> &resource_map, Map<RES, int> &external_resources, Map<StringName, int> &string_map, const PropertyInfo &p_hint) {
+void ResourceFormatSaverBinaryInstance::write_variant(Ref<FileAccess> f, const Variant &p_property, Map<RES, int> &resource_map, Map<RES, int> &external_resources, Map<StringName, int> &string_map, const PropertyInfo &p_hint) {
switch (p_property.get_type()) {
case Variant::NIL: {
f->store_32(VARIANT_NIL);
@@ -1813,14 +1811,14 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant
}
}
-void ResourceFormatSaverBinaryInstance::save_unicode_string(FileAccess *f, const String &p_string, bool p_bit_on_len) {
+void ResourceFormatSaverBinaryInstance::save_unicode_string(Ref<FileAccess> p_f, const String &p_string, bool p_bit_on_len) {
CharString utf8 = p_string.utf8();
if (p_bit_on_len) {
- f->store_32((utf8.length() + 1) | 0x80000000);
+ p_f->store_32((utf8.length() + 1) | 0x80000000);
} else {
- f->store_32(utf8.length() + 1);
+ p_f->store_32(utf8.length() + 1);
}
- f->store_buffer((const uint8_t *)utf8.get_data(), utf8.length() + 1);
+ p_f->store_buffer((const uint8_t *)utf8.get_data(), utf8.length() + 1);
}
int ResourceFormatSaverBinaryInstance::get_string_index(const String &p_string) {
@@ -1836,15 +1834,13 @@ int ResourceFormatSaverBinaryInstance::get_string_index(const String &p_string)
Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
Error err;
+ Ref<FileAccess> f;
if (p_flags & ResourceSaver::FLAG_COMPRESS) {
- FileAccessCompressed *fac = memnew(FileAccessCompressed);
+ Ref<FileAccessCompressed> fac;
+ fac.instantiate();
fac->configure("RSCC");
f = fac;
err = fac->_open(p_path, FileAccess::WRITE);
- if (err) {
- memdelete(f);
- }
-
} else {
f = FileAccess::open(p_path, FileAccess::WRITE, &err);
}
@@ -1885,8 +1881,6 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
f->store_32(FORMAT_VERSION);
if (f->get_error() != OK && f->get_error() != ERR_FILE_EOF) {
- f->close();
- memdelete(f);
return ERR_CANT_CREATE;
}
@@ -2044,14 +2038,9 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
f->store_buffer((const uint8_t *)"RSRC", 4); //magic at end
if (f->get_error() != OK && f->get_error() != ERR_FILE_EOF) {
- f->close();
- memdelete(f);
return ERR_CANT_CREATE;
}
- f->close();
- memdelete(f);
-
return OK;
}
diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h
index c80c9b0ac9..72a3c6751d 100644
--- a/core/io/resource_format_binary.h
+++ b/core/io/resource_format_binary.h
@@ -43,7 +43,7 @@ class ResourceLoaderBinary {
Ref<Resource> resource;
uint32_t ver_format = 0;
- FileAccess *f = nullptr;
+ Ref<FileAccess> f;
uint64_t importmd_ofs = 0;
@@ -98,12 +98,11 @@ public:
void set_translation_remapped(bool p_remapped);
void set_remaps(const Map<String, String> &p_remaps) { remaps = p_remaps; }
- void open(FileAccess *p_f, bool p_no_resources = false, bool p_keep_uuid_paths = false);
- String recognize(FileAccess *p_f);
- void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types);
+ void open(Ref<FileAccess> p_f, bool p_no_resources = false, bool p_keep_uuid_paths = false);
+ String recognize(Ref<FileAccess> p_f);
+ void get_dependencies(Ref<FileAccess> p_f, List<String> *p_dependencies, bool p_add_types);
ResourceLoaderBinary() {}
- ~ResourceLoaderBinary();
};
class ResourceFormatLoaderBinary : public ResourceFormatLoader {
@@ -127,7 +126,6 @@ class ResourceFormatSaverBinaryInstance {
bool skip_editor;
bool big_endian;
bool takeover_paths;
- FileAccess *f;
String magic;
Set<RES> resource_set;
@@ -155,9 +153,9 @@ class ResourceFormatSaverBinaryInstance {
List<Property> properties;
};
- static void _pad_buffer(FileAccess *f, int p_bytes);
+ static void _pad_buffer(Ref<FileAccess> f, int p_bytes);
void _find_resources(const Variant &p_variant, bool p_main = false);
- static void save_unicode_string(FileAccess *f, const String &p_string, bool p_bit_on_len = false);
+ static void save_unicode_string(Ref<FileAccess> f, const String &p_string, bool p_bit_on_len = false);
int get_string_index(const String &p_string);
public:
@@ -170,7 +168,7 @@ public:
RESERVED_FIELDS = 11
};
Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
- static void write_variant(FileAccess *f, const Variant &p_property, Map<RES, int> &resource_map, Map<RES, int> &external_resources, Map<StringName, int> &string_map, const PropertyInfo &p_hint = PropertyInfo());
+ static void write_variant(Ref<FileAccess> f, const Variant &p_property, Map<RES, int> &resource_map, Map<RES, int> &external_resources, Map<StringName, int> &string_map, const PropertyInfo &p_hint = PropertyInfo());
};
class ResourceFormatSaverBinary : public ResourceFormatSaver {
diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp
index 9b6440e2a2..b4f73b3b25 100644
--- a/core/io/resource_importer.cpp
+++ b/core/io/resource_importer.cpp
@@ -40,9 +40,9 @@ bool ResourceFormatImporter::SortImporterByName::operator()(const Ref<ResourceIm
Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid) const {
Error err;
- FileAccess *f = FileAccess::open(p_path + ".import", FileAccess::READ, &err);
+ Ref<FileAccess> f = FileAccess::open(p_path + ".import", FileAccess::READ, &err);
- if (!f) {
+ if (f.is_null()) {
if (r_valid) {
*r_valid = false;
}
@@ -70,11 +70,9 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, nullptr, true);
if (err == ERR_FILE_EOF) {
- memdelete(f);
return OK;
} else if (err != OK) {
ERR_PRINT("ResourceFormatImporter::load - " + p_path + ".import:" + itos(lines) + " error: " + error_text);
- memdelete(f);
return err;
}
@@ -110,8 +108,6 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
}
}
- memdelete(f);
-
if (r_path_and_type.path.is_empty() || r_path_and_type.type.is_empty()) {
return ERR_FILE_CORRUPT;
}
@@ -270,9 +266,9 @@ String ResourceFormatImporter::get_internal_resource_path(const String &p_path)
void ResourceFormatImporter::get_internal_resource_path_list(const String &p_path, List<String> *r_paths) {
Error err;
- FileAccess *f = FileAccess::open(p_path + ".import", FileAccess::READ, &err);
+ Ref<FileAccess> f = FileAccess::open(p_path + ".import", FileAccess::READ, &err);
- if (!f) {
+ if (f.is_null()) {
return;
}
@@ -292,11 +288,9 @@ void ResourceFormatImporter::get_internal_resource_path_list(const String &p_pat
err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, nullptr, true);
if (err == ERR_FILE_EOF) {
- memdelete(f);
return;
} else if (err != OK) {
ERR_PRINT("ResourceFormatImporter::get_internal_resource_path_list - " + p_path + ".import:" + itos(lines) + " error: " + error_text);
- memdelete(f);
return;
}
@@ -310,7 +304,6 @@ void ResourceFormatImporter::get_internal_resource_path_list(const String &p_pat
break;
}
}
- memdelete(f);
}
String ResourceFormatImporter::get_import_group_file(const String &p_path) const {
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 2419c76dd3..fe9693aa20 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -206,7 +206,7 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c
vformat("Failed loading resource: %s. Make sure resources have been imported by opening the project in the editor at least once.", p_path));
#ifdef TOOLS_ENABLED
- FileAccessRef file_check = FileAccess::create(FileAccess::ACCESS_RESOURCES);
+ Ref<FileAccess> file_check = FileAccess::create(FileAccess::ACCESS_RESOURCES);
ERR_FAIL_COND_V_MSG(!file_check->file_exists(p_path), RES(), "Resource file not found: " + p_path + ".");
#endif
@@ -817,9 +817,8 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem
if (new_path == p_path) { // Did not remap.
// Try file remap.
Error err;
- FileAccess *f = FileAccess::open(p_path + ".remap", FileAccess::READ, &err);
-
- if (f) {
+ Ref<FileAccess> f = FileAccess::open(p_path + ".remap", FileAccess::READ, &err);
+ if (f.is_valid()) {
VariantParser::StreamFile stream;
stream.f = f;
@@ -849,8 +848,6 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem
break;
}
}
-
- memdelete(f);
}
}
diff --git a/core/io/resource_uid.cpp b/core/io/resource_uid.cpp
index d0335bed3a..515b7c710e 100644
--- a/core/io/resource_uid.cpp
+++ b/core/io/resource_uid.cpp
@@ -135,12 +135,12 @@ void ResourceUID::remove_id(ID p_id) {
Error ResourceUID::save_to_cache() {
String cache_file = get_cache_file();
if (!FileAccess::exists(cache_file)) {
- DirAccessRef d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ Ref<DirAccess> d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
d->make_dir_recursive(String(cache_file).get_base_dir()); //ensure base dir exists
}
- FileAccessRef f = FileAccess::open(cache_file, FileAccess::WRITE);
- if (!f) {
+ Ref<FileAccess> f = FileAccess::open(cache_file, FileAccess::WRITE);
+ if (f.is_null()) {
return ERR_CANT_OPEN;
}
@@ -163,8 +163,8 @@ Error ResourceUID::save_to_cache() {
}
Error ResourceUID::load_from_cache() {
- FileAccessRef f = FileAccess::open(get_cache_file(), FileAccess::READ);
- if (!f) {
+ Ref<FileAccess> f = FileAccess::open(get_cache_file(), FileAccess::READ);
+ if (f.is_null()) {
return ERR_CANT_OPEN;
}
@@ -201,12 +201,12 @@ Error ResourceUID::update_cache() {
}
MutexLock l(mutex);
- FileAccess *f = nullptr;
+ Ref<FileAccess> f;
for (OrderedHashMap<ID, Cache>::Element E = unique_ids.front(); E; E = E.next()) {
if (!E.get().saved_to_cache) {
- if (f == nullptr) {
+ if (f.is_null()) {
f = FileAccess::open(get_cache_file(), FileAccess::READ_WRITE); //append
- if (!f) {
+ if (f.is_null()) {
return ERR_CANT_OPEN;
}
f->seek_end();
@@ -220,11 +220,9 @@ Error ResourceUID::update_cache() {
}
}
- if (f != nullptr) {
+ if (f.is_valid()) {
f->seek(0);
f->store_32(cache_entries); //update amount of entries
- f->close();
- memdelete(f);
}
changed = false;
diff --git a/core/io/resource_uid.h b/core/io/resource_uid.h
index 1ea44b9d06..0b7ffdf6d0 100644
--- a/core/io/resource_uid.h
+++ b/core/io/resource_uid.h
@@ -46,7 +46,7 @@ public:
static String get_cache_file();
private:
- void *crypto; // CryptoCore::RandomGenerator (avoid including crypto_core.h)
+ void *crypto = nullptr; // CryptoCore::RandomGenerator (avoid including crypto_core.h)
Mutex mutex;
struct Cache {
CharString cs;
diff --git a/core/io/stream_peer.h b/core/io/stream_peer.h
index e71941b7e1..4609e52aa2 100644
--- a/core/io/stream_peer.h
+++ b/core/io/stream_peer.h
@@ -39,7 +39,6 @@
class StreamPeer : public RefCounted {
GDCLASS(StreamPeer, RefCounted);
- OBJ_CATEGORY("Networking");
protected:
static void _bind_methods();
diff --git a/core/io/stream_peer_tcp.cpp b/core/io/stream_peer_tcp.cpp
index 6d5784a8ab..c5c2021e6e 100644
--- a/core/io/stream_peer_tcp.cpp
+++ b/core/io/stream_peer_tcp.cpp
@@ -32,8 +32,28 @@
#include "core/config/project_settings.h"
-Error StreamPeerTCP::_poll_connection() {
- ERR_FAIL_COND_V(status != STATUS_CONNECTING || !_sock.is_valid() || !_sock->is_open(), FAILED);
+Error StreamPeerTCP::poll() {
+ if (status == STATUS_CONNECTED) {
+ Error err;
+ err = _sock->poll(NetSocket::POLL_TYPE_IN, 0);
+ if (err == OK) {
+ // FIN received
+ if (_sock->get_available_bytes() == 0) {
+ disconnect_from_host();
+ return OK;
+ }
+ }
+ // Also poll write
+ err = _sock->poll(NetSocket::POLL_TYPE_IN_OUT, 0);
+ if (err != OK && err != ERR_BUSY) {
+ // Got an error
+ disconnect_from_host();
+ status = STATUS_ERROR;
+ return err;
+ }
+ } else if (status != STATUS_CONNECTING) {
+ return OK;
+ }
Error err = _sock->connect_to_host(peer_host, peer_port);
@@ -121,22 +141,7 @@ Error StreamPeerTCP::connect_to_host(const IPAddress &p_host, int p_port) {
Error StreamPeerTCP::write(const uint8_t *p_data, int p_bytes, int &r_sent, bool p_block) {
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
- if (status == STATUS_NONE || status == STATUS_ERROR) {
- return FAILED;
- }
-
if (status != STATUS_CONNECTED) {
- if (_poll_connection() != OK) {
- return FAILED;
- }
-
- if (status != STATUS_CONNECTED) {
- r_sent = 0;
- return OK;
- }
- }
-
- if (!_sock->is_open()) {
return FAILED;
}
@@ -179,21 +184,10 @@ Error StreamPeerTCP::write(const uint8_t *p_data, int p_bytes, int &r_sent, bool
}
Error StreamPeerTCP::read(uint8_t *p_buffer, int p_bytes, int &r_received, bool p_block) {
- if (!is_connected_to_host()) {
+ if (status != STATUS_CONNECTED) {
return FAILED;
}
- if (status == STATUS_CONNECTING) {
- if (_poll_connection() != OK) {
- return FAILED;
- }
-
- if (status != STATUS_CONNECTED) {
- r_received = 0;
- return OK;
- }
- }
-
Error err;
int to_read = p_bytes;
int total_read = 0;
@@ -243,36 +237,11 @@ Error StreamPeerTCP::read(uint8_t *p_buffer, int p_bytes, int &r_received, bool
}
void StreamPeerTCP::set_no_delay(bool p_enabled) {
- ERR_FAIL_COND(!is_connected_to_host());
+ ERR_FAIL_COND(!_sock.is_valid() || !_sock->is_open());
_sock->set_tcp_no_delay_enabled(p_enabled);
}
-bool StreamPeerTCP::is_connected_to_host() const {
- return _sock.is_valid() && _sock->is_open() && (status == STATUS_CONNECTED || status == STATUS_CONNECTING);
-}
-
-StreamPeerTCP::Status StreamPeerTCP::get_status() {
- if (status == STATUS_CONNECTING) {
- _poll_connection();
- } else if (status == STATUS_CONNECTED) {
- Error err;
- err = _sock->poll(NetSocket::POLL_TYPE_IN, 0);
- if (err == OK) {
- // FIN received
- if (_sock->get_available_bytes() == 0) {
- disconnect_from_host();
- return status;
- }
- }
- // Also poll write
- err = _sock->poll(NetSocket::POLL_TYPE_IN_OUT, 0);
- if (err != OK && err != ERR_BUSY) {
- // Got an error
- disconnect_from_host();
- status = STATUS_ERROR;
- }
- }
-
+StreamPeerTCP::Status StreamPeerTCP::get_status() const {
return status;
}
@@ -287,7 +256,7 @@ void StreamPeerTCP::disconnect_from_host() {
peer_port = 0;
}
-Error StreamPeerTCP::poll(NetSocket::PollType p_type, int timeout) {
+Error StreamPeerTCP::wait(NetSocket::PollType p_type, int timeout) {
ERR_FAIL_COND_V(_sock.is_null() || !_sock->is_open(), ERR_UNAVAILABLE);
return _sock->poll(p_type, timeout);
}
@@ -346,7 +315,7 @@ Error StreamPeerTCP::_connect(const String &p_address, int p_port) {
void StreamPeerTCP::_bind_methods() {
ClassDB::bind_method(D_METHOD("bind", "port", "host"), &StreamPeerTCP::bind, DEFVAL("*"));
ClassDB::bind_method(D_METHOD("connect_to_host", "host", "port"), &StreamPeerTCP::_connect);
- ClassDB::bind_method(D_METHOD("is_connected_to_host"), &StreamPeerTCP::is_connected_to_host);
+ ClassDB::bind_method(D_METHOD("poll"), &StreamPeerTCP::poll);
ClassDB::bind_method(D_METHOD("get_status"), &StreamPeerTCP::get_status);
ClassDB::bind_method(D_METHOD("get_connected_host"), &StreamPeerTCP::get_connected_host);
ClassDB::bind_method(D_METHOD("get_connected_port"), &StreamPeerTCP::get_connected_port);
diff --git a/core/io/stream_peer_tcp.h b/core/io/stream_peer_tcp.h
index f2c47b25cf..39c2e84346 100644
--- a/core/io/stream_peer_tcp.h
+++ b/core/io/stream_peer_tcp.h
@@ -38,7 +38,6 @@
class StreamPeerTCP : public StreamPeer {
GDCLASS(StreamPeerTCP, StreamPeer);
- OBJ_CATEGORY("Networking");
public:
enum Status {
@@ -56,7 +55,6 @@ protected:
uint16_t peer_port = 0;
Error _connect(const String &p_address, int p_port);
- Error _poll_connection();
Error write(const uint8_t *p_data, int p_bytes, int &r_sent, bool p_block);
Error read(uint8_t *p_buffer, int p_bytes, int &r_received, bool p_block);
@@ -67,19 +65,21 @@ public:
Error bind(int p_port, const IPAddress &p_host);
Error connect_to_host(const IPAddress &p_host, int p_port);
- bool is_connected_to_host() const;
IPAddress get_connected_host() const;
int get_connected_port() const;
int get_local_port() const;
void disconnect_from_host();
int get_available_bytes() const override;
- Status get_status();
+ Status get_status() const;
void set_no_delay(bool p_enabled);
- // Poll functions (wait or check for writable, readable)
- Error poll(NetSocket::PollType p_type, int timeout = 0);
+ // Poll socket updating its state.
+ Error poll();
+
+ // Wait or check for writable, readable.
+ Error wait(NetSocket::PollType p_type, int timeout = 0);
// Read/Write from StreamPeer
Error put_data(const uint8_t *p_data, int p_bytes) override;
diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp
index 801bd8b0bf..ae1ad304d7 100644
--- a/core/io/translation_loader_po.cpp
+++ b/core/io/translation_loader_po.cpp
@@ -34,7 +34,7 @@
#include "core/string/translation.h"
#include "core/string/translation_po.h"
-RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
+RES TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_error) {
if (r_error) {
*r_error = ERR_FILE_CORRUPT;
}
@@ -49,9 +49,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
uint16_t version_maj = f->get_16();
uint16_t version_min = f->get_16();
- if (version_maj > 1) {
- ERR_FAIL_V_MSG(RES(), vformat("Unsupported MO file %s, version %d.%d.", path, version_maj, version_min));
- }
+ ERR_FAIL_COND_V_MSG(version_maj > 1, RES(), vformat("Unsupported MO file %s, version %d.%d.", path, version_maj, version_min));
uint32_t num_strings = f->get_32();
uint32_t id_table_offset = f->get_32();
@@ -98,7 +96,6 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
{
Vector<uint8_t> data;
f->seek(trans_table_offset + i * 8);
- uint32_t str_start = 0;
uint32_t str_len = f->get_32();
uint32_t str_offset = f->get_32();
@@ -116,6 +113,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
translation->set_plural_rule(config.substr(p_start, p_end - p_start));
}
} else {
+ uint32_t str_start = 0;
Vector<String> plural_msg;
for (uint32_t j = 0; j < str_len + 1; j++) {
if (data[j] == 0x00) {
@@ -134,7 +132,6 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
}
}
- memdelete(f);
} else {
// Try to load as text PO file.
f->seek(0);
@@ -173,7 +170,6 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
// If we reached last line and it's not a content line, break, otherwise let processing that last loop
if (is_eof && l.is_empty()) {
if (status == STATUS_READING_ID || status == STATUS_READING_CONTEXT || (status == STATUS_READING_PLURAL && plural_index != plural_forms - 1)) {
- memdelete(f);
ERR_FAIL_V_MSG(RES(), "Unexpected EOF while reading PO file at: " + path + ":" + itos(line));
} else {
break;
@@ -181,10 +177,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
}
if (l.begins_with("msgctxt")) {
- if (status != STATUS_READING_STRING && status != STATUS_READING_PLURAL) {
- memdelete(f);
- ERR_FAIL_V_MSG(RES(), "Unexpected 'msgctxt', was expecting 'msgid_plural' or 'msgstr' before 'msgctxt' while parsing: " + path + ":" + itos(line));
- }
+ ERR_FAIL_COND_V_MSG(status != STATUS_READING_STRING && status != STATUS_READING_PLURAL, RES(), "Unexpected 'msgctxt', was expecting 'msgid_plural' or 'msgstr' before 'msgctxt' while parsing: " + path + ":" + itos(line));
// 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.
@@ -192,10 +185,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
if (status == STATUS_READING_STRING) {
translation->add_message(msg_id, msg_str, msg_context);
} else if (status == STATUS_READING_PLURAL) {
- 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));
- }
+ ERR_FAIL_COND_V_MSG(plural_index != plural_forms - 1, RES(), "Number of 'msgstr[]' doesn't match with number of plural forms: " + path + ":" + itos(line));
translation->add_plural_message(msg_id, msgs_plural, msg_context);
}
}
@@ -207,10 +197,8 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
if (l.begins_with("msgid_plural")) {
if (plural_forms == 0) {
- memdelete(f);
ERR_FAIL_V_MSG(RES(), "PO file uses 'msgid_plural' but 'Plural-Forms' is invalid or missing in header: " + path + ":" + itos(line));
} else if (status != STATUS_READING_ID) {
- memdelete(f);
ERR_FAIL_V_MSG(RES(), "Unexpected 'msgid_plural', was expecting 'msgid' before 'msgid_plural' while parsing: " + path + ":" + itos(line));
}
// We don't record the message in "msgid_plural" itself as tr_n(), TTRN(), RTRN() interfaces provide the plural string already.
@@ -221,20 +209,14 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
msgs_plural.resize(plural_forms);
status = STATUS_READING_PLURAL;
} else if (l.begins_with("msgid")) {
- if (status == STATUS_READING_ID) {
- memdelete(f);
- ERR_FAIL_V_MSG(RES(), "Unexpected 'msgid', was expecting 'msgstr' while parsing: " + path + ":" + itos(line));
- }
+ ERR_FAIL_COND_V_MSG(status == STATUS_READING_ID, RES(), "Unexpected 'msgid', was expecting 'msgstr' while parsing: " + path + ":" + itos(line));
if (!msg_id.is_empty()) {
if (!skip_this && !entered_context) {
if (status == STATUS_READING_STRING) {
translation->add_message(msg_id, msg_str, msg_context);
} else if (status == STATUS_READING_PLURAL) {
- 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));
- }
+ ERR_FAIL_COND_V_MSG(plural_index != plural_forms - 1, RES(), "Number of 'msgstr[]' doesn't match with number of plural forms: " + path + ":" + itos(line));
translation->add_plural_message(msg_id, msgs_plural, msg_context);
}
}
@@ -263,18 +245,11 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
}
if (l.begins_with("msgstr[")) {
- if (status != STATUS_READING_PLURAL) {
- memdelete(f);
- ERR_FAIL_V_MSG(RES(), "Unexpected 'msgstr[]', was expecting 'msgid_plural' before 'msgstr[]' while parsing: " + path + ":" + itos(line));
- }
+ ERR_FAIL_COND_V_MSG(status != STATUS_READING_PLURAL, RES(), "Unexpected 'msgstr[]', was expecting 'msgid_plural' before 'msgstr[]' while parsing: " + path + ":" + itos(line));
plural_index++; // Increment to add to the next slot in vector msgs_plural.
l = l.substr(9, l.length()).strip_edges();
} else if (l.begins_with("msgstr")) {
- if (status != STATUS_READING_ID) {
- memdelete(f);
- ERR_FAIL_V_MSG(RES(), "Unexpected 'msgstr', was expecting 'msgid' before 'msgstr' while parsing: " + path + ":" + itos(line));
- }
-
+ ERR_FAIL_COND_V_MSG(status != STATUS_READING_ID, RES(), "Unexpected 'msgstr', was expecting 'msgid' before 'msgstr' while parsing: " + path + ":" + itos(line));
l = l.substr(6, l.length()).strip_edges();
status = STATUS_READING_STRING;
}
@@ -287,10 +262,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
continue; // Nothing to read or comment.
}
- if (!l.begins_with("\"") || status == STATUS_NONE) {
- memdelete(f);
- ERR_FAIL_V_MSG(RES(), "Invalid line '" + l + "' while parsing: " + path + ":" + itos(line));
- }
+ ERR_FAIL_COND_V_MSG(!l.begins_with("\"") || status == STATUS_NONE, RES(), "Invalid line '" + l + "' while parsing: " + path + ":" + itos(line));
l = l.substr(1, l.length());
// Find final quote, ignoring escaped ones (\").
@@ -312,10 +284,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
escape_next = false;
}
- if (end_pos == -1) {
- memdelete(f);
- ERR_FAIL_V_MSG(RES(), "Expected '\"' at end of message while parsing: " + path + ":" + itos(line));
- }
+ ERR_FAIL_COND_V_MSG(end_pos == -1, RES(), "Expected '\"' at end of message while parsing: " + path + ":" + itos(line));
l = l.substr(0, end_pos);
l = l.c_unescape();
@@ -327,18 +296,13 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
} else if (status == STATUS_READING_CONTEXT) {
msg_context += l;
} else if (status == STATUS_READING_PLURAL && plural_index >= 0) {
- if (plural_index >= plural_forms) {
- memdelete(f);
- ERR_FAIL_V_MSG(RES(), "Unexpected plural form while parsing: " + path + ":" + itos(line));
- }
+ ERR_FAIL_COND_V_MSG(plural_index >= plural_forms, RES(), "Unexpected plural form while parsing: " + path + ":" + itos(line));
msgs_plural.write[plural_index] = msgs_plural[plural_index] + l;
}
line++;
}
- memdelete(f);
-
// Add the last set of data from last iteration.
if (status == STATUS_READING_STRING) {
if (!msg_id.is_empty()) {
@@ -350,10 +314,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
}
} else if (status == STATUS_READING_PLURAL) {
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));
- }
+ ERR_FAIL_COND_V_MSG(plural_index != plural_forms - 1, RES(), "Number of 'msgstr[]' doesn't match with number of plural forms: " + path + ":" + itos(line));
translation->add_plural_message(msg_id, msgs_plural, msg_context);
}
}
@@ -388,8 +349,8 @@ RES TranslationLoaderPO::load(const String &p_path, const String &p_original_pat
*r_error = ERR_CANT_OPEN;
}
- FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
- ERR_FAIL_COND_V_MSG(!f, RES(), "Cannot open file '" + p_path + "'.");
+ Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
+ ERR_FAIL_COND_V_MSG(f.is_null(), RES(), "Cannot open file '" + p_path + "'.");
return load_translation(f, r_error);
}
diff --git a/core/io/translation_loader_po.h b/core/io/translation_loader_po.h
index 1c58896a00..7da361cf24 100644
--- a/core/io/translation_loader_po.h
+++ b/core/io/translation_loader_po.h
@@ -37,7 +37,7 @@
class TranslationLoaderPO : public ResourceFormatLoader {
public:
- static RES load_translation(FileAccess *f, Error *r_error = nullptr);
+ static RES load_translation(Ref<FileAccess> f, Error *r_error = nullptr);
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
diff --git a/core/io/udp_server.h b/core/io/udp_server.h
index 4a7546fddf..47f06b2490 100644
--- a/core/io/udp_server.h
+++ b/core/io/udp_server.h
@@ -43,7 +43,7 @@ protected:
};
struct Peer {
- PacketPeerUDP *peer;
+ PacketPeerUDP *peer = nullptr;
IPAddress ip;
uint16_t port = 0;
diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp
index 360da46f96..7b43193f47 100644
--- a/core/io/xml_parser.cpp
+++ b/core/io/xml_parser.cpp
@@ -472,7 +472,7 @@ Error XMLParser::open_buffer(const Vector<uint8_t> &p_buffer) {
Error XMLParser::open(const String &p_path) {
Error err;
- FileAccess *file = FileAccess::open(p_path, FileAccess::READ, &err);
+ Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::READ, &err);
ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot open file '" + p_path + "'.");
@@ -488,8 +488,6 @@ Error XMLParser::open(const String &p_path) {
data[length] = 0;
P = data;
- memdelete(file);
-
return OK;
}
diff --git a/core/io/zip_io.cpp b/core/io/zip_io.cpp
index 2c4f8346ab..2cc844b628 100644
--- a/core/io/zip_io.cpp
+++ b/core/io/zip_io.cpp
@@ -30,73 +30,69 @@
#include "zip_io.h"
-void *zipio_open(void *data, const char *p_fname, int mode) {
- FileAccess *&f = *(FileAccess **)data;
+void *zipio_open(voidpf opaque, const char *p_fname, int mode) {
+ ZipIOData *zd = (ZipIOData *)opaque;
String fname;
fname.parse_utf8(p_fname);
if (mode & ZLIB_FILEFUNC_MODE_WRITE) {
- f = FileAccess::open(fname, FileAccess::WRITE);
+ zd->f = FileAccess::open(fname, FileAccess::WRITE);
} else {
- f = FileAccess::open(fname, FileAccess::READ);
+ zd->f = FileAccess::open(fname, FileAccess::READ);
}
- if (!f) {
+ if (zd->f.is_null()) {
return nullptr;
}
- return data;
+ return opaque;
}
-uLong zipio_read(void *data, void *fdata, void *buf, uLong size) {
- FileAccess *f = *(FileAccess **)data;
- return f->get_buffer((uint8_t *)buf, size);
+uLong zipio_read(voidpf opaque, voidpf stream, void *buf, uLong size) {
+ ZipIOData *zd = (ZipIOData *)opaque;
+ return zd->f->get_buffer((uint8_t *)buf, size);
}
uLong zipio_write(voidpf opaque, voidpf stream, const void *buf, uLong size) {
- FileAccess *f = *(FileAccess **)opaque;
- f->store_buffer((uint8_t *)buf, size);
+ ZipIOData *zd = (ZipIOData *)opaque;
+ zd->f->store_buffer((uint8_t *)buf, size);
return size;
}
long zipio_tell(voidpf opaque, voidpf stream) {
- FileAccess *f = *(FileAccess **)opaque;
- return f->get_position();
+ ZipIOData *zd = (ZipIOData *)opaque;
+ return zd->f->get_position();
}
long zipio_seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
- FileAccess *f = *(FileAccess **)opaque;
+ ZipIOData *zd = (ZipIOData *)opaque;
uint64_t pos = offset;
switch (origin) {
case ZLIB_FILEFUNC_SEEK_CUR:
- pos = f->get_position() + offset;
+ pos = zd->f->get_position() + offset;
break;
case ZLIB_FILEFUNC_SEEK_END:
- pos = f->get_length() + offset;
+ pos = zd->f->get_length() + offset;
break;
default:
break;
}
- f->seek(pos);
+ zd->f->seek(pos);
return 0;
}
int zipio_close(voidpf opaque, voidpf stream) {
- FileAccess *&f = *(FileAccess **)opaque;
- if (f) {
- f->close();
- memdelete(f);
- f = nullptr;
- }
+ ZipIOData *zd = (ZipIOData *)opaque;
+ memdelete(zd);
return 0;
}
int zipio_testerror(voidpf opaque, voidpf stream) {
- FileAccess *f = *(FileAccess **)opaque;
- return (f && f->get_error() != OK) ? 1 : 0;
+ ZipIOData *zd = (ZipIOData *)opaque;
+ return (zd->f.is_valid() && zd->f->get_error() != OK) ? 1 : 0;
}
voidpf zipio_alloc(voidpf opaque, uInt items, uInt size) {
@@ -109,9 +105,9 @@ void zipio_free(voidpf opaque, voidpf address) {
memfree(address);
}
-zlib_filefunc_def zipio_create_io_from_file(FileAccess **p_file) {
+zlib_filefunc_def zipio_create_io() {
zlib_filefunc_def io;
- io.opaque = p_file;
+ io.opaque = (void *)memnew(ZipIOData);
io.zopen_file = zipio_open;
io.zread_file = zipio_read;
io.zwrite_file = zipio_write;
diff --git a/core/io/zip_io.h b/core/io/zip_io.h
index 6a29703449..3bcd1f830d 100644
--- a/core/io/zip_io.h
+++ b/core/io/zip_io.h
@@ -39,8 +39,12 @@
#include "thirdparty/minizip/unzip.h"
#include "thirdparty/minizip/zip.h"
-void *zipio_open(void *data, const char *p_fname, int mode);
-uLong zipio_read(void *data, void *fdata, void *buf, uLong size);
+struct ZipIOData {
+ Ref<FileAccess> f;
+};
+
+void *zipio_open(voidpf opaque, const char *p_fname, int mode);
+uLong zipio_read(voidpf opaque, voidpf stream, void *buf, uLong size);
uLong zipio_write(voidpf opaque, voidpf stream, const void *buf, uLong size);
long zipio_tell(voidpf opaque, voidpf stream);
@@ -53,6 +57,6 @@ int zipio_testerror(voidpf opaque, voidpf stream);
voidpf zipio_alloc(voidpf opaque, uInt items, uInt size);
void zipio_free(voidpf opaque, voidpf address);
-zlib_filefunc_def zipio_create_io_from_file(FileAccess **p_file);
+zlib_filefunc_def zipio_create_io();
#endif // ZIP_IO_H