summaryrefslogtreecommitdiffstats
path: root/src/core/file_sys/fsa/fs_i_directory.h
diff options
context:
space:
mode:
authorFearlessTobi <thm.frey@gmail.com>2024-02-10 18:15:58 +0100
committerFearlessTobi <thm.frey@gmail.com>2024-02-19 19:20:40 +0100
commitd5e4617ab5c8b7e72e2155de886135766ce61c7a (patch)
tree5d76b2101df594324bedb323bb5340e24ed7fa7c /src/core/file_sys/fsa/fs_i_directory.h
parentMerge pull request #13080 from FearlessTobi/scope-exit (diff)
downloadyuzu-d5e4617ab5c8b7e72e2155de886135766ce61c7a.tar
yuzu-d5e4617ab5c8b7e72e2155de886135766ce61c7a.tar.gz
yuzu-d5e4617ab5c8b7e72e2155de886135766ce61c7a.tar.bz2
yuzu-d5e4617ab5c8b7e72e2155de886135766ce61c7a.tar.lz
yuzu-d5e4617ab5c8b7e72e2155de886135766ce61c7a.tar.xz
yuzu-d5e4617ab5c8b7e72e2155de886135766ce61c7a.tar.zst
yuzu-d5e4617ab5c8b7e72e2155de886135766ce61c7a.zip
Diffstat (limited to 'src/core/file_sys/fsa/fs_i_directory.h')
-rw-r--r--src/core/file_sys/fsa/fs_i_directory.h89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/core/file_sys/fsa/fs_i_directory.h b/src/core/file_sys/fsa/fs_i_directory.h
new file mode 100644
index 000000000..a4135efec
--- /dev/null
+++ b/src/core/file_sys/fsa/fs_i_directory.h
@@ -0,0 +1,89 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "common/common_types.h"
+#include "core/file_sys/errors.h"
+#include "core/file_sys/fs_directory.h"
+#include "core/file_sys/fs_file.h"
+#include "core/file_sys/fs_filesystem.h"
+#include "core/file_sys/savedata_factory.h"
+#include "core/file_sys/vfs/vfs.h"
+#include "core/hle/result.h"
+
+namespace FileSys::Fsa {
+
+class IDirectory {
+public:
+ IDirectory(VirtualDir backend_, OpenDirectoryMode mode) : backend(std::move(backend_)) {
+ // TODO(DarkLordZach): Verify that this is the correct behavior.
+ // Build entry index now to save time later.
+ if (True(mode & OpenDirectoryMode::Directory)) {
+ BuildEntryIndex(entries, backend->GetSubdirectories(), DirectoryEntryType::Directory);
+ }
+ if (True(mode & OpenDirectoryMode::File)) {
+ BuildEntryIndex(entries, backend->GetFiles(), DirectoryEntryType::File);
+ }
+ }
+ virtual ~IDirectory() {}
+
+ Result Read(s64* out_count, DirectoryEntry* out_entries, s64 max_entries) {
+ R_UNLESS(out_count != nullptr, ResultNullptrArgument);
+ if (max_entries == 0) {
+ *out_count = 0;
+ R_SUCCEED();
+ }
+ R_UNLESS(out_entries != nullptr, ResultNullptrArgument);
+ R_UNLESS(max_entries > 0, ResultInvalidArgument);
+ R_RETURN(this->DoRead(out_count, out_entries, max_entries));
+ }
+
+ Result GetEntryCount(s64* out) {
+ R_UNLESS(out != nullptr, ResultNullptrArgument);
+ R_RETURN(this->DoGetEntryCount(out));
+ }
+
+private:
+ virtual Result DoRead(s64* out_count, DirectoryEntry* out_entries, s64 max_entries) {
+ const u64 actual_entries =
+ std::min(static_cast<u64>(max_entries), entries.size() - next_entry_index);
+ auto* begin = reinterpret_cast<u8*>(entries.data() + next_entry_index);
+
+ next_entry_index += actual_entries;
+ *out_count = actual_entries;
+
+ out_entries = reinterpret_cast<DirectoryEntry*>(begin);
+
+ R_SUCCEED();
+ }
+
+ virtual Result DoGetEntryCount(s64* out) {
+ *out = entries.size() - next_entry_index;
+ R_SUCCEED();
+ }
+
+ // TODO: Remove this when VFS is gone
+ template <typename T>
+ void BuildEntryIndex(std::vector<DirectoryEntry>& entries, const std::vector<T>& new_data,
+ DirectoryEntryType type) {
+ entries.reserve(entries.size() + new_data.size());
+
+ for (const auto& new_entry : new_data) {
+ auto name = new_entry->GetName();
+
+ if (type == DirectoryEntryType::File && name == GetSaveDataSizeFileName()) {
+ continue;
+ }
+
+ entries.emplace_back(name, static_cast<s8>(type),
+ type == DirectoryEntryType::Directory ? 0 : new_entry->GetSize());
+ }
+ }
+
+ VirtualDir backend;
+ std::vector<DirectoryEntry> entries;
+ u64 next_entry_index = 0;
+};
+
+} // namespace FileSys::Fsa