[ox] Cleanup

This commit is contained in:
Gary Talent 2021-05-12 21:14:18 -05:00
parent 07415a2607
commit 63f4b96d0f
9 changed files with 122 additions and 125 deletions

View File

@ -299,7 +299,7 @@ std::map<std::string, ox::Error(*)()> tests = {
oxAssert(ox::writeMC(dataBuff, dataBuffLen, &testIn), "Data generation failed"); oxAssert(ox::writeMC(dataBuff, dataBuffLen, &testIn), "Data generation failed");
auto type = ox::buildTypeDef(&testIn); auto type = ox::buildTypeDef(&testIn);
oxAssert(type.error, "Descriptor write failed"); oxAssert(type.error, "Descriptor write failed");
oxReturnError(ox::walkModel<ox::MetalClawReader>(type.value, dataBuff, dataBuffLen, oxReturnError(ox::walkModel<ox::MetalClawReader>(type.value.get(), dataBuff, dataBuffLen,
[](const ox::Vector<ox::FieldName>&, const ox::Vector<ox::TypeName>&, const ox::DescriptorField &f, ox::MetalClawReader *rdr) -> ox::Error { [](const ox::Vector<ox::FieldName>&, const ox::Vector<ox::TypeName>&, const ox::DescriptorField &f, ox::MetalClawReader *rdr) -> ox::Error {
//std::cout << f.fieldName.c_str() << '\n'; //std::cout << f.fieldName.c_str() << '\n';
auto fieldName = f.fieldName.c_str(); auto fieldName = f.fieldName.c_str();
@ -385,7 +385,6 @@ std::map<std::string, ox::Error(*)()> tests = {
return OxError(0); return OxError(0);
} }
)); ));
delete type.value;
return OxError(0); return OxError(0);
} }
}, },

View File

@ -25,6 +25,7 @@ install(
descwrite.hpp descwrite.hpp
optype.hpp optype.hpp
model.hpp model.hpp
modelops.hpp
types.hpp types.hpp
walk.hpp walk.hpp
DESTINATION DESTINATION

View File

@ -18,23 +18,23 @@ class TypeDescReader: public ReaderBase {
TypeStore m_typeStore; TypeStore m_typeStore;
public: public:
TypeDescReader(uint8_t *buff, std::size_t buffLen); TypeDescReader(uint8_t *buff, std::size_t buffLen) noexcept;
const TypeStore &typeStore() const; const TypeStore &typeStore() const noexcept;
}; };
template<typename ReaderBase> template<typename ReaderBase>
TypeDescReader<ReaderBase>::TypeDescReader(uint8_t *buff, std::size_t buffLen): ReaderBase(buff, buffLen) { TypeDescReader<ReaderBase>::TypeDescReader(uint8_t *buff, std::size_t buffLen) noexcept: ReaderBase(buff, buffLen) {
} }
template<typename ReaderBase> template<typename ReaderBase>
const TypeStore &TypeDescReader<ReaderBase>::typeStore() const { const TypeStore &TypeDescReader<ReaderBase>::typeStore() const noexcept {
return m_typeStore; return m_typeStore;
} }
template<typename ReaderBase, typename T> template<typename ReaderBase, typename T>
int readMCDef(uint8_t *buff, std::size_t buffLen, T *val) { int readMCDef(uint8_t *buff, std::size_t buffLen, T *val) noexcept {
TypeDescReader<ReaderBase> reader(buff, buffLen); TypeDescReader<ReaderBase> reader(buff, buffLen);
return model(&reader, val); return model(&reader, val);
} }

View File

