[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");
auto type = ox::buildTypeDef(&testIn);
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 {
//std::cout << f.fieldName.c_str() << '\n';
auto fieldName = f.fieldName.c_str();
@ -385,7 +385,6 @@ std::map<std::string, ox::Error(*)()> tests = {
return OxError(0);
}
));
delete type.value;
return OxError(0);
}
},

View File

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

View File

@ -18,23 +18,23 @@ class TypeDescReader: public ReaderBase {
TypeStore m_typeStore;
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>
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>
const TypeStore &TypeDescReader<ReaderBase>::typeStore() const {
const TypeStore &TypeDescReader<ReaderBase>::typeStore() const noexcept {
return m_typeStore;
}
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);
return model(&reader, val);
}

View File

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

View File

@ -34,20 +34,20 @@ static_assert(!preloadable<non_preloadable_type2>::value);
static_assert([] {
int i = 0;
return indirectionLevels(i) == 0;
return detail::indirectionLevels(i) == 0;
}(), "indirectionLevels broken: indirectionLevels(int)");
static_assert([] {
int i = 0;
return indirectionLevels(&i) == 1;
return detail::indirectionLevels(&i) == 1;
}(), "indirectionLevels broken: indirectionLevels(int*)");
static_assert([] {
int i[2] = {};
return indirectionLevels(i) == 1;
return detail::indirectionLevels(i) == 1;
}(), "indirectionLevels broken: indirectionLevels(int[])");
TypeDescWriter::TypeDescWriter(TypeStore *typeStore) {
TypeDescWriter::TypeDescWriter(TypeStore *typeStore) noexcept {
if (!typeStore) {
m_typeStoreOwnerRef = new TypeStore;
typeStore = m_typeStoreOwnerRef;
@ -55,93 +55,93 @@ TypeDescWriter::TypeDescWriter(TypeStore *typeStore) {
m_typeStore = typeStore;
}
TypeDescWriter::~TypeDescWriter() {
TypeDescWriter::~TypeDescWriter() noexcept {
// does not own it's elements
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 PT = PrimitiveType::SignedInteger;
constexpr auto Bytes = 1;
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 PT = PrimitiveType::SignedInteger;
constexpr auto Bytes = 2;
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 PT = PrimitiveType::SignedInteger;
constexpr auto Bytes = 4;
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 PT = PrimitiveType::SignedInteger;
constexpr auto Bytes = 8;
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 PT = PrimitiveType::UnsignedInteger;
constexpr auto Bytes = 1;
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 PT = PrimitiveType::UnsignedInteger;
constexpr auto Bytes = 2;
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 PT = PrimitiveType::UnsignedInteger;
constexpr auto Bytes = 4;
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 PT = PrimitiveType::UnsignedInteger;
constexpr auto Bytes = 8;
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 PT = PrimitiveType::String;
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 PT = PrimitiveType::String;
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 PT = PrimitiveType::String;
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 PT = PrimitiveType::Bool;
constexpr auto Bytes = 0;
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)) {
*alreadyExisted = true;
auto type = m_typeStore->operator[](tn);

View File

@ -10,6 +10,7 @@
#include <ox/std/byteswap.hpp>
#include <ox/std/bstring.hpp>
#include <ox/std/memory.hpp>
#include <ox/std/string.hpp>
#include <ox/std/trace.hpp>
#include <ox/std/types.hpp>
@ -35,18 +36,18 @@ struct preloadable<T, BoolWrapper<T::Preloadable>> {
static constexpr bool value = T::Preloadable;
};
}
template<typename T>
static constexpr int indirectionLevels(T) {
static constexpr int indirectionLevels(T) noexcept {
return 0;
}
template<typename T>
static constexpr int indirectionLevels(T *t) {
static constexpr int indirectionLevels(T *t) noexcept {
return 1 + indirectionLevels(*t);
}
}
class TypeDescWriter {
private:
@ -69,7 +70,7 @@ class TypeDescWriter {
return OxError(0);
}
static constexpr auto opType() {
static constexpr auto opType() noexcept {
return OpType::WriteDefinition;
}
@ -80,70 +81,70 @@ class TypeDescWriter {
DescriptorType *m_type = nullptr;
public:
explicit TypeDescWriter(TypeStore *typeStore = nullptr);
explicit TypeDescWriter(TypeStore *typeStore = nullptr) noexcept;
~TypeDescWriter();
~TypeDescWriter() noexcept;
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>
Error field(const char *name, T val);
Error field(const char *name, T val) noexcept;
template<typename T>
Error field(const char *name, T *val);
Error field(const char *name, T *val) noexcept;
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 {
return m_type;
}
static constexpr auto opType() {
static constexpr auto opType() noexcept {
return OpType::WriteDefinition;
}
private:
DescriptorType *type(int8_t *val, bool *alreadyExisted);
DescriptorType *type(int16_t *val, bool *alreadyExisted);
DescriptorType *type(int32_t *val, bool *alreadyExisted);
DescriptorType *type(int64_t *val, bool *alreadyExisted);
DescriptorType *type(int8_t *val, bool *alreadyExisted) noexcept;
DescriptorType *type(int16_t *val, bool *alreadyExisted) noexcept;
DescriptorType *type(int32_t *val, bool *alreadyExisted) noexcept;
DescriptorType *type(int64_t *val, bool *alreadyExisted) noexcept;
DescriptorType *type(uint8_t *val, bool *alreadyExisted);
DescriptorType *type(uint16_t *val, bool *alreadyExisted);
DescriptorType *type(uint32_t *val, bool *alreadyExisted);
DescriptorType *type(uint64_t *val, bool *alreadyExisted);
DescriptorType *type(uint8_t *val, bool *alreadyExisted) noexcept;
DescriptorType *type(uint16_t *val, bool *alreadyExisted) noexcept;
DescriptorType *type(uint32_t *val, bool *alreadyExisted) noexcept;
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>
DescriptorType *type(BString<sz> *val, bool *alreadyExisted);
DescriptorType *type(BString<sz> *val, bool *alreadyExisted) noexcept;
template<typename T>
DescriptorType *type(T *val, bool *alreadyExisted);
DescriptorType *type(T *val, bool *alreadyExisted) noexcept;
template<typename T>
DescriptorType *type(Vector<T> *val, bool *alreadyExisted);
DescriptorType *type(Vector<T> *val, bool *alreadyExisted) noexcept;
template<typename T>
DescriptorType *type(HashMap<String, T> *val, bool *alreadyExisted);
DescriptorType *type(HashMap<String, T> *val, bool *alreadyExisted) noexcept;
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
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) {
constexpr typename remove_pointer<decltype(val)>::type *p = nullptr;
bool alreadyExisted = false;
@ -152,14 +153,14 @@ Error TypeDescWriter::field(const char *name, T *val, std::size_t) {
if (t == nullptr) {
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(1);
}
template<typename T>
Error TypeDescWriter::field(const char *name, T val) {
Error TypeDescWriter::field(const char *name, T val) noexcept {
if (m_type) {
bool alreadyExisted = false;
const auto t = type(val, &alreadyExisted);
@ -171,7 +172,7 @@ Error TypeDescWriter::field(const char *name, T val) {
}
template<typename T>
Error TypeDescWriter::field(const char *name, T *val) {
Error TypeDescWriter::field(const char *name, T *val) noexcept {
if (m_type) {
bool alreadyExisted = false;
const auto t = type(val, &alreadyExisted);
@ -183,12 +184,12 @@ Error TypeDescWriter::field(const char *name, T *val) {
}
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);
}
template<typename T>
DescriptorType *TypeDescWriter::type(T *val, bool *alreadyExisted) {
DescriptorType *TypeDescWriter::type(T *val, bool *alreadyExisted) noexcept {
NameCatcher nc;
oxLogError(model(&nc, val));
if (m_typeStore->contains(nc.name)) {
@ -203,22 +204,22 @@ DescriptorType *TypeDescWriter::type(T *val, bool *alreadyExisted) {
}
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);
}
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);
}
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);
}
template<typename T>
void TypeDescWriter::setTypeInfo(const char *name, int) {
void TypeDescWriter::setTypeInfo(const char *name, int) noexcept {
auto &t = m_typeStore->operator[](name);
if (!t) {
t = new DescriptorType;
@ -234,21 +235,23 @@ void TypeDescWriter::setTypeInfo(const char *name, int) {
}
template<typename T>
Result<DescriptorType*> buildTypeDef(T *val) {
Result<UniquePtr<DescriptorType>> buildTypeDef(T *val) noexcept {
TypeDescWriter writer;
oxReturnError(model(&writer, val));
return writer.definition();
return UniquePtr<DescriptorType>{writer.definition()};
}
template<typename T>
Error writeTypeDef(uint8_t *buff, std::size_t buffLen, T *val, std::size_t *sizeOut = nullptr) {
auto def = buildTypeDef(val);
auto err = def.error;
if (!err) {
oxReturnError(writeType(buff, buffLen, def.value, sizeOut));
}
delete def.value;
return err;
Error writeTypeDef(uint8_t *buff, std::size_t buffLen, T *val, std::size_t *sizeOut = nullptr) noexcept {
oxRequire(def, buildTypeDef(val));
return writeType(buff, buffLen, def.get(), sizeOut);
}
template<typename T>
Result<Buffer> writeTypeDef(T *val) noexcept {
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
template<typename T, typename O>
constexpr Error modelRead(T*, O*) {
constexpr Error modelRead(T*, O*) noexcept {
return OxError(1, "Model: modelRead not implemented");
}
template<typename T, typename O>
constexpr Error modelWrite(T*, O*) {
constexpr Error modelWrite(T*, O*) noexcept {
return OxError(1, "Model: modelWrite not implemented");
}
template<typename T, typename O>
constexpr Error modelWriteDefinition(T*, O*) {
constexpr Error modelWriteDefinition(T*, O*) noexcept {
return OxError(1, "Model: modelWriteDefinition not implemented");
}
template<typename T, typename O>
constexpr Error model(T *io, O *obj) {
Error err;
constexpr Error model(T *io, O *obj) noexcept {
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) {
err = modelWrite(io, obj);
return modelWrite(io, obj);
} 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>
class DataWalker {
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:
Vector<const DescriptorType*> m_typeStack;
@ -26,26 +26,25 @@ class DataWalker {
Vector<TypeName> m_typePath;
public:
DataWalker(DescriptorType *type, T fieldHandler);
DataWalker(DescriptorType *type, T fieldHandler) noexcept;
[[nodiscard]]
Result<const DescriptorType*> type() const noexcept;
Error read(const DescriptorField&, Reader *rdr);
Error read(const DescriptorField&, Reader *rdr) noexcept;
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>
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);
}
@ -56,7 +55,7 @@ Result<const DescriptorType*> DataWalker<Reader, T>::type() const noexcept {
}
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
const auto &pathCr = m_path;
const auto &typePathCr = m_typePath;
@ -64,32 +63,31 @@ Error DataWalker<Reader, T>::read(const DescriptorField &f, Reader *rdr) {
}
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);
}
template<typename Reader, typename T>
void DataWalker<Reader, T>::popNamePath() {
void DataWalker<Reader, T>::popNamePath() noexcept {
m_path.pop_back();
}
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);
}
template<typename Reader, typename T>
void DataWalker<Reader, T>::popType() {
void DataWalker<Reader, T>::popType() noexcept {
m_typeStack.pop_back();
}
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);
if (field.subscriptLevels) {
// add array handling
const auto [arrayLen, err] = rdr->arrayLength(field.fieldName.c_str(), true);
oxReturnError(err);
oxRequire(arrayLen, rdr->arrayLength(field.fieldName.c_str(), true));
auto child = rdr->child(field.fieldName.c_str());
child.setTypeInfo(field.fieldName.c_str(), arrayLen);
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>
Error model(Reader *rdr, DataWalker<Reader, FH> *walker) {
constexpr Error model(Reader *rdr, DataWalker<Reader, FH> *walker) noexcept {
oxRequire(type, walker->type());
auto typeName = type->typeName.c_str();
auto &fields = type->fieldList;
rdr->setTypeInfo(typeName, fields.size());
for (std::size_t i = 0; i < fields.size(); i++) {
oxReturnError(parseField(fields[i], rdr, walker));
for (const auto &field : fields) {
oxReturnError(parseField(field, rdr, walker));
}
return OxError(0);
}
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);
Reader rdr(bit_cast<uint8_t*>(data), dataLen);
return model(&rdr, &walker);

View File

@ -199,7 +199,7 @@ const std::map<std::string_view, ox::Error(*)()> tests = {
oxAssert(ocErr, "Data generation failed");
auto type = ox::buildTypeDef(&testIn);
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 {
auto fieldName = f.fieldName.c_str();
switch (f.type->primitiveType) {
@ -283,8 +283,6 @@ const std::map<std::string_view, ox::Error(*)()> tests = {
return OxError(0);
}
));
delete type.value;
return OxError(0);
}
},