[ox] Overhaul serialization/model system and add ModelValue/ModelObject/ModelUnion variant system
This commit is contained in:
108
deps/ox/src/ox/oc/read.cpp
vendored
108
deps/ox/src/ox/oc/read.cpp
vendored
@@ -3,10 +3,11 @@
|
||||
*
|
||||
* 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/bit.hpp>
|
||||
#include <utility>
|
||||
|
||||
#include "read.hpp"
|
||||
|
||||
@@ -18,7 +19,7 @@ OrganicClawReader::OrganicClawReader(const uint8_t *buff, std::size_t buffSize)
|
||||
Json::CharReaderBuilder parserBuilder;
|
||||
auto parser = std::unique_ptr<Json::CharReader>(parserBuilder.newCharReader());
|
||||
if (!parser->parse(json, json + jsonLen, &m_json, nullptr)) {
|
||||
throw OxError(1, "Could not parse JSON");
|
||||
throw OxException(1, "Could not parse JSON");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,12 +27,12 @@ OrganicClawReader::OrganicClawReader(const char *json, std::size_t jsonLen) {
|
||||
Json::CharReaderBuilder parserBuilder;
|
||||
auto parser = std::unique_ptr<Json::CharReader>(parserBuilder.newCharReader());
|
||||
if (!parser->parse(json, json + jsonLen, &m_json, nullptr)) {
|
||||
throw OxError(1, "Could not parse JSON");
|
||||
throw OxException(1, "Could not parse JSON");
|
||||
}
|
||||
}
|
||||
|
||||
OrganicClawReader::OrganicClawReader(const Json::Value &json, int unionIdx) noexcept:
|
||||
m_json(json),
|
||||
OrganicClawReader::OrganicClawReader(Json::Value json, int unionIdx) noexcept:
|
||||
m_json(std::move(json)),
|
||||
m_unionIdx(unionIdx) {
|
||||
}
|
||||
|
||||
@@ -208,6 +209,87 @@ Error OrganicClawReader::field(const char *key, SerStr val) noexcept {
|
||||
return err;
|
||||
}
|
||||
|
||||
Error OrganicClawReader::fieldCString(const char *key, char *val, std::size_t buffLen) noexcept {
|
||||
auto err = OxError(0);
|
||||
const char *begin = nullptr, *end = nullptr;
|
||||
const auto &jv = value(key);
|
||||
if (targetValid()) {
|
||||
if (jv.empty()) {
|
||||
auto data = val;
|
||||
if (data) {
|
||||
data[0] = 0;
|
||||
}
|
||||
} else if (jv.isString()) {
|
||||
jv.getString(&begin, &end);
|
||||
const auto strSize = static_cast<std::size_t>(end - begin);
|
||||
auto data = val;
|
||||
if (strSize >= buffLen) {
|
||||
err = OxError(2, "String size exceeds capacity of destination");
|
||||
} else {
|
||||
ox_memcpy(data, begin, static_cast<std::size_t>(strSize));
|
||||
data[strSize] = 0;
|
||||
}
|
||||
} else {
|
||||
err = OxError(1, "Type mismatch");
|
||||
}
|
||||
}
|
||||
++m_fieldIt;
|
||||
return err;
|
||||
}
|
||||
|
||||
Error OrganicClawReader::fieldCString(const char *key, char **val) noexcept {
|
||||
auto err = OxError(0);
|
||||
const char *begin = nullptr, *end = nullptr;
|
||||
const auto &jv = value(key);
|
||||
auto &data = *val;
|
||||
if (targetValid()) {
|
||||
if (jv.empty()) {
|
||||
if (data) {
|
||||
data[0] = 0;
|
||||
}
|
||||
} else if (jv.isString()) {
|
||||
jv.getString(&begin, &end);
|
||||
const auto strSize = static_cast<std::size_t>(end - begin);
|
||||
safeDelete(*val);
|
||||
*val = new char[strSize + 1];
|
||||
ox_memcpy(data, begin, static_cast<std::size_t>(strSize));
|
||||
data[strSize] = 0;
|
||||
} else {
|
||||
err = OxError(1, "Type mismatch");
|
||||
}
|
||||
}
|
||||
++m_fieldIt;
|
||||
return err;
|
||||
}
|
||||
|
||||
Error OrganicClawReader::fieldCString(const char *key, char **val, std::size_t buffLen) noexcept {
|
||||
auto err = OxError(0);
|
||||
const char *begin = nullptr, *end = nullptr;
|
||||
const auto &jv = value(key);
|
||||
if (targetValid()) {
|
||||
if (jv.empty()) {
|
||||
auto data = val;
|
||||
if (data) {
|
||||
data[0] = 0;
|
||||
}
|
||||
} else if (jv.isString()) {
|
||||
jv.getString(&begin, &end);
|
||||
const auto strSize = static_cast<std::size_t>(end - begin);
|
||||
auto data = val;
|
||||
if (strSize >= buffLen) {
|
||||
safeDelete(*val);
|
||||
*val = new char[strSize + 1];
|
||||
}
|
||||
ox_memcpy(data, begin, static_cast<std::size_t>(strSize));
|
||||
data[strSize] = 0;
|
||||
} else {
|
||||
err = OxError(1, "Type mismatch");
|
||||
}
|
||||
}
|
||||
++m_fieldIt;
|
||||
return err;
|
||||
}
|
||||
|
||||
Result<std::size_t> OrganicClawReader::arrayLength(const char *key, bool) noexcept {
|
||||
const auto &jv = value(key);
|
||||
if (jv.empty()) {
|
||||
@@ -234,13 +316,25 @@ std::size_t OrganicClawReader::stringLength(const char *key) noexcept {
|
||||
}
|
||||
|
||||
OrganicClawReader OrganicClawReader::child(const char *key, int unionIdx) noexcept {
|
||||
return OrganicClawReader(m_json[key], unionIdx);
|
||||
return OrganicClawReader(value(key), unionIdx);
|
||||
}
|
||||
|
||||
bool OrganicClawReader::fieldPresent(const char *key) noexcept {
|
||||
return !m_json[key].empty();
|
||||
}
|
||||
|
||||
int OrganicClawReader::whichFieldPresent(const char *name, const ModelUnion &u) const noexcept {
|
||||
const auto &obj = m_json[name];
|
||||
if (!obj.isObject()) {
|
||||
return -1;
|
||||
}
|
||||
const auto &keys = obj.getMemberNames();
|
||||
if (keys.size() != 1) {
|
||||
return -1;
|
||||
}
|
||||
return u.getKeyIdx(keys.front().c_str());
|
||||
}
|
||||
|
||||
Json::Value &OrganicClawReader::value(const char *key) noexcept {
|
||||
if (m_json.isArray()) {
|
||||
return m_json[m_fieldIt];
|
||||
@@ -249,7 +343,7 @@ Json::Value &OrganicClawReader::value(const char *key) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
bool OrganicClawReader::targetValid() noexcept {
|
||||
bool OrganicClawReader::targetValid() const noexcept {
|
||||
return static_cast<int>(m_fieldIt) == m_unionIdx || m_unionIdx == -1;
|
||||
}
|
||||
|
||||
|
58
deps/ox/src/ox/oc/read.hpp
vendored
58
deps/ox/src/ox/oc/read.hpp
vendored
@@ -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
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <json/json.h>
|
||||
|
||||
#include <ox/model/fieldcounter.hpp>
|
||||
#include <ox/model/modelhandleradaptor.hpp>
|
||||
#include <ox/model/optype.hpp>
|
||||
#include <ox/model/typenamecatcher.hpp>
|
||||
#include <ox/model/types.hpp>
|
||||
@@ -37,7 +38,7 @@ class OrganicClawReader {
|
||||
|
||||
OrganicClawReader(const char *json, std::size_t buffSize);
|
||||
|
||||
explicit OrganicClawReader(const Json::Value &json, int unionIdx = -1) noexcept;
|
||||
explicit OrganicClawReader(Json::Value json, int unionIdx = -1) noexcept;
|
||||
|
||||
Error field(const char *key, int8_t *val) noexcept;
|
||||
Error field(const char *key, int16_t *val) noexcept;
|
||||
@@ -61,8 +62,8 @@ class OrganicClawReader {
|
||||
template<typename T>
|
||||
Error field(const char *key, T *val) noexcept;
|
||||
|
||||
template<typename U>
|
||||
Error field(const char *key, UnionView<U> val) noexcept;
|
||||
template<typename U, bool force = false>
|
||||
Error field(const char *key, UnionView<U, force> val) noexcept;
|
||||
|
||||
template<std::size_t L>
|
||||
Error field(const char *key, BasicString<L> *val) noexcept;
|
||||
@@ -72,6 +73,12 @@ class OrganicClawReader {
|
||||
|
||||
Error field(const char *key, SerStr val) noexcept;
|
||||
|
||||
Error fieldCString(const char *key, char *val, std::size_t buffLen) noexcept;
|
||||
|
||||
Error fieldCString(const char *key, char **val) noexcept;
|
||||
|
||||
Error fieldCString(const char *key, char **val, std::size_t buffLen) noexcept;
|
||||
|
||||
/**
|
||||
* Reads an array length from the current location in the buffer.
|
||||
* @param pass indicates that the parsing should iterate past the array length
|
||||
@@ -109,16 +116,23 @@ class OrganicClawReader {
|
||||
// compatibility stub
|
||||
constexpr void nextField() noexcept {}
|
||||
|
||||
[[nodiscard]]
|
||||
bool fieldPresent(const char *key) noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
int whichFieldPresent(const char *name, const ModelUnion &u) const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr auto opType() noexcept {
|
||||
return OpType::Read;
|
||||
}
|
||||
|
||||
private:
|
||||
[[nodiscard]]
|
||||
Json::Value &value(const char *key) noexcept;
|
||||
|
||||
bool targetValid() noexcept;
|
||||
[[nodiscard]]
|
||||
bool targetValid() const noexcept;
|
||||
|
||||
};
|
||||
|
||||
@@ -134,7 +148,8 @@ Error OrganicClawReader::field(const char *key, T *val) noexcept {
|
||||
const auto &jv = value(key);
|
||||
if (jv.empty() || jv.isObject()) {
|
||||
auto reader = child(key);
|
||||
return model(&reader, val);
|
||||
ModelHandlerInterface handler(&reader);
|
||||
return model(&handler, val);
|
||||
} else {
|
||||
err = OxError(1, "Type mismatch");
|
||||
}
|
||||
@@ -143,14 +158,15 @@ Error OrganicClawReader::field(const char *key, T *val) noexcept {
|
||||
return err;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
Error OrganicClawReader::field(const char *key, UnionView<U> val) noexcept {
|
||||
template<typename U, bool force>
|
||||
Error OrganicClawReader::field(const char *key, UnionView<U, force> val) noexcept {
|
||||
auto err = OxError(0);
|
||||
if (targetValid()) {
|
||||
const auto &jv = value(key);
|
||||
if (jv.empty() || jv.isObject()) {
|
||||
auto reader = child(key, val.idx());
|
||||
err = model(&reader, val.get());
|
||||
ModelHandlerInterface handler(&reader);
|
||||
err = model(&handler, val.get());
|
||||
} else {
|
||||
err = OxError(1, "Type mismatch");
|
||||
}
|
||||
@@ -185,13 +201,17 @@ Error OrganicClawReader::field(const char *key, BString<L> *val) noexcept {
|
||||
template<typename T>
|
||||
Error OrganicClawReader::field(const char *key, T *val, std::size_t valLen) noexcept {
|
||||
const auto &srcVal = value(key);
|
||||
if (!srcVal.isNull() && !srcVal.isArray()) {
|
||||
return OxError(1, "Type mismatch");
|
||||
}
|
||||
auto srcSize = srcVal.size();
|
||||
if (srcSize > valLen) {
|
||||
return OxError(1);
|
||||
}
|
||||
OrganicClawReader r(srcVal);
|
||||
ModelHandlerInterface handler{&r};
|
||||
for (decltype(srcSize) i = 0; i < srcSize; ++i) {
|
||||
oxReturnError(r.field("", &val[i]));
|
||||
oxReturnError(handler.field("", &val[i]));
|
||||
}
|
||||
return OxError(0);
|
||||
}
|
||||
@@ -199,28 +219,32 @@ Error OrganicClawReader::field(const char *key, T *val, std::size_t valLen) noex
|
||||
template<typename T>
|
||||
Error OrganicClawReader::field(const char *key, HashMap<String, T> *val) noexcept {
|
||||
const auto &srcVal = value(key);
|
||||
if (!srcVal.isObject()) {
|
||||
return OxError(1, "Type mismatch");
|
||||
}
|
||||
auto keys = srcVal.getMemberNames();
|
||||
auto srcSize = srcVal.size();
|
||||
OrganicClawReader r(srcVal);
|
||||
ModelHandlerInterface handler{&r};
|
||||
for (decltype(srcSize) i = 0; i < srcSize; ++i) {
|
||||
const auto k = keys[i].c_str();
|
||||
oxReturnError(r.field(k, &val->operator[](k)));
|
||||
oxReturnError(handler.field(k, &val->operator[](k)));
|
||||
}
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Error readOC(const char *json, std::size_t jsonSize, T *val) noexcept {
|
||||
Error readOC(const char *buff, std::size_t buffSize, auto *val) noexcept {
|
||||
// OrganicClawReader constructor can throw, but readOC should return its errors.
|
||||
try {
|
||||
Json::Value doc;
|
||||
Json::CharReaderBuilder parserBuilder;
|
||||
auto parser = std::unique_ptr<Json::CharReader>(parserBuilder.newCharReader());
|
||||
if (!parser->parse(json, json + jsonSize, &doc, nullptr)) {
|
||||
auto parser = UniquePtr<Json::CharReader>(parserBuilder.newCharReader());
|
||||
if (!parser->parse(buff, buff + buffSize, &doc, nullptr)) {
|
||||
return OxError(1, "Could not parse JSON");
|
||||
}
|
||||
OrganicClawReader reader(json, jsonSize);
|
||||
return model(&reader, val);
|
||||
OrganicClawReader reader(buff, buffSize);
|
||||
ModelHandlerInterface handler(&reader);
|
||||
return model(&handler, val);
|
||||
} catch (const Error &err) {
|
||||
return err;
|
||||
} catch (...) {
|
||||
|
1
deps/ox/src/ox/oc/test/CMakeLists.txt
vendored
1
deps/ox/src/ox/oc/test/CMakeLists.txt
vendored
@@ -10,4 +10,5 @@ target_link_libraries(
|
||||
|
||||
add_test("[ox/oc] OcTest Writer" OcTest OrganicClawWriter)
|
||||
add_test("[ox/oc] OcTest Reader" OcTest OrganicClawReader)
|
||||
add_test("[ox/oc] OcTest OrganicClawModelValue" OcTest OrganicClawModelValue)
|
||||
add_test("[ox/oc] OcTest OrganicClawDef" OcTest OrganicClawDef)
|
||||
|
79
deps/ox/src/ox/oc/test/tests.cpp
vendored
79
deps/ox/src/ox/oc/test/tests.cpp
vendored
@@ -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
|
||||
@@ -19,7 +19,7 @@ union TestUnion {
|
||||
static constexpr auto TypeVersion = 1;
|
||||
bool Bool;
|
||||
uint32_t Int = 5;
|
||||
char String[32];
|
||||
char *String;
|
||||
};
|
||||
|
||||
struct TestStructNest {
|
||||
@@ -43,8 +43,9 @@ struct TestStruct {
|
||||
int32_t Int6 = 0;
|
||||
int32_t Int7 = 0;
|
||||
int32_t Int8 = 0;
|
||||
int unionIdx = 1;
|
||||
TestUnion Union;
|
||||
ox::BString<32> String = "";
|
||||
ox::String String = "";
|
||||
uint32_t List[4] = {0, 0, 0, 0};
|
||||
ox::HashMap<ox::String, int> Map;
|
||||
TestStructNest EmptyStruct;
|
||||
@@ -55,23 +56,24 @@ struct TestStruct {
|
||||
TestStruct(TestStruct &&other) noexcept;
|
||||
|
||||
constexpr ~TestStruct() noexcept {
|
||||
if (unionIdx == 2) {
|
||||
ox::safeDelete(Union.String);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr TestStruct &operator=(TestStruct&&) noexcept;
|
||||
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
constexpr ox::Error model(T *io, TestUnion *obj) noexcept {
|
||||
constexpr ox::Error model(auto *io, ox::CommonPtrWith<TestUnion> auto *obj) noexcept {
|
||||
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) noexcept {
|
||||
constexpr ox::Error model(auto *io, ox::CommonPtrWith<TestStructNest> auto *obj) noexcept {
|
||||
io->template setTypeInfo<TestStructNest>();
|
||||
oxReturnError(io->field("Bool", &obj->Bool));
|
||||
oxReturnError(io->field("Int", &obj->Int));
|
||||
@@ -79,8 +81,7 @@ constexpr ox::Error model(T *io, TestStructNest *obj) noexcept {
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr ox::Error model(T *io, TestStruct *obj) noexcept {
|
||||
constexpr ox::Error model(auto *io, ox::CommonPtrWith<TestStruct> auto *obj) noexcept {
|
||||
io->template setTypeInfo<TestStruct>();
|
||||
oxReturnError(io->field("Bool", &obj->Bool));
|
||||
oxReturnError(io->field("Int", &obj->Int));
|
||||
@@ -92,7 +93,12 @@ constexpr ox::Error model(T *io, TestStruct *obj) noexcept {
|
||||
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}));
|
||||
oxReturnError(io->field("unionIdx", &obj->unionIdx));
|
||||
if (ox_strcmp(io->opType(), ox::OpType::Reflect) == 0) {
|
||||
oxReturnError(io->field("Union", ox::UnionView{&obj->Union, 0}));
|
||||
} else {
|
||||
oxReturnError(io->field("Union", ox::UnionView{&obj->Union, obj->unionIdx}));
|
||||
}
|
||||
oxReturnError(io->field("String", &obj->String));
|
||||
oxReturnError(io->field("List", obj->List, 4));
|
||||
oxReturnError(io->field("Map", &obj->Map));
|
||||
@@ -173,6 +179,57 @@ const std::map<std::string_view, ox::Error(*)()> tests = {
|
||||
return OxError(0);
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"OrganicClawModelValue",
|
||||
[] {
|
||||
ox::Buffer dataBuff;
|
||||
TestStruct testIn;
|
||||
testIn.Bool = true;
|
||||
testIn.Int = 42;
|
||||
testIn.String = "Test String 1";
|
||||
testIn.List[0] = 1;
|
||||
testIn.List[1] = 2;
|
||||
testIn.List[2] = 3;
|
||||
testIn.List[3] = 4;
|
||||
testIn.Struct.Bool = false;
|
||||
testIn.Struct.Int = 300;
|
||||
testIn.Struct.String = "Test String 2";
|
||||
testIn.unionIdx = 1;
|
||||
testIn.Union.Int = 93;
|
||||
oxAssert(ox::writeOC(&testIn).moveTo(&dataBuff), "Data generation failed");
|
||||
ox::TypeStore typeStore;
|
||||
auto type = ox::buildTypeDef(&typeStore, &testIn);
|
||||
oxAssert(type.error, "Descriptor write failed");
|
||||
ox::ModelObject testOut;
|
||||
oxReturnError(testOut.setType(type.value));
|
||||
oxAssert(ox::readOC(dataBuff.data(), dataBuff.size(), &testOut), "Data read failed");
|
||||
oxAssert(testOut["Int"].get<int>() == testIn.Int, "testOut.Int failed");
|
||||
oxAssert(testOut["Bool"].get<bool>() == testIn.Bool, "testOut.Bool failed");
|
||||
oxAssert(testOut["String"].get<ox::String>() == testIn.String, "testOut.String failed");
|
||||
auto &testOutStruct = testOut["Struct"].get<ox::ModelObject>();
|
||||
auto &testOutUnion = testOut["Union"].get<ox::ModelUnion>();
|
||||
auto &testOutList = testOut["List"].get<ox::ModelValueVector>();
|
||||
auto testOutStructCopy = testOut["Struct"].get<ox::ModelObject>();
|
||||
auto testOutUnionCopy = testOut["Union"].get<ox::ModelUnion>();
|
||||
auto testOutListCopy = testOut["List"].get<ox::ModelValueVector>();
|
||||
oxAssert(testOutStruct.typeName() == TestStructNest::TypeName, "ModelObject TypeName failed");
|
||||
oxAssert(testOutStruct.typeVersion() == TestStructNest::TypeVersion, "ModelObject TypeVersion failed");
|
||||
oxAssert(testOutStruct["Bool"].get<bool>() == testIn.Struct.Bool, "testOut.Struct.Bool failed");
|
||||
oxAssert(testOutStruct["String"].get<ox::String>() == testIn.Struct.String.c_str(), "testOut.Struct.String failed");
|
||||
oxAssert(testOut["unionIdx"].get<int>() == testIn.unionIdx, "testOut.unionIdx failed");
|
||||
oxAssert(testOutUnion.unionIdx() == testIn.unionIdx, "testOut.Union idx wrong");
|
||||
oxAssert(testOutUnion["Int"].get<uint32_t>() == testIn.Union.Int, "testOut.Union.Int failed");
|
||||
oxAssert(testOutList[0].get<uint32_t>() == testIn.List[0], "testOut.List[0] failed");
|
||||
oxAssert(testOutList[1].get<uint32_t>() == testIn.List[1], "testOut.Struct.List[1] failed");
|
||||
oxAssert(testOutStructCopy["Bool"].get<bool>() == testIn.Struct.Bool, "testOut.Struct.Bool (copy) failed");
|
||||
oxAssert(testOutStructCopy["String"].get<ox::String>() == testIn.Struct.String.c_str(), "testOut.Struct.String (copy) failed");
|
||||
oxAssert(testOutListCopy[0].get<uint32_t>() == testIn.List[0], "testOut.Struct.List[0] (copy) failed");
|
||||
oxAssert(testOutListCopy[1].get<uint32_t>() == testIn.List[1], "testOut.Struct.List[1] (copy) failed");
|
||||
return OxError(0);
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"OrganicClawDef",
|
||||
[] {
|
||||
|
103
deps/ox/src/ox/oc/write.cpp
vendored
103
deps/ox/src/ox/oc/write.cpp
vendored
@@ -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 "write.hpp"
|
||||
@@ -18,87 +18,6 @@ OrganicClawWriter::OrganicClawWriter(Json::Value json, int unionIdx) noexcept:
|
||||
m_unionIdx(unionIdx) {
|
||||
}
|
||||
|
||||
Error OrganicClawWriter::field(const char *key, int8_t *val) noexcept {
|
||||
if (*val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
Error OrganicClawWriter::field(const char *key, int16_t *val) noexcept {
|
||||
if (*val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
Error OrganicClawWriter::field(const char *key, int32_t *val) noexcept {
|
||||
if (*val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
Error OrganicClawWriter::field(const char *key, int64_t *val) noexcept {
|
||||
if (*val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
|
||||
Error OrganicClawWriter::field(const char *key, uint8_t *val) noexcept {
|
||||
if (*val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
Error OrganicClawWriter::field(const char *key, uint16_t *val) noexcept {
|
||||
if (targetValid() && *val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
Error OrganicClawWriter::field(const char *key, uint32_t *val) noexcept {
|
||||
if (targetValid() && *val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
Error OrganicClawWriter::field(const char *key, uint64_t *val) noexcept {
|
||||
if (targetValid() && *val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
Error OrganicClawWriter::field(const char *key, bool *val) noexcept {
|
||||
if (targetValid() && *val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
Error OrganicClawWriter::field(const char *key, String *val) noexcept {
|
||||
if (targetValid() && val->len()) {
|
||||
value(key) = val->c_str();
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
Error OrganicClawWriter::field(const char *key, SerStr val) noexcept {
|
||||
if (targetValid() && val.len()) {
|
||||
value(key) = val.c_str();
|
||||
@@ -107,6 +26,26 @@ Error OrganicClawWriter::field(const char *key, SerStr val) noexcept {
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
Error OrganicClawWriter::fieldCString(const char *key, const char **val, int len) noexcept {
|
||||
if (targetValid() && len) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
Error OrganicClawWriter::fieldCString(const char *key, char **val, int len) noexcept {
|
||||
return fieldCString(key, const_cast<const char**>(val), len);
|
||||
}
|
||||
|
||||
Error OrganicClawWriter::fieldCString(const char *key, const char **val) noexcept {
|
||||
return fieldCString(key, const_cast<const char**>(val), {});
|
||||
}
|
||||
|
||||
Error OrganicClawWriter::fieldCString(const char *key, char **val) noexcept {
|
||||
return fieldCString(key, const_cast<const char**>(val), {});
|
||||
}
|
||||
|
||||
Json::Value &OrganicClawWriter::value(const char *key) noexcept {
|
||||
if (m_json.isArray()) {
|
||||
return m_json[m_fieldIt];
|
||||
|
177
deps/ox/src/ox/oc/write.hpp
vendored
177
deps/ox/src/ox/oc/write.hpp
vendored
@@ -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
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <json/json.h>
|
||||
|
||||
#include <ox/model/fieldcounter.hpp>
|
||||
#include <ox/model/modelhandleradaptor.hpp>
|
||||
#include <ox/model/optype.hpp>
|
||||
#include <ox/model/types.hpp>
|
||||
#include <ox/model/typenamecatcher.hpp>
|
||||
@@ -22,8 +23,7 @@ namespace ox {
|
||||
|
||||
class OrganicClawWriter {
|
||||
|
||||
template<typename T>
|
||||
friend Result<Buffer> writeOC(T *val) noexcept;
|
||||
friend Result<Buffer> writeOC(auto *val) noexcept;
|
||||
|
||||
protected:
|
||||
Json::Value m_json;
|
||||
@@ -35,36 +35,140 @@ class OrganicClawWriter {
|
||||
|
||||
explicit OrganicClawWriter(Json::Value json, int unionIdx = -1) noexcept;
|
||||
|
||||
Error field(const char*, int8_t *val) noexcept;
|
||||
Error field(const char*, int16_t *val) noexcept;
|
||||
Error field(const char*, int32_t *val) noexcept;
|
||||
Error field(const char*, int64_t *val) noexcept;
|
||||
Error field(const char *key, CommonPtrWith<int8_t> auto *val) noexcept {
|
||||
if (*val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
Error field(const char*, uint8_t *val) noexcept;
|
||||
Error field(const char*, uint16_t *val) noexcept;
|
||||
Error field(const char*, uint32_t *val) noexcept;
|
||||
Error field(const char*, uint64_t *val) noexcept;
|
||||
Error field(const char *key, CommonPtrWith<int16_t> auto *val) noexcept {
|
||||
if (*val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
Error field(const char*, bool *val) noexcept;
|
||||
Error field(const char *key, CommonPtrWith<int32_t> auto *val) noexcept {
|
||||
if (*val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
Error field(const char *key, CommonPtrWith<int64_t> auto *val) noexcept {
|
||||
if (*val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
|
||||
Error field(const char *key, CommonPtrWith<uint8_t> auto *val) noexcept {
|
||||
if (*val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
Error field(const char *key, CommonPtrWith<uint16_t> auto *val) noexcept {
|
||||
if (targetValid() && *val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
Error field(const char *key, CommonPtrWith<uint32_t> auto *val) noexcept {
|
||||
if (targetValid() && *val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
Error field(const char *key, CommonPtrWith<uint64_t> auto *val) noexcept {
|
||||
if (targetValid() && *val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
Error field(const char *key, CommonPtrWith<bool> auto *val) noexcept {
|
||||
if (targetValid() && *val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Error field(const char*, T *val, std::size_t len) noexcept;
|
||||
|
||||
template<typename U>
|
||||
Error field(const char*, UnionView<U> val) noexcept;
|
||||
template<typename U, bool force = true>
|
||||
Error field(const char*, UnionView<U, force> val) noexcept;
|
||||
|
||||
template<typename T>
|
||||
Error field(const char*, HashMap<String, T> *val) noexcept;
|
||||
Error field(const char *key, const HashMap<String, T> *val) noexcept {
|
||||
if (targetValid()) {
|
||||
const auto &keys = val->keys();
|
||||
OrganicClawWriter w;
|
||||
ModelHandlerInterface handler{&w};
|
||||
for (std::size_t i = 0; i < keys.size(); ++i) {
|
||||
const auto k = keys[i].c_str();
|
||||
oxReturnError(handler.field(k, val->at(k).value));
|
||||
}
|
||||
value(key) = w.m_json;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Error field(const char *key, HashMap<String, T> *val) noexcept {
|
||||
return field(key, const_cast<const HashMap<String, T>*>(val));
|
||||
}
|
||||
|
||||
template<std::size_t L>
|
||||
Error field(const char*, BString<L> *val) noexcept;
|
||||
Error field(const char *key, const BString<L> *val) noexcept {
|
||||
return field(key, SerStr(val->data(), val->cap()));
|
||||
}
|
||||
|
||||
Error field(const char*, String *val) noexcept;
|
||||
template<std::size_t L>
|
||||
Error field(const char *key, BString<L> *val) noexcept {
|
||||
return field(key, SerStr(val->data(), val->cap()));
|
||||
}
|
||||
|
||||
template<std::size_t L>
|
||||
Error field(const char *key, const BasicString<L> *val) noexcept {
|
||||
if (targetValid() && val->len()) {
|
||||
value(key) = val->c_str();
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<std::size_t L>
|
||||
Error field(const char *key, BasicString<L> *val) noexcept {
|
||||
return field(key, const_cast<const BasicString<L>*>(val));
|
||||
}
|
||||
|
||||
Error field(const char*, SerStr val) noexcept;
|
||||
|
||||
Error fieldCString(const char*, const char **val, int len) noexcept;
|
||||
|
||||
Error fieldCString(const char *name, char **val, int len) noexcept;
|
||||
|
||||
Error fieldCString(const char *name, const char **val) noexcept;
|
||||
|
||||
Error fieldCString(const char *name, char **val) noexcept;
|
||||
|
||||
template<typename T>
|
||||
Error field(const char*, T *val) noexcept;
|
||||
|
||||
@@ -91,8 +195,9 @@ template<typename T>
|
||||
Error OrganicClawWriter::field(const char *key, T *val, std::size_t len) noexcept {
|
||||
if (targetValid() && len) {
|
||||
OrganicClawWriter w((Json::Value(Json::arrayValue)));
|
||||
ModelHandlerInterface handler{&w};
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
oxReturnError(w.field("", &val[i]));
|
||||
oxReturnError(handler.field("", &val[i]));
|
||||
}
|
||||
value(key) = w.m_json;
|
||||
}
|
||||
@@ -100,18 +205,14 @@ Error OrganicClawWriter::field(const char *key, T *val, std::size_t len) noexcep
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<std::size_t L>
|
||||
Error OrganicClawWriter::field(const char *key, BString<L> *val) noexcept {
|
||||
return field(key, SerStr(val->data(), val->cap()));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Error OrganicClawWriter::field(const char *key, T *val) noexcept {
|
||||
if constexpr(isVector_v<T>) {
|
||||
return field(key, val->data(), val->size());
|
||||
} else if (val && targetValid()) {
|
||||
OrganicClawWriter w;
|
||||
oxReturnError(model(&w, val));
|
||||
ModelHandlerInterface handler{&w};
|
||||
oxReturnError(model(&handler, val));
|
||||
if (!w.m_json.isNull()) {
|
||||
value(key) = w.m_json;
|
||||
}
|
||||
@@ -120,11 +221,12 @@ Error OrganicClawWriter::field(const char *key, T *val) noexcept {
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
Error OrganicClawWriter::field(const char *key, UnionView<U> val) noexcept {
|
||||
template<typename U, bool force>
|
||||
Error OrganicClawWriter::field(const char *key, UnionView<U, force> val) noexcept {
|
||||
if (targetValid()) {
|
||||
OrganicClawWriter w(val.idx());
|
||||
oxReturnError(model(&w, val.get()));
|
||||
ModelHandlerInterface handler{&w};
|
||||
oxReturnError(model(&handler, val.get()));
|
||||
if (!w.m_json.isNull()) {
|
||||
value(key) = w.m_json;
|
||||
}
|
||||
@@ -133,25 +235,10 @@ Error OrganicClawWriter::field(const char *key, UnionView<U> val) noexcept {
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Error OrganicClawWriter::field(const char *key, HashMap<String, T> *val) noexcept {
|
||||
if (targetValid()) {
|
||||
const auto &keys = val->keys();
|
||||
OrganicClawWriter w;
|
||||
for (std::size_t i = 0; i < keys.size(); ++i) {
|
||||
const auto k = keys[i].c_str();
|
||||
oxReturnError(w.field(k, &val->operator[](k)));
|
||||
}
|
||||
value(key) = w.m_json;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Result<Buffer> writeOC(T *val) noexcept {
|
||||
Result<Buffer> writeOC(auto *val) noexcept {
|
||||
OrganicClawWriter writer;
|
||||
oxReturnError(model(&writer, val));
|
||||
ModelHandlerInterface handler(&writer);
|
||||
oxReturnError(model(&handler, val));
|
||||
Json::StreamWriterBuilder jsonBuilder;
|
||||
const auto str = Json::writeString(jsonBuilder, writer.m_json);
|
||||
Buffer buff(str.size() + 1);
|
||||
|
Reference in New Issue
Block a user