[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(fs)
add_subdirectory(mc) add_subdirectory(mc)
add_subdirectory(ptrarith) add_subdirectory(ptrarith)
add_subdirectory(ser)
add_subdirectory(std) add_subdirectory(std)

View File

@ -1,8 +1,5 @@
add_library( add_library(
OxMetalClaw OxMetalClaw
defread.cpp
deftypes.cpp
defwriter.cpp
presencemask.cpp presencemask.cpp
read.cpp read.cpp
write.cpp write.cpp
@ -10,6 +7,7 @@ add_library(
target_link_libraries( target_link_libraries(
OxMetalClaw PUBLIC OxMetalClaw PUBLIC
OxSerialization
OxStd OxStd
) )
@ -22,15 +20,11 @@ set_property(
install( install(
FILES FILES
defread.hpp
deftypes.hpp
defwriter.hpp
err.hpp err.hpp
optype.hpp mc.hpp
presencemask.hpp presencemask.hpp
read.hpp read.hpp
types.hpp types.hpp
walker.hpp
write.hpp write.hpp
DESTINATION DESTINATION
include/ox/mc 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 #pragma once
#include "defread.hpp"
#include "deftypes.hpp"
#include "defwriter.hpp"
#include "read.hpp" #include "read.hpp"
#include "types.hpp" #include "types.hpp"
#include "walker.hpp" #include "walk.hpp"
#include "write.hpp" #include "write.hpp"

View File

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

View File

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

View File

@ -17,45 +17,4 @@ namespace ox {
using StringLength = uint32_t; using StringLength = uint32_t;
using ArrayLength = 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 #pragma once
#include <ox/ser/optype.hpp>
#include <ox/ser/types.hpp>
#include <ox/std/byteswap.hpp> #include <ox/std/byteswap.hpp>
#include <ox/std/string.hpp> #include <ox/std/string.hpp>
#include <ox/std/vector.hpp> #include <ox/std/vector.hpp>
#include <ox/std/types.hpp> #include <ox/std/types.hpp>
#include "err.hpp" #include "err.hpp"
#include "optype.hpp"
#include "presencemask.hpp" #include "presencemask.hpp"
#include "types.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/. * 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) { if (ownsType) {
delete type; delete type;
} }

View File

@ -12,7 +12,7 @@
#include <ox/std/string.hpp> #include <ox/std/string.hpp>
#include <ox/std/vector.hpp> #include <ox/std/vector.hpp>
namespace ox::mc { namespace ox {
using String = BString<100>; using String = BString<100>;
using FieldName = String; using FieldName = String;
@ -27,11 +27,11 @@ enum class PrimitiveType: uint8_t {
Struct = 5, Struct = 5,
}; };
struct Field { struct DescriptorField {
// order of fields matters // order of fields matters
// only serialize type name if type has already been serialized // only serialize type name if type has already been serialized
const struct Type *type = nullptr; const struct DescriptorType *type = nullptr;
FieldName fieldName; FieldName fieldName;
int subscriptLevels = 0; int subscriptLevels = 0;
@ -39,12 +39,12 @@ struct Field {
TypeName typeName; // gives reference to type for lookup if type is null TypeName typeName; // gives reference to type for lookup if type is null
bool ownsType = false; bool ownsType = false;
constexpr Field() noexcept = default; constexpr DescriptorField() noexcept = default;
/** /**
* Allow for explicit copying. * Allow for explicit copying.
*/ */
constexpr explicit Field(const Field &other) noexcept { constexpr explicit DescriptorField(const DescriptorField &other) noexcept {
type = other.type; type = other.type;
fieldName = other.fieldName; fieldName = other.fieldName;
subscriptLevels = other.subscriptLevels; subscriptLevels = other.subscriptLevels;
@ -52,7 +52,7 @@ struct Field {
ownsType = false; // is copy, only owns type if move 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->type = type;
this->fieldName = fieldName; this->fieldName = fieldName;
this->subscriptLevels = subscriptLevels; this->subscriptLevels = subscriptLevels;
@ -60,7 +60,7 @@ struct Field {
this->ownsType = ownsType; this->ownsType = ownsType;
} }
constexpr Field(Field &&other) noexcept { constexpr DescriptorField(DescriptorField &&other) noexcept {
type = other.type; type = other.type;
fieldName = other.fieldName; fieldName = other.fieldName;
subscriptLevels = other.subscriptLevels; subscriptLevels = other.subscriptLevels;
@ -74,9 +74,9 @@ struct Field {
other.ownsType = {}; other.ownsType = {};
} }
~Field(); ~DescriptorField();
constexpr const Field &operator=(Field &&other) noexcept { constexpr const DescriptorField &operator=(DescriptorField &&other) noexcept {
type = other.type; type = other.type;
fieldName = other.fieldName; fieldName = other.fieldName;
subscriptLevels = other.subscriptLevels; subscriptLevels = other.subscriptLevels;
@ -94,9 +94,9 @@ struct Field {
}; };
using FieldList = Vector<Field>; using FieldList = Vector<DescriptorField>;
struct Type { struct DescriptorType {
TypeName typeName; TypeName typeName;
PrimitiveType primitiveType; PrimitiveType primitiveType;
// fieldList only applies to structs // fieldList only applies to structs
@ -105,20 +105,20 @@ struct Type {
// - number of fields for structs and lists // - number of fields for structs and lists
int64_t length = 0; 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> template<typename T>
int ioOp(T *io, Type *type) { int ioOp(T *io, DescriptorType *type) {
int32_t err = 0; int32_t err = 0;
io->setTypeInfo("ox::mc::Type", 4); io->setTypeInfo("ox::DescriptorType", 4);
err |= io->op("typeName", &type->typeName); err |= io->op("typeName", &type->typeName);
err |= io->op("primitiveType", &type->primitiveType); err |= io->op("primitiveType", &type->primitiveType);
err |= io->op("fieldList", &type->fieldList); err |= io->op("fieldList", &type->fieldList);
@ -127,9 +127,9 @@ int ioOp(T *io, Type *type) {
} }
template<typename T> template<typename T>
int ioOpWrite(T *io, Field *field) { int ioOpWrite(T *io, DescriptorField *field) {
int32_t err = 0; int32_t err = 0;
io->setTypeInfo("ox::mc::Field", 4); io->setTypeInfo("ox::DescriptorField", 4);
if (field->ownsType) { if (field->ownsType) {
err |= io->op("typeName", ""); err |= io->op("typeName", "");
err |= io->op("type", field->type); err |= io->op("type", field->type);
@ -145,21 +145,21 @@ int ioOpWrite(T *io, Field *field) {
} }
template<typename T> template<typename T>
int ioOpRead(T *io, Field *field) { int ioOpRead(T *io, DescriptorField *field) {
int32_t err = 0; int32_t err = 0;
auto &typeStore = io->typeStore(); auto &typeStore = io->typeStore();
io->setTypeInfo("ox::mc::Field", 4); io->setTypeInfo("ox::DescriptorField", 4);
err |= io->op("typeName", &field->typeName); err |= io->op("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 Type; field->type = new DescriptorType;
} }
err |= io->op("type", field->type); err |= io->op("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
Type t; DescriptorType t;
err |= io->op("type", &t); err |= io->op("type", &t);
field->type = typeStore[field->typeName]; field->type = typeStore[field->typeName];
} }
@ -169,6 +169,6 @@ int ioOpRead(T *io, Field *field) {
return err; 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 <ox/std/typeinfo.hpp>
#include "defwriter.hpp" #include "descwrite.hpp"
namespace ox { namespace ox {
@ -33,115 +33,115 @@ static_assert([] {
}(), "indirectionLevels broken: indirectionLevels(int[][])"); }(), "indirectionLevels broken: indirectionLevels(int[][])");
MetalClawDefWriter::MetalClawDefWriter(mc::TypeStore *typeStore) { TypeDescWriter::TypeDescWriter(TypeStore *typeStore) {
if (!typeStore) { if (!typeStore) {
m_typeStoreOwnerRef = new mc::TypeStore; m_typeStoreOwnerRef = new TypeStore;
typeStore = m_typeStoreOwnerRef; typeStore = m_typeStoreOwnerRef;
} }
m_typeStore = typeStore; m_typeStore = typeStore;
} }
MetalClawDefWriter::~MetalClawDefWriter() { TypeDescWriter::~TypeDescWriter() {
// does not own it's elements // does not own it's elements
delete m_typeStoreOwnerRef; 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 TypeName = "B:int8_t";
constexpr auto PT = mc::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);
} }
mc::Type *MetalClawDefWriter::type(int16_t*, bool *alreadyExisted) { DescriptorType *TypeDescWriter::type(int16_t*, bool *alreadyExisted) {
constexpr auto TypeName = "B:int16_t"; constexpr auto TypeName = "B:int16_t";
constexpr auto PT = mc::PrimitiveType::SignedInteger; constexpr auto PT = PrimitiveType::SignedInteger;
constexpr auto Bytes = 16; constexpr auto Bytes = 16;
return getType(TypeName, PT, Bytes, alreadyExisted); 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 TypeName = "B:int32_t";
constexpr auto PT = mc::PrimitiveType::SignedInteger; constexpr auto PT = PrimitiveType::SignedInteger;
constexpr auto Bytes = 32; constexpr auto Bytes = 32;
return getType(TypeName, PT, Bytes, alreadyExisted); 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 TypeName = "B:int64_t";
constexpr auto PT = mc::PrimitiveType::SignedInteger; constexpr auto PT = PrimitiveType::SignedInteger;
constexpr auto Bytes = 64; constexpr auto Bytes = 64;
return getType(TypeName, PT, Bytes, alreadyExisted); 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 TypeName = "B:uint8_t";
constexpr auto PT = mc::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);
} }
mc::Type *MetalClawDefWriter::type(uint16_t*, bool *alreadyExisted) { DescriptorType *TypeDescWriter::type(uint16_t*, bool *alreadyExisted) {
constexpr auto TypeName = "B:uint16_t"; constexpr auto TypeName = "B:uint16_t";
constexpr auto PT = mc::PrimitiveType::UnsignedInteger; constexpr auto PT = PrimitiveType::UnsignedInteger;
constexpr auto Bytes = 16; constexpr auto Bytes = 16;
return getType(TypeName, PT, Bytes, alreadyExisted); 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 TypeName = "B:uint32_t";
constexpr auto PT = mc::PrimitiveType::UnsignedInteger; constexpr auto PT = PrimitiveType::UnsignedInteger;
constexpr auto Bytes = 32; constexpr auto Bytes = 32;
return getType(TypeName, PT, Bytes, alreadyExisted); 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 TypeName = "B:uint64_t";
constexpr auto PT = mc::PrimitiveType::UnsignedInteger; constexpr auto PT = PrimitiveType::UnsignedInteger;
constexpr auto Bytes = 64; constexpr auto Bytes = 64;
return getType(TypeName, PT, Bytes, alreadyExisted); 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 TypeName = "B:string";
constexpr auto PT = mc::PrimitiveType::String; constexpr auto PT = PrimitiveType::String;
return getType(TypeName, PT, 0, alreadyExisted); 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 TypeName = "B:string";
constexpr auto PT = mc::PrimitiveType::String; constexpr auto PT = PrimitiveType::String;
return getType(TypeName, PT, 0, alreadyExisted); 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 TypeName = "B:bool";
constexpr auto PT = mc::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);
} }
void MetalClawDefWriter::setTypeInfo(const char *name, int) { void TypeDescWriter::setTypeInfo(const char *name, int) {
auto &t = m_typeStore->at(name); auto &t = m_typeStore->at(name);
if (!t) { if (!t) {
t = new mc::Type; t = new DescriptorType;
} }
m_type = t; m_type = t;
m_type->typeName = name; 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)) { if (m_typeStore->contains(tn)) {
*alreadyExisted = true; *alreadyExisted = true;
auto type = m_typeStore->at(tn); auto type = m_typeStore->at(tn);
oxAssert(type != nullptr, "MetalClawDefWriter::getType returning null Type"); oxAssert(type != nullptr, "TypeDescWriter::getType returning null DescriptorType");
return type; return type;
} else { } else {
*alreadyExisted = false; *alreadyExisted = false;
auto &t = m_typeStore->at(tn); auto &t = m_typeStore->at(tn);
if (!t) { if (!t) {
t = new mc::Type; t = new DescriptorType;
} }
t->typeName = tn; t->typeName = tn;
t->primitiveType = pt; t->primitiveType = pt;

View File

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

View File

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

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