@ -38,7 +38,7 @@ struct DescriptorField {
// only serialize type name if type has already been serialized // only serialize type name if type has already been serialized
struct DescriptorType *type = nullptr; struct DescriptorType *type = nullptr;
FieldName fieldName; String fieldName;
int subscriptLevels = 0; int subscriptLevels = 0;
// do not serialize the following // do not serialize the following
@ -58,7 +58,7 @@ struct DescriptorField {
ownsType = false; // is copy, only owns type if move ownsType = false; // is copy, only owns type if move
} }
constexpr DescriptorField(DescriptorType *type, const FieldName &fieldName, int subscriptLevels, const TypeName &typeName, bool ownsType) noexcept { constexpr DescriptorField(DescriptorType *type, const String &fieldName, int subscriptLevels, const TypeName &typeName, bool ownsType) noexcept {
this->type = type; this->type = type;
this->fieldName = fieldName; this->fieldName = fieldName;
this->subscriptLevels = subscriptLevels; this->subscriptLevels = subscriptLevels;
@ -115,16 +115,16 @@ struct DescriptorType {
DescriptorType() = default; DescriptorType() = default;
DescriptorType(TypeName tn, PrimitiveType t, int b): typeName(tn), primitiveType(t), length(b) { DescriptorType(const TypeName &tn, PrimitiveType t, int b): typeName(tn), primitiveType(t), length(b) {
} }
DescriptorType(TypeName tn, PrimitiveType t, FieldList fl): typeName(tn), primitiveType(t), fieldList(fl) { DescriptorType(const TypeName &tn, PrimitiveType t, FieldList fl): typeName(tn), primitiveType(t), fieldList(fl) {
} }
}; };
template<typename T> template<typename T>
Error model(T *io, DescriptorType *type) { constexpr Error model(T *io, DescriptorType *type) noexcept {
io->template setTypeInfo<T>("net.drinkingtea.ox.DescriptorType", 5); io->template setTypeInfo<T>("net.drinkingtea.ox.DescriptorType", 5);
oxReturnError(io->field("typeName", &type->typeName)); oxReturnError(io->field("typeName", &type->typeName));
oxReturnError(io->field("primitiveType", bit_cast<uint8_t*>(&type->primitiveType))); oxReturnError(io->field("primitiveType", bit_cast<uint8_t*>(&type->primitiveType)));
@ -135,8 +135,7 @@ Error model(T *io, DescriptorType *type) {
} }
template<typename T> template<typename T>
Error modelWrite(T *io, DescriptorField *field) { Error modelWrite(T *io, DescriptorField *field) noexcept {
auto err = OxError(0);
io->setTypeInfo("ox::DescriptorField", 4); io->setTypeInfo("ox::DescriptorField", 4);
if (field->ownsType) { if (field->ownsType) {
BString<2> empty = ""; BString<2> empty = "";
@ -150,32 +149,31 @@ Error modelWrite(T *io, DescriptorField *field) {
// defaultValue is unused now, but leave placeholder for backwards compatibility // defaultValue is unused now, but leave placeholder for backwards compatibility
int DefaultValue = 0; int DefaultValue = 0;
oxReturnError(io->field("defaultValue", &DefaultValue)); oxReturnError(io->field("defaultValue", &DefaultValue));
return err; return OxError(0);
} }
template<typename T> template<typename T>
Error modelRead(T *io, DescriptorField *field) { Error modelRead(T *io, DescriptorField *field) noexcept {
auto err = OxError(0);
auto &typeStore = io->typeStore(); auto &typeStore = io->typeStore();
io->setTypeInfo("ox::DescriptorField", 4); io->setTypeInfo("ox::DescriptorField", 4);
err |= io->field("typeName", &field->typeName); oxReturnError(io->field("typeName", &field->typeName));
if (field->typeName == "") { if (field->typeName == "") {
field->ownsType = true; field->ownsType = true;
if (field->type == nullptr) { if (field->type == nullptr) {
field->type = new DescriptorType; field->type = new DescriptorType;
} }
err |= io->field("type", field->type); oxReturnError(io->field("type", field->type));
typeStore[field->type->typeName] = field->type; typeStore[field->type->typeName] = field->type;
} else { } else {
// should be empty, so discard // should be empty, so discard
DescriptorType t; DescriptorType t;
err |= io->field("type", &t); oxReturnError(io->field("type", &t));
field->type = typeStore[field->typeName]; field->type = typeStore[field->typeName];
} }
err |= io->field("fieldName", &field->fieldName); oxReturnError(io->field("fieldName", &field->fieldName));
// defaultValue is unused now, but placeholder for backwards compatibility // defaultValue is unused now, but placeholder for backwards compatibility
err |= io->field("defaultValue", nullptr); oxReturnError(io->field("defaultValue", nullptr));
return err; return OxError(0);
} }
using TypeStore = HashMap<String, DescriptorType*>; using TypeStore = HashMap<String, DescriptorType*>;

View File

@ -34,20 +34,20 @@ static_assert(!preloadable<non_preloadable_type2>::value);
static_assert([] { static_assert([] {
int i = 0; int i = 0;
return indirectionLevels(i) == 0; return detail::indirectionLevels(i) == 0;
}(), "indirectionLevels broken: indirectionLevels(int)"); }(), "indirectionLevels broken: indirectionLevels(int)");
static_assert([] { static_assert([] {
int i = 0; int i = 0;
return indirectionLevels(&i) == 1; return detail::indirectionLevels(&i) == 1;
}(), "indirectionLevels broken: indirectionLevels(int*)"); }(), "indirectionLevels broken: indirectionLevels(int*)");
static_assert([] { static_assert([] {
int i[2] = {}; int i[2] = {};
return indirectionLevels(i) == 1; return detail::indirectionLevels(i) == 1;
}(), "indirectionLevels broken: indirectionLevels(int[])"); }(), "indirectionLevels broken: indirectionLevels(int[])");
TypeDescWriter::TypeDescWriter(TypeStore *typeStore) { TypeDescWriter::TypeDescWriter(TypeStore *typeStore) noexcept {
if (!typeStore) { if (!typeStore) {
m_typeStoreOwnerRef = new TypeStore; m_typeStoreOwnerRef = new TypeStore;
typeStore = m_typeStoreOwnerRef; typeStore = m_typeStoreOwnerRef;
@ -55,93 +55,93 @@ TypeDescWriter::TypeDescWriter(TypeStore *typeStore) {
m_typeStore = typeStore; m_typeStore = typeStore;
} }
TypeDescWriter::~TypeDescWriter() { TypeDescWriter::~TypeDescWriter() noexcept {
// does not own it's elements // does not own it's elements
delete m_typeStoreOwnerRef; delete m_typeStoreOwnerRef;
} }
DescriptorType *TypeDescWriter::type(int8_t*, bool *alreadyExisted) { DescriptorType *TypeDescWriter::type(int8_t*, bool *alreadyExisted) noexcept {
constexpr auto TypeName = "B:int8_t"; constexpr auto TypeName = "B:int8_t";
constexpr auto PT = PrimitiveType::SignedInteger; constexpr auto PT = PrimitiveType::SignedInteger;
constexpr auto Bytes = 1; constexpr auto Bytes = 1;
return getType(TypeName, PT, Bytes, alreadyExisted); return getType(TypeName, PT, Bytes, alreadyExisted);
} }
DescriptorType *TypeDescWriter::type(int16_t*, bool *alreadyExisted) { DescriptorType *TypeDescWriter::type(int16_t*, bool *alreadyExisted) noexcept {
constexpr auto TypeName = "B:int16_t"; constexpr auto TypeName = "B:int16_t";
constexpr auto PT = PrimitiveType::SignedInteger; constexpr auto PT = PrimitiveType::SignedInteger;
constexpr auto Bytes = 2; constexpr auto Bytes = 2;
return getType(TypeName, PT, Bytes, alreadyExisted); return getType(TypeName, PT, Bytes, alreadyExisted);
} }
DescriptorType *TypeDescWriter::type(int32_t*, bool *alreadyExisted) { DescriptorType *TypeDescWriter::type(int32_t*, bool *alreadyExisted) noexcept {
constexpr auto TypeName = "B:int32_t"; constexpr auto TypeName = "B:int32_t";
constexpr auto PT = PrimitiveType::SignedInteger; constexpr auto PT = PrimitiveType::SignedInteger;
constexpr auto Bytes = 4; constexpr auto Bytes = 4;
return getType(TypeName, PT, Bytes, alreadyExisted); return getType(TypeName, PT, Bytes, alreadyExisted);
} }
DescriptorType *TypeDescWriter::type(int64_t*, bool *alreadyExisted) { DescriptorType *TypeDescWriter::type(int64_t*, bool *alreadyExisted) noexcept {
constexpr auto TypeName = "B:int64_t"; constexpr auto TypeName = "B:int64_t";
constexpr auto PT = PrimitiveType::SignedInteger; constexpr auto PT = PrimitiveType::SignedInteger;
constexpr auto Bytes = 8; constexpr auto Bytes = 8;
return getType(TypeName, PT, Bytes, alreadyExisted); return getType(TypeName, PT, Bytes, alreadyExisted);
} }
DescriptorType *TypeDescWriter::type(uint8_t*, bool *alreadyExisted) { DescriptorType *TypeDescWriter::type(uint8_t*, bool *alreadyExisted) noexcept {
constexpr auto TypeName = "B:uint8_t"; constexpr auto TypeName = "B:uint8_t";
constexpr auto PT = PrimitiveType::UnsignedInteger; constexpr auto PT = PrimitiveType::UnsignedInteger;
constexpr auto Bytes = 1; constexpr auto Bytes = 1;
return getType(TypeName, PT, Bytes, alreadyExisted); return getType(TypeName, PT, Bytes, alreadyExisted);
} }
DescriptorType *TypeDescWriter::type(uint16_t*, bool *alreadyExisted) { DescriptorType *TypeDescWriter::type(uint16_t*, bool *alreadyExisted) noexcept {
constexpr auto TypeName = "B:uint16_t"; constexpr auto TypeName = "B:uint16_t";
constexpr auto PT = PrimitiveType::UnsignedInteger; constexpr auto PT = PrimitiveType::UnsignedInteger;
constexpr auto Bytes = 2; constexpr auto Bytes = 2;
return getType(TypeName, PT, Bytes, alreadyExisted); return getType(TypeName, PT, Bytes, alreadyExisted);
} }
DescriptorType *TypeDescWriter::type(uint32_t*, bool *alreadyExisted) { DescriptorType *TypeDescWriter::type(uint32_t*, bool *alreadyExisted) noexcept {
constexpr auto TypeName = "B:uint32_t"; constexpr auto TypeName = "B:uint32_t";
constexpr auto PT = PrimitiveType::UnsignedInteger; constexpr auto PT = PrimitiveType::UnsignedInteger;
constexpr auto Bytes = 4; constexpr auto Bytes = 4;
return getType(TypeName, PT, Bytes, alreadyExisted); return getType(TypeName, PT, Bytes, alreadyExisted);
} }
DescriptorType *TypeDescWriter::type(uint64_t*, bool *alreadyExisted) { DescriptorType *TypeDescWriter::type(uint64_t*, bool *alreadyExisted) noexcept {
constexpr auto TypeName = "B:uint64_t"; constexpr auto TypeName = "B:uint64_t";
constexpr auto PT = PrimitiveType::UnsignedInteger; constexpr auto PT = PrimitiveType::UnsignedInteger;
constexpr auto Bytes = 8; constexpr auto Bytes = 8;
return getType(TypeName, PT, Bytes, alreadyExisted); return getType(TypeName, PT, Bytes, alreadyExisted);
} }
DescriptorType *TypeDescWriter::type(char*, bool *alreadyExisted) { DescriptorType *TypeDescWriter::type(char*, bool *alreadyExisted) noexcept {
constexpr auto TypeName = "B:string"; constexpr auto TypeName = "B:string";
constexpr auto PT = PrimitiveType::String; constexpr auto PT = PrimitiveType::String;
return getType(TypeName, PT, 0, alreadyExisted); return getType(TypeName, PT, 0, alreadyExisted);
} }
DescriptorType *TypeDescWriter::type(SerStr, bool *alreadyExisted) { DescriptorType *TypeDescWriter::type(SerStr, bool *alreadyExisted) noexcept {
constexpr auto TypeName = "B:string"; constexpr auto TypeName = "B:string";
constexpr auto PT = PrimitiveType::String; constexpr auto PT = PrimitiveType::String;
return getType(TypeName, PT, 0, alreadyExisted); return getType(TypeName, PT, 0, alreadyExisted);
} }
DescriptorType *TypeDescWriter::type(String*, bool *alreadyExisted) { DescriptorType *TypeDescWriter::type(String*, bool *alreadyExisted) noexcept {
constexpr auto TypeName = "B:string"; constexpr auto TypeName = "B:string";
constexpr auto PT = PrimitiveType::String; constexpr auto PT = PrimitiveType::String;
return getType(TypeName, PT, 0, alreadyExisted); return getType(TypeName, PT, 0, alreadyExisted);
} }
DescriptorType *TypeDescWriter::type(bool*, bool *alreadyExisted) { DescriptorType *TypeDescWriter::type(bool*, bool *alreadyExisted) noexcept {
constexpr auto TypeName = "B:bool"; constexpr auto TypeName = "B:bool";
constexpr auto PT = PrimitiveType::Bool; constexpr auto PT = PrimitiveType::Bool;
constexpr auto Bytes = 0; constexpr auto Bytes = 0;
return getType(TypeName, PT, Bytes, alreadyExisted); return getType(TypeName, PT, Bytes, alreadyExisted);
} }
DescriptorType *TypeDescWriter::getType(TypeName tn, PrimitiveType pt, int b, bool *alreadyExisted) { DescriptorType *TypeDescWriter::getType(const TypeName &tn, PrimitiveType pt, int b, bool *alreadyExisted) noexcept {
if (m_typeStore->contains(tn)) { if (m_typeStore->contains(tn)) {
*alreadyExisted = true; *alreadyExisted = true;
auto type = m_typeStore->operator[](tn); auto type = m_typeStore->operator[](tn);

View File

@ -10,6 +10,7 @@
#include <ox/std/byteswap.hpp> #include <ox/std/byteswap.hpp>
#include <ox/std/bstring.hpp> #include <ox/std/bstring.hpp>
#include <ox/std/memory.hpp>
#include <ox/std/string.hpp> #include <ox/std/string.hpp>
#include <ox/std/trace.hpp> #include <ox/std/trace.hpp>
#include <ox/std/types.hpp> #include <ox/std/types.hpp>
@ -35,18 +36,18 @@ struct preloadable<T, BoolWrapper<T::Preloadable>> {
static constexpr bool value = T::Preloadable; static constexpr bool value = T::Preloadable;
}; };
}
template<typename T> template<typename T>
static constexpr int indirectionLevels(T) { static constexpr int indirectionLevels(T) noexcept {
return 0; return 0;
} }
template<typename T> template<typename T>
static constexpr int indirectionLevels(T *t) { static constexpr int indirectionLevels(T *t) noexcept {
return 1 + indirectionLevels(*t); return 1 + indirectionLevels(*t);
} }
}
class TypeDescWriter { class TypeDescWriter {
private: private:
@ -69,7 +70,7 @@ class TypeDescWriter {
return OxError(0); return OxError(0);
} }
static constexpr auto opType() { static constexpr auto opType() noexcept {
return OpType::WriteDefinition; return OpType::WriteDefinition;
} }
@ -80,70 +81,70 @@ class TypeDescWriter {
DescriptorType *m_type = nullptr; DescriptorType *m_type = nullptr;
public: public:
explicit TypeDescWriter(TypeStore *typeStore = nullptr); explicit TypeDescWriter(TypeStore *typeStore = nullptr) noexcept;
~TypeDescWriter(); ~TypeDescWriter() noexcept;
template<typename T> template<typename T>
Error field(const char *name, T *val, std::size_t valLen); Error field(const char *name, T *val, std::size_t valLen) noexcept;
template<typename T> template<typename T>
Error field(const char *name, T val); Error field(const char *name, T val) noexcept;
template<typename T> template<typename T>
Error field(const char *name, T *val); Error field(const char *name, T *val) noexcept;
template<typename T = std::nullptr_t> template<typename T = std::nullptr_t>
void setTypeInfo(const char *name = T::TypeName, int fields = T::Fields); void setTypeInfo(const char *name = T::TypeName, int fields = T::Fields) noexcept;
[[nodiscard]] DescriptorType *definition() noexcept { [[nodiscard]] DescriptorType *definition() noexcept {
return m_type; return m_type;
} }
static constexpr auto opType() { static constexpr auto opType() noexcept {
return OpType::WriteDefinition; return OpType::WriteDefinition;
} }
private: private:
DescriptorType *type(int8_t *val, bool *alreadyExisted); DescriptorType *type(int8_t *val, bool *alreadyExisted) noexcept;
DescriptorType *type(int16_t *val, bool *alreadyExisted); DescriptorType *type(int16_t *val, bool *alreadyExisted) noexcept;
DescriptorType *type(int32_t *val, bool *alreadyExisted); DescriptorType *type(int32_t *val, bool *alreadyExisted) noexcept;
DescriptorType *type(int64_t *val, bool *alreadyExisted); DescriptorType *type(int64_t *val, bool *alreadyExisted) noexcept;
DescriptorType *type(uint8_t *val, bool *alreadyExisted); DescriptorType *type(uint8_t *val, bool *alreadyExisted) noexcept;
DescriptorType *type(uint16_t *val, bool *alreadyExisted); DescriptorType *type(uint16_t *val, bool *alreadyExisted) noexcept;
DescriptorType *type(uint32_t *val, bool *alreadyExisted); DescriptorType *type(uint32_t *val, bool *alreadyExisted) noexcept;
DescriptorType *type(uint64_t *val, bool *alreadyExisted); DescriptorType *type(uint64_t *val, bool *alreadyExisted) noexcept;
DescriptorType *type(bool *val, bool *alreadyExisted); DescriptorType *type(bool *val, bool *alreadyExisted) noexcept;
DescriptorType *type(char *val, bool *alreadyExisted); DescriptorType *type(char *val, bool *alreadyExisted) noexcept;
DescriptorType *type(SerStr val, bool *alreadyExisted); DescriptorType *type(SerStr val, bool *alreadyExisted) noexcept;
DescriptorType *type(String *val, bool *alreadyExisted); DescriptorType *type(String *val, bool *alreadyExisted) noexcept;
template<std::size_t sz> template<std::size_t sz>
DescriptorType *type(BString<sz> *val, bool *alreadyExisted); DescriptorType *type(BString<sz> *val, bool *alreadyExisted) noexcept;
template<typename T> template<typename T>
DescriptorType *type(T *val, bool *alreadyExisted); DescriptorType *type(T *val, bool *alreadyExisted) noexcept;
template<typename T> template<typename T>
DescriptorType *type(Vector<T> *val, bool *alreadyExisted); DescriptorType *type(Vector<T> *val, bool *alreadyExisted) noexcept;
template<typename T> template<typename T>
DescriptorType *type(HashMap<String, T> *val, bool *alreadyExisted); DescriptorType *type(HashMap<String, T> *val, bool *alreadyExisted) noexcept;
template<typename U> template<typename U>
DescriptorType *type(UnionView<U> val, bool *alreadyExisted); DescriptorType *type(UnionView<U> val, bool *alreadyExisted) noexcept;
DescriptorType *getType(TypeName tn, PrimitiveType t, int b, bool *alreadyExisted); DescriptorType *getType(const TypeName &tn, PrimitiveType t, int b, bool *alreadyExisted) noexcept;
}; };
// array handler // array handler
template<typename T> template<typename T>
Error TypeDescWriter::field(const char *name, T *val, std::size_t) { Error TypeDescWriter::field(const char *name, T *val, std::size_t) noexcept {
if (m_type) { if (m_type) {
constexpr typename remove_pointer<decltype(val)>::type *p = nullptr; constexpr typename remove_pointer<decltype(val)>::type *p = nullptr;
bool alreadyExisted = false; bool alreadyExisted = false;
@ -152,14 +153,14 @@ Error TypeDescWriter::field(const char *name, T *val, std::size_t) {
if (t == nullptr) { if (t == nullptr) {
type(p, &alreadyExisted); type(p, &alreadyExisted);
} }
m_type->fieldList.emplace_back(t, name, indirectionLevels(val), alreadyExisted ? t->typeName : "", !alreadyExisted); m_type->fieldList.emplace_back(t, name, detail::indirectionLevels(val), alreadyExisted ? t->typeName : "", !alreadyExisted);
return OxError(0); return OxError(0);
} }
return OxError(1); return OxError(1);
} }
template<typename T> template<typename T>
Error TypeDescWriter::field(const char *name, T val) { Error TypeDescWriter::field(const char *name, T val) noexcept {
if (m_type) { if (m_type) {
bool alreadyExisted = false; bool alreadyExisted = false;
const auto t = type(val, &alreadyExisted); const auto t = type(val, &alreadyExisted);
@ -171,7 +172,7 @@ Error TypeDescWriter::field(const char *name, T val) {
} }
template<typename T> template<typename T>
Error TypeDescWriter::field(const char *name, T *val) { Error TypeDescWriter::field(const char *name, T *val) noexcept {
if (m_type) { if (m_type) {
bool alreadyExisted = false; bool alreadyExisted = false;
const auto t = type(val, &alreadyExisted); const auto t = type(val, &alreadyExisted);
@ -183,12 +184,12 @@ Error TypeDescWriter::field(const char *name, T *val) {
} }
template<std::size_t sz> template<std::size_t sz>
DescriptorType *TypeDescWriter::type(BString<sz> *val, bool *alreadyExisted) { DescriptorType *TypeDescWriter::type(BString<sz> *val, bool *alreadyExisted) noexcept {
return type(SerStr(val), alreadyExisted); return type(SerStr(val), alreadyExisted);
} }
template<typename T> template<typename T>
DescriptorType *TypeDescWriter::type(T *val, bool *alreadyExisted) { DescriptorType *TypeDescWriter::type(T *val, bool *alreadyExisted) noexcept {
NameCatcher nc; NameCatcher nc;
oxLogError(model(&nc, val)); oxLogError(model(&nc, val));
if (m_typeStore->contains(nc.name)) { if (m_typeStore->contains(nc.name)) {
@ -203,22 +204,22 @@ DescriptorType *TypeDescWriter::type(T *val, bool *alreadyExisted) {
} }
template<typename T> template<typename T>
DescriptorType *TypeDescWriter::type(Vector<T> *val, bool *alreadyExisted) { DescriptorType *TypeDescWriter::type(Vector<T> *val, bool *alreadyExisted) noexcept {
return type(val->data(), alreadyExisted); return type(val->data(), alreadyExisted);
} }
template<typename T> template<typename T>
DescriptorType *TypeDescWriter::type(HashMap<String, T>*, bool *alreadyExisted) { DescriptorType *TypeDescWriter::type(HashMap<String, T>*, bool *alreadyExisted) noexcept {
return type(static_cast<T*>(nullptr), alreadyExisted); return type(static_cast<T*>(nullptr), alreadyExisted);
} }
template<typename U> template<typename U>
DescriptorType *TypeDescWriter::type(UnionView<U> val, bool *alreadyExisted) { DescriptorType *TypeDescWriter::type(UnionView<U> val, bool *alreadyExisted) noexcept {
return type(val.get(), alreadyExisted); return type(val.get(), alreadyExisted);
} }
template<typename T> template<typename T>
void TypeDescWriter::setTypeInfo(const char *name, int) { void TypeDescWriter::setTypeInfo(const char *name, int) noexcept {
auto &t = m_typeStore->operator[](name); auto &t = m_typeStore->operator[](name);
if (!t) { if (!t) {
t = new DescriptorType; t = new DescriptorType;
@ -234,21 +235,23 @@ void TypeDescWriter::setTypeInfo(const char *name, int) {
} }
template<typename T> template<typename T>
Result<DescriptorType*> buildTypeDef(T *val) { Result<UniquePtr<DescriptorType>> buildTypeDef(T *val) noexcept {
TypeDescWriter writer; TypeDescWriter writer;
oxReturnError(model(&writer, val)); oxReturnError(model(&writer, val));
return writer.definition(); return UniquePtr<DescriptorType>{writer.definition()};
} }
template<typename T> template<typename T>
Error writeTypeDef(uint8_t *buff, std::size_t buffLen, T *val, std::size_t *sizeOut = nullptr) { Error writeTypeDef(uint8_t *buff, std::size_t buffLen, T *val, std::size_t *sizeOut = nullptr) noexcept {
auto def = buildTypeDef(val); oxRequire(def, buildTypeDef(val));
auto err = def.error; return writeType(buff, buffLen, def.get(), sizeOut);
if (!err) { }
oxReturnError(writeType(buff, buffLen, def.value, sizeOut));
} template<typename T>
delete def.value; Result<Buffer> writeTypeDef(T *val) noexcept {
return err; Buffer buff(units::MB);
oxReturnError(writeTypeDef(buff.data(), buff.size(), val));
return move(buff);
} }
} }

View File

@ -23,32 +23,32 @@ namespace OpType {
// empty default implementations of model functions // empty default implementations of model functions
template<typename T, typename O> template<typename T, typename O>
constexpr Error modelRead(T*, O*) { constexpr Error modelRead(T*, O*) noexcept {
return OxError(1, "Model: modelRead not implemented"); return OxError(1, "Model: modelRead not implemented");
} }
template<typename T, typename O> template<typename T, typename O>
constexpr Error modelWrite(T*, O*) { constexpr Error modelWrite(T*, O*) noexcept {
return OxError(1, "Model: modelWrite not implemented"); return OxError(1, "Model: modelWrite not implemented");
} }
template<typename T, typename O> template<typename T, typename O>
constexpr Error modelWriteDefinition(T*, O*) { constexpr Error modelWriteDefinition(T*, O*) noexcept {
return OxError(1, "Model: modelWriteDefinition not implemented"); return OxError(1, "Model: modelWriteDefinition not implemented");
} }
template<typename T, typename O> template<typename T, typename O>
constexpr Error model(T *io, O *obj) { constexpr Error model(T *io, O *obj) noexcept {
Error err;
if constexpr(ox_strcmp(T::opType(), OpType::Read) == 0) { if constexpr(ox_strcmp(T::opType(), OpType::Read) == 0) {
err = modelRead(io, obj); return modelRead(io, obj);
} else if constexpr(ox_strcmp(T::opType(), OpType::Write) == 0) { } else if constexpr(ox_strcmp(T::opType(), OpType::Write) == 0) {
err = modelWrite(io, obj); return modelWrite(io, obj);
} else if constexpr(ox_strcmp(T::opType(), OpType::WriteDefinition) == 0) { } else if constexpr(ox_strcmp(T::opType(), OpType::WriteDefinition) == 0) {
err = modelWriteDefinition(io, obj); return modelWriteDefinition(io, obj);
} else {
oxAssert(OxError(1), "Missing model function");
return OxError(1);
} }
oxAssert(err, "Missing model function");
return err;
} }
} }

View File

@ -17,7 +17,7 @@ namespace ox {
template<typename Reader, typename T> template<typename Reader, typename T>
class DataWalker { class DataWalker {
template<typename ReaderBase, typename FH> template<typename ReaderBase, typename FH>
friend Error parseField(const DescriptorField &field, ReaderBase *rdr, DataWalker<ReaderBase, FH> *walker); friend Error parseField(const DescriptorField &field, ReaderBase *rdr, DataWalker<ReaderBase, FH> *walker) noexcept;
private: private:
Vector<const DescriptorType*> m_typeStack; Vector<const DescriptorType*> m_typeStack;
@ -26,26 +26,25 @@ class DataWalker {
Vector<TypeName> m_typePath; Vector<TypeName> m_typePath;
public: public:
DataWalker(DescriptorType *type, T fieldHandler); DataWalker(DescriptorType *type, T fieldHandler) noexcept;
[[nodiscard]]
Result<const DescriptorType*> type() const noexcept; Result<const DescriptorType*> type() const noexcept;
Error read(const DescriptorField&, Reader *rdr); Error read(const DescriptorField&, Reader *rdr) noexcept;
protected: protected:
void pushNamePath(FieldName fn); void pushNamePath(const FieldName &fn) noexcept;
void popNamePath(); void popNamePath() noexcept;
void pushType(const DescriptorType *type); void pushType(const DescriptorType *type) noexcept;
void popType(); void popType() noexcept;
}; };
template<typename Reader, typename T> template<typename Reader, typename T>
DataWalker<Reader, T>::DataWalker(DescriptorType *type, T fieldHandler): m_fieldHandler(fieldHandler) { DataWalker<Reader, T>::DataWalker(DescriptorType *type, T fieldHandler) noexcept: m_fieldHandler(fieldHandler) {
m_typeStack.push_back(type); m_typeStack.push_back(type);
} }
@ -56,7 +55,7 @@ Result<const DescriptorType*> DataWalker<Reader, T>::type() const noexcept {
} }
template<typename Reader, typename T> template<typename Reader, typename T>
Error DataWalker<Reader, T>::read(const DescriptorField &f, Reader *rdr) { Error DataWalker<Reader, T>::read(const DescriptorField &f, Reader *rdr) noexcept {
// get const ref of paths // get const ref of paths
const auto &pathCr = m_path; const auto &pathCr = m_path;
const auto &typePathCr = m_typePath; const auto &typePathCr = m_typePath;
@ -64,32 +63,31 @@ Error DataWalker<Reader, T>::read(const DescriptorField &f, Reader *rdr) {
} }
template<typename Reader, typename T> template<typename Reader, typename T>
void DataWalker<Reader, T>::pushNamePath(FieldName fn) { void DataWalker<Reader, T>::pushNamePath(const FieldName &fn) noexcept {
m_path.push_back(fn); m_path.push_back(fn);
} }
template<typename Reader, typename T> template<typename Reader, typename T>
void DataWalker<Reader, T>::popNamePath() { void DataWalker<Reader, T>::popNamePath() noexcept {
m_path.pop_back(); m_path.pop_back();
} }
template<typename Reader, typename T> template<typename Reader, typename T>
void DataWalker<Reader, T>::pushType(const DescriptorType *type) { void DataWalker<Reader, T>::pushType(const DescriptorType *type) noexcept {
m_typeStack.push_back(type); m_typeStack.push_back(type);
} }
template<typename Reader, typename T> template<typename Reader, typename T>
void DataWalker<Reader, T>::popType() { void DataWalker<Reader, T>::popType() noexcept {
m_typeStack.pop_back(); m_typeStack.pop_back();
} }
template<typename Reader, typename FH> template<typename Reader, typename FH>
static Error parseField(const DescriptorField &field, Reader *rdr, DataWalker<Reader, FH> *walker) { static Error parseField(const DescriptorField &field, Reader *rdr, DataWalker<Reader, FH> *walker) noexcept {
walker->pushNamePath(field.fieldName); walker->pushNamePath(field.fieldName);
if (field.subscriptLevels) { if (field.subscriptLevels) {
// add array handling // add array handling
const auto [arrayLen, err] = rdr->arrayLength(field.fieldName.c_str(), true); oxRequire(arrayLen, rdr->arrayLength(field.fieldName.c_str(), true));
oxReturnError(err);
auto child = rdr->child(field.fieldName.c_str()); auto child = rdr->child(field.fieldName.c_str());
child.setTypeInfo(field.fieldName.c_str(), arrayLen); child.setTypeInfo(field.fieldName.c_str(), arrayLen);
DescriptorField f(field); // create mutable copy DescriptorField f(field); // create mutable copy
@ -133,19 +131,19 @@ static Error parseField(const DescriptorField &field, Reader *rdr, DataWalker<Re
} }
template<typename Reader, typename FH> template<typename Reader, typename FH>
Error model(Reader *rdr, DataWalker<Reader, FH> *walker) { constexpr Error model(Reader *rdr, DataWalker<Reader, FH> *walker) noexcept {
oxRequire(type, walker->type()); oxRequire(type, walker->type());
auto typeName = type->typeName.c_str(); auto typeName = type->typeName.c_str();
auto &fields = type->fieldList; auto &fields = type->fieldList;
rdr->setTypeInfo(typeName, fields.size()); rdr->setTypeInfo(typeName, fields.size());
for (std::size_t i = 0; i < fields.size(); i++) { for (const auto &field : fields) {
oxReturnError(parseField(fields[i], rdr, walker)); oxReturnError(parseField(field, rdr, walker));
} }
return OxError(0); return OxError(0);
} }
template<typename Reader, typename Handler> template<typename Reader, typename Handler>
Error walkModel(DescriptorType *type, char *data, std::size_t dataLen, Handler handler) { Error walkModel(DescriptorType *type, char *data, std::size_t dataLen, Handler handler) noexcept {
DataWalker<Reader, Handler> walker(type, handler); DataWalker<Reader, Handler> walker(type, handler);
Reader rdr(bit_cast<uint8_t*>(data), dataLen); Reader rdr(bit_cast<uint8_t*>(data), dataLen);
return model(&rdr, &walker); return model(&rdr, &walker);

View File

@ -199,7 +199,7 @@ const std::map<std::string_view, ox::Error(*)()> tests = {
oxAssert(ocErr, "Data generation failed"); oxAssert(ocErr, "Data generation failed");
auto type = ox::buildTypeDef(&testIn); auto type = ox::buildTypeDef(&testIn);
oxAssert(type.error, "Descriptor write failed"); oxAssert(type.error, "Descriptor write failed");
oxReturnError(ox::walkModel<ox::OrganicClawReader>(type.value, oc.data(), oc.size(), oxReturnError(ox::walkModel<ox::OrganicClawReader>(type.value.get(), oc.data(), oc.size(),
[](const ox::Vector<ox::FieldName>&, const ox::Vector<ox::TypeName>&, const ox::DescriptorField &f, ox::OrganicClawReader *rdr) -> ox::Error { [](const ox::Vector<ox::FieldName>&, const ox::Vector<ox::TypeName>&, const ox::DescriptorField &f, ox::OrganicClawReader *rdr) -> ox::Error {
auto fieldName = f.fieldName.c_str(); auto fieldName = f.fieldName.c_str();
switch (f.type->primitiveType) { switch (f.type->primitiveType) {
@ -283,8 +283,6 @@ const std::map<std::string_view, ox::Error(*)()> tests = {
return OxError(0); return OxError(0);
} }
)); ));
delete type.value;
return OxError(0); return OxError(0);
} }
}, },