[ox/model] Fix infinite recursion caused by have a vector of the same type in ModelValue
This commit is contained in:
parent
80d0df2f46
commit
ef6e3af735
8
deps/ox/src/ox/mc/read.hpp
vendored
8
deps/ox/src/ox/mc/read.hpp
vendored
@ -265,10 +265,10 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, T *val)
|
|||||||
// 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));
|
||||||
val->resize(len);
|
oxReturnError(ox::resizeVector(*val, len));
|
||||||
return field(name, val->data(), val->size());
|
return field(name, val->data(), val->size());
|
||||||
}
|
}
|
||||||
val->resize(0);
|
oxReturnError(ox::resizeVector(*val, 0));
|
||||||
}
|
}
|
||||||
++m_field;
|
++m_field;
|
||||||
return {};
|
return {};
|
||||||
@ -302,12 +302,12 @@ 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.has_value() || 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("", ox::Optional<int>(ox::in_place_t{}, val.idx()));
|
auto reader = child("", ox::Optional<int>(ox::in_place, val.idx()));
|
||||||
oxReturnError(model(reader.interface(), val.get()));
|
oxReturnError(model(reader.interface(), val.get()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++m_field;
|
++m_field;
|
||||||
return OxError(0);
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Reader_c Reader>
|
template<Reader_c Reader>
|
||||||
|
17
deps/ox/src/ox/mc/write.hpp
vendored
17
deps/ox/src/ox/mc/write.hpp
vendored
@ -261,15 +261,16 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const T *val) noexce
|
|||||||
} else {
|
} else {
|
||||||
bool fieldSet = false;
|
bool fieldSet = false;
|
||||||
if (val && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
|
if (val && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
|
||||||
|
auto const writeIdx = m_writer.tellp();
|
||||||
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));
|
||||||
oxReturnError(writer.finalize());
|
oxReturnError(writer.finalize());
|
||||||
fieldSet = true;
|
fieldSet = writeIdx != m_writer.tellp();
|
||||||
}
|
}
|
||||||
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||||
++m_field;
|
++m_field;
|
||||||
return OxError(0);
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,15 +279,16 @@ 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.has_value() || *m_unionIdx == m_field)) {
|
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, 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());
|
||||||
fieldSet = true;
|
fieldSet = writeIdx != m_writer.tellp();
|
||||||
}
|
}
|
||||||
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||||
++m_field;
|
++m_field;
|
||||||
return OxError(0);
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Writer_c Writer>
|
template<Writer_c Writer>
|
||||||
@ -297,15 +299,16 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const T *val, std::s
|
|||||||
// 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));
|
||||||
|
auto const writeIdx = m_writer.tellp();
|
||||||
MetalClawWriter<Writer> writer(m_writer);
|
MetalClawWriter<Writer> writer(m_writer);
|
||||||
ModelHandlerInterface handler{&writer};
|
ModelHandlerInterface handler{&writer};
|
||||||
oxReturnError(handler.template setTypeInfo<T>("List", 0, {}, static_cast<std::size_t>(len)));
|
oxReturnError(handler.template setTypeInfo<T>("List", 0, {}, static_cast<std::size_t>(len)));
|
||||||
// write the array
|
// write the array
|
||||||
for (std::size_t i = 0; i < len; i++) {
|
for (std::size_t i = 0; i < len; ++i) {
|
||||||
oxReturnError(handler.field("", &val[i]));
|
oxReturnError(handler.field("", &val[i]));
|
||||||
}
|
}
|
||||||
oxReturnError(writer.finalize());
|
oxReturnError(writer.finalize());
|
||||||
fieldSet = true;
|
fieldSet = writeIdx != m_writer.tellp();
|
||||||
}
|
}
|
||||||
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||||
++m_field;
|
++m_field;
|
||||||
@ -337,7 +340,7 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const HashMap<String
|
|||||||
return handler.field("", value);
|
return handler.field("", value);
|
||||||
};
|
};
|
||||||
// write the array
|
// write the array
|
||||||
for (std::size_t i = 0; i < len; i++) {
|
for (std::size_t i = 0; i < len; ++i) {
|
||||||
auto const&key = keys[i];
|
auto const&key = keys[i];
|
||||||
oxReturnError(loopBody(handler, key, *val));
|
oxReturnError(loopBody(handler, key, *val));
|
||||||
}
|
}
|
||||||
|
12
deps/ox/src/ox/model/modelhandleradaptor.hpp
vendored
12
deps/ox/src/ox/model/modelhandleradaptor.hpp
vendored
@ -196,7 +196,6 @@ class ModelHandlerInterface {
|
|||||||
constexpr auto handler() noexcept {
|
constexpr auto handler() noexcept {
|
||||||
return m_handler;
|
return m_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Handler, ox::OpType opType_v = Handler::opType()>
|
template<typename Handler, ox::OpType opType_v = Handler::opType()>
|
||||||
@ -215,7 +214,16 @@ class ModelHandlerBase {
|
|||||||
static constexpr ox::OpType opType() noexcept {
|
static constexpr ox::OpType opType() noexcept {
|
||||||
return opType_v;
|
return opType_v;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
constexpr ox::Error resizeVector(auto &vec, size_t sz) {
|
||||||
|
if constexpr(ox::is_same_v<decltype(vec.resize(0)), ox::Error>) {
|
||||||
|
return vec.resize(sz);
|
||||||
|
} else {
|
||||||
|
vec.resize(sz);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
16
deps/ox/src/ox/model/modelvalue.hpp
vendored
16
deps/ox/src/ox/model/modelvalue.hpp
vendored
@ -202,7 +202,8 @@ class ModelValue {
|
|||||||
class ModelValueVector {
|
class ModelValueVector {
|
||||||
private:
|
private:
|
||||||
Vector<ModelValue> m_vec;
|
Vector<ModelValue> m_vec;
|
||||||
ModelValue m_templateValue;
|
const DescriptorType *m_type = nullptr;
|
||||||
|
int m_typeSubscriptLevels = 0;
|
||||||
String m_typeName;
|
String m_typeName;
|
||||||
int m_typeVersion = 0;
|
int m_typeVersion = 0;
|
||||||
|
|
||||||
@ -227,14 +228,15 @@ class ModelValueVector {
|
|||||||
return m_vec.data();
|
return m_vec.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr void resize(std::size_t sz) noexcept {
|
constexpr ox::Error resize(std::size_t sz) noexcept {
|
||||||
const auto oldSz = m_vec.size();
|
const auto oldSz = m_vec.size();
|
||||||
m_vec.resize(sz);
|
m_vec.resize(sz);
|
||||||
if (sz > oldSz) {
|
if (sz > oldSz) {
|
||||||
for (auto i = oldSz; i < sz; ++i) {
|
for (auto i = oldSz; i < sz; ++i) {
|
||||||
m_vec[i] = m_templateValue;
|
oxReturnError(m_vec[i].setType(m_type, m_typeSubscriptLevels));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
@ -248,7 +250,9 @@ class ModelValueVector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constexpr Error setType(const DescriptorType *type, int subscriptLevels) noexcept {
|
constexpr Error setType(const DescriptorType *type, int subscriptLevels) noexcept {
|
||||||
return m_templateValue.setType(type, subscriptLevels);
|
m_type = type;
|
||||||
|
m_typeSubscriptLevels = subscriptLevels;
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
@ -1089,14 +1093,12 @@ constexpr ModelValueVector::ModelValueVector(const ModelValueVector &other) noex
|
|||||||
for (auto &v : other.m_vec) {
|
for (auto &v : other.m_vec) {
|
||||||
m_vec.emplace_back(v);
|
m_vec.emplace_back(v);
|
||||||
}
|
}
|
||||||
m_templateValue = other.m_templateValue;
|
|
||||||
m_typeName = other.m_typeName;
|
m_typeName = other.m_typeName;
|
||||||
m_typeVersion = other.m_typeVersion;
|
m_typeVersion = other.m_typeVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr ModelValueVector::ModelValueVector(ModelValueVector &&other) noexcept {
|
constexpr ModelValueVector::ModelValueVector(ModelValueVector &&other) noexcept {
|
||||||
m_vec = std::move(other.m_vec);
|
m_vec = std::move(other.m_vec);
|
||||||
m_templateValue = std::move(other.m_templateValue);
|
|
||||||
m_typeName = std::move(other.m_typeName);
|
m_typeName = std::move(other.m_typeName);
|
||||||
m_typeVersion = other.m_typeVersion;
|
m_typeVersion = other.m_typeVersion;
|
||||||
}
|
}
|
||||||
@ -1108,7 +1110,6 @@ constexpr ModelValueVector &ModelValueVector::operator=(const ModelValueVector &
|
|||||||
for (auto &v : other.m_vec) {
|
for (auto &v : other.m_vec) {
|
||||||
m_vec.emplace_back(v);
|
m_vec.emplace_back(v);
|
||||||
}
|
}
|
||||||
m_templateValue = other.m_templateValue;
|
|
||||||
m_typeName = other.m_typeName;
|
m_typeName = other.m_typeName;
|
||||||
m_typeVersion = other.m_typeVersion;
|
m_typeVersion = other.m_typeVersion;
|
||||||
return *this;
|
return *this;
|
||||||
@ -1119,7 +1120,6 @@ constexpr ModelValueVector &ModelValueVector::operator=(ModelValueVector &&other
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
m_vec = std::move(other.m_vec);
|
m_vec = std::move(other.m_vec);
|
||||||
m_templateValue = std::move(other.m_templateValue);
|
|
||||||
m_typeName = std::move(other.m_typeName);
|
m_typeName = std::move(other.m_typeName);
|
||||||
m_typeVersion = other.m_typeVersion;
|
m_typeVersion = other.m_typeVersion;
|
||||||
return *this;
|
return *this;
|
||||||
|
2
deps/ox/src/ox/oc/read.hpp
vendored
2
deps/ox/src/ox/oc/read.hpp
vendored
@ -147,7 +147,7 @@ Error OrganicClawReader::field(const char *key, T *val) noexcept {
|
|||||||
if constexpr(isVector_v<T>) {
|
if constexpr(isVector_v<T>) {
|
||||||
const auto &srcVal = value(key);
|
const auto &srcVal = value(key);
|
||||||
const auto srcSize = srcVal.size();
|
const auto srcSize = srcVal.size();
|
||||||
val->resize(srcSize);
|
oxReturnError(ox::resizeVector(*val, srcSize));
|
||||||
err = field(key, val->data(), val->size());
|
err = field(key, val->data(), val->size());
|
||||||
} else if constexpr(isArray_v<T>) {
|
} else if constexpr(isArray_v<T>) {
|
||||||
const auto &srcVal = value(key);
|
const auto &srcVal = value(key);
|
||||||
|
Loading…
Reference in New Issue
Block a user