[ox] Split generalizable portion MC into ser package
This commit is contained in:
parent
fa1cf8bb73
commit
f218ec44af
1
deps/ox/src/ox/CMakeLists.txt
vendored
1
deps/ox/src/ox/CMakeLists.txt
vendored
@ -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)
|
||||
|
10
deps/ox/src/ox/mc/CMakeLists.txt
vendored
10
deps/ox/src/ox/mc/CMakeLists.txt
vendored
@ -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
|
||||
|
34
deps/ox/src/ox/mc/defread.hpp
vendored
34
deps/ox/src/ox/mc/defread.hpp
vendored
@ -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);
|
||||
}
|
||||
|
||||
}
|
5
deps/ox/src/ox/mc/mc.hpp
vendored
5
deps/ox/src/ox/mc/mc.hpp
vendored
@ -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"
|
||||
|
3
deps/ox/src/ox/mc/read.hpp
vendored
3
deps/ox/src/ox/mc/read.hpp
vendored
@ -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"
|
||||
|
||||
|
15
deps/ox/src/ox/mc/test/tests.cpp
vendored
15
deps/ox/src/ox/mc/test/tests.cpp
vendored
@ -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);
|
||||
|
41
deps/ox/src/ox/mc/types.hpp
vendored
41
deps/ox/src/ox/mc/types.hpp
vendored
@ -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
22
deps/ox/src/ox/mc/walk.hpp
vendored
Normal 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);
|
||||
}
|
||||
|
||||
}
|
3
deps/ox/src/ox/mc/write.hpp
vendored
3
deps/ox/src/ox/mc/write.hpp
vendored
@ -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
35
deps/ox/src/ox/ser/CMakeLists.txt
vendored
Normal 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
42
deps/ox/src/ox/ser/descread.hpp
vendored
Normal 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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
@ -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*>;
|
||||
|
||||
}
|
@ -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;
|
@ -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};
|
||||
}
|
@ -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
61
deps/ox/src/ox/ser/types.hpp
vendored
Normal 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;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user