Merge pull request #14267 from jordan-woyak/std-expected

Common: Replace Result with std::expected.
This commit is contained in:
iwubcode
2026-01-17 22:33:15 -06:00
committed by GitHub
24 changed files with 164 additions and 197 deletions
-1
View File
@@ -127,7 +127,6 @@ add_library(common
QoSSession.h
Random.cpp
Random.h
Result.h
ScopeGuard.h
SDCardUtil.cpp
SDCardUtil.h
-36
View File
@@ -1,36 +0,0 @@
// Copyright 2018 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <variant>
namespace Common
{
template <typename Expected, typename Unexpected>
class Result final
{
public:
constexpr Result(const Expected& value) : m_variant{value} {}
constexpr Result(Expected&& value) : m_variant{std::move(value)} {}
constexpr Result(const Unexpected& value) : m_variant{value} {}
constexpr Result(Unexpected&& value) : m_variant{std::move(value)} {}
constexpr explicit operator bool() const { return Succeeded(); }
constexpr bool Succeeded() const { return std::holds_alternative<Expected>(m_variant); }
// Must only be called when Succeeded() returns true.
constexpr const Expected& operator*() const { return std::get<Expected>(m_variant); }
constexpr const Expected* operator->() const { return &std::get<Expected>(m_variant); }
constexpr Expected& operator*() { return std::get<Expected>(m_variant); }
constexpr Expected* operator->() { return &std::get<Expected>(m_variant); }
// Must only be called when Succeeded() returns false.
constexpr Unexpected& Error() { return std::get<Unexpected>(m_variant); }
constexpr const Unexpected& Error() const { return std::get<Unexpected>(m_variant); }
private:
std::variant<Expected, Unexpected> m_variant;
};
} // namespace Common
+3 -3
View File
@@ -703,13 +703,13 @@ void UpdateStateFlags(std::function<void(StateFlags*)> update_function)
StateFlags state{};
if (file->GetStatus()->size == sizeof(StateFlags))
file->Read(&state, 1);
(void)file->Read(&state, 1);
update_function(&state);
state.UpdateChecksum();
file->Seek(0, IOS::HLE::FS::SeekMode::Set);
file->Write(&state, 1);
(void)file->Seek(0, IOS::HLE::FS::SeekMode::Set);
(void)file->Write(&state, 1);
}
void CreateSystemMenuTitleDirs()
+1 -1
View File
@@ -526,7 +526,7 @@ static void WriteEmptyPlayRecord()
if (!playrec_file)
return;
std::vector<u8> empty_record(0x80);
playrec_file->Write(empty_record.data(), empty_record.size());
(void)playrec_file->Write(empty_record.data(), empty_record.size());
}
// __________________________________________________________________________________________________
+5 -5
View File
@@ -3,13 +3,13 @@
#include "Core/CheatGeneration.h"
#include <expected>
#include <vector>
#include <fmt/format.h>
#include "Common/Align.h"
#include "Common/CommonTypes.h"
#include "Common/Result.h"
#include "Common/Swap.h"
#include "Core/ActionReplay.h"
@@ -52,20 +52,20 @@ static std::vector<ActionReplay::AREntry> ResultToAREntries(u32 addr, const Chea
return codes;
}
Common::Result<ActionReplay::ARCode, Cheats::GenerateActionReplayCodeErrorCode>
std::expected<ActionReplay::ARCode, Cheats::GenerateActionReplayCodeErrorCode>
Cheats::GenerateActionReplayCode(const Cheats::CheatSearchSessionBase& session, size_t index)
{
if (index >= session.GetResultCount())
return Cheats::GenerateActionReplayCodeErrorCode::IndexOutOfRange;
return std::unexpected{Cheats::GenerateActionReplayCodeErrorCode::IndexOutOfRange};
if (session.GetResultValueState(index) != Cheats::SearchResultValueState::ValueFromVirtualMemory)
return Cheats::GenerateActionReplayCodeErrorCode::NotVirtualMemory;
return std::unexpected{Cheats::GenerateActionReplayCodeErrorCode::NotVirtualMemory};
u32 address = session.GetResultAddress(index);
// check if the address is actually addressable by the ActionReplay system
if (((address & 0x01ff'ffffu) | 0x8000'0000u) != address)
return Cheats::GenerateActionReplayCodeErrorCode::InvalidAddress;
return std::unexpected{Cheats::GenerateActionReplayCodeErrorCode::InvalidAddress};
ActionReplay::ARCode ar_code;
ar_code.enabled = true;
+2 -2
View File
@@ -3,7 +3,7 @@
#pragma once
#include "Common/Result.h"
#include <expected>
#include "Core/ActionReplay.h"
@@ -18,6 +18,6 @@ enum class GenerateActionReplayCodeErrorCode
InvalidAddress,
};
Common::Result<ActionReplay::ARCode, GenerateActionReplayCodeErrorCode>
std::expected<ActionReplay::ARCode, GenerateActionReplayCodeErrorCode>
GenerateActionReplayCode(const Cheats::CheatSearchSessionBase& session, size_t index);
} // namespace Cheats
+13 -12
View File
@@ -4,6 +4,7 @@
#include "Core/CheatSearch.h"
#include <bit>
#include <expected>
#include <functional>
#include <memory>
#include <optional>
@@ -113,19 +114,19 @@ auto Cheats::NewSearch(const Core::CPUThreadGuard& guard,
const std::vector<Cheats::MemoryRange>& memory_ranges,
PowerPC::RequestedAddressSpace address_space, bool aligned,
const std::function<bool(const T& value)>& validator)
-> Common::Result<std::vector<SearchResult<T>>, SearchErrorCode>
-> std::expected<std::vector<SearchResult<T>>, SearchErrorCode>
{
if (AchievementManager::GetInstance().IsHardcoreModeActive())
return Cheats::SearchErrorCode::DisabledInHardcoreMode;
return std::unexpected{Cheats::SearchErrorCode::DisabledInHardcoreMode};
auto& system = guard.GetSystem();
std::vector<Cheats::SearchResult<T>> results;
const Core::State core_state = Core::GetState(system);
if (core_state != Core::State::Running && core_state != Core::State::Paused)
return Cheats::SearchErrorCode::NoEmulationActive;
return std::unexpected{Cheats::SearchErrorCode::NoEmulationActive};
const auto& ppc_state = system.GetPPCState();
if (address_space == PowerPC::RequestedAddressSpace::Virtual && !ppc_state.msr.DR)
return Cheats::SearchErrorCode::VirtualAddressesCurrentlyNotAccessible;
return std::unexpected{Cheats::SearchErrorCode::VirtualAddressesCurrentlyNotAccessible};
for (const Cheats::MemoryRange& range : memory_ranges)
{
@@ -166,19 +167,19 @@ auto Cheats::NextSearch(
const Core::CPUThreadGuard& guard, const std::vector<Cheats::SearchResult<T>>& previous_results,
PowerPC::RequestedAddressSpace address_space,
const std::function<bool(const T& new_value, const T& old_value)>& validator)
-> Common::Result<std::vector<SearchResult<T>>, SearchErrorCode>
-> std::expected<std::vector<SearchResult<T>>, SearchErrorCode>
{
if (AchievementManager::GetInstance().IsHardcoreModeActive())
return Cheats::SearchErrorCode::DisabledInHardcoreMode;
return std::unexpected{Cheats::SearchErrorCode::DisabledInHardcoreMode};
auto& system = guard.GetSystem();
std::vector<Cheats::SearchResult<T>> results;
const Core::State core_state = Core::GetState(system);
if (core_state != Core::State::Running && core_state != Core::State::Paused)
return Cheats::SearchErrorCode::NoEmulationActive;
return std::unexpected{Cheats::SearchErrorCode::NoEmulationActive};
const auto& ppc_state = system.GetPPCState();
if (address_space == PowerPC::RequestedAddressSpace::Virtual && !ppc_state.msr.DR)
return Cheats::SearchErrorCode::VirtualAddressesCurrentlyNotAccessible;
return std::unexpected{Cheats::SearchErrorCode::VirtualAddressesCurrentlyNotAccessible};
for (const auto& previous_result : previous_results)
{
@@ -335,8 +336,8 @@ Cheats::SearchErrorCode Cheats::CheatSearchSession<T>::RunSearch(const Core::CPU
{
if (AchievementManager::GetInstance().IsHardcoreModeActive())
return Cheats::SearchErrorCode::DisabledInHardcoreMode;
Common::Result<std::vector<SearchResult<T>>, SearchErrorCode> result =
Cheats::SearchErrorCode::InvalidParameters;
std::expected<std::vector<SearchResult<T>>, SearchErrorCode> result =
std::unexpected{Cheats::SearchErrorCode::InvalidParameters};
if (m_filter_type == FilterType::CompareAgainstSpecificValue)
{
if (!m_value)
@@ -376,14 +377,14 @@ Cheats::SearchErrorCode Cheats::CheatSearchSession<T>::RunSearch(const Core::CPU
}
}
if (result.Succeeded())
if (result.has_value())
{
m_search_results = std::move(*result);
m_first_search_done = true;
return Cheats::SearchErrorCode::Success;
}
return result.Error();
return result.error();
}
template <typename T>
+3 -3
View File
@@ -3,6 +3,7 @@
#pragma once
#include <expected>
#include <functional>
#include <memory>
#include <optional>
@@ -12,7 +13,6 @@
#include <vector>
#include "Common/CommonTypes.h"
#include "Common/Result.h"
#include "Core/PowerPC/MMU.h"
namespace Core
@@ -116,7 +116,7 @@ std::vector<u8> GetValueAsByteVector(const SearchValue& value);
// Do a new search across the given memory region in the given address space, only keeping values
// for which the given validator returns true.
template <typename T>
Common::Result<std::vector<SearchResult<T>>, SearchErrorCode>
std::expected<std::vector<SearchResult<T>>, SearchErrorCode>
NewSearch(const Core::CPUThreadGuard& guard, const std::vector<MemoryRange>& memory_ranges,
PowerPC::RequestedAddressSpace address_space, bool aligned,
const std::function<bool(const T& value)>& validator);
@@ -124,7 +124,7 @@ NewSearch(const Core::CPUThreadGuard& guard, const std::vector<MemoryRange>& mem
// Refresh the values for the given results in the given address space, only keeping values for
// which the given validator returns true.
template <typename T>
Common::Result<std::vector<SearchResult<T>>, SearchErrorCode>
std::expected<std::vector<SearchResult<T>>, SearchErrorCode>
NextSearch(const Core::CPUThreadGuard& guard, const std::vector<SearchResult<T>>& previous_results,
PowerPC::RequestedAddressSpace address_space,
const std::function<bool(const T& new_value, const T& old_value)>& validator);
+3 -3
View File
@@ -161,7 +161,7 @@ void ESDevice::FinishInit()
if (launch_file)
{
u64 id;
if (launch_file->Read(&id, 1).Succeeded())
if (launch_file->Read(&id, 1).has_value())
pending_launch_title_id = id;
}
}
@@ -811,7 +811,7 @@ static ReturnCode WriteTmdForDiVerify(FS::FileSystem* fs, const ES::TMDReader& t
{
const auto file = fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, temp_path, internal_modes);
if (!file)
return FS::ConvertResult(file.Error());
return FS::ConvertResult(file.error());
if (!file->Write(tmd.GetBytes().data(), tmd.GetBytes().size()))
return ES_EIO;
}
@@ -1039,7 +1039,7 @@ ReturnCode ESCore::ReadCertStore(std::vector<u8>* buffer) const
const auto store_file =
m_ios.GetFS()->OpenFile(PID_KERNEL, PID_KERNEL, CERT_STORE_PATH, FS::Mode::Read);
if (!store_file)
return FS::ConvertResult(store_file.Error());
return FS::ConvertResult(store_file.error());
buffer->resize(store_file->GetStatus()->size);
if (!store_file->Read(buffer->data(), buffer->size()))
+3 -3
View File
@@ -198,7 +198,7 @@ ESCore::GetStoredContentsFromTMD(const ES::TMDReader& tmd,
// Check whether the content file exists.
const auto file = fs->OpenFile(PID_KERNEL, PID_KERNEL, path, FS::Mode::Read);
if (!file.Succeeded())
if (!file.has_value())
return false;
// If content hash checks are disabled, all we have to do is check for existence.
@@ -237,7 +237,7 @@ static bool DeleteDirectoriesIfEmpty(FS::FileSystem* fs, const std::string& path
{
const auto directory = fs->ReadDirectory(PID_KERNEL, PID_KERNEL, path.substr(0, position));
if ((directory && directory->empty()) ||
(!directory && directory.Error() != FS::ResultCode::NotFound))
(!directory && directory.error() != FS::ResultCode::NotFound))
{
if (fs->Delete(PID_KERNEL, PID_KERNEL, path.substr(0, position)) != FS::ResultCode::Success)
return false;
@@ -268,7 +268,7 @@ bool ESCore::CreateTitleDirectories(u64 title_id, u16 group_id) const
const std::string data_dir = Common::GetTitleDataPath(title_id);
const auto data_dir_contents = fs->ReadDirectory(PID_KERNEL, PID_KERNEL, data_dir);
if (!data_dir_contents && (data_dir_contents.Error() != FS::ResultCode::NotFound ||
if (!data_dir_contents && (data_dir_contents.error() != FS::ResultCode::NotFound ||
fs->CreateDirectory(PID_KERNEL, PID_KERNEL, data_dir, 0,
data_dir_modes) != FS::ResultCode::Success))
{
+3 -3
View File
@@ -33,7 +33,7 @@ static ReturnCode WriteTicket(FS::FileSystem* fs, const ES::TicketReader& ticket
fs->CreateFullPath(PID_KERNEL, PID_KERNEL, path, 0, ticket_modes);
const auto file = fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, path, ticket_modes);
if (!file)
return FS::ConvertResult(file.Error());
return FS::ConvertResult(file.error());
const std::vector<u8>& raw_ticket = ticket.GetBytes();
return file->Write(raw_ticket.data(), raw_ticket.size()) ? IPC_SUCCESS : ES_EIO;
@@ -472,7 +472,7 @@ static bool HasAllRequiredContents(Kernel& ios, const ES::TMDReader& tmd)
// Note: the import hasn't been finalised yet, so the whole title directory
// is still in /import, not /title.
const std::string path = GetImportContentPath(title_id, content.id);
return ios.GetFS()->GetMetadata(PID_KERNEL, PID_KERNEL, path).Succeeded();
return ios.GetFS()->GetMetadata(PID_KERNEL, PID_KERNEL, path).has_value();
});
}
@@ -640,7 +640,7 @@ ReturnCode ESCore::DeleteTitleContent(u64 title_id) const
const std::string content_dir = Common::GetTitleContentPath(title_id);
const auto files = m_ios.GetFS()->ReadDirectory(PID_KERNEL, PID_KERNEL, content_dir);
if (!files)
return FS::ConvertResult(files.Error());
return FS::ConvertResult(files.error());
for (const std::string& file_name : *files)
{
+5 -5
View File
@@ -3,6 +3,7 @@
#pragma once
#include <expected>
#include <memory>
#include <optional>
#include <string>
@@ -15,7 +16,6 @@
#endif
#include "Common/CommonTypes.h"
#include "Common/Result.h"
class PointerWrap;
@@ -49,7 +49,7 @@ enum class ResultCode
};
template <typename T>
using Result = Common::Result<T, ResultCode>;
using Result = std::expected<T, ResultCode>;
using Uid = u32;
using Gid = u16;
@@ -289,9 +289,9 @@ Result<size_t> FileHandle::Read(T* ptr, size_t count) const
const Result<u32> bytes = m_fs->ReadBytesFromFile(*m_fd, reinterpret_cast<u8*>(ptr),
static_cast<u32>(sizeof(T) * count));
if (!bytes)
return bytes.Error();
return bytes;
if (*bytes != sizeof(T) * count)
return ResultCode::ShortRead;
return std::unexpected{ResultCode::ShortRead};
return count;
}
@@ -301,7 +301,7 @@ Result<size_t> FileHandle::Write(const T* ptr, size_t count) const
const auto result = m_fs->WriteBytesToFile(*m_fd, reinterpret_cast<const u8*>(ptr),
static_cast<u32>(sizeof(T) * count));
if (!result)
return result.Error();
return result;
return count;
}
+4 -3
View File
@@ -4,6 +4,7 @@
#include "Core/IOS/FS/FileSystem.h"
#include <algorithm>
#include <expected>
#include "Common/Assert.h"
#include "Common/FileUtil.h"
@@ -100,7 +101,7 @@ Result<FileHandle> FileSystem::CreateAndOpenFile(Uid uid, Gid gid, const std::st
const ResultCode result = CreateFile(uid, gid, path, 0, modes);
if (result != ResultCode::Success)
return result;
return std::unexpected{result};
return OpenFile(uid, gid, path, Mode::ReadWrite);
}
@@ -117,8 +118,8 @@ ResultCode FileSystem::CreateFullPath(Uid uid, Gid gid, const std::string& path,
const std::string subpath = path.substr(0, position);
const Result<Metadata> metadata = GetMetadata(uid, gid, subpath);
if (!metadata && metadata.Error() != ResultCode::NotFound)
return metadata.Error();
if (!metadata && metadata.error() != ResultCode::NotFound)
return metadata.error();
if (metadata && metadata->is_file)
return ResultCode::Invalid;
+17 -17
View File
@@ -5,13 +5,13 @@
#include <algorithm>
#include <cstring>
#include <expected>
#include <string_view>
#include <utility>
#include <fmt/format.h>
#include "Common/ChunkFile.h"
#include "Common/StringUtil.h"
#include "Common/Swap.h"
#include "Core/HW/Memmap.h"
#include "Core/HW/SystemTimers.h"
@@ -126,7 +126,7 @@ static void LogResult(ResultCode code, fmt::format_string<Args...> format, Args&
template <typename T, typename... Args>
static void LogResult(const Result<T>& result, fmt::format_string<Args...> format, Args&&... args)
{
const auto result_code = result.Succeeded() ? ResultCode::Success : result.Error();
const auto result_code = result.has_value() ? ResultCode::Success : result.error();
LogResult(result_code, format, std::forward<Args>(args)...);
}
@@ -202,7 +202,7 @@ FSCore::ScopedFd FSCore::Open(FS::Uid uid, FS::Gid gid, const std::string& path,
auto backend_fd = m_ios.GetFS()->OpenFile(uid, gid, path, mode);
LogResult(backend_fd, "OpenFile({})", path);
if (!backend_fd)
return {this, ConvertResult(backend_fd.Error()), ticks};
return {this, ConvertResult(backend_fd.error()), ticks};
auto& handle = m_fd_map[fd] = {gid, uid, backend_fd->Release()};
std::strncpy(handle.name.data(), path.c_str(), handle.name.size());
@@ -347,7 +347,7 @@ s32 FSCore::Read(u64 fd, u8* data, u32 size, std::optional<u32> ipc_buffer_addr,
LogResult(result, "Read({}, 0x{:08x}, {})", handle.name.data(), *ipc_buffer_addr, size);
if (!result)
return ConvertResult(result.Error());
return ConvertResult(result.error());
return *result;
}
@@ -378,7 +378,7 @@ s32 FSCore::Write(u64 fd, const u8* data, u32 size, std::optional<u32> ipc_buffe
LogResult(result, "Write({}, 0x{:08x}, {})", handle.name.data(), *ipc_buffer_addr, size);
if (!result)
return ConvertResult(result.Error());
return ConvertResult(result.error());
return *result;
}
@@ -401,7 +401,7 @@ s32 FSCore::Seek(u64 fd, u32 offset, FS::SeekMode mode, Ticks ticks)
const Result<u32> result = m_ios.GetFS()->SeekFile(handle.fs_fd, offset, mode);
LogResult(result, "Seek({}, 0x{:08x}, {})", handle.name.data(), offset, static_cast<int>(mode));
if (!result)
return ConvertResult(result.Error());
return ConvertResult(result.error());
return *result;
}
@@ -437,7 +437,7 @@ template <typename T>
static Result<T> GetParams(Memory::MemoryManager& memory, const IOCtlRequest& request)
{
if (request.buffer_in_size < sizeof(T))
return ResultCode::Invalid;
return std::unexpected{ResultCode::Invalid};
T params;
memory.CopyFromEmu(&params, request.buffer_in, sizeof(params));
@@ -513,7 +513,7 @@ IPCReply FSDevice::GetStats(const Handle& handle, const IOCtlRequest& request)
const Result<NandStats> stats = m_ios.GetFS()->GetNandStats();
LogResult(stats, "GetNandStats");
if (!stats)
return IPCReply(ConvertResult(stats.Error()));
return IPCReply(ConvertResult(stats.error()));
auto& system = GetSystem();
auto& memory = system.GetMemory();
@@ -534,7 +534,7 @@ IPCReply FSDevice::CreateDirectory(const Handle& handle, const IOCtlRequest& req
{
const auto params = GetParams<ISFSParams>(GetSystem().GetMemory(), request);
if (!params)
return GetFSReply(ConvertResult(params.Error()));
return GetFSReply(ConvertResult(params.error()));
const ResultCode result = m_ios.GetFS()->CreateDirectory(handle.uid, handle.gid, params->path,
params->attribute, params->modes);
@@ -579,7 +579,7 @@ IPCReply FSDevice::ReadDirectory(const Handle& handle, const IOCtlVRequest& requ
m_ios.GetFS()->ReadDirectory(handle.uid, handle.gid, directory);
LogResult(list, "ReadDirectory({})", directory);
if (!list)
return GetFSReply(ConvertResult(list.Error()));
return GetFSReply(ConvertResult(list.error()));
if (!file_list_address)
{
@@ -603,7 +603,7 @@ IPCReply FSDevice::SetAttribute(const Handle& handle, const IOCtlRequest& reques
{
const auto params = GetParams<ISFSParams>(GetSystem().GetMemory(), request);
if (!params)
return GetFSReply(ConvertResult(params.Error()));
return GetFSReply(ConvertResult(params.error()));
const ResultCode result = m_ios.GetFS()->SetMetadata(
handle.uid, params->path, params->uid, params->gid, params->attribute, params->modes);
@@ -624,7 +624,7 @@ IPCReply FSDevice::GetAttribute(const Handle& handle, const IOCtlRequest& reques
const Result<Metadata> metadata = m_ios.GetFS()->GetMetadata(handle.uid, handle.gid, path);
LogResult(metadata, "GetMetadata({})", path);
if (!metadata)
return GetFSReply(ConvertResult(metadata.Error()), ticks);
return GetFSReply(ConvertResult(metadata.error()), ticks);
// Yes, the other members aren't copied at all. Actually, IOS does not even memset
// the struct at all, which means uninitialised bytes from the stack are returned.
@@ -703,7 +703,7 @@ IPCReply FSDevice::CreateFile(const Handle& handle, const IOCtlRequest& request)
{
const auto params = GetParams<ISFSParams>(GetSystem().GetMemory(), request);
if (!params)
return GetFSReply(ConvertResult(params.Error()));
return GetFSReply(ConvertResult(params.error()));
return MakeIPCReply([&](Ticks ticks) {
return ConvertResult(
m_core.CreateFile(handle.uid, handle.gid, params->path, params->attribute, params->modes));
@@ -714,7 +714,7 @@ IPCReply FSDevice::SetFileVersionControl(const Handle& handle, const IOCtlReques
{
const auto params = GetParams<ISFSParams>(GetSystem().GetMemory(), request);
if (!params)
return GetFSReply(ConvertResult(params.Error()));
return GetFSReply(ConvertResult(params.error()));
// FS_SetFileVersionControl(ctx->uid, params->path, params->attribute)
ERROR_LOG_FMT(IOS_FS, "SetFileVersionControl({}, {:#x}): Stubbed", params->path,
@@ -730,7 +730,7 @@ IPCReply FSDevice::GetFileStats(const Handle& handle, const IOCtlRequest& reques
return MakeIPCReply([&](Ticks ticks) {
const Result<FileStatus> status = m_core.GetFileStatus(request.fd, ticks);
if (!status)
return ConvertResult(status.Error());
return ConvertResult(status.error());
auto& system = GetSystem();
auto& memory = system.GetMemory();
@@ -748,7 +748,7 @@ FS::Result<FS::FileStatus> FSCore::GetFileStatus(u64 fd, Ticks ticks)
ticks.Add(IPC_OVERHEAD_TICKS);
const auto& handle = m_fd_map[fd];
if (handle.fs_fd == INVALID_FD)
return ResultCode::Invalid;
return std::unexpected{ResultCode::Invalid};
auto status = m_ios.GetFS()->GetFileStatus(handle.fs_fd);
LogResult(status, "GetFileStatus({})", handle.name.data());
@@ -770,7 +770,7 @@ IPCReply FSDevice::GetUsage(const Handle& handle, const IOCtlVRequest& request)
const Result<DirectoryStats> stats = m_ios.GetFS()->GetDirectoryStats(directory);
LogResult(stats, "GetDirectoryStats({})", directory);
if (!stats)
return GetFSReply(ConvertResult(stats.Error()));
return GetFSReply(ConvertResult(stats.error()));
memory.Write_U32(stats->used_clusters, request.io_vectors[0].address);
memory.Write_U32(stats->used_inodes, request.io_vectors[1].address);
+14 -14
View File
@@ -4,7 +4,7 @@
#include "Core/IOS/FS/HostBackend/FS.h"
#include <algorithm>
#include <cmath>
#include <expected>
#include <optional>
#include <string_view>
#include <type_traits>
@@ -652,17 +652,17 @@ Result<std::vector<std::string>> HostFileSystem::ReadDirectory(Uid uid, Gid gid,
const std::string& path)
{
if (!IsValidPath(path))
return ResultCode::Invalid;
return std::unexpected{ResultCode::Invalid};
const FstEntry* entry = GetFstEntryForPath(path);
if (!entry)
return ResultCode::NotFound;
return std::unexpected{ResultCode::NotFound};
if (!entry->CheckPermission(uid, gid, Mode::Read))
return ResultCode::AccessDenied;
return std::unexpected{ResultCode::AccessDenied};
if (entry->data.is_file)
return ResultCode::Invalid;
return std::unexpected{ResultCode::Invalid};
const std::string host_path = BuildFilename(path).host_path;
File::FSTEntry host_entry = File::ScanDirectoryTree(host_path, false);
@@ -712,19 +712,19 @@ Result<Metadata> HostFileSystem::GetMetadata(Uid uid, Gid gid, const std::string
else
{
if (!IsValidNonRootPath(path))
return ResultCode::Invalid;
return std::unexpected{ResultCode::Invalid};
const auto split_path = SplitPathAndBasename(path);
const FstEntry* parent = GetFstEntryForPath(split_path.parent);
if (!parent)
return ResultCode::NotFound;
return std::unexpected{ResultCode::NotFound};
if (!parent->CheckPermission(uid, gid, Mode::Read))
return ResultCode::AccessDenied;
return std::unexpected{ResultCode::AccessDenied};
entry = GetFstEntryForPath(path);
}
if (!entry)
return ResultCode::NotFound;
return std::unexpected{ResultCode::NotFound};
Metadata metadata = entry->data;
metadata.size = File::GetSize(BuildFilename(path).host_path);
@@ -780,7 +780,7 @@ Result<NandStats> HostFileSystem::GetNandStats()
{
const auto root_stats = GetDirectoryStats("/");
if (!root_stats)
return root_stats.Error(); // TODO: is this right? can this fail on hardware?
return std::unexpected{root_stats.error()}; // TODO: is this right? can this fail on hardware?
NandStats stats{};
stats.cluster_size = CLUSTER_SIZE;
@@ -798,7 +798,7 @@ Result<DirectoryStats> HostFileSystem::GetDirectoryStats(const std::string& wii_
{
const auto result = GetExtendedDirectoryStats(wii_path);
if (!result)
return result.Error();
return std::unexpected{result.error()};
DirectoryStats stats{};
stats.used_inodes = static_cast<u32>(std::min<u64>(result->used_inodes, TOTAL_INODES));
@@ -810,14 +810,14 @@ Result<ExtendedDirectoryStats>
HostFileSystem::GetExtendedDirectoryStats(const std::string& wii_path)
{
if (!IsValidPath(wii_path))
return ResultCode::Invalid;
return std::unexpected{ResultCode::Invalid};
ExtendedDirectoryStats stats{};
std::string path(BuildFilename(wii_path).host_path);
File::FileInfo info(path);
if (!info.Exists())
{
return ResultCode::NotFound;
return std::unexpected{ResultCode::NotFound};
}
if (info.IsDirectory())
{
@@ -830,7 +830,7 @@ HostFileSystem::GetExtendedDirectoryStats(const std::string& wii_path)
}
else
{
return ResultCode::Invalid;
return std::unexpected{ResultCode::Invalid};
}
return stats;
}
+15 -14
View File
@@ -4,6 +4,7 @@
#include "Core/IOS/FS/HostBackend/FS.h"
#include <algorithm>
#include <expected>
#include <memory>
#include "Common/FileUtil.h"
@@ -78,26 +79,26 @@ Result<FileHandle> HostFileSystem::OpenFile(Uid, Gid, const std::string& path, M
{
Handle* handle = AssignFreeHandle();
if (!handle)
return ResultCode::NoFreeHandle;
return std::unexpected{ResultCode::NoFreeHandle};
const std::string host_path = BuildFilename(path).host_path;
if (File::IsDirectory(host_path))
{
*handle = Handle{};
return ResultCode::Invalid;
return std::unexpected{ResultCode::Invalid};
}
if (!File::IsFile(host_path))
{
*handle = Handle{};
return ResultCode::NotFound;
return std::unexpected{ResultCode::NotFound};
}
handle->host_file = OpenHostFile(host_path);
if (!handle->host_file)
{
*handle = Handle{};
return ResultCode::AccessDenied;
return std::unexpected{ResultCode::AccessDenied};
}
handle->wii_path = path;
@@ -122,10 +123,10 @@ Result<u32> HostFileSystem::ReadBytesFromFile(Fd fd, u8* ptr, u32 count)
{
Handle* handle = GetHandleFromFd(fd);
if (!handle || !handle->host_file->IsOpen())
return ResultCode::Invalid;
return std::unexpected{ResultCode::Invalid};
if ((u8(handle->mode) & u8(Mode::Read)) == 0)
return ResultCode::AccessDenied;
return std::unexpected{ResultCode::AccessDenied};
const u32 file_size = static_cast<u32>(handle->host_file->GetSize());
// IOS has this check in the read request handler.
@@ -137,7 +138,7 @@ Result<u32> HostFileSystem::ReadBytesFromFile(Fd fd, u8* ptr, u32 count)
const u32 actually_read = static_cast<u32>(fread(ptr, 1, count, handle->host_file->GetHandle()));
if (actually_read != count && ferror(handle->host_file->GetHandle()))
return ResultCode::AccessDenied;
return std::unexpected{ResultCode::AccessDenied};
// IOS returns the number of bytes read and adds that value to the seek position,
// instead of adding the *requested* read length.
@@ -149,15 +150,15 @@ Result<u32> HostFileSystem::WriteBytesToFile(Fd fd, const u8* ptr, u32 count)
{
Handle* handle = GetHandleFromFd(fd);
if (!handle || !handle->host_file->IsOpen())
return ResultCode::Invalid;
return std::unexpected{ResultCode::Invalid};
if ((u8(handle->mode) & u8(Mode::Write)) == 0)
return ResultCode::AccessDenied;
return std::unexpected{ResultCode::AccessDenied};
// File might be opened twice, need to seek before we read
handle->host_file->Seek(handle->file_offset, File::SeekOrigin::Begin);
if (!handle->host_file->WriteBytes(ptr, count))
return ResultCode::AccessDenied;
return std::unexpected{ResultCode::AccessDenied};
handle->file_offset += count;
return count;
@@ -167,7 +168,7 @@ Result<u32> HostFileSystem::SeekFile(Fd fd, std::uint32_t offset, SeekMode mode)
{
Handle* handle = GetHandleFromFd(fd);
if (!handle || !handle->host_file->IsOpen())
return ResultCode::Invalid;
return std::unexpected{ResultCode::Invalid};
u32 new_position = 0;
switch (mode)
@@ -182,12 +183,12 @@ Result<u32> HostFileSystem::SeekFile(Fd fd, std::uint32_t offset, SeekMode mode)
new_position = handle->host_file->GetSize() + offset;
break;
default:
return ResultCode::Invalid;
return std::unexpected{ResultCode::Invalid};
}
// This differs from POSIX behaviour which allows seeking past the end of the file.
if (handle->host_file->GetSize() < new_position)
return ResultCode::Invalid;
return std::unexpected{ResultCode::Invalid};
handle->file_offset = new_position;
return handle->file_offset;
@@ -197,7 +198,7 @@ Result<FileStatus> HostFileSystem::GetFileStatus(Fd fd)
{
const Handle* handle = GetHandleFromFd(fd);
if (!handle || !handle->host_file->IsOpen())
return ResultCode::Invalid;
return std::unexpected{ResultCode::Invalid};
FileStatus status;
status.size = handle->host_file->GetSize();
+9 -9
View File
@@ -66,29 +66,29 @@ void SysConf::Load()
bool SysConf::LoadFromFile(const IOS::HLE::FS::FileHandle& file)
{
file.Seek(4, IOS::HLE::FS::SeekMode::Set);
(void)file.Seek(4, IOS::HLE::FS::SeekMode::Set);
u16 number_of_entries;
file.Read(&number_of_entries, 1);
(void)file.Read(&number_of_entries, 1);
number_of_entries = Common::swap16(number_of_entries);
std::vector<u16> offsets(number_of_entries);
for (u16& offset : offsets)
{
file.Read(&offset, 1);
(void)file.Read(&offset, 1);
offset = Common::swap16(offset);
}
for (const u16 offset : offsets)
{
file.Seek(offset, IOS::HLE::FS::SeekMode::Set);
(void)file.Seek(offset, IOS::HLE::FS::SeekMode::Set);
// Metadata
u8 description = 0;
file.Read(&description, 1);
(void)file.Read(&description, 1);
const Entry::Type type = static_cast<Entry::Type>((description & 0xe0) >> 5);
const u8 name_length = (description & 0x1f) + 1;
std::string name(name_length, '\0');
file.Read(&name[0], name.size());
(void)file.Read(name.data(), name.size());
// Data
std::vector<u8> data;
@@ -97,7 +97,7 @@ bool SysConf::LoadFromFile(const IOS::HLE::FS::FileHandle& file)
case Entry::Type::BigArray:
{
u16 data_length = 0;
file.Read(&data_length, 1);
(void)file.Read(&data_length, 1);
// The stored u16 is length - 1, not length.
data.resize(Common::swap16(data_length) + 1);
break;
@@ -105,7 +105,7 @@ bool SysConf::LoadFromFile(const IOS::HLE::FS::FileHandle& file)
case Entry::Type::SmallArray:
{
u8 data_length = 0;
file.Read(&data_length, 1);
(void)file.Read(&data_length, 1);
data.resize(data_length + 1);
break;
}
@@ -122,7 +122,7 @@ bool SysConf::LoadFromFile(const IOS::HLE::FS::FileHandle& file)
return false;
}
file.Read(data.data(), data.size());
(void)file.Read(data.data(), data.size());
AddEntry({type, name, std::move(data)});
}
return true;
+1 -1
View File
@@ -300,7 +300,7 @@ static bool CopySysmenuFilesToFS(FS::FileSystem* fs, const std::string& host_sou
else
{
// Do not overwrite any existing files.
if (fs->GetMetadata(IOS::SYSMENU_UID, IOS::SYSMENU_UID, nand_path).Succeeded())
if (fs->GetMetadata(IOS::SYSMENU_UID, IOS::SYSMENU_UID, nand_path).has_value())
continue;
File::IOFile host_file{host_path, "rb"};
+2 -1
View File
@@ -5,6 +5,7 @@
#include <algorithm>
#include <cstring>
#include <expected>
#include <memory>
#include <string>
#include <utility>
@@ -210,7 +211,7 @@ static ConversionResult<OutputParameters> Compress(CompressThreadState* state,
if (retval != Z_OK)
{
ERROR_LOG_FMT(DISCIO, "Deflate failed");
return ConversionResultCode::InternalError;
return std::unexpected{ConversionResultCode::InternalError};
}
const int status = deflate(&state->z, Z_FINISH);
+3 -3
View File
@@ -4,6 +4,7 @@
#pragma once
#include <atomic>
#include <expected>
#include <functional>
#include <memory>
#include <thread>
@@ -11,7 +12,6 @@
#include "Common/Assert.h"
#include "Common/Event.h"
#include "Common/Result.h"
namespace DiscIO
{
@@ -25,7 +25,7 @@ enum class ConversionResultCode
};
template <typename T>
using ConversionResult = Common::Result<T, ConversionResultCode>;
using ConversionResult = std::expected<T, ConversionResultCode>;
// This class starts a number of compression threads and one output thread.
// The set_up_compress_thread_state function is called at the start of each compression thread.
@@ -165,7 +165,7 @@ private:
}
else
{
SetError(result.Error());
SetError(result.error());
}
state->compress_done_event.Set();

Some files were not shown because too many files have changed in this diff Show More