[ox/mc] Fix issue with -1 union index

This commit is contained in:
Gary Talent 2023-12-22 04:42:13 -06:00
parent 907ead2948
commit 3fa9d132ae
2 changed files with 38 additions and 38 deletions

View File

@ -15,6 +15,7 @@
#include <ox/model/types.hpp> #include <ox/model/types.hpp>
#include <ox/std/buffer.hpp> #include <ox/std/buffer.hpp>
#include <ox/std/byteswap.hpp> #include <ox/std/byteswap.hpp>
#include <ox/std/optional.hpp>
#include <ox/std/string.hpp> #include <ox/std/string.hpp>
#include <ox/std/trace.hpp> #include <ox/std/trace.hpp>
#include <ox/std/vector.hpp> #include <ox/std/vector.hpp>
@ -33,15 +34,13 @@ class MetalClawReaderTemplate: public ModelHandlerBase<MetalClawReaderTemplate<R
FieldBitmapReader<Reader> m_fieldPresence; FieldBitmapReader<Reader> m_fieldPresence;
std::size_t m_fields = 0; std::size_t m_fields = 0;
std::size_t m_field = 0; std::size_t m_field = 0;
int m_unionIdx = -1; ox::Optional<int> m_unionIdx;
Reader &m_reader; Reader &m_reader;
MetalClawReaderTemplate<Reader> *m_parent = nullptr;
public: public:
explicit constexpr MetalClawReaderTemplate( explicit constexpr MetalClawReaderTemplate(
Reader &reader, Reader &reader,
int unionIdx = -1, ox::Optional<int> const&unionIdx = {}) noexcept;
MetalClawReaderTemplate<Reader> *parent = nullptr) noexcept;
constexpr ~MetalClawReaderTemplate() noexcept; constexpr ~MetalClawReaderTemplate() noexcept;
@ -108,7 +107,7 @@ class MetalClawReaderTemplate: public ModelHandlerBase<MetalClawReaderTemplate<R
* Returns a MetalClawReader to parse a child object. * Returns a MetalClawReader to parse a child object.
*/ */
[[nodiscard]] [[nodiscard]]
constexpr MetalClawReaderTemplate<Reader> child(const char *name, int unionIdx = -1) noexcept; constexpr MetalClawReaderTemplate<Reader> child(const char *name, ox::Optional<int> unionIdx = {}) noexcept;
/** /**
* Indicates whether or not the next field to be read is present. * Indicates whether or not the next field to be read is present.
@ -136,12 +135,10 @@ class MetalClawReaderTemplate: public ModelHandlerBase<MetalClawReaderTemplate<R
template<Reader_c Reader> template<Reader_c Reader>
constexpr MetalClawReaderTemplate<Reader>::MetalClawReaderTemplate( constexpr MetalClawReaderTemplate<Reader>::MetalClawReaderTemplate(
Reader &reader, Reader &reader,
int unionIdx, ox::Optional<int> const&unionIdx) noexcept:
MetalClawReaderTemplate *parent) noexcept:
m_fieldPresence(reader), m_fieldPresence(reader),
m_unionIdx(unionIdx), m_unionIdx(unionIdx),
m_reader(reader), m_reader(reader) {
m_parent(parent) {
} }
template<Reader_c Reader> template<Reader_c Reader>
@ -194,7 +191,7 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, uint64_t *va
template<Reader_c Reader> template<Reader_c Reader>
constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, bool *val) noexcept { constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, bool *val) noexcept {
if (m_unionIdx == -1 || static_cast<std::size_t>(m_unionIdx) == m_field) { if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
auto const result = m_fieldPresence.get(static_cast<std::size_t>(m_field)); auto const result = m_fieldPresence.get(static_cast<std::size_t>(m_field));
*val = result.value; *val = result.value;
oxReturnError(result); oxReturnError(result);
@ -206,7 +203,7 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, bool *val) n
// array handler // array handler
template<Reader_c Reader> template<Reader_c Reader>
constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, auto *val, std::size_t valLen) noexcept { constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, auto *val, std::size_t valLen) noexcept {
if (m_unionIdx == -1 || static_cast<std::size_t>(m_unionIdx) == m_field) { if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length // read the length
std::size_t bytesRead = 0; std::size_t bytesRead = 0;
@ -232,7 +229,7 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, auto *v
template<Reader_c Reader> template<Reader_c Reader>
template<typename T> template<typename T>
constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, HashMap<String, T> *val) noexcept { constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, HashMap<String, T> *val) noexcept {
if (m_unionIdx == -1 || static_cast<std::size_t>(m_unionIdx) == m_field) { if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length // read the length
oxRequire(g, m_reader.tellg()); oxRequire(g, m_reader.tellg());
@ -264,7 +261,7 @@ template<Reader_c Reader>
template<typename T> template<typename T>
constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, T *val) noexcept { constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, T *val) noexcept {
if constexpr(isVector_v<T>) { if constexpr(isVector_v<T>) {
if (m_unionIdx == -1 || static_cast<std::size_t>(m_unionIdx) == m_field) { if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
// set size of val if the field is present, don't worry about it if not // set size of val if the field is present, don't worry about it if not
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
oxRequire(len, arrayLength(name, false)); oxRequire(len, arrayLength(name, false));
@ -276,7 +273,7 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, T *val)
++m_field; ++m_field;
return {}; return {};
} else if constexpr(isArray_v<T>) { } else if constexpr(isArray_v<T>) {
if (m_unionIdx == -1 || static_cast<std::size_t>(m_unionIdx) == m_field) { if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
// set size of val if the field is present, don't worry about it if not // set size of val if the field is present, don't worry about it if not
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
oxRequire(len, arrayLength(name, false)); oxRequire(len, arrayLength(name, false));
@ -289,7 +286,7 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, T *val)
++m_field; ++m_field;
return {}; return {};
} else { } else {
if ((m_unionIdx == -1 || static_cast<std::size_t>(m_unionIdx) == m_field) && val) { if ((!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) && val) {
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
auto reader = child(""); auto reader = child("");
oxReturnError(model(reader.interface(), val)); oxReturnError(model(reader.interface(), val));
@ -303,9 +300,9 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, T *val)
template<Reader_c Reader> template<Reader_c Reader>
template<typename U, bool force> template<typename U, bool force>
constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, UnionView<U, force> val) noexcept { constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, UnionView<U, force> val) noexcept {
if ((m_unionIdx == -1 || static_cast<std::size_t>(m_unionIdx) == m_field) && val.get()) { if ((!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) && val.get()) {
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
auto reader = child("", val.idx()); auto reader = child("", ox::Optional<int>(ox::in_place_t{}, val.idx()));
oxReturnError(model(reader.interface(), val.get())); oxReturnError(model(reader.interface(), val.get()));
} }
} }
@ -316,7 +313,7 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, UnionView<U,
template<Reader_c Reader> template<Reader_c Reader>
template<std::size_t SmallStringSize> template<std::size_t SmallStringSize>
constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, BasicString<SmallStringSize> *val) noexcept { constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, BasicString<SmallStringSize> *val) noexcept {
if (m_unionIdx == -1 || static_cast<std::size_t>(m_unionIdx) == m_field) { if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length // read the length
std::size_t bytesRead = 0; std::size_t bytesRead = 0;
@ -382,7 +379,7 @@ constexpr Error MetalClawReaderTemplate<Reader>::fieldCString(const char*, char
template<Reader_c Reader> template<Reader_c Reader>
constexpr Error MetalClawReaderTemplate<Reader>::fieldCString(const char*, char **val, std::size_t buffLen) noexcept { constexpr Error MetalClawReaderTemplate<Reader>::fieldCString(const char*, char **val, std::size_t buffLen) noexcept {
if (m_unionIdx == -1 || static_cast<std::size_t>(m_unionIdx) == m_field) { if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length // read the length
std::size_t bytesRead = 0; std::size_t bytesRead = 0;
@ -410,7 +407,7 @@ constexpr Error MetalClawReaderTemplate<Reader>::fieldCString(const char*, char
template<Reader_c Reader> template<Reader_c Reader>
constexpr Result<ArrayLength> MetalClawReaderTemplate<Reader>::arrayLength(const char*, bool pass) noexcept { constexpr Result<ArrayLength> MetalClawReaderTemplate<Reader>::arrayLength(const char*, bool pass) noexcept {
if (m_unionIdx == -1 || static_cast<std::size_t>(m_unionIdx) == m_field) { if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length // read the length
std::size_t bytesRead = 0; std::size_t bytesRead = 0;
@ -427,7 +424,7 @@ constexpr Result<ArrayLength> MetalClawReaderTemplate<Reader>::arrayLength(const
template<Reader_c Reader> template<Reader_c Reader>
constexpr Result<StringLength> MetalClawReaderTemplate<Reader>::stringLength(const char*) noexcept { constexpr Result<StringLength> MetalClawReaderTemplate<Reader>::stringLength(const char*) noexcept {
if (m_unionIdx == -1 || static_cast<std::size_t>(m_unionIdx) == m_field) { if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length // read the length
std::size_t bytesRead = 0; std::size_t bytesRead = 0;
@ -442,7 +439,7 @@ constexpr Result<StringLength> MetalClawReaderTemplate<Reader>::stringLength(con
template<Reader_c Reader> template<Reader_c Reader>
template<typename I> template<typename I>
constexpr Error MetalClawReaderTemplate<Reader>::readInteger(I *val) noexcept { constexpr Error MetalClawReaderTemplate<Reader>::readInteger(I *val) noexcept {
if (m_unionIdx == -1 || static_cast<std::size_t>(m_unionIdx) == m_field) { if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
std::size_t bytesRead = 0; std::size_t bytesRead = 0;
auto const result = mc::decodeInteger<I>(m_reader, &bytesRead); auto const result = mc::decodeInteger<I>(m_reader, &bytesRead);
@ -459,7 +456,7 @@ constexpr Error MetalClawReaderTemplate<Reader>::readInteger(I *val) noexcept {
template<Reader_c Reader> template<Reader_c Reader>
template<typename T, typename CB> template<typename T, typename CB>
constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, CB cb) noexcept { constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, CB cb) noexcept {
if (m_unionIdx == -1 || static_cast<std::size_t>(m_unionIdx) == m_field) { if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length // read the length
std::size_t bytesRead = 0; std::size_t bytesRead = 0;
@ -491,8 +488,10 @@ constexpr ox::Error MetalClawReaderTemplate<Reader>::setTypeInfo(
} }
template<Reader_c Reader> template<Reader_c Reader>
constexpr MetalClawReaderTemplate<Reader> MetalClawReaderTemplate<Reader>::child(const char*, int unionIdx) noexcept { constexpr MetalClawReaderTemplate<Reader> MetalClawReaderTemplate<Reader>::child(
return MetalClawReaderTemplate<Reader>(m_reader, unionIdx, this); const char*,
ox::Optional<int> unionIdx) noexcept {
return MetalClawReaderTemplate<Reader>(m_reader, unionIdx);
} }
template<Reader_c Reader> template<Reader_c Reader>

View File

@ -16,6 +16,7 @@
#include <ox/std/buffer.hpp> #include <ox/std/buffer.hpp>
#include <ox/std/byteswap.hpp> #include <ox/std/byteswap.hpp>
#include <ox/std/hashmap.hpp> #include <ox/std/hashmap.hpp>
#include <ox/std/optional.hpp>
#include <ox/std/string.hpp> #include <ox/std/string.hpp>
#include <ox/std/types.hpp> #include <ox/std/types.hpp>
#include <ox/std/units.hpp> #include <ox/std/units.hpp>
@ -34,12 +35,12 @@ class MetalClawWriter {
ox::Vector<uint8_t, 16> m_presenceMapBuff{}; ox::Vector<uint8_t, 16> m_presenceMapBuff{};
FieldBitmap m_fieldPresence; FieldBitmap m_fieldPresence;
int m_field = 0; int m_field = 0;
int m_unionIdx = -1; ox::Optional<int> m_unionIdx;
std::size_t m_writerBeginP{}; std::size_t m_writerBeginP{};
Writer &m_writer; Writer &m_writer;
public: public:
constexpr explicit MetalClawWriter(Writer &writer, int unionIdx = -1) noexcept; constexpr explicit MetalClawWriter(Writer &writer, ox::Optional<int> const&unionIdx = {}) noexcept;
constexpr ~MetalClawWriter() noexcept = default; constexpr ~MetalClawWriter() noexcept = default;
@ -114,7 +115,7 @@ class MetalClawWriter {
private: private:
constexpr Error appendInteger(Integer_c auto val) noexcept { constexpr Error appendInteger(Integer_c auto val) noexcept {
bool fieldSet = false; bool fieldSet = false;
if (val && (m_unionIdx == -1 || m_unionIdx == m_field)) { if (val && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
auto mi = mc::encodeInteger(val); auto mi = mc::encodeInteger(val);
oxReturnError(m_writer.write(reinterpret_cast<const char*>(mi.data), mi.length)); oxReturnError(m_writer.write(reinterpret_cast<const char*>(mi.data), mi.length));
fieldSet = true; fieldSet = true;
@ -130,7 +131,7 @@ extern template class ModelHandlerInterface<MetalClawWriter<BufferWriter>>;
extern template class ModelHandlerInterface<MetalClawWriter<CharBuffWriter>>; extern template class ModelHandlerInterface<MetalClawWriter<CharBuffWriter>>;
template<Writer_c Writer> template<Writer_c Writer>
constexpr MetalClawWriter<Writer>::MetalClawWriter(Writer &writer, int unionIdx) noexcept: constexpr MetalClawWriter<Writer>::MetalClawWriter(Writer &writer, ox::Optional<int> const&unionIdx) noexcept:
m_fieldPresence(m_presenceMapBuff.data(), m_presenceMapBuff.size()), m_fieldPresence(m_presenceMapBuff.data(), m_presenceMapBuff.size()),
m_unionIdx(unionIdx), m_unionIdx(unionIdx),
m_writerBeginP(writer.tellp()), m_writerBeginP(writer.tellp()),
@ -179,7 +180,7 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const uint64_t *val)
template<Writer_c Writer> template<Writer_c Writer>
constexpr Error MetalClawWriter<Writer>::field(const char*, const bool *val) noexcept { constexpr Error MetalClawWriter<Writer>::field(const char*, const bool *val) noexcept {
if (m_unionIdx == -1 || m_unionIdx == m_field) { if (!m_unionIdx.has_value() || *m_unionIdx == m_field) {
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), *val)); oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), *val));
} }
++m_field; ++m_field;
@ -190,7 +191,7 @@ template<Writer_c Writer>
template<std::size_t SmallStringSize> template<std::size_t SmallStringSize>
constexpr Error MetalClawWriter<Writer>::field(const char*, const BasicString<SmallStringSize> *val) noexcept { constexpr Error MetalClawWriter<Writer>::field(const char*, const BasicString<SmallStringSize> *val) noexcept {
bool fieldSet = false; bool fieldSet = false;
if (val->len() && (m_unionIdx == -1 || m_unionIdx == m_field)) { if (val->len() && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
// write the length // write the length
const auto strLen = mc::encodeInteger(val->len()); const auto strLen = mc::encodeInteger(val->len());
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLen.data), strLen.length)); oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLen.data), strLen.length));
@ -212,7 +213,7 @@ constexpr Error MetalClawWriter<Writer>::field(const char *name, const BString<L
template<Writer_c Writer> template<Writer_c Writer>
constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *const*val, std::size_t) noexcept { constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *const*val, std::size_t) noexcept {
bool fieldSet = false; bool fieldSet = false;
if (m_unionIdx == -1 || m_unionIdx == m_field) { if (!m_unionIdx.has_value() || *m_unionIdx == m_field) {
const auto strLen = *val ? ox_strlen(*val) : 0; const auto strLen = *val ? ox_strlen(*val) : 0;
// write the length // write the length
const auto strLenBuff = mc::encodeInteger(strLen); const auto strLenBuff = mc::encodeInteger(strLen);
@ -239,7 +240,7 @@ constexpr Error MetalClawWriter<Writer>::fieldCString(const char *name, const ch
template<Writer_c Writer> template<Writer_c Writer>
constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *val, std::size_t strLen) noexcept { constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *val, std::size_t strLen) noexcept {
bool fieldSet = false; bool fieldSet = false;
if (strLen && (m_unionIdx == -1 || m_unionIdx == m_field)) { if (strLen && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
// write the length // write the length
const auto strLenBuff = mc::encodeInteger(strLen); const auto strLenBuff = mc::encodeInteger(strLen);
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data), strLenBuff.length)); oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data), strLenBuff.length));
@ -259,7 +260,7 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const T *val) noexce
return field(nullptr, val->data(), val->size()); return field(nullptr, val->data(), val->size());
} else { } else {
bool fieldSet = false; bool fieldSet = false;
if (val && (m_unionIdx == -1 || m_unionIdx == m_field)) { if (val && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
MetalClawWriter<Writer> writer(m_writer); MetalClawWriter<Writer> writer(m_writer);
ModelHandlerInterface<MetalClawWriter<Writer>> handler{&writer}; ModelHandlerInterface<MetalClawWriter<Writer>> handler{&writer};
oxReturnError(model(&handler, val)); oxReturnError(model(&handler, val));
@ -276,8 +277,8 @@ template<Writer_c Writer>
template<typename U, bool force> template<typename U, bool force>
constexpr Error MetalClawWriter<Writer>::field(const char*, UnionView<U, force> val) noexcept { constexpr Error MetalClawWriter<Writer>::field(const char*, UnionView<U, force> val) noexcept {
bool fieldSet = false; bool fieldSet = false;
if (val.get() && (m_unionIdx == -1 || m_unionIdx == m_field)) { if (val.get() && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
MetalClawWriter<Writer> writer(m_writer, val.idx()); MetalClawWriter<Writer> writer(m_writer, ox::Optional<int>(ox::in_place, val.idx()));
ModelHandlerInterface handler{&writer}; ModelHandlerInterface handler{&writer};
oxReturnError(model(&handler, val.get())); oxReturnError(model(&handler, val.get()));
oxReturnError(writer.finalize()); oxReturnError(writer.finalize());
@ -292,7 +293,7 @@ template<Writer_c Writer>
template<typename T> template<typename T>
constexpr Error MetalClawWriter<Writer>::field(const char*, const T *val, std::size_t len) noexcept { constexpr Error MetalClawWriter<Writer>::field(const char*, const T *val, std::size_t len) noexcept {
bool fieldSet = false; bool fieldSet = false;
if (len && (m_unionIdx == -1 || m_unionIdx == m_field)) { if (len && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
// write the length // write the length
const auto arrLen = mc::encodeInteger(len); const auto arrLen = mc::encodeInteger(len);
oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data), arrLen.length)); oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data), arrLen.length));
@ -317,7 +318,7 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const HashMap<String
const auto &keys = val->keys(); const auto &keys = val->keys();
const auto len = keys.size(); const auto len = keys.size();
bool fieldSet = false; bool fieldSet = false;
if (len && (m_unionIdx == -1 || m_unionIdx == m_field)) { if (len && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
// write the length // write the length
const auto arrLen = mc::encodeInteger(len); const auto arrLen = mc::encodeInteger(len);
oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data), arrLen.length)); oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data), arrLen.length));