From 84d54ba34035c35937968d96b6fe4e1bf11b49d2 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 13 Aug 2022 01:35:17 -0500 Subject: [PATCH] [ox/mc] Fix decoding of int64s --- deps/ox/src/ox/mc/intops.hpp | 30 ++++++++++++++++++------------ deps/ox/src/ox/std/byteswap.hpp | 16 +++++++++++++++- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/deps/ox/src/ox/mc/intops.hpp b/deps/ox/src/ox/mc/intops.hpp index d2da8255..0740c478 100644 --- a/deps/ox/src/ox/mc/intops.hpp +++ b/deps/ox/src/ox/mc/intops.hpp @@ -8,6 +8,7 @@ #pragma once +#include #include #include #include @@ -55,7 +56,7 @@ static_assert(highestBit(uint64_t(1) << 31) == 31); static_assert(highestBit(uint64_t(1) << 63) == 63); struct McInt { - uint8_t data[9] = {0}; + uint8_t data[9] = {}; // length of integer in bytes std::size_t length = 0; }; @@ -113,7 +114,7 @@ constexpr McInt encodeInteger(I input) noexcept { * length integer. */ [[nodiscard]] -static constexpr std::size_t countBytes(uint8_t b) noexcept { +static constexpr std::size_t countBytes(unsigned b) noexcept { std::size_t i = 0; while ((b >> i) & 1) ++i; return i + 1; @@ -130,13 +131,13 @@ static_assert(countBytes(0b0111'1111) == 8); static_assert(countBytes(0b1111'1111) == 9); template -Result decodeInteger(const uint8_t buff[9], std::size_t buffLen, std::size_t *bytesRead) noexcept { +constexpr Result decodeInteger(const uint8_t buff[9], std::size_t buffLen, std::size_t *bytesRead) noexcept { const auto bytes = countBytes(buff[0]); if (bytes == 9) { *bytesRead = bytes; I out = 0; ox_memcpy(&out, &buff[1], sizeof(I)); - return static_cast(LittleEndian(out)); + return fromLittleEndian(out); } else if (buffLen >= bytes) { *bytesRead = bytes; uint64_t decoded = 0; @@ -150,28 +151,33 @@ Result decodeInteger(const uint8_t buff[9], std::size_t buffLen, std::size_t if (negative) { // fill in all bits between encoded sign and real sign with 1s // split it up because the 32-bit ARM can't shift more than 32 bits - uint32_t *d = reinterpret_cast(&decoded); + ox::Array d = {}; + ox_memcpy(d.data(), &decoded, sizeof(decoded)); auto bit = negBit; for (; bit < ox::min(Bits, 32); ++bit) { d[0] |= 1 << bit; } + bit -= 32; for (; bit < Bits; ++bit) { d[1] |= 1 << bit; } + I out = 0; + if constexpr(ox::defines::BigEndian) { + const auto d0Tmp = d[0]; + d[0] = d[1]; + d[1] = d0Tmp; + } + ox_memcpy(&out, d.data(), sizeof(out)); + return out; } - I out = 0; - ox_memcpy(&out, &decoded, sizeof(out)); - return out; - } else { - auto out = static_cast(decoded); - return out; } + return static_cast(decoded); } return OxError(1); } template -Result decodeInteger(McInt m) noexcept { +constexpr Result decodeInteger(McInt m) noexcept { std::size_t bytesRead; return decodeInteger(m.data, 9, &bytesRead); } diff --git a/deps/ox/src/ox/std/byteswap.hpp b/deps/ox/src/ox/std/byteswap.hpp index 494d00a6..68365d44 100644 --- a/deps/ox/src/ox/std/byteswap.hpp +++ b/deps/ox/src/ox/std/byteswap.hpp @@ -64,13 +64,27 @@ constexpr T conditionalByteSwap(T i) noexcept { } template +[[nodiscard]] +constexpr T fromLittleEndian(T i) noexcept { + return conditionalByteSwap(i); +} + +template +[[nodiscard]] +constexpr T fromBigEndian(T i) noexcept { + return conditionalByteSwap(i); +} + +template +[[nodiscard]] constexpr T toLittleEndian(T i) noexcept { return conditionalByteSwap(i); } template +[[nodiscard]] constexpr T toBigEndian(T i) noexcept { - return conditionalByteSwap(i); + return conditionalByteSwap(i); } template