Skip to content

Commit

Permalink
OrcLib: add std::expected support
Browse files Browse the repository at this point in the history
  • Loading branch information
jgautier-anssi authored and fabienfl-orc committed Jun 4, 2024
1 parent 69b4f37 commit 09c0e1f
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 31 deletions.
2 changes: 1 addition & 1 deletion src/OrcLib/Authenticode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ Orc::Result<void> CheckCatalogSignature(std::string_view catalog)
}
}

return Success<void>();
return Orc::Success<void>();
}

bool FindPeHash(std::string_view buffer, const Orc::Authenticode::PE_Hashs& peHashes)
Expand Down
2 changes: 1 addition & 1 deletion src/OrcLib/DriverMgmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ class Driver : public std::enable_shared_from_this<Driver>
NULL);
FAILED(hr))
return SystemError(hr);
return Success {};
return {};
}

template <typename _Tout>
Expand Down
1 change: 1 addition & 0 deletions src/OrcLib/OrcLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <map>
#include <memory>
#include <functional>
#include <string>
#include <vector>
#include <type_traits>
Expand Down
6 changes: 3 additions & 3 deletions src/OrcLib/Text/Format.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,20 +71,20 @@ inline void FormatWithEncodingTo(OutputIt out, FmtArg0&& arg0, FmtArgs&&... args

if constexpr (std::is_same_v<FmtCharT, BufferCharT>)
{
fmt::format_to(out, std::forward<FmtArg0>(arg0), std::forward<FmtArgs>(args)...);
fmt::format_to(out, std::forward<FmtArg0>(arg0), args...);
}
else if constexpr (std::is_same_v<FmtCharT, char>)
{
fmt::basic_memory_buffer<char, 32768> utf8;
fmt::vformat_to(
std::back_inserter(utf8), fmt::string_view(arg0), fmt::make_format_args(std::forward<FmtArgs>(args)...));
std::back_inserter(utf8), fmt::string_view(arg0), fmt::make_format_args(args...));
details::ToUtf16(utf8, out);
}
else if constexpr (std::is_same_v<FmtCharT, wchar_t>)
{
fmt::basic_memory_buffer<wchar_t, 32768> utf16;
fmt::vformat_to(
std::back_inserter(utf16), fmt::wstring_view(arg0), fmt::make_wformat_args(std::forward<FmtArgs>(args)...));
std::back_inserter(utf16), fmt::wstring_view(arg0), fmt::make_wformat_args(args...));
details::ToUtf8(utf16, out);
}
else
Expand Down
1 change: 1 addition & 0 deletions src/OrcLib/Text/Iconv.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#pragma once

#include <string>
#include <string_view>
#include <system_error>
#include <type_traits>

Expand Down
2 changes: 1 addition & 1 deletion src/OrcLib/Utils/Dump.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Result<void> Dump(const T& container, const std::filesystem::path& output)
return std::make_error_code(std::errc::message_size);
}

return Orc::Success<>();
return {};
}

} // namespace Orc
182 changes: 157 additions & 25 deletions src/OrcLib/Utils/Result.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,133 @@
#pragma once

#include <optional>
#include <winternl.h>
#include <system_error>
#include <cassert>

#include <boost/outcome/outcome.hpp>
#ifdef __cpp_lib_expected
# include <expected>

