[ox/mc] Make VLI encode/decode constexpr
This commit is contained in:
parent
b33cd06031
commit
f191ade18b
34
deps/ox/src/ox/mc/intops.hpp
vendored
34
deps/ox/src/ox/mc/intops.hpp
vendored
@ -49,22 +49,18 @@ static_assert(highestBit(uint64_t(1) << 31) == 31);
|
|||||||
static_assert(highestBit(uint64_t(1) << 63) == 63);
|
static_assert(highestBit(uint64_t(1) << 63) == 63);
|
||||||
|
|
||||||
struct McInt {
|
struct McInt {
|
||||||
uint8_t data[9];
|
uint8_t data[9] = {0};
|
||||||
// length of integer in bytes
|
// length of integer in bytes
|
||||||
std::size_t length = 0;
|
std::size_t length = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename I>
|
template<typename I>
|
||||||
[[nodiscard]] McInt encodeInteger(I input) noexcept {
|
[[nodiscard]] constexpr McInt encodeInteger(I input) noexcept {
|
||||||
McInt out;
|
McInt out;
|
||||||
// move input to uint64_t to allow consistent bit manipulation, and to avoid
|
// move input to uint64_t to allow consistent bit manipulation, and to avoid
|
||||||
// overflow concerns
|
// overflow concerns
|
||||||
uint64_t val = *reinterpret_cast<Unsigned<I>*>(&input);
|
uint64_t val = 0;
|
||||||
|
ox_memcpy(&val, &input, sizeof(I));
|
||||||
if (val) {
|
if (val) {
|
||||||
// bits needed to represent number factoring in space possibly
|
// bits needed to represent number factoring in space possibly
|
||||||
// needed for signed bit
|
// needed for signed bit
|
||||||
@ -83,19 +79,20 @@ template<typename I>
|
|||||||
// move sign bit
|
// move sign bit
|
||||||
if constexpr(ox::is_signed<I>) {
|
if constexpr(ox::is_signed<I>) {
|
||||||
if (val < 0) {
|
if (val < 0) {
|
||||||
*reinterpret_cast<uint64_t*>(&val) ^= uint64_t(1) << (sizeof(I) * 8 - 1);
|
val ^= uint64_t(1) << (sizeof(I) * 8 - 1);
|
||||||
*reinterpret_cast<uint64_t*>(&val) |= uint64_t(1) << (bitsAvailable - 1);
|
val |= uint64_t(1) << (bitsAvailable - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ensure we are copying from little endian represenstation
|
// ensure we are copying from little endian represenstation
|
||||||
LittleEndian<I> leVal = val;
|
LittleEndian<I> leVal = val;
|
||||||
if (bytes == 9) {
|
if (bytes == 9) {
|
||||||
out.data[0] = bytesIndicator;
|
out.data[0] = bytesIndicator;
|
||||||
*reinterpret_cast<I*>(&out.data[1]) = leVal.raw();
|
ox_memcpy(&out.data[1], &leVal, sizeof(I));
|
||||||
} else {
|
} else {
|
||||||
*reinterpret_cast<uint64_t*>(&out.data[0]) =
|
auto intermediate =
|
||||||
static_cast<uint64_t>(leVal.raw()) << bytes |
|
static_cast<uint64_t>(leVal.raw()) << bytes |
|
||||||
static_cast<uint64_t>(bytesIndicator);
|
static_cast<uint64_t>(bytesIndicator);
|
||||||
|
ox_memcpy(out.data, &intermediate, sizeof(intermediate));
|
||||||
}
|
}
|
||||||
out.length = bytes;
|
out.length = bytes;
|
||||||
}
|
}
|
||||||
@ -123,11 +120,13 @@ static_assert(countBytes(0b01111111) == 8);
|
|||||||
static_assert(countBytes(0b11111111) == 9);
|
static_assert(countBytes(0b11111111) == 9);
|
||||||
|
|
||||||
template<typename I>
|
template<typename I>
|
||||||
[[nodiscard]] ValErr<I> decodeInteger(uint8_t buff[9], std::size_t buffLen, std::size_t *bytesRead) noexcept {
|
[[nodiscard]] constexpr ValErr<I> decodeInteger(uint8_t buff[9], std::size_t buffLen, std::size_t *bytesRead) noexcept {
|
||||||
const auto bytes = countBytes(buff[0]);
|
const auto bytes = countBytes(buff[0]);
|
||||||
if (bytes == 9) {
|
if (bytes == 9) {
|
||||||
*bytesRead = bytes;
|
*bytesRead = bytes;
|
||||||
return {LittleEndian<I>(*reinterpret_cast<I*>(&buff[1])), 0};
|
I out;
|
||||||
|
ox_memcpy(&out, &buff[1], sizeof(I));
|
||||||
|
return {LittleEndian<I>(out), 0};
|
||||||
} else if (buffLen >= bytes) {
|
} else if (buffLen >= bytes) {
|
||||||
*bytesRead = bytes;
|
*bytesRead = bytes;
|
||||||
uint64_t decoded = 0;
|
uint64_t decoded = 0;
|
||||||
@ -142,17 +141,14 @@ template<typename I>
|
|||||||
// remove sign
|
// remove sign
|
||||||
decoded &= uint64_t(~0) ^ (uint64_t(1) << valBits);
|
decoded &= uint64_t(~0) ^ (uint64_t(1) << valBits);
|
||||||
// set sign
|
// set sign
|
||||||
*reinterpret_cast<Unsigned<I>*>(&out) |= sign << (Bits<I> - 1);
|
decoded |= sign << (Bits<I> - 1);
|
||||||
|
ox_memcpy(&out, &decoded, sizeof(out));
|
||||||
}
|
}
|
||||||
return {out, 0};
|
return {out, 0};
|
||||||
}
|
}
|
||||||
return {0, OxError(1)};
|
return {0, OxError(1)};
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename I>
|
template<typename I>
|
||||||
[[nodiscard]] ValErr<I> decodeInteger(McInt m) noexcept {
|
[[nodiscard]] ValErr<I> decodeInteger(McInt m) noexcept {
|
||||||
std::size_t bytesRead;
|
std::size_t bytesRead;
|
||||||
|
17
deps/ox/src/ox/std/memops.cpp
vendored
17
deps/ox/src/ox/std/memops.cpp
vendored
@ -23,20 +23,3 @@ int ox_memcmp(const void *ptr1, const void *ptr2, std::size_t size) noexcept {
|
|||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *ox_memcpy(void *dest, const void *src, std::size_t size) noexcept {
|
|
||||||
auto srcBuf = static_cast<const char*>(src);
|
|
||||||
auto dstBuf = static_cast<char*>(dest);
|
|
||||||
for (std::size_t i = 0; i < size; i++) {
|
|
||||||
dstBuf[i] = static_cast<char>(srcBuf[i]);
|
|
||||||
}
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *ox_memset(void *ptr, int val, std::size_t size) noexcept {
|
|
||||||
auto buf = static_cast<char*>(ptr);
|
|
||||||
for (std::size_t i = 0; i < size; i++) {
|
|
||||||
buf[i] = val;
|
|
||||||
}
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
17
deps/ox/src/ox/std/memops.hpp
vendored
17
deps/ox/src/ox/std/memops.hpp
vendored
@ -11,6 +11,19 @@
|
|||||||
|
|
||||||
int ox_memcmp(const void *ptr1, const void *ptr2, std::size_t size) noexcept;
|
int ox_memcmp(const void *ptr1, const void *ptr2, std::size_t size) noexcept;
|
||||||
|
|
||||||
void *ox_memcpy(void *dest, const void *src, std::size_t size) noexcept;
|
constexpr void *ox_memcpy(void *dest, const void *src, std::size_t size) noexcept {
|
||||||
|
auto srcBuf = static_cast<const char*>(src);
|
||||||
|
auto dstBuf = static_cast<char*>(dest);
|
||||||
|
for (std::size_t i = 0; i < size; i++) {
|
||||||
|
dstBuf[i] = static_cast<char>(srcBuf[i]);
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
void *ox_memset(void *ptr, int val, std::size_t size) noexcept;
|
constexpr void *ox_memset(void *ptr, int val, std::size_t size) noexcept {
|
||||||
|
auto buf = static_cast<char*>(ptr);
|
||||||
|
for (std::size_t i = 0; i < size; i++) {
|
||||||
|
buf[i] = val;
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user