[ox/mc] Fix decoding of int64s
This commit is contained in:
parent
714d9fe433
commit
84d54ba340
30
deps/ox/src/ox/mc/intops.hpp
vendored
30
deps/ox/src/ox/mc/intops.hpp
vendored
@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/std/array.hpp>
|
||||
#include <ox/std/assert.hpp>
|
||||
#include <ox/std/bit.hpp>
|
||||
#include <ox/std/byteswap.hpp>
|
||||
@ -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<typename I>
|
||||
Result<I> decodeInteger(const uint8_t buff[9], std::size_t buffLen, std::size_t *bytesRead) noexcept {
|
||||
constexpr Result<I> 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<I>(LittleEndian<I>(out));
|
||||
return fromLittleEndian<I>(out);
|
||||
} else if (buffLen >= bytes) {
|
||||
*bytesRead = bytes;
|
||||
uint64_t decoded = 0;
|
||||
@ -150,28 +151,33 @@ Result<I> 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<uint32_t*>(&decoded);
|
||||
ox::Array<uint32_t, 2> d = {};
|
||||
ox_memcpy(d.data(), &decoded, sizeof(decoded));
|
||||
auto bit = negBit;
|
||||
for (; bit < ox::min<std::size_t>(Bits<I>, 32); ++bit) {
|
||||
d[0] |= 1 << bit;
|
||||
}
|
||||
bit -= 32;
|
||||
for (; bit < Bits<I>; ++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<I>(decoded);
|
||||
return out;
|
||||
}
|
||||
return static_cast<I>(decoded);
|
||||
}
|
||||
return OxError(1);
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
Result<I> decodeInteger(McInt m) noexcept {
|
||||
constexpr Result<I> decodeInteger(McInt m) noexcept {
|
||||
std::size_t bytesRead;
|
||||
return decodeInteger<I>(m.data, 9, &bytesRead);
|
||||
}
|
||||
|
16
deps/ox/src/ox/std/byteswap.hpp
vendored
16
deps/ox/src/ox/std/byteswap.hpp
vendored
@ -64,13 +64,27 @@ constexpr T conditionalByteSwap(T i) noexcept {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
[[nodiscard]]
|
||||
constexpr T fromLittleEndian(T i) noexcept {
|
||||
return conditionalByteSwap<T, defines::BigEndian>(i);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
[[nodiscard]]
|
||||
constexpr T fromBigEndian(T i) noexcept {
|
||||
return conditionalByteSwap<T, defines::LittleEndian>(i);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
[[nodiscard]]
|
||||
constexpr T toLittleEndian(T i) noexcept {
|
||||
return conditionalByteSwap<T, defines::BigEndian>(i);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
[[nodiscard]]
|
||||
constexpr T toBigEndian(T i) noexcept {
|
||||
return conditionalByteSwap<T, defines::BigEndian>(i);
|
||||
return conditionalByteSwap<T, defines::LittleEndian>(i);
|
||||
}
|
||||
|
||||
template<typename T, bool byteSwap>
|
||||
|
Loading…
Reference in New Issue
Block a user