mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
Merge pull request #14267 from jordan-woyak/std-expected
Common: Replace Result with std::expected.
This commit is contained in:
@@ -127,7 +127,6 @@ add_library(common
|
||||
QoSSession.h
|
||||
Random.cpp
|
||||
Random.h
|
||||
Result.h
|
||||
ScopeGuard.h
|
||||
SDCardUtil.cpp
|
||||
SDCardUtil.h
|
||||
|
||||
@@ -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
|
||||
@@ -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()
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
// __________________________________________________________________________________________________
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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);
|
||||
|
||||
@@ -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()))
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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,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;
|
||||
|
||||
|
||||
@@ -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(¶ms, 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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user