summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <rverschelde@gmail.com>2020-11-10 10:59:34 +0100
committerGitHub <noreply@github.com>2020-11-10 10:59:34 +0100
commit32464e569f8e9d8b4146e49ee5daee777a8e3323 (patch)
treecc74b6c4aef73de30f8a07fa9300aec4ff721753
parentcb5d5ff41359c94af2fdc6b2effe2af430080135 (diff)
parentf38949a44d3164acdaf501ebd6a593a2a20b56f0 (diff)
Merge pull request #40748 from RandomShaper/improve_packed_fs_api
Improve/fix packed data API
-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 b63e0adc45..a025ca5730 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -442,8 +442,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://", "");
@@ -483,13 +489,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) {
@@ -507,13 +521,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 5c58dc01b4..c13626a5aa 100644
--- a/core/io/file_access_pack.h
+++ b/core/io/file_access_pack.h
@@ -122,6 +122,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();
};
@@ -199,6 +202,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;
@@ -206,6 +219,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();
@@ -235,4 +250,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 ef3eb6800a..fd3c6f8806 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 + "'.");