diff options
author | FearlessTobi <thm.frey@gmail.com> | 2024-01-05 05:23:58 +0100 |
---|---|---|
committer | Liam <byteslice@airmail.cc> | 2024-01-25 22:40:42 +0100 |
commit | 06fb7f90da0b465e723a562134c12b513aa77dff (patch) | |
tree | a256bbe22aa4c2a6704f41eb22b3d2cfba0fed72 /src/core/hle/service/filesystem/fsp/fs_i_directory.cpp | |
parent | Merge pull request #12759 from liamwhite/mp-misc (diff) | |
download | yuzu-06fb7f90da0b465e723a562134c12b513aa77dff.tar yuzu-06fb7f90da0b465e723a562134c12b513aa77dff.tar.gz yuzu-06fb7f90da0b465e723a562134c12b513aa77dff.tar.bz2 yuzu-06fb7f90da0b465e723a562134c12b513aa77dff.tar.lz yuzu-06fb7f90da0b465e723a562134c12b513aa77dff.tar.xz yuzu-06fb7f90da0b465e723a562134c12b513aa77dff.tar.zst yuzu-06fb7f90da0b465e723a562134c12b513aa77dff.zip |
Diffstat (limited to 'src/core/hle/service/filesystem/fsp/fs_i_directory.cpp')
-rw-r--r-- | src/core/hle/service/filesystem/fsp/fs_i_directory.cpp | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/core/hle/service/filesystem/fsp/fs_i_directory.cpp b/src/core/hle/service/filesystem/fsp/fs_i_directory.cpp new file mode 100644 index 000000000..62512ad0f --- /dev/null +++ b/src/core/hle/service/filesystem/fsp/fs_i_directory.cpp @@ -0,0 +1,79 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/file_sys/savedata_factory.h" +#include "core/hle/service/filesystem/fsp/fs_i_directory.h" +#include "core/hle/service/ipc_helpers.h" + +namespace Service::FileSystem { + +template <typename T> +static void BuildEntryIndex(std::vector<FileSys::Entry>& entries, const std::vector<T>& new_data, + FileSys::EntryType type) { + entries.reserve(entries.size() + new_data.size()); + + for (const auto& new_entry : new_data) { + auto name = new_entry->GetName(); + + if (type == FileSys::EntryType::File && name == FileSys::GetSaveDataSizeFileName()) { + continue; + } + + entries.emplace_back(name, type, + type == FileSys::EntryType::Directory ? 0 : new_entry->GetSize()); + } +} + +IDirectory::IDirectory(Core::System& system_, FileSys::VirtualDir backend_, OpenDirectoryMode mode) + : ServiceFramework{system_, "IDirectory"}, backend(std::move(backend_)) { + static const FunctionInfo functions[] = { + {0, &IDirectory::Read, "Read"}, + {1, &IDirectory::GetEntryCount, "GetEntryCount"}, + }; + RegisterHandlers(functions); + + // 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(), FileSys::EntryType::Directory); + } + if (True(mode & OpenDirectoryMode::File)) { + BuildEntryIndex(entries, backend->GetFiles(), FileSys::EntryType::File); + } +} + +void IDirectory::Read(HLERequestContext& ctx) { + LOG_DEBUG(Service_FS, "called."); + + // Calculate how many entries we can fit in the output buffer + const u64 count_entries = ctx.GetWriteBufferNumElements<FileSys::Entry>(); + + // Cap at total number of entries. + const u64 actual_entries = std::min(count_entries, entries.size() - next_entry_index); + + // Determine data start and end + const auto* begin = reinterpret_cast<u8*>(entries.data() + next_entry_index); + const auto* end = reinterpret_cast<u8*>(entries.data() + next_entry_index + actual_entries); + const auto range_size = static_cast<std::size_t>(std::distance(begin, end)); + + next_entry_index += actual_entries; + + // Write the data to memory + ctx.WriteBuffer(begin, range_size); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(actual_entries); +} + +void IDirectory::GetEntryCount(HLERequestContext& ctx) { + LOG_DEBUG(Service_FS, "called"); + + u64 count = entries.size() - next_entry_index; + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(count); +} + +} // namespace Service::FileSystem |