diff options
Diffstat (limited to 'core')
45 files changed, 476 insertions, 756 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 93c1abe7b5..06bfc0c562 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -145,7 +145,7 @@ String ProjectSettings::localize_path(const String &p_path) const { return p_path.simplify_path(); } - DirAccessRef dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + Ref<DirAccess> dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); String path = p_path.replace("\\", "/").simplify_path(); @@ -537,8 +537,8 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b // Nothing was found, try to find a project file in provided path (`p_path`) // or, if requested (`p_upwards`) in parent directories. - DirAccessRef d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - ERR_FAIL_COND_V_MSG(!d, ERR_CANT_CREATE, "Cannot create DirAccess for path '" + p_path + "'."); + Ref<DirAccess> d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + ERR_FAIL_COND_V_MSG(d.is_null(), ERR_CANT_CREATE, "Cannot create DirAccess for path '" + p_path + "'."); d->change_dir(p_path); String current_dir = d->get_current_dir(); @@ -613,17 +613,14 @@ bool ProjectSettings::has_setting(String p_var) const { Error ProjectSettings::_load_settings_binary(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 (err != OK) { return err; } uint8_t hdr[4]; f->get_buffer(hdr, 4); - if (hdr[0] != 'E' || hdr[1] != 'C' || hdr[2] != 'F' || hdr[3] != 'G') { - memdelete(f); - ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Corrupted header in binary project.binary (not ECFG)."); - } + ERR_FAIL_COND_V_MSG((hdr[0] != 'E' || hdr[1] != 'C' || hdr[2] != 'F' || hdr[3] != 'G'), ERR_FILE_CORRUPT, "Corrupted header in binary project.binary (not ECFG)."); uint32_t count = f->get_32(); @@ -646,16 +643,14 @@ Error ProjectSettings::_load_settings_binary(const String &p_path) { set(key, value); } - f->close(); - memdelete(f); return OK; } Error ProjectSettings::_load_settings_text(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()) { // FIXME: Above 'err' error code is ERR_FILE_CANT_OPEN if the file is missing // This needs to be streamlined if we want decent error reporting return ERR_FILE_NOT_FOUND; @@ -680,25 +675,18 @@ Error ProjectSettings::_load_settings_text(const String &p_path) { err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, nullptr, true); if (err == ERR_FILE_EOF) { - memdelete(f); // If we're loading a project.godot from source code, we can operate some // ProjectSettings conversions if need be. _convert_to_last_version(config_version); last_save_time = FileAccess::get_modified_time(get_resource_path().plus_file("project.godot")); return OK; - } else if (err != OK) { - ERR_PRINT("Error parsing " + p_path + " at line " + itos(lines) + ": " + error_text + " File might be corrupted."); - memdelete(f); - return err; } + ERR_FAIL_COND_V_MSG(err != OK, err, "Error parsing " + p_path + " at line " + itos(lines) + ": " + error_text + " File might be corrupted."); if (!assign.is_empty()) { if (section.is_empty() && assign == "config_version") { config_version = value; - if (config_version > CONFIG_VERSION) { - memdelete(f); - ERR_FAIL_V_MSG(ERR_FILE_CANT_OPEN, vformat("Can't open project at '%s', its `config_version` (%d) is from a more recent and incompatible version of the engine. Expected config version: %d.", p_path, config_version, CONFIG_VERSION)); - } + ERR_FAIL_COND_V_MSG(config_version > CONFIG_VERSION, ERR_FILE_CANT_OPEN, vformat("Can't open project at '%s', its `config_version` (%d) is from a more recent and incompatible version of the engine. Expected config version: %d.", p_path, config_version, CONFIG_VERSION)); } else { if (section.is_empty()) { set(assign, value); @@ -778,7 +766,7 @@ Error ProjectSettings::save() { Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<String, List<String>> &props, const CustomMap &p_custom, const String &p_custom_features) { Error err; - FileAccess *file = FileAccess::open(p_file, FileAccess::WRITE, &err); + Ref<FileAccess> file = FileAccess::open(p_file, FileAccess::WRITE, &err); ERR_FAIL_COND_V_MSG(err != OK, err, "Couldn't save project.binary at " + p_file + "."); uint8_t hdr[4] = { 'E', 'C', 'F', 'G' }; @@ -798,19 +786,13 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str int len; err = encode_variant(p_custom_features, nullptr, len, false); - if (err != OK) { - memdelete(file); - ERR_FAIL_V(err); - } + ERR_FAIL_COND_V(err != OK, err); Vector<uint8_t> buff; buff.resize(len); err = encode_variant(p_custom_features, buff.ptrw(), len, false); - if (err != OK) { - memdelete(file); - ERR_FAIL_V(err); - } + ERR_FAIL_COND_V(err != OK, err); file->store_32(len); file->store_buffer(buff.ptr(), buff.size()); @@ -834,33 +816,24 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str int len; err = encode_variant(value, nullptr, len, true); - if (err != OK) { - memdelete(file); - } ERR_FAIL_COND_V_MSG(err != OK, ERR_INVALID_DATA, "Error when trying to encode Variant."); Vector<uint8_t> buff; buff.resize(len); err = encode_variant(value, buff.ptrw(), len, true); - if (err != OK) { - memdelete(file); - } ERR_FAIL_COND_V_MSG(err != OK, ERR_INVALID_DATA, "Error when trying to encode Variant."); file->store_32(len); file->store_buffer(buff.ptr(), buff.size()); } } - file->close(); - memdelete(file); - return OK; } Error ProjectSettings::_save_settings_text(const String &p_file, const Map<String, List<String>> &props, const CustomMap &p_custom, const String &p_custom_features) { Error err; - FileAccess *file = FileAccess::open(p_file, FileAccess::WRITE, &err); + Ref<FileAccess> file = FileAccess::open(p_file, FileAccess::WRITE, &err); ERR_FAIL_COND_V_MSG(err != OK, err, "Couldn't save project.godot - " + p_file + "."); @@ -905,9 +878,6 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const Map<Strin } } - file->close(); - memdelete(file); - return OK; } diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 706395afa9..7d8ec6064d 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -1027,10 +1027,10 @@ Error File::open_encrypted(const String &p_path, ModeFlags p_mode_flags, const V return err; } - FileAccessEncrypted *fae = memnew(FileAccessEncrypted); + Ref<FileAccessEncrypted> fae; + fae.instantiate(); err = fae->open_and_parse(f, p_key, (p_mode_flags == WRITE) ? FileAccessEncrypted::MODE_WRITE_AES256 : FileAccessEncrypted::MODE_READ); if (err) { - memdelete(fae); close(); return err; } @@ -1044,10 +1044,10 @@ Error File::open_encrypted_pass(const String &p_path, ModeFlags p_mode_flags, co return err; } - FileAccessEncrypted *fae = memnew(FileAccessEncrypted); + Ref<FileAccessEncrypted> fae; + fae.instantiate(); err = fae->open_and_parse_password(f, p_pass, (p_mode_flags == WRITE) ? FileAccessEncrypted::MODE_WRITE_AES256 : FileAccessEncrypted::MODE_READ); if (err) { - memdelete(fae); close(); return err; } @@ -1057,14 +1057,13 @@ Error File::open_encrypted_pass(const String &p_path, ModeFlags p_mode_flags, co } Error File::open_compressed(const String &p_path, ModeFlags p_mode_flags, CompressionMode p_compress_mode) { - FileAccessCompressed *fac = memnew(FileAccessCompressed); - + Ref<FileAccessCompressed> fac; + fac.instantiate(); fac->configure("GCPF", (Compression::Mode)p_compress_mode); Error err = fac->_open(p_path, p_mode_flags); if (err) { - memdelete(fac); return err; } @@ -1076,22 +1075,20 @@ Error File::open(const String &p_path, ModeFlags p_mode_flags) { close(); Error err; f = FileAccess::open(p_path, p_mode_flags, &err); - if (f) { + if (f.is_valid()) { f->set_big_endian(big_endian); } return err; } void File::flush() { - ERR_FAIL_COND_MSG(!f, "File must be opened before flushing."); + ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before flushing."); f->flush(); } void File::close() { - if (f) { - memdelete(f); - } - f = nullptr; + ERR_FAIL_COND_MSG(f.is_null(), "File must be opened."); + f = Ref<FileAccess>(); } bool File::is_open() const { @@ -1099,79 +1096,79 @@ bool File::is_open() const { } String File::get_path() const { - ERR_FAIL_COND_V_MSG(!f, "", "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_V_MSG(f.is_null(), "", "File must be opened before use, or is lacking read-write permission."); return f->get_path(); } String File::get_path_absolute() const { - ERR_FAIL_COND_V_MSG(!f, "", "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_V_MSG(f.is_null(), "", "File must be opened before use, or is lacking read-write permission."); return f->get_path_absolute(); } void File::seek(int64_t p_position) { - ERR_FAIL_COND_MSG(!f, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before use, or is lacking read-write permission."); ERR_FAIL_COND_MSG(p_position < 0, "Seek position must be a positive integer."); f->seek(p_position); } void File::seek_end(int64_t p_position) { - ERR_FAIL_COND_MSG(!f, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before use, or is lacking read-write permission."); f->seek_end(p_position); } uint64_t File::get_position() const { - ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_V_MSG(f.is_null(), 0, "File must be opened before use, or is lacking read-write permission."); return f->get_position(); } uint64_t File::get_length() const { - ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_V_MSG(f.is_null(), 0, "File must be opened before use, or is lacking read-write permission."); return f->get_length(); } bool File::eof_reached() const { - ERR_FAIL_COND_V_MSG(!f, false, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_V_MSG(f.is_null(), false, "File must be opened before use, or is lacking read-write permission."); return f->eof_reached(); } uint8_t File::get_8() const { - ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_V_MSG(f.is_null(), 0, "File must be opened before use, or is lacking read-write permission."); return f->get_8(); } uint16_t File::get_16() const { - ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_V_MSG(f.is_null(), 0, "File must be opened before use, or is lacking read-write permission."); return f->get_16(); } uint32_t File::get_32() const { - ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_V_MSG(f.is_null(), 0, "File must be opened before use, or is lacking read-write permission."); return f->get_32(); } uint64_t File::get_64() const { - ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_V_MSG(f.is_null(), 0, "File must be opened before use, or is lacking read-write permission."); return f->get_64(); } float File::get_float() const { - ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_V_MSG(f.is_null(), 0, "File must be opened before use, or is lacking read-write permission."); return f->get_float(); } double File::get_double() const { - ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_V_MSG(f.is_null(), 0, "File must be opened before use, or is lacking read-write permission."); return f->get_double(); } real_t File::get_real() const { - ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_V_MSG(f.is_null(), 0, "File must be opened before use, or is lacking read-write permission."); return f->get_real(); } Vector<uint8_t> File::get_buffer(int64_t p_length) const { Vector<uint8_t> data; - ERR_FAIL_COND_V_MSG(!f, data, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_V_MSG(f.is_null(), data, "File must be opened before use, or is lacking read-write permission."); ERR_FAIL_COND_V_MSG(p_length < 0, data, "Length of buffer cannot be smaller than 0."); if (p_length == 0) { @@ -1192,11 +1189,11 @@ Vector<uint8_t> File::get_buffer(int64_t p_length) const { } String File::get_as_text() const { - ERR_FAIL_COND_V_MSG(!f, String(), "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_V_MSG(f.is_null(), String(), "File must be opened before use, or is lacking read-write permission."); String text; uint64_t original_pos = f->get_position(); - f->seek(0); + const_cast<FileAccess *>(*f)->seek(0); String l = get_line(); while (!eof_reached()) { @@ -1205,7 +1202,7 @@ String File::get_as_text() const { } text += l; - f->seek(original_pos); + const_cast<FileAccess *>(*f)->seek(original_pos); return text; } @@ -1219,12 +1216,12 @@ String File::get_sha256(const String &p_path) const { } String File::get_line() const { - ERR_FAIL_COND_V_MSG(!f, String(), "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_V_MSG(f.is_null(), String(), "File must be opened before use, or is lacking read-write permission."); return f->get_line(); } Vector<String> File::get_csv_line(const String &p_delim) const { - ERR_FAIL_COND_V_MSG(!f, Vector<String>(), "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_V_MSG(f.is_null(), Vector<String>(), "File must be opened before use, or is lacking read-write permission."); return f->get_csv_line(p_delim); } @@ -1235,7 +1232,7 @@ Vector<String> File::get_csv_line(const String &p_delim) const { void File::set_big_endian(bool p_big_endian) { big_endian = p_big_endian; - if (f) { + if (f.is_valid()) { f->set_big_endian(p_big_endian); } } @@ -1245,84 +1242,84 @@ bool File::is_big_endian() { } Error File::get_error() const { - if (!f) { + if (f.is_null()) { return ERR_UNCONFIGURED; } return f->get_error(); } void File::store_8(uint8_t p_dest) { - ERR_FAIL_COND_MSG(!f, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before use, or is lacking read-write permission."); f->store_8(p_dest); } void File::store_16(uint16_t p_dest) { - ERR_FAIL_COND_MSG(!f, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before use, or is lacking read-write permission."); f->store_16(p_dest); } void File::store_32(uint32_t p_dest) { - ERR_FAIL_COND_MSG(!f, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before use, or is lacking read-write permission."); f->store_32(p_dest); } void File::store_64(uint64_t p_dest) { - ERR_FAIL_COND_MSG(!f, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before use, or is lacking read-write permission."); f->store_64(p_dest); } void File::store_float(float p_dest) { - ERR_FAIL_COND_MSG(!f, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before use, or is lacking read-write permission."); f->store_float(p_dest); } void File::store_double(double p_dest) { - ERR_FAIL_COND_MSG(!f, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before use, or is lacking read-write permission."); f->store_double(p_dest); } void File::store_real(real_t p_real) { - ERR_FAIL_COND_MSG(!f, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before use, or is lacking read-write permission."); f->store_real(p_real); } void File::store_string(const String &p_string) { - ERR_FAIL_COND_MSG(!f, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before use, or is lacking read-write permission."); f->store_string(p_string); } void File::store_pascal_string(const String &p_string) { - ERR_FAIL_COND_MSG(!f, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before use, or is lacking read-write permission."); f->store_pascal_string(p_string); } String File::get_pascal_string() { - ERR_FAIL_COND_V_MSG(!f, "", "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_V_MSG(f.is_null(), "", "File must be opened before use, or is lacking read-write permission."); return f->get_pascal_string(); } void File::store_line(const String &p_string) { - ERR_FAIL_COND_MSG(!f, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before use, or is lacking read-write permission."); f->store_line(p_string); } void File::store_csv_line(const Vector<String> &p_values, const String &p_delim) { - ERR_FAIL_COND_MSG(!f, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before use, or is lacking read-write permission."); f->store_csv_line(p_values, p_delim); } void File::store_buffer(const Vector<uint8_t> &p_buffer) { - ERR_FAIL_COND_MSG(!f, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before use, or is lacking read-write permission."); uint64_t len = p_buffer.size(); if (len == 0) { @@ -1339,7 +1336,7 @@ bool File::file_exists(const String &p_name) { } void File::store_var(const Variant &p_var, bool p_full_objects) { - ERR_FAIL_COND_MSG(!f, "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_MSG(f.is_null(), "File must be opened before use, or is lacking read-write permission."); int len; Error err = encode_variant(p_var, nullptr, len, p_full_objects); ERR_FAIL_COND_MSG(err != OK, "Error when trying to encode Variant."); @@ -1356,7 +1353,7 @@ void File::store_var(const Variant &p_var, bool p_full_objects) { } Variant File::get_var(bool p_allow_objects) const { - ERR_FAIL_COND_V_MSG(!f, Variant(), "File must be opened before use, or is lacking read-write permission."); + ERR_FAIL_COND_V_MSG(f.is_null(), Variant(), "File must be opened before use, or is lacking read-write permission."); uint32_t len = get_32(); Vector<uint8_t> buff = get_buffer(len); ERR_FAIL_COND_V((uint32_t)buff.size() != len, Variant()); @@ -1440,24 +1437,14 @@ void File::_bind_methods() { BIND_ENUM_CONSTANT(COMPRESSION_GZIP); } -File::~File() { - if (f) { - memdelete(f); - } -} - ////// Directory ////// Error Directory::open(const String &p_path) { Error err; - DirAccess *alt = DirAccess::open(p_path, &err); - - if (!alt) { + Ref<DirAccess> alt = DirAccess::open(p_path, &err); + if (alt.is_null()) { return err; } - if (d) { - memdelete(d); - } d = alt; dir_open = true; @@ -1465,7 +1452,7 @@ Error Directory::open(const String &p_path) { } bool Directory::is_open() const { - return d && dir_open; + return d.is_valid() && dir_open; } Error Directory::list_dir_begin() { @@ -1550,7 +1537,7 @@ int Directory::get_current_drive() { } Error Directory::change_dir(String p_dir) { - ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory is not configured properly."); + ERR_FAIL_COND_V_MSG(d.is_null(), ERR_UNCONFIGURED, "Directory is not configured properly."); Error err = d->change_dir(p_dir); if (err != OK) { @@ -1567,25 +1554,25 @@ String Directory::get_current_dir() { } Error Directory::make_dir(String p_dir) { - ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory is not configured properly."); + ERR_FAIL_COND_V_MSG(d.is_null(), ERR_UNCONFIGURED, "Directory is not configured properly."); if (!p_dir.is_relative_path()) { - DirAccessRef da = DirAccess::create_for_path(p_dir); + Ref<DirAccess> da = DirAccess::create_for_path(p_dir); return da->make_dir(p_dir); } return d->make_dir(p_dir); } Error Directory::make_dir_recursive(String p_dir) { - ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory is not configured properly."); + ERR_FAIL_COND_V_MSG(d.is_null(), ERR_UNCONFIGURED, "Directory is not configured properly."); if (!p_dir.is_relative_path()) { - DirAccessRef da = DirAccess::create_for_path(p_dir); + Ref<DirAccess> da = DirAccess::create_for_path(p_dir); return da->make_dir_recursive(p_dir); } return d->make_dir_recursive(p_dir); } bool Directory::file_exists(String p_file) { - ERR_FAIL_COND_V_MSG(!d, false, "Directory is not configured properly."); + ERR_FAIL_COND_V_MSG(d.is_null(), false, "Directory is not configured properly."); if (!p_file.is_relative_path()) { return FileAccess::exists(p_file); } @@ -1593,7 +1580,7 @@ bool Directory::file_exists(String p_file) { } bool Directory::dir_exists(String p_dir) { - ERR_FAIL_COND_V_MSG(!d, false, "Directory is not configured properly."); + ERR_FAIL_COND_V_MSG(d.is_null(), false, "Directory is not configured properly."); if (!p_dir.is_relative_path()) { return DirAccess::exists(p_dir); } @@ -1601,7 +1588,7 @@ bool Directory::dir_exists(String p_dir) { } uint64_t Directory::get_space_left() { - ERR_FAIL_COND_V_MSG(!d, 0, "Directory must be opened before use."); + ERR_FAIL_COND_V_MSG(d.is_null(), 0, "Directory must be opened before use."); return d->get_space_left() / 1024 * 1024; // Truncate to closest MiB. } @@ -1615,7 +1602,7 @@ Error Directory::rename(String p_from, String p_to) { ERR_FAIL_COND_V_MSG(p_from.is_empty() || p_from == "." || p_from == "..", ERR_INVALID_PARAMETER, "Invalid path to rename."); if (!p_from.is_relative_path()) { - DirAccessRef da = DirAccess::create_for_path(p_from); + Ref<DirAccess> da = DirAccess::create_for_path(p_from); ERR_FAIL_COND_V_MSG(!da->file_exists(p_from) && !da->dir_exists(p_from), ERR_DOES_NOT_EXIST, "File or directory does not exist."); return da->rename(p_from, p_to); } @@ -1627,7 +1614,7 @@ Error Directory::rename(String p_from, String p_to) { Error Directory::remove(String p_name) { ERR_FAIL_COND_V_MSG(!is_open(), ERR_UNCONFIGURED, "Directory must be opened before use."); if (!p_name.is_relative_path()) { - DirAccessRef da = DirAccess::create_for_path(p_name); + Ref<DirAccess> da = DirAccess::create_for_path(p_name); return da->remove(p_name); } @@ -1669,12 +1656,6 @@ Directory::Directory() { d = DirAccess::create(DirAccess::ACCESS_RESOURCES); } -Directory::~Directory() { - if (d) { - memdelete(d); - } -} - ////// Marshalls ////// Marshalls *Marshalls::singleton = nullptr; diff --git a/core/core_bind.h b/core/core_bind.h index 4d26698f99..591cacdabb 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -349,7 +349,7 @@ public: class File : public RefCounted { GDCLASS(File, RefCounted); - FileAccess *f = nullptr; + Ref<FileAccess> f; bool big_endian = false; protected: @@ -442,12 +442,11 @@ public: uint64_t get_modified_time(const String &p_file) const; File() {} - virtual ~File(); }; class Directory : public RefCounted { GDCLASS(Directory, RefCounted); - DirAccess *d = nullptr; + Ref<DirAccess> d; bool dir_open = false; bool include_navigational = false; @@ -495,7 +494,6 @@ public: Error remove(String p_name); Directory(); - virtual ~Directory(); }; class Marshalls : public Object { diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp index 9acc28f51e..f64c30dca5 100644 --- a/core/extension/extension_api_dump.cpp +++ b/core/extension/extension_api_dump.cpp @@ -869,9 +869,8 @@ void NativeExtensionAPIDump::generate_extension_json_file(const String &p_path) json.instantiate(); String text = json->stringify(api, "\t", false); - FileAccessRef fa = FileAccess::open(p_path, FileAccess::WRITE); + Ref<FileAccess> fa = FileAccess::open(p_path, FileAccess::WRITE); CharString cs = text.ascii(); fa->store_buffer((const uint8_t *)cs.ptr(), cs.length()); - fa->close(); } #endif diff --git a/core/extension/native_extension_manager.cpp b/core/extension/native_extension_manager.cpp index 509405494b..5436f7d51e 100644 --- a/core/extension/native_extension_manager.cpp +++ b/core/extension/native_extension_manager.cpp @@ -112,8 +112,8 @@ void NativeExtensionManager::deinitialize_extensions(NativeExtension::Initializa } void NativeExtensionManager::load_extensions() { - FileAccessRef f = FileAccess::open(NativeExtension::get_extension_list_config_file(), FileAccess::READ); - while (f && !f->eof_reached()) { + Ref<FileAccess> f = FileAccess::open(NativeExtension::get_extension_list_config_file(), FileAccess::READ); + while (f.is_valid() && !f->eof_reached()) { String s = f->get_line().strip_edges(); if (!s.is_empty()) { LoadStatus err = load_extension(s); 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..dd994fe2fb 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,34 +262,24 @@ 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; - } + Ref<FileAccess> fsrc = FileAccess::open(p_from, FileAccess::READ, &err); + ERR_FAIL_COND_V_MSG(err != OK, err, "Failed to open " + p_from); - 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> 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(); @@ -311,7 +299,6 @@ Error DirAccess::copy(String p_from, String p_to, int p_chmod_flags) { } 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 +306,6 @@ Error DirAccess::copy(String p_from, String p_to, int p_chmod_flags) { } } - memdelete(fsrc); - memdelete(fdst); - return err; } @@ -343,7 +327,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 +383,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 +397,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 b97d097842..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,51 +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(DirAccessRef &&other) { - f = other.f; - other.f = nullptr; - } - ~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..87c10074af 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 = Ref<FileAccess>(); } 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 a5150010da..60abfe3c5e 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); } @@ -148,9 +149,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,27 +177,4 @@ public: virtual ~FileAccess() {} }; -struct FileAccessRef { - _FORCE_INLINE_ FileAccess *operator->() { - return f; - } - - operator bool() const { return f != nullptr; } - - FileAccess *f = nullptr; - - operator FileAccess *() { return f; } - - FileAccessRef(FileAccess *fa) { f = fa; } - FileAccessRef(FileAccessRef &&other) { - f = other.f; - other.f = nullptr; - } - ~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..0c961ba8fb 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 = Ref<FileAccess>(); 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(); @@ -98,7 +98,7 @@ 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) { + if (f.is_valid()) { close(); } @@ -106,8 +106,7 @@ Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) { f = FileAccess::open(p_path, p_mode_flags, &err); if (err != OK) { //not openable - - f = nullptr; + f = Ref<FileAccess>(); return err; } @@ -127,8 +126,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 = Ref<FileAccess>(); return err; } } @@ -137,7 +135,7 @@ Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) { } void FileAccessCompressed::close() { - if (!f) { + if (f.is_null()) { return; } @@ -182,17 +180,15 @@ void FileAccessCompressed::close() { buffer.clear(); read_blocks.clear(); } - - memdelete(f); - f = nullptr; + f = Ref<FileAccess>(); } 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 +218,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 +227,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 +236,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 +245,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 +254,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 +287,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 +328,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 +343,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 +359,21 @@ 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) { + if (f.is_valid()) { close(); } } diff --git a/core/io/file_access_compressed.h b/core/io/file_access_compressed.h index 97ef3fbdeb..cd28c576cf 100644 --- a/core/io/file_access_compressed.h +++ b/core/io/file_access_compressed.h @@ -61,12 +61,12 @@ class FileAccessCompressed : public FileAccess { String magic = "GCMP"; mutable Vector<uint8_t> buffer; - FileAccess *f = nullptr; + Ref<FileAccess> f; 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 diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index 8ee19d3d06..2443e2bea0 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; @@ -116,26 +116,25 @@ Error FileAccessEncrypted::_open(const String &p_path, int p_mode_flags) { } void FileAccessEncrypted::close() { - if (!file) { + if (file.is_null()) { return; } _release(); file->close(); - memdelete(file); - file = nullptr; + file = Ref<FileAccess>(); } void FileAccessEncrypted::release() { - if (!file) { + if (file.is_null()) { return; } _release(); - file = nullptr; + file = Ref<FileAccess>(); } void FileAccessEncrypted::_release() { @@ -183,7 +182,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 +190,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 +290,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 +311,7 @@ Error FileAccessEncrypted::_set_unix_permissions(const String &p_file, uint32_t } FileAccessEncrypted::~FileAccessEncrypted() { - if (file) { + if (file.is_valid()) { close(); } } diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h index be5904c894..5d0b369fbf 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; @@ -57,8 +57,8 @@ private: void _release(); 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 diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp index 4aca26b007..62da51b09f 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); } diff --git a/core/io/file_access_memory.h b/core/io/file_access_memory.h index 50b23e1f32..baaad5f086 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); diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index 7dbea96c3d..0b8deb8ec2 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -126,8 +126,8 @@ 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; } @@ -137,19 +137,13 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, if (magic != PACK_HEADER_MAGIC) { // 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."); - } + ERR_FAIL_COND_V_MSG(p_offset != 0, 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; } f->seek(f->get_position() - 12); @@ -159,8 +153,6 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, magic = f->get_32(); if (magic != PACK_HEADER_MAGIC) { - f->close(); - memdelete(f); return false; } } @@ -170,16 +162,8 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, 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 +178,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 +189,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 +212,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)); } @@ -351,16 +325,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 +342,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 +350,6 @@ FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFil eof = false; } -FileAccessPack::~FileAccessPack() { - if (f) { - f->close(); - memdelete(f); - } -} - ////////////////////////////////////////////////////////////////////////////////// // DIR ACCESS ////////////////////////////////////////////////////////////////////////////////// @@ -507,7 +470,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 d4b32df2c7..399b345b35 100644 --- a/core/io/file_access_pack.h +++ b/core/io/file_access_pack.h @@ -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) override; - virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file) override; + virtual Ref<FileAccess> get_file(const String &p_path, PackedData::PackedFile *p_file) override; }; class FileAccessPack : public FileAccess { @@ -150,7 +150,7 @@ class FileAccessPack : public FileAccess { mutable bool eof; uint64_t off; - FileAccess *f = nullptr; + 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; } @@ -183,10 +183,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 +203,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 +231,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 +250,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..1caff2dc02 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)); } diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h index a238c66437..f6249add4b 100644 --- a/core/io/file_access_zip.h +++ b/core/io/file_access_zip.h @@ -68,7 +68,7 @@ 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) override; - FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file) override; + Ref<FileAccess> get_file(const String &p_path, PackedData::PackedFile *p_file) override; static ZipArchive *get_singleton(); 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/logger.cpp b/core/io/logger.cpp index 2b6f230434..0caa2af5c4 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 = Ref<FileAccess>(); 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..e3ac00f11c 100644 --- a/core/io/logger.h +++ b/core/io/logger.h @@ -81,9 +81,8 @@ 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(); @@ -91,8 +90,6 @@ public: 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(); }; class CompositeLogger : public Logger { diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp index b3bf0cff2d..d1a305e836 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,8 @@ Error PCKPacker::flush(bool p_verbose) { fhead->store_32(flags); } - if (fae) { + if (fae.is_valid()) { fae->release(); - memdelete(fae); } int header_padding = _get_pad(alignment, file->get_position()); @@ -222,14 +213,14 @@ 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; + fae = Ref<FileAccess>(); + 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,8 @@ Error PCKPacker::flush(bool p_verbose) { to_write -= read; } - if (fae) { + if (fae.is_valid()) { fae->release(); - memdelete(fae); } int pad = _get_pad(alignment, file->get_position()); @@ -252,8 +242,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 +253,8 @@ Error PCKPacker::flush(bool p_verbose) { printf("\n"); } - file->close(); + file = Ref<FileAccess>(); 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..bf91438810 100644 --- a/core/io/resource.cpp +++ b/core/io/resource.cpp @@ -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_format_binary.cpp b/core/io/resource_format_binary.cpp index 3ef895ab01..87e4a01819 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -101,11 +101,11 @@ void ResourceLoaderBinary::_advance_padding(uint32_t p_len) { } } -static Error read_reals(real_t *dst, FileAccess &f, size_t count) { - if (f.real_is_double) { +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)); + f->get_buffer((uint8_t *)dst, count * sizeof(double)); #ifdef BIG_ENDIAN_ENABLED { uint64_t *dst = (uint64_t *)dst; @@ -117,7 +117,7 @@ static Error read_reals(real_t *dst, FileAccess &f, size_t count) { } 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(); + dst[i] = f->get_double(); } } else { ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "real_t size is neither 4 nor 8!"); @@ -125,7 +125,7 @@ static Error read_reals(real_t *dst, FileAccess &f, size_t count) { } else { if (sizeof(real_t) == 4) { // Ideal case with float-precision - f.get_buffer((uint8_t *)dst, count * sizeof(float)); + f->get_buffer((uint8_t *)dst, count * sizeof(float)); #ifdef BIG_ENDIAN_ENABLED { uint32_t *dst = (uint32_t *)dst; @@ -136,7 +136,7 @@ static Error read_reals(real_t *dst, FileAccess &f, size_t count) { #endif } else if (sizeof(real_t) == 8) { for (size_t i = 0; i < count; ++i) { - dst[i] = f.get_float(); + dst[i] = f->get_float(); } } else { ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "real_t size is neither 4 nor 8!"); @@ -573,7 +573,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { array.resize(len); Vector2 *w = array.ptrw(); static_assert(sizeof(Vector2) == 2 * sizeof(real_t)); - const Error err = read_reals(reinterpret_cast<real_t *>(w), *f, len * 2); + const Error err = read_reals(reinterpret_cast<real_t *>(w), f, len * 2); ERR_FAIL_COND_V(err != OK, err); r_v = array; @@ -586,7 +586,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { array.resize(len); Vector3 *w = array.ptrw(); static_assert(sizeof(Vector3) == 3 * sizeof(real_t)); - const Error err = read_reals(reinterpret_cast<real_t *>(w), *f, len * 3); + const Error err = read_reals(reinterpret_cast<real_t *>(w), f, len * 3); ERR_FAIL_COND_V(err != OK, err); r_v = array; @@ -789,7 +789,7 @@ Error ResourceLoaderBinary::load() { resource_cache.push_back(res); if (main) { - f->close(); + f = Ref<FileAccess>(); resource = res; resource->set_as_translation_remapped(translation_remapped); error = OK; @@ -804,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); @@ -834,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; @@ -856,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; @@ -864,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 = Ref<FileAccess>(); ERR_FAIL_MSG("Failed to open binary resource file: " + local_path + "."); } f = fac; @@ -876,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 = Ref<FileAccess>(); ERR_FAIL_MSG("Unrecognized binary resource file: " + local_path + "."); } @@ -901,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 = Ref<FileAccess>(); 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)); } @@ -978,12 +978,11 @@ void ResourceLoaderBinary::open(FileAccess *p_f, bool p_no_resources, bool p_kee if (f->eof_reached()) { error = ERR_FILE_CORRUPT; - f->close(); 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; @@ -991,11 +990,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 = Ref<FileAccess>(); return ""; } f = fac; @@ -1003,7 +1002,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 = Ref<FileAccess>(); return ""; } @@ -1017,7 +1016,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 = Ref<FileAccess>(); return ""; } @@ -1026,19 +1025,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 + "'."); @@ -1096,8 +1089,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); @@ -1106,10 +1099,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(); @@ -1117,36 +1110,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); @@ -1169,10 +1152,8 @@ 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); { - DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); da->remove(p_path + ".depren"); } @@ -1201,8 +1182,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)); @@ -1311,22 +1290,19 @@ 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); + 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 } @@ -1343,8 +1319,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 } @@ -1362,7 +1338,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++) { @@ -1371,7 +1347,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); @@ -1830,14 +1806,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) { @@ -1853,15 +1829,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); } @@ -1902,8 +1876,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; } @@ -2061,14 +2033,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 5403168a53..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 = nullptr; 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..8f1f354e90 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(); @@ -223,8 +223,6 @@ Error ResourceUID::update_cache() { if (f != nullptr) { f->seek(0); f->store_32(cache_entries); //update amount of entries - f->close(); - memdelete(f); } changed = false; diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp index 30df46a6b4..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(); @@ -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/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 diff --git a/core/object/object.cpp b/core/object/object.cpp index c2cd42ff91..897b5d18de 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -1848,6 +1848,13 @@ Object::Object() { _construct_object(false); } +void Object::detach_from_objectdb() { + if (_instance_id != ObjectID()) { + ObjectDB::remove_instance(this); + _instance_id = ObjectID(); + } +} + Object::~Object() { if (script_instance) { memdelete(script_instance); @@ -1887,8 +1894,10 @@ Object::~Object() { c.signal.get_object()->_disconnect(c.signal.get_name(), c.callable, true); } - ObjectDB::remove_instance(this); - _instance_id = ObjectID(); + if (_instance_id != ObjectID()) { + ObjectDB::remove_instance(this); + _instance_id = ObjectID(); + } _predelete_ok = 2; if (_instance_bindings != nullptr) { diff --git a/core/object/object.h b/core/object/object.h index eeef03dcb9..c3e3c68b59 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -633,6 +633,7 @@ public: bool _is_gpl_reversed() const { return false; } + void detach_from_objectdb(); _FORCE_INLINE_ ObjectID get_instance_id() const { return _instance_id; } template <class T> diff --git a/core/os/os.cpp b/core/os/os.cpp index 2e5db145a4..bf6cd4c9ab 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -80,7 +80,9 @@ void OS::print_error(const char *p_function, const char *p_file, int p_line, con return; } - _logger->log_error(p_function, p_file, p_line, p_code, p_rationale, p_editor_notify, p_type); + if (_logger) { + _logger->log_error(p_function, p_file, p_line, p_code, p_rationale, p_editor_notify, p_type); + } } void OS::print(const char *p_format, ...) { @@ -91,7 +93,9 @@ void OS::print(const char *p_format, ...) { va_list argp; va_start(argp, p_format); - _logger->logv(p_format, argp, false); + if (_logger) { + _logger->logv(p_format, argp, false); + } va_end(argp); } @@ -104,7 +108,9 @@ void OS::printerr(const char *p_format, ...) { va_list argp; va_start(argp, p_format); - _logger->logv(p_format, argp, true); + if (_logger) { + _logger->logv(p_format, argp, true); + } va_end(argp); } @@ -173,7 +179,7 @@ void OS::dump_memory_to_file(const char *p_file) { //Memory::dump_static_mem_to_file(p_file); } -static FileAccess *_OSPRF = nullptr; +static Ref<FileAccess> _OSPRF; static void _OS_printres(Object *p_obj) { Resource *res = Object::cast_to<Resource>(p_obj); @@ -182,7 +188,7 @@ static void _OS_printres(Object *p_obj) { } String str = vformat("%s - %s - %s", res->to_string(), res->get_name(), res->get_path()); - if (_OSPRF) { + if (_OSPRF.is_valid()) { _OSPRF->store_line(str); } else { print_line(str); @@ -190,24 +196,19 @@ static void _OS_printres(Object *p_obj) { } void OS::print_all_resources(String p_to_file) { - ERR_FAIL_COND(!p_to_file.is_empty() && _OSPRF); + ERR_FAIL_COND(!p_to_file.is_empty() && _OSPRF.is_valid()); if (!p_to_file.is_empty()) { Error err; _OSPRF = FileAccess::open(p_to_file, FileAccess::WRITE, &err); if (err != OK) { - _OSPRF = nullptr; + _OSPRF = Ref<FileAccess>(); ERR_FAIL_MSG("Can't print all resources to file: " + String(p_to_file) + "."); } } ObjectDB::debug_objects(_OS_printres); - if (!p_to_file.is_empty()) { - if (_OSPRF) { - memdelete(_OSPRF); - } - _OSPRF = nullptr; - } + _OSPRF = Ref<FileAccess>(); } void OS::print_resources_in_use(bool p_short) { @@ -332,7 +333,7 @@ void OS::ensure_user_data_dir() { return; } - DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); Error err = da->make_dir_recursive(dd); ERR_FAIL_COND_MSG(err != OK, "Error attempting to create data dir: " + dd + "."); } @@ -550,6 +551,8 @@ OS::OS() { } OS::~OS() { - memdelete(_logger); + if (_logger) { + memdelete(_logger); + } singleton = nullptr; } diff --git a/core/string/print_string.h b/core/string/print_string.h index f19573ad45..f7d0f25030 100644 --- a/core/string/print_string.h +++ b/core/string/print_string.h @@ -61,6 +61,14 @@ extern bool _print_error_enabled; extern void __print_line(String p_string); extern void print_error(String p_string); extern void print_verbose(String p_string); -#define print_line(...) __print_line(stringify_variants(__VA_ARGS__)) + +inline void print_line(Variant v) { + __print_line(stringify_variants(v)); +} + +template <typename... Args> +void print_line(Variant p_var, Args... p_args) { + __print_line(stringify_variants(p_var, p_args...)); +} #endif // PRINT_STRING_H diff --git a/core/string/translation_po.cpp b/core/string/translation_po.cpp index 1c991ee12d..3f94e064ec 100644 --- a/core/string/translation_po.cpp +++ b/core/string/translation_po.cpp @@ -35,7 +35,7 @@ #ifdef DEBUG_TRANSLATION_PO void TranslationPO::print_translation_map() { Error err; - FileAccess *file = FileAccess::open("translation_map_print_test.txt", FileAccess::WRITE, &err); + Ref<FileAccess> file = FileAccess::open("translation_map_print_test.txt", FileAccess::WRITE, &err); if (err != OK) { ERR_PRINT("Failed to open translation_map_print_test.txt"); return; @@ -62,7 +62,6 @@ void TranslationPO::print_translation_map() { file->store_line(""); } } - file->close(); } #endif diff --git a/core/templates/safe_list.h b/core/templates/safe_list.h index ae31525dd0..e850f3bd5e 100644 --- a/core/templates/safe_list.h +++ b/core/templates/safe_list.h @@ -203,7 +203,7 @@ public: } // Calling this will cause zero to many deallocations. - void maybe_cleanup() { + bool maybe_cleanup() { SafeListNode *cursor = nullptr; SafeListNode *new_graveyard_head = nullptr; do { @@ -212,7 +212,7 @@ public: if (active_iterator_count.load() != 0) { // It's not safe to clean up with an active iterator, because that iterator // could be pointing to an element that we want to delete. - return; + return false; } // Any iterator created after this point will never point to a deleted node. // Swap it out with the current graveyard head. @@ -225,6 +225,17 @@ public: tmp->deletion_fn(tmp->val); memdelete_allocator<SafeListNode, A>(tmp); } + return true; + } + + ~SafeList() { +#ifdef DEBUG_ENABLED + if (!maybe_cleanup()) { + ERR_PRINT("There are still iterators around when destructing a SafeList. Memory will be leaked. This is a bug."); + } +#else + maybe_cleanup(); +#endif } }; @@ -353,11 +364,11 @@ public: } // Calling this will cause zero to many deallocations. - void maybe_cleanup() { + bool maybe_cleanup() { SafeListNode *cursor = graveyard_head; if (active_iterator_count != 0) { // It's not safe to clean up with an active iterator, because that iterator could be pointing to an element that we want to delete. - return; + return false; } graveyard_head = nullptr; // Our graveyard list is now unreachable by any active iterators, detached from the main graveyard head and ready for deletion. @@ -367,6 +378,17 @@ public: tmp->deletion_fn(tmp->val); memdelete_allocator<SafeListNode, A>(tmp); } + return true; + } + + ~SafeList() { +#ifdef DEBUG_ENABLED + if (!maybe_cleanup()) { + ERR_PRINT("There are still iterators around when destructing a SafeList. Memory will be leaked. This is a bug."); + } +#else + maybe_cleanup(); +#endif } }; diff --git a/core/variant/variant_parser.h b/core/variant/variant_parser.h index b297babd6f..07d89d30cb 100644 --- a/core/variant/variant_parser.h +++ b/core/variant/variant_parser.h @@ -49,7 +49,7 @@ public: }; struct StreamFile : public Stream { - FileAccess *f = nullptr; + Ref<FileAccess> f; virtual char32_t get_char() override; virtual bool is_utf8() const override; |