[ox] Split generalizable portion MC into ser package

This commit is contained in:
Gary Talent 2019-03-07 21:47:46 -06:00
parent fa1cf8bb73
commit f218ec44af
20 changed files with 309 additions and 247 deletions

View File

@ -4,4 +4,5 @@ endif(OX_USE_STDLIB STREQUAL "ON")
add_subdirectory(fs)
add_subdirectory(mc)
add_subdirectory(ptrarith)
add_subdirectory(ser)
add_subdirectory(std)

View File

@ -1,8 +1,5 @@
add_library(
OxMetalClaw
defread.cpp
deftypes.cpp
defwriter.cpp
presencemask.cpp
read.cpp
write.cpp
@ -10,6 +7,7 @@ add_library(
target_link_libraries(
OxMetalClaw PUBLIC
OxSerialization
OxStd
)
@ -22,15 +20,11 @@ set_property(
install(
FILES
defread.hpp
deftypes.hpp
defwriter.hpp
err.hpp
optype.hpp
mc.hpp
presencemask.hpp
read.hpp
types.hpp
walker.hpp
write.hpp
DESTINATION
include/ox/mc

View File

@ -1,34 +0,0 @@
/*
* Copyright 2015 - 2018 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "deftypes.hpp"
#include "read.hpp"
namespace ox::mc {
class MetalClawDefReader: public MetalClawReader {
private:
TypeStore m_typeStore;
public:
MetalClawDefReader(uint8_t *buff, std::size_t buffLen);
const mc::TypeStore &typeStore() const;
};
template<typename T>
int readMCDef(uint8_t *buff, std::size_t buffLen, T *val) {
MetalClawDefReader reader(buff, buffLen);
return ioOp(&reader, val);
}
}

View File

@ -8,10 +8,7 @@
#pragma once
#include "defread.hpp"
#include "deftypes.hpp"
#include "defwriter.hpp"
#include "read.hpp"
#include "types.hpp"
#include "walker.hpp"
#include "walk.hpp"
#include "write.hpp"

View File

@ -8,12 +8,13 @@
#pragma once
#include <ox/ser/optype.hpp>
#include <ox/ser/types.hpp>
#include <ox/std/byteswap.hpp>
#include <ox/std/string.hpp>
#include <ox/std/vector.hpp>
#include "err.hpp"
#include "optype.hpp"
#include "presencemask.hpp"
#include "types.hpp"

View File

@ -12,6 +12,7 @@
#include <memory>
#include <string>
#include <ox/mc/mc.hpp>
#include <ox/ser/ser.hpp>
#include <ox/std/std.hpp>
struct TestStructNest {
@ -155,12 +156,12 @@ std::map<std::string, ox::Error(*)()> tests = {
oxAssert(ox::writeMC(dataBuff, dataBuffLen, &testIn), "Data generation failed");
auto type = ox::buildMCDef(&testIn);
oxAssert(type.error, "Descriptor write failed");
ox::walkMC(type.value, dataBuff, dataBuffLen,
[](const ox::Vector<ox::mc::FieldName>&, const ox::Vector<ox::mc::TypeName>&, const ox::mc::Field &f, ox::MetalClawReader *rdr) -> ox::Error {
ox::walkMC<ox::MetalClawReader>(type.value, 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();
switch (f.type->primitiveType) {
case ox::mc::PrimitiveType::UnsignedInteger:
case ox::PrimitiveType::UnsignedInteger:
std::cout << fieldName << ":\tuint" << f.type->length << "_t:\t";
switch (f.type->length) {
case 8: {
@ -190,7 +191,7 @@ std::map<std::string, ox::Error(*)()> tests = {
}
std::cout << '\n';
break;
case ox::mc::PrimitiveType::SignedInteger:
case ox::PrimitiveType::SignedInteger:
std::cout << fieldName << ":\tint" << f.type->length << "_t:\t";
switch (f.type->length) {
case 8: {
@ -220,20 +221,20 @@ std::map<std::string, ox::Error(*)()> tests = {
}
std::cout << '\n';
break;
case ox::mc::PrimitiveType::Bool: {
case ox::PrimitiveType::Bool: {
bool i = {};
oxAssert(rdr->op(fieldName, &i), "Walking ioOp failed.");
std::cout << fieldName << ":\t" << "bool:\t" << (i ? "true" : "false") << '\n';
break;
}
case ox::mc::PrimitiveType::String: {
case ox::PrimitiveType::String: {
ox::Vector<char> v(rdr->stringLength());
//std::cout << rdr->stringLength() << '\n';
oxAssert(rdr->op(fieldName, ox::McStr(v.data(), v.size())), "Walking ioOp failed.");
std::cout << fieldName << ":\t" << "string: " << v.data() << '\n';
break;
}
case ox::mc::PrimitiveType::Struct:
case ox::PrimitiveType::Struct:
break;
}
return OxError(0);

View File

@ -17,45 +17,4 @@ namespace ox {
using StringLength = uint32_t;
using ArrayLength = uint32_t;
class McStr {
protected:
int m_cap = 0;
char *m_str = nullptr;
public:
template<std::size_t sz>
constexpr McStr(BString<sz> *str) noexcept {
m_str = str->data();
m_cap = str->cap();
}
constexpr McStr(char *str, int cap) noexcept {
m_str = str;
m_cap = cap;
}
constexpr const char *c_str() noexcept {
return m_str;
}
constexpr char *data() noexcept {
// do not return a non-const pointer to the const_casted m_str
return m_str;
}
constexpr int len() noexcept {
return ox_strlen(m_str);
}
constexpr int bytes() noexcept {
return ox_strlen(m_str) + 1; // adds 1 for \0
}
constexpr int cap() noexcept {
return m_cap;
}
};
}

22
deps/ox/src/ox/mc/walk.hpp vendored Normal file
View File

@ -0,0 +1,22 @@
/*
* Copyright 2015 - 2018 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include <ox/ser/walk.hpp>
namespace ox {
template<typename Reader, typename Handler>
ox::Error walkMC(DescriptorType *type, uint8_t *data, std::size_t dataLen, Handler handler) {
DataWalker<Reader, Handler> walker(type, handler);
Reader rdr(data, dataLen);
return ioOp(&rdr, &walker);
}
}

View File

@ -8,13 +8,14 @@
#pragma once
#include <ox/ser/optype.hpp>
#include <ox/ser/types.hpp>
#include <ox/std/byteswap.hpp>
#include <ox/std/string.hpp>
#include <ox/std/vector.hpp>
#include <ox/std/types.hpp>
#include "err.hpp"
#include "optype.hpp"
#include "presencemask.hpp"
#include "types.hpp"

35
deps/ox/src/ox/ser/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,35 @@
add_library(
OxSerialization
desctypes.cpp
descwrite.cpp
)
target_link_libraries(
OxSerialization PUBLIC
OxStd
)
set_property(
TARGET
OxSerialization
PROPERTY
POSITION_INDEPENDENT_CODE ON
)
install(
FILES
descread.hpp
desctypes.hpp
descwrite.hpp
optype.hpp
ser.hpp
types.hpp
walk.hpp
DESTINATION
include/ox/ser
)
install(TARGETS OxSerialization
LIBRARY DESTINATION lib/ox
ARCHIVE DESTINATION lib/ox
)

42
deps/ox/src/ox/ser/descread.hpp vendored Normal file
View File

@ -0,0 +1,42 @@
/*
* Copyright 2015 - 2018 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "desctypes.hpp"
namespace ox {
template<typename ReaderBase>
class TypeDescReader: public ReaderBase {
private:
TypeStore m_typeStore;
public:
TypeDescReader(uint8_t *buff, std::size_t buffLen);
const TypeStore &typeStore() const;
};
template<typename ReaderBase>
TypeDescReader<ReaderBase>::TypeDescReader(uint8_t *buff, std::size_t buffLen): ReaderBase(buff, buffLen) {
}
template<typename ReaderBase>
const TypeStore &TypeDescReader<ReaderBase>::typeStore() const {
return m_typeStore;
}
template<typename ReaderBase, typename T>
int readMCDef(uint8_t *buff, std::size_t buffLen, T *val) {
TypeDescReader<ReaderBase> reader(buff, buffLen);
return ioOp(&reader, val);
}
}

View File

@ -6,11 +6,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "deftypes.hpp"
#include "desctypes.hpp"
namespace ox::mc {
namespace ox {
Field::~Field() {
DescriptorField::~DescriptorField() {
if (ownsType) {
delete type;
}

View File

@ -12,7 +12,7 @@
#include <ox/std/string.hpp>
#include <ox/std/vector.hpp>
namespace ox::mc {
namespace ox {
using String = BString<100>;
using FieldName = String;
@ -27,11 +27,11 @@ enum class PrimitiveType: uint8_t {
Struct = 5,
};
struct Field {
struct DescriptorField {
// order of fields matters
// only serialize type name if type has already been serialized
const struct Type *type = nullptr;
const struct DescriptorType *type = nullptr;
FieldName fieldName;
int subscriptLevels = 0;
@ -39,12 +39,12 @@ struct Field {
TypeName typeName; // gives reference to type for lookup if type is null
bool ownsType = false;
constexpr Field() noexcept = default;
constexpr DescriptorField() noexcept = default;
/**
* Allow for explicit copying.
*/
constexpr explicit Field(const Field &other) noexcept {
constexpr explicit DescriptorField(const DescriptorField &other) noexcept {
type = other.type;
fieldName = other.fieldName;
subscriptLevels = other.subscriptLevels;
@ -52,7 +52,7 @@ struct Field {
ownsType = false; // is copy, only owns type if move
}
constexpr Field(const Type *type, const FieldName &fieldName, int subscriptLevels, const TypeName &typeName, bool ownsType) noexcept {
constexpr DescriptorField(const DescriptorType *type, const FieldName &fieldName, int subscriptLevels, const TypeName &typeName, bool ownsType) noexcept {
this->type = type;
this->fieldName = fieldName;
this->subscriptLevels = subscriptLevels;
@ -60,7 +60,7 @@ struct Field {
this->ownsType = ownsType;
}
constexpr Field(Field &&other) noexcept {
constexpr DescriptorField(DescriptorField &&other) noexcept {
type = other.type;
fieldName = other.fieldName;
subscriptLevels = other.subscriptLevels;
@ -74,9 +74,9 @@ struct Field {
other.ownsType = {};
}
~Field();
~DescriptorField();
constexpr const Field &operator=(Field &&other) noexcept {
constexpr const DescriptorField &operator=(DescriptorField &&other) noexcept {
type = other.type;
fieldName = other.fieldName;
subscriptLevels = other.subscriptLevels;
@ -94,9 +94,9 @@ struct Field {
};
using FieldList = Vector<Field>;
using FieldList = Vector<DescriptorField>;
struct Type {
struct DescriptorType {
TypeName typeName;
PrimitiveType primitiveType;
// fieldList only applies to structs
@ -105,20 +105,20 @@ struct Type {
// - number of fields for structs and lists
int64_t length = 0;
Type() = default;
DescriptorType() = default;
Type(TypeName tn, PrimitiveType t, int b): typeName(tn), primitiveType(t), length(b) {
DescriptorType(TypeName tn, PrimitiveType t, int b): typeName(tn), primitiveType(t), length(b) {
}
Type(TypeName tn, PrimitiveType t, FieldList fl): typeName(tn), primitiveType(t), fieldList(fl) {
DescriptorType(TypeName tn, PrimitiveType t, FieldList fl): typeName(tn), primitiveType(t), fieldList(fl) {
}
};
template<typename T>
int ioOp(T *io, Type *type) {
int ioOp(T *io, DescriptorType *type) {
int32_t err = 0;
io->setTypeInfo("ox::mc::Type", 4);
io->setTypeInfo("ox::DescriptorType", 4);
err |= io->op("typeName", &type->typeName);
err |= io->op("primitiveType", &type->primitiveType);
err |= io->op("fieldList", &type->fieldList);
@ -127,9 +127,9 @@ int ioOp(T *io, Type *type) {
}
template<typename T>
int ioOpWrite(T *io, Field *field) {
int ioOpWrite(T *io, DescriptorField *field) {
int32_t err = 0;
io->setTypeInfo("ox::mc::Field", 4);
io->setTypeInfo("ox::DescriptorField", 4);
if (field->ownsType) {
err |= io->op("typeName", "");
err |= io->op("type", field->type);
@ -145,21 +145,21 @@ int ioOpWrite(T *io, Field *field) {
}
template<typename T>
int ioOpRead(T *io, Field *field) {
int ioOpRead(T *io, DescriptorField *field) {
int32_t err = 0;
auto &typeStore = io->typeStore();
io->setTypeInfo("ox::mc::Field", 4);
io->setTypeInfo("ox::DescriptorField", 4);
err |= io->op("typeName", &field->typeName);
if (field->typeName == "") {
field->ownsType = true;
if (field->type == nullptr) {
field->type = new Type;
field->type = new DescriptorType;
}
err |= io->op("type", field->type);
typeStore[field->type->typeName] = field->type;
} else {
// should be empty, so discard
Type t;
DescriptorType t;
err |= io->op("type", &t);
field->type = typeStore[field->typeName];
}
@ -169,6 +169,6 @@ int ioOpRead(T *io, Field *field) {
return err;
}
using TypeStore = ox::HashMap<mc::String, mc::Type*>;
using TypeStore = ox::HashMap<String, DescriptorType*>;
}

View File

@ -8,7 +8,7 @@
#include <ox/std/typeinfo.hpp>
#include "defwriter.hpp"
#include "descwrite.hpp"
namespace ox {
@ -33,115 +33,115 @@ static_assert([] {
}(), "indirectionLevels broken: indirectionLevels(int[][])");
MetalClawDefWriter::MetalClawDefWriter(mc::TypeStore *typeStore) {
TypeDescWriter::TypeDescWriter(TypeStore *typeStore) {
if (!typeStore) {
m_typeStoreOwnerRef = new mc::TypeStore;
m_typeStoreOwnerRef = new TypeStore;
typeStore = m_typeStoreOwnerRef;
}
m_typeStore = typeStore;
}
MetalClawDefWriter::~MetalClawDefWriter() {
TypeDescWriter::~TypeDescWriter() {
// does not own it's elements
delete m_typeStoreOwnerRef;
}
mc::Type *MetalClawDefWriter::type(int8_t*, bool *alreadyExisted) {
DescriptorType *TypeDescWriter::type(int8_t*, bool *alreadyExisted) {
constexpr auto TypeName = "B:int8_t";
constexpr auto PT = mc::PrimitiveType::SignedInteger;
constexpr auto PT = PrimitiveType::SignedInteger;
constexpr auto Bytes = 8;
return getType(TypeName, PT, Bytes, alreadyExisted);
}
mc::Type *MetalClawDefWriter::type(int16_t*, bool *alreadyExisted) {
DescriptorType *TypeDescWriter::type(int16_t*, bool *alreadyExisted) {
constexpr auto TypeName = "B:int16_t";
constexpr auto PT = mc::PrimitiveType::SignedInteger;
constexpr auto PT = PrimitiveType::SignedInteger;
constexpr auto Bytes = 16;
return getType(TypeName, PT, Bytes, alreadyExisted);
}
mc::Type *MetalClawDefWriter::type(int32_t*, bool *alreadyExisted) {
DescriptorType *TypeDescWriter::type(int32_t*, bool *alreadyExisted) {
constexpr auto TypeName = "B:int32_t";
constexpr auto PT = mc::PrimitiveType::SignedInteger;
constexpr auto PT = PrimitiveType::SignedInteger;
constexpr auto Bytes = 32;
return getType(TypeName, PT, Bytes, alreadyExisted);
}
mc::Type *MetalClawDefWriter::type(int64_t*, bool *alreadyExisted) {
DescriptorType *TypeDescWriter::type(int64_t*, bool *alreadyExisted) {
constexpr auto TypeName = "B:int64_t";
constexpr auto PT = mc::PrimitiveType::SignedInteger;
constexpr auto PT = PrimitiveType::SignedInteger;
constexpr auto Bytes = 64;
return getType(TypeName, PT, Bytes, alreadyExisted);
}
mc::Type *MetalClawDefWriter::type(uint8_t*, bool *alreadyExisted) {
DescriptorType *TypeDescWriter::type(uint8_t*, bool *alreadyExisted) {
constexpr auto TypeName = "B:uint8_t";
constexpr auto PT = mc::PrimitiveType::UnsignedInteger;
constexpr auto PT = PrimitiveType::UnsignedInteger;
constexpr auto Bytes = 8;
return getType(TypeName, PT, Bytes, alreadyExisted);
}
mc::Type *MetalClawDefWriter::type(uint16_t*, bool *alreadyExisted) {
DescriptorType *TypeDescWriter::type(uint16_t*, bool *alreadyExisted) {
constexpr auto TypeName = "B:uint16_t";
constexpr auto PT = mc::PrimitiveType::UnsignedInteger;
constexpr auto PT = PrimitiveType::UnsignedInteger;
constexpr auto Bytes = 16;
return getType(TypeName, PT, Bytes, alreadyExisted);
}
mc::Type *MetalClawDefWriter::type(uint32_t*, bool *alreadyExisted) {
DescriptorType *TypeDescWriter::type(uint32_t*, bool *alreadyExisted) {
constexpr auto TypeName = "B:uint32_t";
constexpr auto PT = mc::PrimitiveType::UnsignedInteger;
constexpr auto PT = PrimitiveType::UnsignedInteger;
constexpr auto Bytes = 32;
return getType(TypeName, PT, Bytes, alreadyExisted);
}
mc::Type *MetalClawDefWriter::type(uint64_t*, bool *alreadyExisted) {
DescriptorType *TypeDescWriter::type(uint64_t*, bool *alreadyExisted) {
constexpr auto TypeName = "B:uint64_t";
constexpr auto PT = mc::PrimitiveType::UnsignedInteger;
constexpr auto PT = PrimitiveType::UnsignedInteger;
constexpr auto Bytes = 64;
return getType(TypeName, PT, Bytes, alreadyExisted);
}
mc::Type *MetalClawDefWriter::type(const char*, bool *alreadyExisted) {
DescriptorType *TypeDescWriter::type(const char*, bool *alreadyExisted) {
constexpr auto TypeName = "B:string";
constexpr auto PT = mc::PrimitiveType::String;
constexpr auto PT = PrimitiveType::String;
return getType(TypeName, PT, 0, alreadyExisted);
}
mc::Type *MetalClawDefWriter::type(McStr, bool *alreadyExisted) {
DescriptorType *TypeDescWriter::type(McStr, bool *alreadyExisted) {
constexpr auto TypeName = "B:string";
constexpr auto PT = mc::PrimitiveType::String;
constexpr auto PT = PrimitiveType::String;
return getType(TypeName, PT, 0, alreadyExisted);
}
mc::Type *MetalClawDefWriter::type(bool*, bool *alreadyExisted) {
DescriptorType *TypeDescWriter::type(bool*, bool *alreadyExisted) {
constexpr auto TypeName = "B:bool";
constexpr auto PT = mc::PrimitiveType::Bool;
constexpr auto PT = PrimitiveType::Bool;
constexpr auto Bytes = 0;
return getType(TypeName, PT, Bytes, alreadyExisted);
}
void MetalClawDefWriter::setTypeInfo(const char *name, int) {
void TypeDescWriter::setTypeInfo(const char *name, int) {
auto &t = m_typeStore->at(name);
if (!t) {
t = new mc::Type;
t = new DescriptorType;
}
m_type = t;
m_type->typeName = name;
m_type->primitiveType = mc::PrimitiveType::Struct;
m_type->primitiveType = PrimitiveType::Struct;
}
mc::Type *MetalClawDefWriter::getType(mc::TypeName tn, mc::PrimitiveType pt, int b, bool *alreadyExisted) {
DescriptorType *TypeDescWriter::getType(TypeName tn, PrimitiveType pt, int b, bool *alreadyExisted) {
if (m_typeStore->contains(tn)) {
*alreadyExisted = true;
auto type = m_typeStore->at(tn);
oxAssert(type != nullptr, "MetalClawDefWriter::getType returning null Type");
oxAssert(type != nullptr, "TypeDescWriter::getType returning null DescriptorType");
return type;
} else {
*alreadyExisted = false;
auto &t = m_typeStore->at(tn);
if (!t) {
t = new mc::Type;
t = new DescriptorType;
}
t->typeName = tn;
t->primitiveType = pt;

View File

@ -15,11 +15,9 @@
#include <ox/std/types.hpp>
#include <ox/std/vector.hpp>
#include "deftypes.hpp"
#include "err.hpp"
#include "desctypes.hpp"
#include "optype.hpp"
#include "types.hpp"
#include "write.hpp"
namespace ox {
@ -33,12 +31,12 @@ static constexpr int indirectionLevels(T *t) {
return 1 + indirectionLevels(*t);
}
class MetalClawDefWriter {
class TypeDescWriter {
private:
struct NameCatcher {
mc::TypeName name;
TypeName name;
constexpr void setTypeInfo(const char *name, int) noexcept {
this->name = name;
@ -56,14 +54,14 @@ class MetalClawDefWriter {
};
mc::TypeStore *m_typeStoreOwnerRef = nullptr;
mc::TypeStore *m_typeStore = nullptr;
mc::Type *m_type = nullptr;
TypeStore *m_typeStoreOwnerRef = nullptr;
TypeStore *m_typeStore = nullptr;
DescriptorType *m_type = nullptr;
public:
explicit MetalClawDefWriter(mc::TypeStore *typeStore = nullptr);
explicit TypeDescWriter(TypeStore *typeStore = nullptr);
~MetalClawDefWriter();
~TypeDescWriter();
template<typename T>
ox::Error op(const char *name, T *val, std::size_t valLen);
@ -76,7 +74,7 @@ class MetalClawDefWriter {
void setTypeInfo(const char *name, int fields);
[[nodiscard]] mc::Type *definition() noexcept {
[[nodiscard]] DescriptorType *definition() noexcept {
return m_type;
}
@ -85,34 +83,34 @@ class MetalClawDefWriter {
}
private:
mc::Type *type(int8_t *val, bool *alreadyExisted);
mc::Type *type(int16_t *val, bool *alreadyExisted);
mc::Type *type(int32_t *val, bool *alreadyExisted);
mc::Type *type(int64_t *val, bool *alreadyExisted);
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);
mc::Type *type(uint8_t *val, bool *alreadyExisted);
mc::Type *type(uint16_t *val, bool *alreadyExisted);
mc::Type *type(uint32_t *val, bool *alreadyExisted);
mc::Type *type(uint64_t *val, bool *alreadyExisted);
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);
mc::Type *type(bool *val, bool *alreadyExisted);
DescriptorType *type(bool *val, bool *alreadyExisted);
mc::Type *type(const char *val, bool *alreadyExisted);
DescriptorType *type(const char *val, bool *alreadyExisted);
mc::Type *type(McStr val, bool *alreadyExisted);
DescriptorType *type(McStr val, bool *alreadyExisted);
template<std::size_t sz>
mc::Type *type(BString<sz> *val, bool *alreadyExisted);
DescriptorType *type(BString<sz> *val, bool *alreadyExisted);
template<typename T>
mc::Type *type(T *val, bool *alreadyExisted);
DescriptorType *type(T *val, bool *alreadyExisted);
mc::Type *getType(mc::TypeName tn, mc::PrimitiveType t, int b, bool *alreadyExisted);
DescriptorType *getType(TypeName tn, PrimitiveType t, int b, bool *alreadyExisted);
};
// array handler
template<typename T>
ox::Error MetalClawDefWriter::op(const char *name, T *val, std::size_t) {
ox::Error TypeDescWriter::op(const char *name, T *val, std::size_t) {
if (m_type) {
constexpr typename ox::remove_pointer<decltype(val)>::type *p = nullptr;
bool alreadyExisted = false;
@ -128,12 +126,12 @@ ox::Error MetalClawDefWriter::op(const char *name, T *val, std::size_t) {
}
template<typename T>
ox::Error MetalClawDefWriter::op(const char *name, ox::Vector<T> *val) {
ox::Error TypeDescWriter::op(const char *name, ox::Vector<T> *val) {
return op(name, val->data(), val->size());
}
template<typename T>
ox::Error MetalClawDefWriter::op(const char *name, T *val) {
ox::Error TypeDescWriter::op(const char *name, T *val) {
if (m_type) {
bool alreadyExisted = false;
const auto t = type(val, &alreadyExisted);
@ -145,19 +143,19 @@ ox::Error MetalClawDefWriter::op(const char *name, T *val) {
}
template<std::size_t sz>
mc::Type *MetalClawDefWriter::type(BString<sz> *val, bool *alreadyExisted) {
DescriptorType *TypeDescWriter::type(BString<sz> *val, bool *alreadyExisted) {
return type(McStr(val), alreadyExisted);
}
template<typename T>
mc::Type *MetalClawDefWriter::type(T *val, bool *alreadyExisted) {
DescriptorType *TypeDescWriter::type(T *val, bool *alreadyExisted) {
NameCatcher nc;
ioOp(&nc, val);
if (m_typeStore->contains(nc.name)) {
*alreadyExisted = true;
return m_typeStore->at(nc.name);
} else {
MetalClawDefWriter dw(m_typeStore);
TypeDescWriter dw(m_typeStore);
oxLogError(ioOp(&dw, val));
*alreadyExisted = false;
return dw.m_type;
@ -165,8 +163,8 @@ mc::Type *MetalClawDefWriter::type(T *val, bool *alreadyExisted) {
}
template<typename T>
[[nodiscard]] ValErr<mc::Type*> buildMCDef(T *val) {
MetalClawDefWriter writer;
[[nodiscard]] ValErr<DescriptorType*> buildMCDef(T *val) {
TypeDescWriter writer;
Error err = ioOp(&writer, val);
return {writer.definition(), err};
}

View File

@ -6,15 +6,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "defread.hpp"
#pragma once
namespace ox::mc {
MetalClawDefReader::MetalClawDefReader(uint8_t *buff, std::size_t buffLen): MetalClawReader(buff, buffLen) {
}
const mc::TypeStore &MetalClawDefReader::typeStore() const {
return m_typeStore;
}
}
#include "descread.hpp"
#include "desctypes.hpp"
#include "descwrite.hpp"
#include "types.hpp"
#include "walk.hpp"

61
deps/ox/src/ox/ser/types.hpp vendored Normal file
View File

@ -0,0 +1,61 @@
/*
* Copyright 2015 - 2018 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include <ox/std/string.hpp>
#include <ox/std/strops.hpp>
#include <ox/std/types.hpp>
namespace ox {
using StringLength = uint32_t;
using ArrayLength = uint32_t;
class McStr {
protected:
int m_cap = 0;
char *m_str = nullptr;
public:
template<std::size_t sz>
constexpr McStr(BString<sz> *str) noexcept {
m_str = str->data();
m_cap = str->cap();
}
constexpr McStr(char *str, int cap) noexcept {
m_str = str;
m_cap = cap;
}
constexpr const char *c_str() noexcept {
return m_str;
}
constexpr char *data() noexcept {
// do not return a non-const pointer to the const_casted m_str
return m_str;
}
constexpr int len() noexcept {
return ox_strlen(m_str);
}
constexpr int bytes() noexcept {
return ox_strlen(m_str) + 1; // adds 1 for \0
}
constexpr int cap() noexcept {
return m_cap;
}
};
}

View File

@ -10,90 +10,86 @@
#include <ox/std/error.hpp>
#include "deftypes.hpp"
#include "read.hpp"
#include "desctypes.hpp"
namespace ox {
template<typename T>
class MetalClawWalker {
template<typename FH>
friend ox::Error ioOp(class MetalClawReader*, MetalClawWalker<FH>*);
template<typename FH>
friend ox::Error parseField(const mc::Field &field, MetalClawReader *rdr, MetalClawWalker<FH> *walker);
template<typename Reader, typename T>
class DataWalker {
template<typename ReaderBase, typename FH>
friend ox::Error parseField(const DescriptorField &field, ReaderBase *rdr, DataWalker<ReaderBase, FH> *walker);
private:
Vector<const mc::Type*> m_typeStack;
Vector<const DescriptorType*> m_typeStack;
T m_fieldHandler;
Vector<mc::FieldName> m_path;
Vector<mc::TypeName> m_typePath;
Vector<FieldName> m_path;
Vector<TypeName> m_typePath;
public:
MetalClawWalker(mc::Type *type, T fieldHandler);
DataWalker(DescriptorType *type, T fieldHandler);
[[nodiscard]] const mc::Type *type() const noexcept;
[[nodiscard]] const DescriptorType *type() const noexcept;
ox::Error read(const mc::Field&, MetalClawReader *rdr);
ox::Error read(const DescriptorField&, Reader *rdr);
protected:
void pushNamePath(mc::FieldName fn);
void pushNamePath(FieldName fn);
void popNamePath();
void pushType(const mc::Type *type);
void pushType(const DescriptorType *type);
void popType();
};
template<typename T>
MetalClawWalker<T>::MetalClawWalker(mc::Type *type, T fieldHandler): m_fieldHandler(fieldHandler) {
template<typename Reader, typename T>
DataWalker<Reader, T>::DataWalker(DescriptorType *type, T fieldHandler): m_fieldHandler(fieldHandler) {
m_typeStack.push_back(type);
}
template<typename T>
const mc::Type *MetalClawWalker<T>::type() const noexcept {
template<typename Reader, typename T>
const DescriptorType *DataWalker<Reader, T>::type() const noexcept {
return m_typeStack.back();
}
template<typename T>
ox::Error MetalClawWalker<T>::read(const mc::Field &f, MetalClawReader *rdr) {
template<typename Reader, typename T>
ox::Error DataWalker<Reader, T>::read(const DescriptorField &f, Reader *rdr) {
// get const ref of paths
const auto &pathCr = m_path;
const auto &typePathCr = m_typePath;
return m_fieldHandler(pathCr, typePathCr, f, rdr);
}
template<typename T>
void MetalClawWalker<T>::pushNamePath(mc::FieldName fn) {
template<typename Reader, typename T>
void DataWalker<Reader, T>::pushNamePath(FieldName fn) {
m_path.push_back(fn);
}
template<typename T>
void MetalClawWalker<T>::popNamePath() {
template<typename Reader, typename T>
void DataWalker<Reader, T>::popNamePath() {
m_path.pop_back();
}
template<typename T>
void MetalClawWalker<T>::pushType(const mc::Type *type) {
template<typename Reader, typename T>
void DataWalker<Reader, T>::pushType(const DescriptorType *type) {
m_typeStack.push_back(type);
}
template<typename T>
void MetalClawWalker<T>::popType() {
template<typename Reader, typename T>
void DataWalker<Reader, T>::popType() {
m_typeStack.pop_back();
}
template<typename FH>
static ox::Error parseField(const mc::Field &field, MetalClawReader *rdr, MetalClawWalker<FH> *walker) {
template<typename Reader, typename FH>
static ox::Error parseField(const DescriptorField &field, Reader *rdr, DataWalker<Reader, FH> *walker) {
walker->pushNamePath(field.fieldName);
if (field.subscriptLevels) {
// add array handling
const auto arrayLen = rdr->arrayLength(true);
auto child = rdr->child();
child.setTypeInfo(field.fieldName.c_str(), arrayLen);
mc::Field f(field); // create mutable copy
DescriptorField f(field); // create mutable copy
--f.subscriptLevels;
BString<100> subscript;
for (ArrayLength i = 0; i < arrayLen; i++) {
@ -107,13 +103,13 @@ static ox::Error parseField(const mc::Field &field, MetalClawReader *rdr, MetalC
rdr->nextField();
} else {
switch (field.type->primitiveType) {
case mc::PrimitiveType::UnsignedInteger:
case mc::PrimitiveType::SignedInteger:
case mc::PrimitiveType::Bool:
case mc::PrimitiveType::String:
case PrimitiveType::UnsignedInteger:
case PrimitiveType::SignedInteger:
case PrimitiveType::Bool:
case PrimitiveType::String:
oxReturnError(walker->read(field, rdr));
break;
case mc::PrimitiveType::Struct:
case PrimitiveType::Struct:
if (rdr->fieldPresent()) {
auto child = rdr->child();
walker->pushType(field.type);
@ -132,8 +128,8 @@ static ox::Error parseField(const mc::Field &field, MetalClawReader *rdr, MetalC
return OxError(0);
}
template<typename FH>
ox::Error ioOp(MetalClawReader *rdr, MetalClawWalker<FH> *walker) {
template<typename Reader, typename FH>
ox::Error ioOp(Reader *rdr, DataWalker<Reader, FH> *walker) {
auto type = walker->type();
if (!type) {
return OxError(1);
@ -143,18 +139,11 @@ ox::Error ioOp(MetalClawReader *rdr, MetalClawWalker<FH> *walker) {
rdr->setTypeInfo(typeName, fields.size());
for (std::size_t i = 0; i < fields.size(); i++) {
auto &field = fields[i];
if (field.type->primitiveType == mc::PrimitiveType::Struct) {
if (field.type->primitiveType == PrimitiveType::Struct) {
}
oxReturnError(parseField(field, rdr, walker));
}
return OxError(0);
}
template<typename Handler>
ox::Error walkMC(mc::Type *type, uint8_t *data, std::size_t dataLen, Handler handler) {
MetalClawWalker walker(type, handler);
MetalClawReader rdr(data, dataLen);
return ioOp(&rdr, &walker);
}
}