Skip to content

Commit 32464e5

Browse files
authored
Merge pull request #40748 from RandomShaper/improve_packed_fs_api
Improve/fix packed data API
2 parents cb5d5ff + f38949a commit 32464e5

File tree

3 files changed

+55
-9
lines changed

3 files changed

+55
-9
lines changed

core/io/file_access_pack.cpp

+24-6
Original file line numberDiff line numberDiff line change
@@ -442,8 +442,14 @@ String DirAccessPack::get_drive(int p_drive) {
442442
return "";
443443
}
444444

445-
Error DirAccessPack::change_dir(String p_dir) {
445+
PackedData::PackedDir *DirAccessPack::_find_dir(String p_dir) {
446446
String nd = p_dir.replace("\\", "/");
447+
448+
// Special handling since simplify_path() will forbid it
449+
if (p_dir == "..") {
450+
return current->parent;
451+
}
452+
447453
bool absolute = false;
448454
if (nd.begins_with("res://")) {
449455
nd = nd.replace_first("res://", "");
@@ -483,13 +489,21 @@ Error DirAccessPack::change_dir(String p_dir) {
483489
pd = pd->subdirs[p];
484490

485491
} else {
486-
return ERR_INVALID_PARAMETER;
492+
return nullptr;
487493
}
488494
}
489495

490-
current = pd;
496+
return pd;
497+
}
491498

492-
return OK;
499+
Error DirAccessPack::change_dir(String p_dir) {
500+
PackedData::PackedDir *pd = _find_dir(p_dir);
501+
if (pd) {
502+
current = pd;
503+
return OK;
504+
} else {
505+
return ERR_INVALID_PARAMETER;
506+
}
493507
}
494508

495509
String DirAccessPack::get_current_dir(bool p_include_drive) {
@@ -507,13 +521,17 @@ String DirAccessPack::get_current_dir(bool p_include_drive) {
507521
bool DirAccessPack::file_exists(String p_file) {
508522
p_file = fix_path(p_file);
509523

510-
return current->files.has(p_file);
524+
PackedData::PackedDir *pd = _find_dir(p_file.get_base_dir());
525+
if (!pd) {
526+
return false;
527+
}
528+
return pd->files.has(p_file.get_file());
511529
}
512530

513531
bool DirAccessPack::dir_exists(String p_dir) {
514532
p_dir = fix_path(p_dir);
515533

516-
return current->subdirs.has(p_dir);
534+
return _find_dir(p_dir) != nullptr;
517535
}
518536

519537
Error DirAccessPack::make_dir(String p_dir) {

core/io/file_access_pack.h

+24
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ class PackedData {
122122
_FORCE_INLINE_ FileAccess *try_open_path(const String &p_path);
123123
_FORCE_INLINE_ bool has_path(const String &p_path);
124124

125+
_FORCE_INLINE_ DirAccess *try_open_directory(const String &p_path);
126+
_FORCE_INLINE_ bool has_directory(const String &p_path);
127+
125128
PackedData();
126129
~PackedData();
127130
};
@@ -199,13 +202,25 @@ bool PackedData::has_path(const String &p_path) {
199202
return files.has(PathMD5(p_path.md5_buffer()));
200203
}
201204

205+
bool PackedData::has_directory(const String &p_path) {
206+
DirAccess *da = try_open_directory(p_path);
207+
if (da) {
208+
memdelete(da);
209+
return true;
210+
} else {
211+
return false;
212+
}
213+
}
214+
202215
class DirAccessPack : public DirAccess {
203216
PackedData::PackedDir *current;
204217

205218
List<String> list_dirs;
206219
List<String> list_files;
207220
bool cdir = false;
208221

222+
PackedData::PackedDir *_find_dir(String p_dir);
223+
209224
public:
210225
virtual Error list_dir_begin();
211226
virtual String get_next();
@@ -235,4 +250,13 @@ class DirAccessPack : public DirAccess {
235250
~DirAccessPack() {}
236251
};
237252

253+
DirAccess *PackedData::try_open_directory(const String &p_path) {
254+
DirAccess *da = memnew(DirAccessPack());
255+
if (da->change_dir(p_path) != OK) {
256+
memdelete(da);
257+
da = nullptr;
258+
}
259+
return da;
260+
}
261+
238262
#endif // FILE_ACCESS_PACK_H

core/os/file_access.cpp

+7-3
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ FileAccess *FileAccess::create(AccessType p_access) {
5151
}
5252

5353
bool FileAccess::exists(const String &p_name) {
54-
if (PackedData::get_singleton() && PackedData::get_singleton()->has_path(p_name)) {
54+
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_name)) {
5555
return true;
5656
}
5757

@@ -456,7 +456,7 @@ void FileAccess::store_double(double p_dest) {
456456
}
457457

458458
uint64_t FileAccess::get_modified_time(const String &p_file) {
459-
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_file)) {
459+
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
460460
return 0;
461461
}
462462

@@ -469,7 +469,7 @@ uint64_t FileAccess::get_modified_time(const String &p_file) {
469469
}
470470

471471
uint32_t FileAccess::get_unix_permissions(const String &p_file) {
472-
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_file)) {
472+
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
473473
return 0;
474474
}
475475

@@ -482,6 +482,10 @@ uint32_t FileAccess::get_unix_permissions(const String &p_file) {
482482
}
483483

484484
Error FileAccess::set_unix_permissions(const String &p_file, uint32_t p_permissions) {
485+
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
486+
return ERR_UNAVAILABLE;
487+
}
488+
485489
FileAccess *fa = create_for_path(p_file);
486490
ERR_FAIL_COND_V_MSG(!fa, ERR_CANT_CREATE, "Cannot create FileAccess for path '" + p_file + "'.");
487491

0 commit comments

Comments
 (0)