[ox] Add support for unions to model and mc

This commit is contained in:
2020-04-13 02:28:38 -05:00
parent 82a07737ec
commit 1d07890668
14 changed files with 329 additions and 195 deletions

View File

@@ -29,44 +29,49 @@ class MetalClawWriter {
FieldPresenceIndicator m_fieldPresence;
int m_fields = 0;
int m_field = 0;
int m_unionIdx = -1;
std::size_t m_buffIt = 0;
std::size_t m_buffLen = 0;
uint8_t *m_buff = nullptr;
public:
MetalClawWriter(uint8_t *buff, std::size_t buffLen);
MetalClawWriter(uint8_t *buff, std::size_t buffLen, int unionIdx = -1) noexcept;
~MetalClawWriter() noexcept;
Error field(const char*, int8_t *val);
Error field(const char*, int16_t *val);
Error field(const char*, int32_t *val);
Error field(const char*, int64_t *val);
[[nodiscard]] Error field(const char*, int8_t *val) noexcept;
[[nodiscard]] Error field(const char*, int16_t *val) noexcept;
[[nodiscard]] Error field(const char*, int32_t *val) noexcept;
[[nodiscard]] Error field(const char*, int64_t *val) noexcept;
Error field(const char*, uint8_t *val);
Error field(const char*, uint16_t *val);
Error field(const char*, uint32_t *val);
Error field(const char*, uint64_t *val);
[[nodiscard]] Error field(const char*, uint8_t *val) noexcept;
[[nodiscard]] Error field(const char*, uint16_t *val) noexcept;
[[nodiscard]] Error field(const char*, uint32_t *val) noexcept;
[[nodiscard]] Error field(const char*, uint64_t *val) noexcept;
Error field(const char*, bool *val);
[[nodiscard]] Error field(const char*, bool *val) noexcept;
template<typename T>
Error field(const char*, T *val, std::size_t len);
[[nodiscard]] Error field(const char*, T *val, std::size_t len);
template<typename T>
Error field(const char*, ox::Vector<T> *val);
[[nodiscard]] Error field(const char*, ox::Vector<T> *val);
template<std::size_t L>
Error field(const char*, ox::BString<L> *val);
[[nodiscard]] Error field(const char*, ox::BString<L> *val) noexcept;
Error field(const char*, SerStr val);
[[nodiscard]] Error field(const char*, SerStr val) noexcept;
template<typename T>
Error field(const char*, T *val);
[[nodiscard]] Error field(const char*, T *val);
void setTypeInfo(const char *name, int fields);
template<typename U>
[[nodiscard]] Error field(const char*, UnionView<U> val);
std::size_t size();
template<typename T = std::nullptr_t>
void setTypeInfo(const char *name = T::TypeName, int fields = T::Fields);
std::size_t size() noexcept;
static constexpr auto opType() {
return OpType::Write;
@@ -74,20 +79,20 @@ class MetalClawWriter {
private:
template<typename I>
Error appendInteger(I val);
[[nodiscard]] Error appendInteger(I val) noexcept;
};
template<std::size_t L>
Error MetalClawWriter::field(const char *name, ox::BString<L> *val) {
Error MetalClawWriter::field(const char *name, ox::BString<L> *val) noexcept {
return field(name, SerStr(val->data(), val->cap()));
}
template<typename T>
Error MetalClawWriter::field(const char*, T *val) {
bool fieldSet = false;
MetalClawWriter writer(m_buff + m_buffIt, m_buffLen - m_buffIt);
if (val) {
if (val && (m_unionIdx == -1 || m_unionIdx == m_field)) {
MetalClawWriter writer(m_buff + m_buffIt, m_buffLen - m_buffIt);
oxReturnError(model(&writer, val));
if (static_cast<std::size_t>(writer.m_fieldPresence.getMaxLen()) < writer.m_buffIt) {
m_buffIt += writer.m_buffIt;
@@ -99,27 +104,42 @@ Error MetalClawWriter::field(const char*, T *val) {
return OxError(0);
}
template<typename U>
Error MetalClawWriter::field(const char*, UnionView<U> val) {
bool fieldSet = false;
if (val.get() && (m_unionIdx == -1 || m_unionIdx == m_field)) {
MetalClawWriter writer(m_buff + m_buffIt, m_buffLen - m_buffIt, val.idx());
oxReturnError(model(&writer, val.get()));
if (static_cast<std::size_t>(writer.m_fieldPresence.getMaxLen()) < writer.m_buffIt) {
m_buffIt += writer.m_buffIt;
fieldSet = true;
}
}
oxReturnError(m_fieldPresence.set(m_field, fieldSet));
m_field++;
return OxError(0);
}
template<typename T>
Error MetalClawWriter::field(const char*, T *val, std::size_t len) {
auto err = OxError(0);
bool fieldSet = false;
if (len) {
if (len && (m_unionIdx == -1 || m_unionIdx == m_field)) {
// write the length
const auto arrLen = mc::encodeInteger(len);
if (m_buffIt + arrLen.length < m_buffLen) {
ox_memcpy(&m_buff[m_buffIt], arrLen.data, arrLen.length);
m_buffIt += arrLen.length;
} else {
err = OxError(MC_BUFFENDED);
return OxError(MC_BUFFENDED);
}
MetalClawWriter writer(m_buff + m_buffIt, m_buffLen - m_buffIt);
writer.setTypeInfo("List", len);
writer.setTypeInfo<T>("List", len);
// write the array
for (std::size_t i = 0; i < len; i++) {
err |= writer.field("", &val[i]);
oxReturnError(writer.field("", &val[i]));
}
m_buffIt += writer.m_buffIt;
@@ -128,7 +148,7 @@ Error MetalClawWriter::field(const char*, T *val, std::size_t len) {
oxReturnError(m_fieldPresence.set(m_field, fieldSet));
m_field++;
return err;
return OxError(0);
}
template<typename T>
@@ -137,22 +157,30 @@ Error MetalClawWriter::field(const char*, ox::Vector<T> *val) {
}
template<typename I>
Error MetalClawWriter::appendInteger(I val) {
auto err = OxError(0);
Error MetalClawWriter::appendInteger(I val) noexcept {
bool fieldSet = false;
if (val) {
if (val && (m_unionIdx == -1 || m_unionIdx == m_field)) {
auto mi = mc::encodeInteger(val);
if (mi.length < m_buffLen) {
fieldSet = true;
ox_memcpy(&m_buff[m_buffIt], mi.data, mi.length);
m_buffIt += mi.length;
} else {
err |= OxError(MC_BUFFENDED);
oxReturnError(OxError(MC_BUFFENDED));
}
}
err |= m_fieldPresence.set(m_field, fieldSet);
oxReturnError(m_fieldPresence.set(m_field, fieldSet));
m_field++;
return err;
return OxError(0);
;
}
template<typename T>
void MetalClawWriter::setTypeInfo(const char*, int fields) {
m_fields = fields;
m_fieldPresence.setFields(fields);
m_buffIt = m_fieldPresence.getMaxLen();
memset(m_buff, 0, m_buffIt);
}
template<typename T>