diff options
author | Liam <byteslice@airmail.cc> | 2023-08-10 21:34:43 -0400 |
---|---|---|
committer | Liam <byteslice@airmail.cc> | 2023-08-15 17:47:25 -0400 |
commit | 86f6b6b7b2d930e8203114332b04a5c49a780b06 (patch) | |
tree | bf7ff58b0a36051d3c3489a40999d80357c570d0 /src/common | |
parent | a8c4f01f6ca040672e85faaf42a8ef12d373dd65 (diff) |
vfs: expand support for NCA reading
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/alignment.h | 29 | ||||
-rw-r--r-- | src/common/lz4_compression.cpp | 6 | ||||
-rw-r--r-- | src/common/lz4_compression.h | 2 |
3 files changed, 35 insertions, 2 deletions
diff --git a/src/common/alignment.h b/src/common/alignment.h index fa715d497..0057052af 100644 --- a/src/common/alignment.h +++ b/src/common/alignment.h @@ -3,6 +3,7 @@ #pragma once +#include <bit> #include <cstddef> #include <new> #include <type_traits> @@ -10,7 +11,7 @@ namespace Common { template <typename T> - requires std::is_unsigned_v<T> + requires std::is_integral_v<T> [[nodiscard]] constexpr T AlignUp(T value, size_t size) { auto mod{static_cast<T>(value % size)}; value -= mod; @@ -24,7 +25,7 @@ template <typename T> } template <typename T> - requires std::is_unsigned_v<T> + requires std::is_integral_v<T> [[nodiscard]] constexpr T AlignDown(T value, size_t size) { return static_cast<T>(value - value % size); } @@ -55,6 +56,30 @@ template <typename T, typename U> return (x + (y - 1)) / y; } +template <typename T> + requires std::is_integral_v<T> +[[nodiscard]] constexpr T LeastSignificantOneBit(T x) { + return x & ~(x - 1); +} + +template <typename T> + requires std::is_integral_v<T> +[[nodiscard]] constexpr T ResetLeastSignificantOneBit(T x) { + return x & (x - 1); +} + +template <typename T> + requires std::is_integral_v<T> +[[nodiscard]] constexpr bool IsPowerOfTwo(T x) { + return x > 0 && ResetLeastSignificantOneBit(x) == 0; +} + +template <typename T> + requires std::is_integral_v<T> +[[nodiscard]] constexpr T FloorPowerOfTwo(T x) { + return T{1} << (sizeof(T) * 8 - std::countl_zero(x) - 1); +} + template <typename T, size_t Align = 16> class AlignmentAllocator { public: diff --git a/src/common/lz4_compression.cpp b/src/common/lz4_compression.cpp index ffb32fecf..6867c03c4 100644 --- a/src/common/lz4_compression.cpp +++ b/src/common/lz4_compression.cpp @@ -71,4 +71,10 @@ std::vector<u8> DecompressDataLZ4(std::span<const u8> compressed, std::size_t un return uncompressed; } +int DecompressLZ4(void* dst, size_t dst_size, const void* src, size_t src_size) { + // This is just a thin wrapper around LZ4. + return LZ4_decompress_safe(reinterpret_cast<const char*>(src), reinterpret_cast<char*>(dst), + static_cast<int>(src_size), static_cast<int>(dst_size)); +} + } // namespace Common::Compression diff --git a/src/common/lz4_compression.h b/src/common/lz4_compression.h index 7fd53a960..7200e0f22 100644 --- a/src/common/lz4_compression.h +++ b/src/common/lz4_compression.h @@ -56,4 +56,6 @@ namespace Common::Compression { [[nodiscard]] std::vector<u8> DecompressDataLZ4(std::span<const u8> compressed, std::size_t uncompressed_size); +int DecompressLZ4(void* dst, size_t dst_size, const void* src, size_t src_size); + } // namespace Common::Compression |