[ox] Overhaul serialization/model system and add ModelValue/ModelObject/ModelUnion variant system

This commit is contained in:
2022-06-21 21:43:49 -05:00
parent bc391b45fc
commit ca64f95be3
47 changed files with 2696 additions and 973 deletions

View File

@@ -3,7 +3,7 @@
*
* 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/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include <ox/std/buffer.hpp>
@@ -72,4 +72,34 @@ Result<Buffer> stripClawHeader(const ox::Buffer &buff) noexcept {
return stripClawHeader(buff.data(), buff.size());
}
Result<ModelObject> readClaw(TypeStore *ts, const Buffer &buff) noexcept {
oxRequire(header, readClawHeader(buff));
oxRequire(t, ts->template getLoad(header.typeName, header.typeVersion));
ModelObject obj;
oxReturnError(obj.setType(t));
switch (header.fmt) {
case ClawFormat::Metal:
{
MetalClawReader reader(reinterpret_cast<const uint8_t*>(header.data), header.dataSize);
ModelHandlerInterface handler(&reader);
oxReturnError(model(&handler, &obj));
return obj;
}
case ClawFormat::Organic:
{
#ifdef OX_USE_STDLIB
OrganicClawReader reader(header.data, header.dataSize);
ModelHandlerInterface handler(&reader);
oxReturnError(model(&handler, &obj));
return obj;
#else
break;
#endif
}
case ClawFormat::None:
return OxError(1);
}
return OxError(1);
}
}

View File

@@ -3,7 +3,7 @@
*
* 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/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
@@ -50,13 +50,14 @@ Error readClaw(const char *buff, std::size_t buffLen, T *val) {
switch (header.fmt) {
case ClawFormat::Metal:
{
MetalClawReader reader(reinterpret_cast<const uint8_t*>(header.data), buffLen);
return model(&reader, val);
MetalClawReader reader(reinterpret_cast<const uint8_t*>(header.data), header.dataSize);
ModelHandlerInterface handler(&reader);
return model(&handler, val);
}
case ClawFormat::Organic:
{
#ifdef OX_USE_STDLIB
OrganicClawReader reader(header.data, buffLen);
OrganicClawReader reader(header.data, header.dataSize);
return model(&reader, val);
#else
break;
@@ -85,4 +86,6 @@ Result<T> readClaw(const Buffer &buff) {
return readClaw<T>(buff.data(), buff.size());
}
Result<ModelObject> readClaw(TypeStore *ts, const Buffer &buff) noexcept;
}

View File

@@ -3,7 +3,7 @@
*
* 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/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#undef NDEBUG
@@ -25,7 +25,7 @@ union TestUnion {
static constexpr auto TypeVersion = 1;
bool Bool;
uint32_t Int = 5;
char String[32];
char *String;
};
struct TestStructNest {
@@ -49,6 +49,7 @@ struct TestStruct {
int32_t Int6 = 0;
int32_t Int7 = 0;
int32_t Int8 = 0;
int unionIdx = 1;
TestUnion Union;
ox::BString<32> String = "";
uint32_t List[4] = {0, 0, 0, 0};
@@ -56,21 +57,24 @@ struct TestStruct {
TestStructNest Struct;
~TestStruct() {
if (unionIdx == 2) {
ox::safeDelete(Union.String);
}
}
};
template<typename T>
constexpr ox::Error model(T *io, TestUnion *obj) {
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestUnion> auto *obj) {
io->template setTypeInfo<TestUnion>();
oxReturnError(io->field("Bool", &obj->Bool));
oxReturnError(io->field("Int", &obj->Int));
oxReturnError(io->field("String", ox::SerStr(obj->String)));
oxReturnError(io->fieldCString("String", &obj->String));
return OxError(0);
}
template<typename T>
constexpr ox::Error model(T *io, TestStructNest *obj) {
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStructNest> auto *obj) {
io->template setTypeInfo<TestStructNest>();
oxReturnError(io->field("Bool", &obj->Bool));
oxReturnError(io->field("Int", &obj->Int));
@@ -79,7 +83,7 @@ constexpr ox::Error model(T *io, TestStructNest *obj) {
}
template<typename T>
constexpr ox::Error model(T *io, TestStruct *obj) {
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStruct> auto *obj) {
io->template setTypeInfo<TestStruct>();
oxReturnError(io->field("Bool", &obj->Bool));
oxReturnError(io->field("Int", &obj->Int));
@@ -91,7 +95,11 @@ constexpr ox::Error model(T *io, TestStruct *obj) {
oxReturnError(io->field("Int6", &obj->Int6));
oxReturnError(io->field("Int7", &obj->Int7));
oxReturnError(io->field("Int8", &obj->Int8));
oxReturnError(io->field("Union", ox::UnionView{&obj->Union, 1}));
int unionIdx = 0;
if constexpr(ox_strcmp(T::opType(), ox::OpType::Reflect) != 0) {
unionIdx = obj->unionIdx;
}
oxReturnError(io->field("Union", ox::UnionView{&obj->Union, unionIdx}));
oxReturnError(io->field("String", &obj->String));
oxReturnError(io->field("List", obj->List, 4));
oxReturnError(io->field("EmptyStruct", &obj->EmptyStruct));
@@ -99,7 +107,7 @@ constexpr ox::Error model(T *io, TestStruct *obj) {
return OxError(0);
}
std::map<std::string_view, ox::Error(*)()> tests = {
static std::map<std::string_view, ox::Error(*)()> tests = {
{
{
"ClawHeaderReader",
@@ -153,7 +161,7 @@ std::map<std::string_view, ox::Error(*)()> tests = {
auto [buff, err] = ox::writeClaw(&testIn, ox::ClawFormat::Metal);
oxAssert(err, "writeMC failed");
oxAssert(ox::readClaw(buff.data(), buff.size(), &testOut), "writeMC failed");
oxAssert(ox::readClaw(buff.data(), buff.size(), &testOut), "readMC failed");
//std::cout << testIn.Union.Int << "|" << testOut.Union.Int << "|\n";
oxAssert(testIn.Bool == testOut.Bool, "Bool value mismatch");

View File

@@ -82,8 +82,7 @@ Result<String> writeClawHeader(T *t, ClawFormat fmt) noexcept {
}
template<typename T>
Result<Buffer> writeClaw(T *t, ClawFormat fmt = ClawFormat::Metal) {
Result<Buffer> writeClaw(auto *t, ClawFormat fmt = ClawFormat::Metal) {
oxRequire(header, detail::writeClawHeader(t, fmt));
oxRequire(data, fmt == ClawFormat::Metal ? writeMC(t) : writeOC(t));
Buffer out(header.len() + data.size());