namespace Orc {

template <typename T>
concept not_void = !std::is_same_v<T, void>;

template <typename T = void>
struct Result : std::expected<T, std::error_code>
{
constexpr Result(Result<T>&& value) noexcept = default;
constexpr Result(const Result<T>& value) noexcept = delete;

constexpr Result& operator=(Result<T>&& value) noexcept = default;
constexpr Result& operator=(const Result<T>& value) noexcept = default;

constexpr Result& operator=(const std::errc& ec)
{
return *this = std::unexpected(std::make_error_code(ec));
}

constexpr Result& operator=(const std::error_code& ec)
{
return *this = std::unexpected(ec);
}

template <typename U = T>
constexpr Result(U&& value) noexcept
requires(!std::is_same_v<U, void> && std::is_convertible_v<U, T>)
: std::expected<T, std::error_code>(std::forward<U>(value)) {};

constexpr Result(std::errc ec)
: std::expected<T, std::error_code>(std::unexpected(std::make_error_code(ec))) {};

constexpr Result(std::error_code ec)
: std::expected<T, std::error_code>(std::unexpected(ec)) {};

constexpr Result(std::unexpected<std::error_code> unexpected)
: std::expected<T, std::error_code>(std::move(unexpected)) {};

template <typename... Args>
constexpr Result(Args&&... args) noexcept
requires std::constructible_from<T, Args...>
: std::expected<T, std::error_code>(std::in_place, args...)
{
}

constexpr inline bool has_error() const { return !this->has_value(); }
};


template <>
struct Result<void> : std::expected<void, std::error_code>
{

constexpr Result(std::errc ec)
: std::expected<void, std::error_code>(std::unexpected(std::make_error_code(ec))) {};

Result(std::error_code ec) noexcept
: std::expected<void, std::error_code>(std::unexpected(ec)) {};

Result(std::unexpected<std::error_code> unexpected)
: std::expected<void, std::error_code>(std::move(unexpected)) {};

template <typename... Args>
constexpr Result(Args&&... args)
: std::expected<void, std::error_code>()
{
}

constexpr inline bool has_error() const { return !this->has_value(); }
};

template <typename T>
inline Result<T> Success(auto... args)
requires not_void<T> && std::constructible_from<T, decltype(args)...>
{
return {std::in_place, args...};
}

template <>
inline Result<void> Success()
{
return {std::in_place};
}

using Fail = std::unexpected<std::error_code>;


inline std::error_code SystemError(HRESULT hr)
{
return {hr, std::system_category()};
}

inline std::error_code Win32Error(DWORD win32Error)
{
return {HRESULT_FROM_WIN32(win32Error), std::system_category()};
}

inline std::error_code NtError(NTSTATUS ntStatus)
{
return std::error_code {HRESULT_FROM_NT(ntStatus), std::system_category()};
}

// Return std::error_code from GetLastError() value
inline std::error_code LastWin32Error()
{
return std::error_code {HRESULT_FROM_WIN32(::GetLastError()), std::system_category()};
}

} // namespace Orc

# define ORC_TRY(value, expr) \
auto&& _result = expr; \
if (!_result.has_value()) \
return std::unexpected(_result.error()); \
auto value = *_result;

#else

# include <boost/outcome/outcome.hpp>

#include <winternl.h>

namespace Orc {

Expand Down Expand Up @@ -64,8 +187,38 @@ struct Result<void> : boost::outcome_v2::std_result<void>
}
};

template <typename T = void>
using Success = boost::outcome_v2::success_type<T>;
template <typename T, typename... Args>
inline Result<T> Success(Args&&... args)
{
return {boost::outcome_v2::in_place_type<void>, args...};
}

inline std::error_code SystemError(HRESULT hr)
{
return {hr, std::system_category()};
}

inline std::error_code Win32Error(DWORD win32Error)
{
return {HRESULT_FROM_WIN32(win32Error), std::system_category()};
}

inline std::error_code NtError(NTSTATUS ntStatus)
{
return {HRESULT_FROM_NT(ntStatus), std::system_category()};
}

// Return std::error_code from GetLastError() value
inline std::error_code LastWin32Error()
{
return {HRESULT_FROM_WIN32(::GetLastError()), std::system_category()};
}

} // namespace Orc

#endif

namespace Orc {

template <typename T>
T& operator*(Result<T>& result)
Expand Down Expand Up @@ -123,27 +276,6 @@ T ValueOr(Orc::Result<T>&& result, T&& fallback_value)
return std::move(fallback_value);
}

inline std::error_code SystemError(HRESULT hr)
{
return {hr, std::system_category()};
}

inline std::error_code Win32Error(DWORD win32Error)
{
return {HRESULT_FROM_WIN32(win32Error), std::system_category()};
}

inline std::error_code NtError(NTSTATUS ntStatus)
{
return {HRESULT_FROM_NT(ntStatus), std::system_category()};
}

// Return std::error_code from GetLastError() value
inline std::error_code LastWin32Error()
{
return {HRESULT_FROM_WIN32(::GetLastError()), std::system_category()};
}

inline HRESULT ToHRESULT(const std::error_code& ec)
{
if (ec.category() != std::system_category())
Expand Down

0 comments on commit 09c0e1f

Please sign in to comment.