A tool for deriving PKG packet encryption keys for ps4 written in c++
| 1 | // SPDX-FileCopyrightText: 2014 Citra Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | |
| 4 | #pragma once |
| 5 | |
| 6 | #include <utility> |
| 7 | |
| 8 | namespace detail { |
| 9 | template <class F> |
| 10 | class ScopeGuard { |
| 11 | private: |
| 12 | F f; |
| 13 | bool active; |
| 14 | |
| 15 | public: |
| 16 | constexpr ScopeGuard(F f_) : f(std::move(f_)), active(true) {} |
| 17 | constexpr ~ScopeGuard() { |
| 18 | if (active) { |
| 19 | f(); |
| 20 | } |
| 21 | } |
| 22 | constexpr void Cancel() { |
| 23 | active = false; |
| 24 | } |
| 25 | |
| 26 | constexpr ScopeGuard(ScopeGuard&& rhs) : f(std::move(rhs.f)), active(rhs.active) { |
| 27 | rhs.Cancel(); |
| 28 | } |
| 29 | |
| 30 | ScopeGuard& operator=(ScopeGuard&& rhs) = delete; |
| 31 | }; |
| 32 | |
| 33 | template <class F> |
| 34 | constexpr ScopeGuard<F> MakeScopeGuard(F f) { |
| 35 | return ScopeGuard<F>(std::move(f)); |
| 36 | } |
| 37 | |
| 38 | enum class ScopeGuardOnExit {}; |
| 39 | |
| 40 | template <typename F> |
| 41 | constexpr ScopeGuard<F> operator+(ScopeGuardOnExit, F&& f) { |
| 42 | return ScopeGuard<F>(std::forward<F>(f)); |
| 43 | } |
| 44 | |
| 45 | } // namespace detail |
| 46 | |
| 47 | #define CONCATENATE_IMPL(s1, s2) s1##s2 |
| 48 | #define CONCATENATE(s1, s2) CONCATENATE_IMPL(s1, s2) |
| 49 | |
| 50 | #ifdef __COUNTER__ |
| 51 | #define ANONYMOUS_VARIABLE(pref) CONCATENATE(pref, __COUNTER__) |
| 52 | #else |
| 53 | #define ANONYMOUS_VARIABLE(pref) CONCATENATE(pref, __LINE__) |
| 54 | #endif |
| 55 | |
| 56 | /** |
| 57 | * This macro is similar to SCOPE_EXIT, except the object is caller managed. This is intended to be |
| 58 | * used when the caller might want to cancel the ScopeExit. |
| 59 | */ |
| 60 | #define SCOPE_GUARD detail::ScopeGuardOnExit() + [&]() |
| 61 | |
| 62 | /** |
| 63 | * This macro allows you to conveniently specify a block of code that will run on scope exit. Handy |
| 64 | * for doing ad-hoc clean-up tasks in a function with multiple returns. |
| 65 | * |
| 66 | * Example usage: |
| 67 | * \code |
| 68 | * const int saved_val = g_foo; |
| 69 | * g_foo = 55; |
| 70 | * SCOPE_EXIT{ g_foo = saved_val; }; |
| 71 | * |
| 72 | * if (Bar()) { |
| 73 | * return 0; |
| 74 | * } else { |
| 75 | * return 20; |
| 76 | * } |
| 77 | * \endcode |
| 78 | */ |
| 79 | #define SCOPE_EXIT auto ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE_) = SCOPE_GUARD |
| 80 |