[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
|
||||
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
|
||||
oxRequire(len, arrayLength(name, false));
|
||||
val->resize(len);
|
||||
oxReturnError(ox::resizeVector(*val, len));
|
||||
return field(name, val->data(), val->size());
|
||||
}
|
||||
val->resize(0);
|
||||
oxReturnError(ox::resizeVector(*val, 0));
|
||||
}
|
||||
++m_field;
|
||||
return {};
|
||||
@ -302,12 +302,12 @@ template<typename U, bool force>
|
||||
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_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()));
|
||||
}
|
||||
}
|
||||
++m_field;
|
||||
return OxError(0);
|
||||
return {};
|
||||
}
|
||||
|
||||
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 {
|
||||
bool fieldSet = false;
|
||||
if (val && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
|
||||
auto const writeIdx = m_writer.tellp();
|
||||
MetalClawWriter<Writer> writer(m_writer);
|
||||
ModelHandlerInterface<MetalClawWriter<Writer>> handler{&writer};
|
||||
oxReturnError(model(&handler, val));
|
||||
oxReturnError(writer.finalize());
|
||||
fieldSet = true;
|
||||
fieldSet = writeIdx != m_writer.tellp();
|
||||
}
|
||||
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||
++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 {
|
||||
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()));
|
||||
ModelHandlerInterface handler{&writer};
|
||||
oxReturnError(model(&handler, val.get()));
|
||||
oxReturnError(writer.finalize());
|
||||
fieldSet = true;
|
||||
fieldSet = writeIdx != m_writer.tellp();
|
||||
}
|
||||
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||
++m_field;
|
||||
return OxError(0);
|
||||
return {};
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
@ -297,15 +299,16 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const T *val, std::s
|
||||
// write the length
|
||||
const auto arrLen = mc::encodeInteger(len);
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data), arrLen.length));
|
||||
auto const writeIdx = m_writer.tellp();
|
||||
MetalClawWriter<Writer> writer(m_writer);
|
||||
ModelHandlerInterface handler{&writer};
|
||||
oxReturnError(handler.template setTypeInfo<T>("List", 0, {}, static_cast<std::size_t>(len)));
|
||||
// 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(writer.finalize());
|
||||
fieldSet = true;
|
||||
fieldSet = writeIdx != m_writer.tellp();
|
||||
}
|
||||
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||
++m_field;
|
||||
@ -337,7 +340,7 @@ 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++) {
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
auto const&key = keys[i];
|
||||
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 {
|
||||
return m_handler;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename Handler, ox::OpType opType_v = Handler::opType()>
|
||||
@ -215,7 +214,16 @@ class ModelHandlerBase {
|
||||
static constexpr ox::OpType opType() noexcept {
|
||||
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 {
|
||||
private:
|
||||
Vector<ModelValue> m_vec;
|
||||
ModelValue m_templateValue;
|
||||
const DescriptorType *m_type = nullptr;
|
||||
int m_typeSubscriptLevels = 0;
|
||||
String m_typeName;
|
||||
int m_typeVersion = 0;
|
||||
|
||||
@ -227,14 +228,15 @@ class ModelValueVector {
|
||||
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();
|
||||
m_vec.resize(sz);
|
||||
if (sz > oldSz) {
|
||||
for (auto i = oldSz; i < sz; ++i) {
|
||||
m_vec[i] = m_templateValue;
|
||||
oxReturnError(m_vec[i].setType(m_type, m_typeSubscriptLevels));
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@ -248,7 +250,9 @@ class ModelValueVector {
|
||||
}
|
||||
|
||||
constexpr Error setType(const DescriptorType *type, int subscriptLevels) noexcept {
|
||||
return m_templateValue.setType(type, subscriptLevels);
|
||||
m_type = type;
|
||||
m_typeSubscriptLevels = subscriptLevels;
|
||||
return {};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@ -1089,14 +1093,12 @@ constexpr ModelValueVector::ModelValueVector(const ModelValueVector &other) noex
|
||||
for (auto &v : other.m_vec) {
|
||||
m_vec.emplace_back(v);
|
||||
}
|
||||
m_templateValue = other.m_templateValue;
|
||||
m_typeName = other.m_typeName;
|
||||
m_typeVersion = other.m_typeVersion;
|
||||
}
|
||||
|
||||
constexpr ModelValueVector::ModelValueVector(ModelValueVector &&other) noexcept {
|
||||
m_vec = std::move(other.m_vec);
|
||||
m_templateValue = std::move(other.m_templateValue);
|
||||
m_typeName = std::move(other.m_typeName);
|
||||
m_typeVersion = other.m_typeVersion;
|
||||
}
|
||||
@ -1108,7 +1110,6 @@ constexpr ModelValueVector &ModelValueVector::operator=(const ModelValueVector &
|
||||
for (auto &v : other.m_vec) {
|
||||
m_vec.emplace_back(v);
|
||||
}
|
||||
m_templateValue = other.m_templateValue;
|
||||
m_typeName = other.m_typeName;
|
||||
m_typeVersion = other.m_typeVersion;
|
||||
return *this;
|
||||
@ -1119,7 +1120,6 @@ constexpr ModelValueVector &ModelValueVector::operator=(ModelValueVector &&other
|
||||
return *this;
|
||||
}
|
||||
m_vec = std::move(other.m_vec);
|
||||
m_templateValue = std::move(other.m_templateValue);
|
||||
m_typeName = std::move(other.m_typeName);
|
||||
m_typeVersion = other.m_typeVersion;
|
||||
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>) {
|
||||
const auto &srcVal = value(key);
|
||||
const auto srcSize = srcVal.size();
|
||||
val->resize(srcSize);
|
||||
oxReturnError(ox::resizeVector(*val, srcSize));
|
||||
err = field(key, val->data(), val->size());
|
||||
} else if constexpr(isArray_v<T>) {
|
||||
const auto &srcVal = value(key);
|
||||
|
Loading…
Reference in New Issue
Block a user