summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorPedro J. Estébanez <pedrojrulez@gmail.com>2020-07-27 12:06:40 +0200
committerPedro J. Estébanez <pedrojrulez@gmail.com>2020-07-27 12:06:40 +0200
commitf38949a44d3164acdaf501ebd6a593a2a20b56f0 (patch)
tree81734ecc52bb09eb98211013fdf5167cb8c02ac2 /core
parent4fdc3e683a2121d280de5a91c0e46467963e523d (diff)
Improve/fix packed data API
- Enhance directory API - Fix `FileAccess::exists()` not checking for PackedData being disabled - Fix moving to the parent directory (`..`) - Allow absolute paths in existence checks
Diffstat (limited to 'core')
-rw-r--r--core/io/file_access_pack.cpp30
-rw-r--r--core/io/file_access_pack.h24
-rw-r--r--core/os/file_access.cpp10
3 files changed, 55 insertions, 9 deletions
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index 37240f234a..8e8142e813 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -376,8 +376,14 @@ String DirAccessPack::get_drive(int p_drive) {
return "";
}
-Error DirAccessPack::change_dir(String p_dir) {
+PackedData::PackedDir *DirAccessPack::_find_dir(String p_dir) {
String nd = p_dir.replace("\\", "/");
+
+ // Special handling since simplify_path() will forbid it
+ if (p_dir == "..") {
+ return current->parent;
+ }
+
bool absolute = false;
if (nd.begins_with("res://")) {
nd = nd.replace_first("res://", "");
@@ -417,13 +423,21 @@ Error DirAccessPack::change_dir(String p_dir) {
pd = pd->subdirs[p];
} else {
- return ERR_INVALID_PARAMETER;
+ return nullptr;
}
}
- current = pd;
+ return pd;
+}
- return OK;
+Error DirAccessPack::change_dir(String p_dir) {
+ PackedData::PackedDir *pd = _find_dir(p_dir);
+ if (pd) {
+ current = pd;
+ return OK;
+ } else {
+ return ERR_INVALID_PARAMETER;
+ }
}
String DirAccessPack::get_current_dir(bool p_include_drive) {
@@ -441,13 +455,17 @@ String DirAccessPack::get_current_dir(bool p_include_drive) {
bool DirAccessPack::file_exists(String p_file) {
p_file = fix_path(p_file);
- return current->files.has(p_file);
+ PackedData::PackedDir *pd = _find_dir(p_file.get_base_dir());
+ if (!pd) {
+ return false;
+ }
+ return pd->files.has(p_file.get_file());
}
bool DirAccessPack::dir_exists(String p_dir) {
p_dir = fix_path(p_dir);
- return current->subdirs.has(p_dir);
+ return _find_dir(p_dir) != nullptr;
}
Error DirAccessPack::make_dir(String p_dir) {
diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h
index 348bc0c450..8c5a032732 100644
--- a/core/io/file_access_pack.h
+++ b/core/io/file_access_pack.h
@@ -113,6 +113,9 @@ public:
_FORCE_INLINE_ 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_ bool has_directory(const String &p_path);
+
PackedData();
~PackedData();
};
@@ -189,6 +192,16 @@ bool PackedData::has_path(const String &p_path) {
return files.has(PathMD5(p_path.md5_buffer()));
}
+bool PackedData::has_directory(const String &p_path) {
+ DirAccess *da = try_open_directory(p_path);
+ if (da) {
+ memdelete(da);
+ return true;
+ } else {
+ return false;
+ }
+}
+
class DirAccessPack : public DirAccess {
PackedData::PackedDir *current;
@@ -196,6 +209,8 @@ class DirAccessPack : public DirAccess {
List<String> list_files;
bool cdir = false;
+ PackedData::PackedDir *_find_dir(String p_dir);
+
public:
virtual Error list_dir_begin();
virtual String get_next();
@@ -225,4 +240,13 @@ public:
~DirAccessPack() {}
};
+DirAccess *PackedData::try_open_directory(const String &p_path) {
+ DirAccess *da = memnew(DirAccessPack());
+ if (da->change_dir(p_path) != OK) {
+ memdelete(da);
+ da = nullptr;
+ }
+ return da;
+}
+
#endif // FILE_ACCESS_PACK_H
diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp
index 20b3435911..bc2b208d81 100644
--- a/core/os/file_access.cpp
+++ b/core/os/file_access.cpp
@@ -51,7 +51,7 @@ FileAccess *FileAccess::create(AccessType p_access) {
}
bool FileAccess::exists(const String &p_name) {
- if (PackedData::get_singleton() && PackedData::get_singleton()->has_path(p_name)) {
+ if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_name)) {
return true;
}
@@ -456,7 +456,7 @@ void FileAccess::store_double(double p_dest) {
}
uint64_t FileAccess::get_modified_time(const String &p_file) {
- if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_file)) {
+ if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
return 0;
}
@@ -469,7 +469,7 @@ uint64_t FileAccess::get_modified_time(const String &p_file) {
}
uint32_t FileAccess::get_unix_permissions(const String &p_file) {
- if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_file)) {
+ if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
return 0;
}
@@ -482,6 +482,10 @@ uint32_t FileAccess::get_unix_permissions(const String &p_file) {
}
Error FileAccess::set_unix_permissions(const String &p_file, uint32_t p_permissions) {
+ if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
+ 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 + "'.");