This commit is contained in:
81
deps/ox/src/ox/mc/intops.hpp
vendored
81
deps/ox/src/ox/mc/intops.hpp
vendored
@@ -18,25 +18,25 @@
|
||||
|
||||
namespace ox::mc {
|
||||
|
||||
template<typename T>
|
||||
template<Integer_c T>
|
||||
static constexpr auto Bits = sizeof(T) << 3;
|
||||
|
||||
/**
|
||||
* Returns highest bit other than possible signed bit.
|
||||
* Bit numbering starts at 0.
|
||||
*/
|
||||
template<typename I>
|
||||
template<Integer_c I>
|
||||
[[nodiscard]]
|
||||
constexpr std::size_t highestBit(I val) noexcept {
|
||||
constexpr size_t highestBit(I const val) noexcept {
|
||||
unsigned shiftStart = sizeof(I) * 8 - 1;
|
||||
// find most significant non-sign indicator bit
|
||||
std::size_t highestBit = 0;
|
||||
// find the most significant non-sign indicator bit
|
||||
size_t highestBit = 0;
|
||||
// start at one bit lower if signed
|
||||
if constexpr(is_signed_v<I>) {
|
||||
--shiftStart;
|
||||
}
|
||||
for (auto i = shiftStart; i > 0; --i) {
|
||||
const auto bitValue = (val >> i) & 1;
|
||||
auto const bitValue = (val >> i) & 1;
|
||||
if (bitValue) {
|
||||
highestBit = i;
|
||||
break;
|
||||
@@ -45,7 +45,7 @@ constexpr std::size_t highestBit(I val) noexcept {
|
||||
return highestBit;
|
||||
}
|
||||
|
||||
static_assert(highestBit(int8_t(0b10000000)) == 0);
|
||||
static_assert(highestBit(static_cast<int8_t>(0b10000000)) == 0);
|
||||
static_assert(highestBit(~static_cast<int8_t>(-1)) == 0);
|
||||
static_assert(highestBit(~static_cast<int8_t>(-2)) == 0);
|
||||
static_assert(highestBit(~static_cast<int8_t>(-3)) == 1);
|
||||
@@ -53,42 +53,39 @@ static_assert(highestBit(1) == 0);
|
||||
static_assert(highestBit(2) == 1);
|
||||
static_assert(highestBit(4) == 2);
|
||||
static_assert(highestBit(8) == 3);
|
||||
static_assert(highestBit(uint64_t(1) << 31) == 31);
|
||||
static_assert(highestBit(uint64_t(1) << 63) == 63);
|
||||
static_assert(highestBit(static_cast<uint64_t>(1) << 31) == 31);
|
||||
static_assert(highestBit(static_cast<uint64_t>(1) << 63) == 63);
|
||||
|
||||
struct McInt {
|
||||
ox::Array<uint8_t, 9> data{};
|
||||
Array<uint8_t, 9> data{};
|
||||
// length of integer in bytes
|
||||
std::size_t length = 0;
|
||||
size_t length = 0;
|
||||
};
|
||||
|
||||
template<typename I>
|
||||
template<Integer_c I>
|
||||
[[nodiscard]]
|
||||
constexpr McInt encodeInteger(I pInput) noexcept {
|
||||
auto const input = ox::ResizedInt_t<I, 64>{pInput};
|
||||
constexpr McInt encodeInteger(I const pInput) noexcept {
|
||||
auto const input = ResizedInt_t<I, 64>{pInput};
|
||||
McInt out;
|
||||
const auto inputNegative = is_signed_v<I> && input < 0;
|
||||
// move input to uint64_t to allow consistent bit manipulation, and to avoid
|
||||
auto const inputNegative = is_signed_v<I> && input < 0;
|
||||
// move input to uint64_t to allow consistent bit manipulation and to avoid
|
||||
// overflow concerns
|
||||
uint64_t val = 0;
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
ox::memcpy(&val, &input, sizeof(input));
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
auto const val = std::bit_cast<uint64_t>(input);
|
||||
if (val) {
|
||||
// bits needed to represent number factoring in space possibly
|
||||
// needed for signed bit
|
||||
const auto highBit = inputNegative ? highestBit(~val) : highestBit(val);
|
||||
const auto bits = highBit + 1 + (is_signed_v<I> ? 1 : 0);
|
||||
auto const highBit = inputNegative ? highestBit(~val) : highestBit(val);
|
||||
auto const bits = highBit + 1 + (is_signed_v<I> ? 1 : 0);
|
||||
// bytes needed to store value
|
||||
std::size_t bytes = bits / 8 + (bits % 8 != 0);
|
||||
const auto bitsAvailable = bytes * 8; // bits available to integer value
|
||||
const auto bitsNeeded = bits + bytes;
|
||||
size_t bytes = bits / 8 + (bits % 8 != 0);
|
||||
auto const bitsAvailable = bytes * 8; // bits available to integer value
|
||||
auto const bitsNeeded = bits + bytes;
|
||||
// factor in bits needed for bytesIndicator (does not affect bytesIndicator)
|
||||
// bits for integer + bits needed to represent bytes > bits available
|
||||
if (bitsNeeded > bitsAvailable && bytes != 9) {
|
||||
++bytes;
|
||||
}
|
||||
const auto bytesIndicator = onMask<uint8_t>(bytes - 1);
|
||||
auto const bytesIndicator = onMask<uint8_t>(bytes - 1);
|
||||
// ensure we are copying from little endian representation
|
||||
LittleEndian<uint64_t> leVal = val;
|
||||
if (inputNegative) {
|
||||
@@ -103,9 +100,9 @@ constexpr McInt encodeInteger(I pInput) noexcept {
|
||||
out.data[1] |= 0b1000'0000;
|
||||
}
|
||||
} else {
|
||||
const auto valBits = bytes * 8;
|
||||
uint64_t negBit = inputNegative ? 1 : 0;
|
||||
auto intermediate =
|
||||
auto const valBits = bytes * 8;
|
||||
uint64_t const negBit = inputNegative ? 1 : 0;
|
||||
auto const intermediate =
|
||||
static_cast<uint64_t>(leVal.raw() | (negBit << (valBits - 1))) << bytes |
|
||||
static_cast<uint64_t>(bytesIndicator);
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
@@ -122,8 +119,8 @@ constexpr McInt encodeInteger(I pInput) noexcept {
|
||||
* length integer.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
constexpr std::size_t countBytes(unsigned b) noexcept {
|
||||
std::size_t i = 0;
|
||||
constexpr size_t countBytes(unsigned const b) noexcept {
|
||||
size_t i = 0;
|
||||
while ((b >> i) & 1) ++i;
|
||||
return i + 1;
|
||||
}
|
||||
@@ -138,12 +135,12 @@ static_assert(countBytes(0b0011'1111) == 7);
|
||||
static_assert(countBytes(0b0111'1111) == 8);
|
||||
static_assert(countBytes(0b1111'1111) == 9);
|
||||
|
||||
template<typename I>
|
||||
constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t &bytesRead) noexcept {
|
||||
template<Integer_c I>
|
||||
constexpr Result<I> decodeInteger(Reader_c auto &rdr, size_t &bytesRead) noexcept {
|
||||
uint8_t firstByte = 0;
|
||||
OX_RETURN_ERROR(rdr.read(&firstByte, 1));
|
||||
OX_RETURN_ERROR(rdr.seekg(-1, ox::ios_base::cur));
|
||||
const auto bytes = countBytes(firstByte);
|
||||
auto const bytes = countBytes(firstByte);
|
||||
if (bytes == 9) {
|
||||
bytesRead = bytes;
|
||||
I out = 0;
|
||||
@@ -157,20 +154,20 @@ constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t &bytesRead) noe
|
||||
decoded >>= bytes;
|
||||
// move sign bit
|
||||
if constexpr(is_signed_v<I>) {
|
||||
const auto negBit = bytes * 8 - bytes - 1;
|
||||
auto const negBit = bytes * 8 - bytes - 1;
|
||||
// move sign
|
||||
const auto negative = (decoded >> negBit) == 1;
|
||||
auto const negative = (decoded >> negBit) == 1;
|
||||
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
|
||||
ox::Array<uint32_t, 2> d = {};
|
||||
Array<uint32_t, 2> d = {};
|
||||
//d[0] = decoded & 0xffff'ffff;
|
||||
//d[1] = decoded >> 32;
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
ox::memcpy(&d[0], &decoded, sizeof(decoded));
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
auto bit = negBit;
|
||||
for (; bit < ox::min<std::size_t>(Bits<I>, 32); ++bit) {
|
||||
for (; bit < ox::min<size_t>(Bits<I>, 32); ++bit) {
|
||||
d[0] |= 1 << bit;
|
||||
}
|
||||
bit -= 32;
|
||||
@@ -179,7 +176,7 @@ constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t &bytesRead) noe
|
||||
}
|
||||
I out = 0;
|
||||
if constexpr(ox::defines::BigEndian) {
|
||||
const auto d0Tmp = d[0];
|
||||
auto const d0Tmp = d[0];
|
||||
d[0] = d[1];
|
||||
d[1] = d0Tmp;
|
||||
}
|
||||
@@ -192,9 +189,9 @@ constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t &bytesRead) noe
|
||||
return static_cast<I>(decoded);
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
Result<I> decodeInteger(McInt m) noexcept {
|
||||
std::size_t bytesRead{};
|
||||
template<Integer_c I>
|
||||
Result<I> decodeInteger(McInt const &m) noexcept {
|
||||
size_t bytesRead{};
|
||||
BufferReader br({reinterpret_cast<const char*>(m.data.data()), 9});
|
||||
return decodeInteger<I>(br, bytesRead);
|
||||
}
|
||||
|
||||
196
deps/ox/src/ox/mc/write.hpp
vendored
196
deps/ox/src/ox/mc/write.hpp
vendored
@@ -32,68 +32,68 @@ template<Writer_c Writer>
|
||||
class MetalClawWriter {
|
||||
|
||||
private:
|
||||
ox::Vector<uint8_t, 16> m_presenceMapBuff{};
|
||||
Vector<uint8_t, 16> m_presenceMapBuff{};
|
||||
FieldBitmap m_fieldPresence;
|
||||
int m_field = 0;
|
||||
ox::Optional<int> m_unionIdx;
|
||||
std::size_t m_writerBeginP{};
|
||||
Optional<int> m_unionIdx;
|
||||
size_t m_writerBeginP{};
|
||||
Writer &m_writer;
|
||||
|
||||
public:
|
||||
constexpr explicit MetalClawWriter(Writer &writer, ox::Optional<int> const&unionIdx = {}) noexcept;
|
||||
constexpr explicit MetalClawWriter(Writer &writer, Optional<int> const &unionIdx = {}) noexcept;
|
||||
|
||||
constexpr ~MetalClawWriter() noexcept = default;
|
||||
|
||||
constexpr Error field(const char*, const int8_t *val) noexcept;
|
||||
constexpr Error field(const char*, const int16_t *val) noexcept;
|
||||
constexpr Error field(const char*, const int32_t *val) noexcept;
|
||||
constexpr Error field(const char*, const int64_t *val) noexcept;
|
||||
constexpr Error field(CString, int8_t const *val) noexcept;
|
||||
constexpr Error field(CString, int16_t const *val) noexcept;
|
||||
constexpr Error field(CString, int32_t const *val) noexcept;
|
||||
constexpr Error field(CString, int64_t const *val) noexcept;
|
||||
|
||||
constexpr Error field(const char*, const uint8_t *val) noexcept;
|
||||
constexpr Error field(const char*, const uint16_t *val) noexcept;
|
||||
constexpr Error field(const char*, const uint32_t *val) noexcept;
|
||||
constexpr Error field(const char*, const uint64_t *val) noexcept;
|
||||
constexpr Error field(CString, uint8_t const *val) noexcept;
|
||||
constexpr Error field(CString, uint16_t const *val) noexcept;
|
||||
constexpr Error field(CString, uint32_t const *val) noexcept;
|
||||
constexpr Error field(CString, uint64_t const *val) noexcept;
|
||||
|
||||
constexpr Error field(const char*, const bool *val) noexcept;
|
||||
constexpr Error field(CString, bool const *val) noexcept;
|
||||
|
||||
template<typename T>
|
||||
constexpr Error field(const char*, const T *val, std::size_t len) noexcept;
|
||||
constexpr Error field(CString, T const *val, size_t len) noexcept;
|
||||
|
||||
template<typename T>
|
||||
constexpr Error field(const char *name, const HashMap<String, T> *val) noexcept;
|
||||
constexpr Error field(CString name, HashMap<String, T> const *val) noexcept;
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
constexpr Error field(const char*, const BasicString<SmallStringSize> *val) noexcept;
|
||||
template<size_t SmallStringSize>
|
||||
constexpr Error field(CString, BasicString<SmallStringSize> const *val) noexcept;
|
||||
|
||||
template<std::size_t L>
|
||||
constexpr Error field(const char*, const IString<L> *val) noexcept;
|
||||
template<size_t L>
|
||||
constexpr Error field(CString, IString<L> const *val) noexcept;
|
||||
|
||||
constexpr Error fieldCString(const char *name, const char *const*val, std::size_t buffLen) noexcept;
|
||||
constexpr Error fieldCString(CString name, CString const*val, size_t buffLen) noexcept;
|
||||
|
||||
constexpr Error fieldCString(const char *name, const char **val) noexcept;
|
||||
constexpr Error fieldCString(CString name, CString *val) noexcept;
|
||||
|
||||
constexpr Error fieldCString(const char *name, const char *const*val) noexcept;
|
||||
constexpr Error fieldCString(CString name, CString const*val) noexcept;
|
||||
|
||||
constexpr Error fieldCString(const char *name, const char *val, std::size_t len) noexcept;
|
||||
constexpr Error fieldCString(CString name, CString val, size_t strLen) noexcept;
|
||||
|
||||
template<typename T>
|
||||
constexpr Error field(const char*, const T *val) noexcept;
|
||||
constexpr Error field(CString, T const *val) noexcept;
|
||||
|
||||
template<typename U, bool force = false>
|
||||
constexpr Error field(const char*, UnionView<U, force> val) noexcept;
|
||||
constexpr Error field(CString, UnionView<U, force> val) noexcept;
|
||||
|
||||
template<typename T = std::nullptr_t>
|
||||
constexpr ox::Error setTypeInfo(
|
||||
const char *name = T::TypeName,
|
||||
constexpr Error setTypeInfo(
|
||||
CString name = T::TypeName,
|
||||
int version = T::TypeVersion,
|
||||
const Vector<String>& = {},
|
||||
std::size_t fields = ModelFieldCount_v<T>) noexcept;
|
||||
Vector<String> const& = {},
|
||||
size_t fields = ModelFieldCount_v<T>) noexcept;
|
||||
|
||||
/**
|
||||
* stringLength is not implemented in MetalClawWriter
|
||||
*/
|
||||
[[nodiscard]]
|
||||
constexpr auto stringLength(const char*) noexcept {
|
||||
constexpr auto stringLength(CString) noexcept {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ class MetalClawWriter {
|
||||
* stringLength is not implemented in MetalClawWriter
|
||||
*/
|
||||
[[nodiscard]]
|
||||
constexpr auto arrayLength(const char*, bool = true) noexcept {
|
||||
constexpr auto arrayLength(CString, bool = true) noexcept {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -110,17 +110,17 @@ class MetalClawWriter {
|
||||
return OpType::Write;
|
||||
}
|
||||
|
||||
ox::Error finalize() noexcept;
|
||||
Error finalize() noexcept;
|
||||
|
||||
private:
|
||||
constexpr Error appendInteger(Integer_c auto val) noexcept {
|
||||
bool fieldSet = false;
|
||||
if (val && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
|
||||
auto mi = mc::encodeInteger(val);
|
||||
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(mi.data.data()), mi.length));
|
||||
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<CString>(mi.data.data()), mi.length));
|
||||
fieldSet = true;
|
||||
}
|
||||
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<size_t>(m_field), fieldSet));
|
||||
++m_field;
|
||||
return {};
|
||||
}
|
||||
@@ -131,7 +131,7 @@ extern template class ModelHandlerInterface<MetalClawWriter<BufferWriter>>;
|
||||
extern template class ModelHandlerInterface<MetalClawWriter<CharBuffWriter>>;
|
||||
|
||||
template<Writer_c Writer>
|
||||
constexpr MetalClawWriter<Writer>::MetalClawWriter(Writer &writer, ox::Optional<int> const&unionIdx) noexcept:
|
||||
constexpr MetalClawWriter<Writer>::MetalClawWriter(Writer &writer, Optional<int> const &unionIdx) noexcept:
|
||||
m_fieldPresence(m_presenceMapBuff.data(), m_presenceMapBuff.size()),
|
||||
m_unionIdx(unionIdx),
|
||||
m_writerBeginP(writer.tellp()),
|
||||
@@ -139,128 +139,128 @@ constexpr MetalClawWriter<Writer>::MetalClawWriter(Writer &writer, ox::Optional<
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, const int8_t *val) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::field(CString, int8_t const *val) noexcept {
|
||||
return appendInteger(*val);
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, const int16_t *val) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::field(CString, int16_t const *val) noexcept {
|
||||
return appendInteger(*val);
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, const int32_t *val) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::field(CString, int32_t const *val) noexcept {
|
||||
return appendInteger(*val);
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, const int64_t *val) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::field(CString, int64_t const *val) noexcept {
|
||||
return appendInteger(*val);
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, const uint8_t *val) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::field(CString, uint8_t const *val) noexcept {
|
||||
return appendInteger(*val);
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, const uint16_t *val) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::field(CString, uint16_t const *val) noexcept {
|
||||
return appendInteger(*val);
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, const uint32_t *val) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::field(CString, uint32_t const *val) noexcept {
|
||||
return appendInteger(*val);
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, const uint64_t *val) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::field(CString, uint64_t const *val) noexcept {
|
||||
return appendInteger(*val);
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, const bool *val) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::field(CString, bool const *val) noexcept {
|
||||
if (!m_unionIdx.has_value() || *m_unionIdx == m_field) {
|
||||
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), *val));
|
||||
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<size_t>(m_field), *val));
|
||||
}
|
||||
++m_field;
|
||||
return {};
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
template<std::size_t SmallStringSize>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, const BasicString<SmallStringSize> *val) noexcept {
|
||||
template<size_t SmallStringSize>
|
||||
constexpr Error MetalClawWriter<Writer>::field(CString, BasicString<SmallStringSize> const *val) noexcept {
|
||||
bool fieldSet = false;
|
||||
if (val->size() && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
|
||||
// write the length
|
||||
const auto strLen = mc::encodeInteger(val->size());
|
||||
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(strLen.data.data()), strLen.length));
|
||||
auto const strLen = mc::encodeInteger(val->size());
|
||||
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<CString>(strLen.data.data()), strLen.length));
|
||||
// write the string
|
||||
OX_RETURN_ERROR(m_writer.write(val->c_str(), static_cast<std::size_t>(val->size())));
|
||||
OX_RETURN_ERROR(m_writer.write(val->c_str(), static_cast<size_t>(val->size())));
|
||||
fieldSet = true;
|
||||
}
|
||||
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<size_t>(m_field), fieldSet));
|
||||
++m_field;
|
||||
return {};
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
template<std::size_t L>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char *name, const IString<L> *val) noexcept {
|
||||
template<size_t L>
|
||||
constexpr Error MetalClawWriter<Writer>::field(CString name, IString<L> const *val) noexcept {
|
||||
return fieldCString(name, val->data(), val->size());
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *const*val, std::size_t) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::fieldCString(CString, CString const *val, size_t) noexcept {
|
||||
bool fieldSet = false;
|
||||
if (!m_unionIdx.has_value() || *m_unionIdx == m_field) {
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
// this strlen is tolerated because sometimes 0 gets passed to
|
||||
// the size param, which is a lie
|
||||
// this code should be cleaned up at some point...
|
||||
const auto strLen = *val ? ox::strlen(*val) : 0;
|
||||
auto const strLen = *val ? ox::strlen(*val) : 0;
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
// write the length
|
||||
const auto strLenBuff = mc::encodeInteger(strLen);
|
||||
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data.data()), strLenBuff.length));
|
||||
auto const strLenBuff = mc::encodeInteger(strLen);
|
||||
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<CString>(strLenBuff.data.data()), strLenBuff.length));
|
||||
// write the string
|
||||
OX_RETURN_ERROR(m_writer.write(*val, static_cast<std::size_t>(strLen)));
|
||||
OX_RETURN_ERROR(m_writer.write(*val, static_cast<size_t>(strLen)));
|
||||
fieldSet = true;
|
||||
}
|
||||
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<size_t>(m_field), fieldSet));
|
||||
++m_field;
|
||||
return {};
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::fieldCString(const char *name, const char **val) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::fieldCString(CString const name, CString *val) noexcept {
|
||||
return fieldCString(name, val, {});
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::fieldCString(const char *name, const char *const*val) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::fieldCString(CString const name, CString const *val) noexcept {
|
||||
return fieldCString(name, val, {});
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *val, std::size_t strLen) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::fieldCString(CString, CString const val, size_t const strLen) noexcept {
|
||||
bool fieldSet = false;
|
||||
if (strLen && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
|
||||
// write the length
|
||||
const auto strLenBuff = mc::encodeInteger(strLen);
|
||||
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data.data()), strLenBuff.length));
|
||||
auto const strLenBuff = mc::encodeInteger(strLen);
|
||||
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<CString>(strLenBuff.data.data()), strLenBuff.length));
|
||||
// write the string
|
||||
OX_RETURN_ERROR(m_writer.write(val, static_cast<std::size_t>(strLen)));
|
||||
OX_RETURN_ERROR(m_writer.write(val, static_cast<size_t>(strLen)));
|
||||
fieldSet = true;
|
||||
}
|
||||
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<size_t>(m_field), fieldSet));
|
||||
++m_field;
|
||||
return {};
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
template<typename T>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, const T *val) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::field(CString, T const *val) noexcept {
|
||||
if constexpr(isVector_v<T> || isArray_v<T>) {
|
||||
return field(nullptr, val->data(), val->size());
|
||||
} else {
|
||||
@@ -273,7 +273,7 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const T *val) noexce
|
||||
OX_RETURN_ERROR(writer.finalize());
|
||||
fieldSet = writeIdx != m_writer.tellp();
|
||||
}
|
||||
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<size_t>(m_field), fieldSet));
|
||||
++m_field;
|
||||
return {};
|
||||
}
|
||||
@@ -281,35 +281,35 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const T *val) noexce
|
||||
|
||||
template<Writer_c Writer>
|
||||
template<typename U, bool force>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, UnionView<U, force> val) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::field(CString, UnionView<U, force> val) noexcept {
|
||||
bool fieldSet = false;
|
||||
if (val.get() && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
|
||||
auto const writeIdx = m_writer.tellp();
|
||||
MetalClawWriter<Writer> writer(m_writer, ox::Optional<int>(ox::in_place, val.idx()));
|
||||
MetalClawWriter<Writer> writer(m_writer, Optional<int>(in_place, val.idx()));
|
||||
ModelHandlerInterface handler{writer};
|
||||
OX_RETURN_ERROR(model(&handler, val.get()));
|
||||
OX_RETURN_ERROR(writer.finalize());
|
||||
fieldSet = writeIdx != m_writer.tellp();
|
||||
}
|
||||
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<size_t>(m_field), fieldSet));
|
||||
++m_field;
|
||||
return {};
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
template<typename T>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, const T *val, std::size_t len) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::field(CString, T const *val, size_t const len) noexcept {
|
||||
bool fieldSet = false;
|
||||
if (len && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
|
||||
// write the length
|
||||
const auto arrLen = mc::encodeInteger(len);
|
||||
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(arrLen.data.data()), arrLen.length));
|
||||
auto const arrLen = mc::encodeInteger(len);
|
||||
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<CString>(arrLen.data.data()), arrLen.length));
|
||||
auto const writeIdx = m_writer.tellp();
|
||||
MetalClawWriter<Writer> writer(m_writer);
|
||||
ModelHandlerInterface handler{writer};
|
||||
OX_RETURN_ERROR(handler.template setTypeInfo<T>("List", 0, {}, static_cast<std::size_t>(len)));
|
||||
OX_RETURN_ERROR(handler.template setTypeInfo<T>("List", 0, {}, static_cast<size_t>(len)));
|
||||
// write the array
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
for (size_t i{}; i < len; ++i) {
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
OX_RETURN_ERROR(handler.field("", &val[i]));
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
@@ -317,29 +317,29 @@ OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
OX_RETURN_ERROR(writer.finalize());
|
||||
fieldSet = writeIdx != m_writer.tellp();
|
||||
}
|
||||
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<size_t>(m_field), fieldSet));
|
||||
++m_field;
|
||||
return {};
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
template<typename T>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, const HashMap<String, T> *val) noexcept {
|
||||
const auto &keys = val->keys();
|
||||
const auto len = keys.size();
|
||||
constexpr Error MetalClawWriter<Writer>::field(CString, HashMap<String, T> const *val) noexcept {
|
||||
auto const &keys = val->keys();
|
||||
auto const len = keys.size();
|
||||
bool fieldSet = false;
|
||||
if (len && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
|
||||
// write the length
|
||||
const auto arrLen = mc::encodeInteger(len);
|
||||
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(arrLen.data.data()), arrLen.length));
|
||||
auto const arrLen = mc::encodeInteger(len);
|
||||
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<CString>(arrLen.data.data()), arrLen.length));
|
||||
// write map
|
||||
MetalClawWriter<Writer> writer(m_writer);
|
||||
ModelHandlerInterface handler{writer};
|
||||
// double len for both key and value
|
||||
OX_RETURN_ERROR(handler.setTypeInfo("Map", 0, {}, len * 2));
|
||||
// this loop body needs to be in a lambda because of the potential alloca call
|
||||
constexpr auto loopBody = [](auto &handler, auto const&key, auto const&val) -> ox::Error {
|
||||
const auto keyLen = key.size();
|
||||
constexpr auto loopBody = [](auto &handler, auto const &key, auto const &val) -> Error {
|
||||
auto const keyLen = key.size();
|
||||
auto wkey = ox_malloca(keyLen + 1, char, 0);
|
||||
memcpy(wkey.get(), key.c_str(), keyLen + 1);
|
||||
OX_RETURN_ERROR(handler.fieldCString("", wkey.get(), keyLen));
|
||||
@@ -347,26 +347,26 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const HashMap<String
|
||||
return handler.field("", value);
|
||||
};
|
||||
// write the array
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
auto const&key = keys[i];
|
||||
for (size_t i{}; i < len; ++i) {
|
||||
auto const &key = keys[i];
|
||||
OX_RETURN_ERROR(loopBody(handler, key, *val));
|
||||
}
|
||||
OX_RETURN_ERROR(writer.finalize());
|
||||
fieldSet = true;
|
||||
}
|
||||
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<size_t>(m_field), fieldSet));
|
||||
++m_field;
|
||||
return {};
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
template<typename T>
|
||||
constexpr ox::Error MetalClawWriter<Writer>::setTypeInfo(
|
||||
const char*,
|
||||
constexpr Error MetalClawWriter<Writer>::setTypeInfo(
|
||||
CString,
|
||||
int,
|
||||
const Vector<String>&,
|
||||
std::size_t fields) noexcept {
|
||||
const auto fieldPresenceLen = (fields - 1) / 8 + 1;
|
||||
Vector<String> const&,
|
||||
size_t const fields) noexcept {
|
||||
auto const fieldPresenceLen = (fields - 1) / 8 + 1;
|
||||
OX_RETURN_ERROR(m_writer.write(nullptr, fieldPresenceLen));
|
||||
m_presenceMapBuff.resize(fieldPresenceLen);
|
||||
m_fieldPresence.setBuffer(m_presenceMapBuff.data(), m_presenceMapBuff.size());
|
||||
@@ -375,17 +375,17 @@ constexpr ox::Error MetalClawWriter<Writer>::setTypeInfo(
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
ox::Error MetalClawWriter<Writer>::finalize() noexcept {
|
||||
const auto end = m_writer.tellp();
|
||||
Error MetalClawWriter<Writer>::finalize() noexcept {
|
||||
auto const end = m_writer.tellp();
|
||||
OX_RETURN_ERROR(m_writer.seekp(m_writerBeginP));
|
||||
OX_RETURN_ERROR(m_writer.write(
|
||||
reinterpret_cast<const char*>(m_presenceMapBuff.data()),
|
||||
reinterpret_cast<CString>(m_presenceMapBuff.data()),
|
||||
m_presenceMapBuff.size()));
|
||||
OX_RETURN_ERROR(m_writer.seekp(end));
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<Buffer> writeMC(Writer_c auto &writer, const auto &val) noexcept {
|
||||
Result<Buffer> writeMC(Writer_c auto &writer, auto const &val) noexcept {
|
||||
MetalClawWriter mcWriter(writer);
|
||||
ModelHandlerInterface handler{mcWriter};
|
||||
OX_RETURN_ERROR(model(&handler, &val));
|
||||
@@ -393,7 +393,7 @@ Result<Buffer> writeMC(Writer_c auto &writer, const auto &val) noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<Buffer> writeMC(auto const&val, std::size_t buffReserveSz = 2 * units::KB) noexcept {
|
||||
Result<Buffer> writeMC(auto const &val, size_t const buffReserveSz = 2 * units::KB) noexcept {
|
||||
Buffer buff(buffReserveSz);
|
||||
BufferWriter bw(&buff, 0);
|
||||
OX_RETURN_ERROR(writeMC(bw, val));
|
||||
@@ -401,7 +401,7 @@ Result<Buffer> writeMC(auto const&val, std::size_t buffReserveSz = 2 * units::KB
|
||||
return buff;
|
||||
}
|
||||
|
||||
Error writeMC(char *buff, std::size_t buffLen, auto const&val, std::size_t *sizeOut = nullptr) noexcept {
|
||||
Error writeMC(char *buff, size_t const buffLen, auto const &val, size_t *sizeOut = nullptr) noexcept {
|
||||
CharBuffWriter bw{{buff, buffLen}};
|
||||
OX_RETURN_ERROR(writeMC(bw, val));
|
||||
if (sizeOut) {
|
||||
|
||||
Reference in New Issue
Block a user