[ox/oc] Add union support
This commit is contained in:
parent
d2e7528dae
commit
d0f5819072
235
deps/ox/src/ox/oc/read.cpp
vendored
235
deps/ox/src/ox/oc/read.cpp
vendored
@ -12,8 +12,7 @@
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename Key>
|
||||
OrganicClawReader<Key>::OrganicClawReader(const uint8_t *buff, std::size_t buffSize) {
|
||||
OrganicClawReader::OrganicClawReader(const uint8_t *buff, std::size_t buffSize) {
|
||||
auto json = bit_cast<const char*>(buff);
|
||||
auto jsonLen = ox_strnlen(json, buffSize);
|
||||
Json::CharReaderBuilder parserBuilder;
|
||||
@ -23,8 +22,7 @@ OrganicClawReader<Key>::OrganicClawReader(const uint8_t *buff, std::size_t buffS
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
OrganicClawReader<Key>::OrganicClawReader(const char *json, std::size_t jsonLen) {
|
||||
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)) {
|
||||
@ -32,163 +30,182 @@ OrganicClawReader<Key>::OrganicClawReader(const char *json, std::size_t jsonLen)
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
OrganicClawReader<Key>::OrganicClawReader(const Json::Value &json) {
|
||||
m_json = json;
|
||||
OrganicClawReader::OrganicClawReader(const Json::Value &json, int unionIdx):
|
||||
m_json(json),
|
||||
m_unionIdx(unionIdx) {
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
Error OrganicClawReader<Key>::field(Key key, int8_t *val) {
|
||||
Error OrganicClawReader::field(const char *key, int8_t *val) {
|
||||
auto err = OxError(0);
|
||||
if (targetValid()) {
|
||||
const auto &jv = value(key);
|
||||
++m_fieldIt;
|
||||
if (jv.empty()) {
|
||||
return OxError(0);
|
||||
}
|
||||
if (jv.isInt()) {
|
||||
*val = 0;
|
||||
} else if (jv.isInt()) {
|
||||
*val = static_cast<int8_t>(jv.asInt());
|
||||
return OxError(0);
|
||||
} else {
|
||||
err = OxError(1, "Type mismatch");
|
||||
}
|
||||
return OxError(1, "Type mismatch");
|
||||
}
|
||||
++m_fieldIt;
|
||||
return err;
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
Error OrganicClawReader<Key>::field(Key key, int16_t *val) {
|
||||
Error OrganicClawReader::field(const char *key, int16_t *val) {
|
||||
auto err = OxError(0);
|
||||
if (targetValid()) {
|
||||
const auto &jv = value(key);
|
||||
++m_fieldIt;
|
||||
if (jv.empty()) {
|
||||
return OxError(0);
|
||||
}
|
||||
if (jv.isInt()) {
|
||||
*val = 0;
|
||||
} else if (jv.isInt()) {
|
||||
*val = static_cast<int16_t>(jv.asInt());
|
||||
return OxError(0);
|
||||
} else {
|
||||
err = OxError(1, "Type mismatch");
|
||||
}
|
||||
return OxError(1, "Type mismatch");
|
||||
}
|
||||
++m_fieldIt;
|
||||
return err;
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
Error OrganicClawReader<Key>::field(Key key, int32_t *val) {
|
||||
Error OrganicClawReader::field(const char *key, int32_t *val) {
|
||||
auto err = OxError(0);
|
||||
if (targetValid()) {
|
||||
const auto &jv = value(key);
|
||||
++m_fieldIt;
|
||||
if (jv.empty()) {
|
||||
return OxError(0);
|
||||
}
|
||||
if (jv.isInt()) {
|
||||
*val = 0;
|
||||
} else if (jv.isInt()) {
|
||||
*val = static_cast<int32_t>(jv.asInt());
|
||||
return OxError(0);
|
||||
} else {
|
||||
err = OxError(1, "Type mismatch");
|
||||
}
|
||||
return OxError(1, "Type mismatch");
|
||||
}
|
||||
++m_fieldIt;
|
||||
return err;
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
Error OrganicClawReader<Key>::field(Key key, int64_t *val) {
|
||||
Error OrganicClawReader::field(const char *key, int64_t *val) {
|
||||
auto err = OxError(0);
|
||||
if (targetValid()) {
|
||||
const auto &jv = value(key);
|
||||
++m_fieldIt;
|
||||
if (jv.empty()) {
|
||||
return OxError(0);
|
||||
}
|
||||
if (jv.isInt() || jv.isInt64()) {
|
||||
*val = 0;
|
||||
} else if (jv.isInt() || jv.isInt64()) {
|
||||
*val = static_cast<int64_t>(jv.asInt64());
|
||||
return OxError(0);
|
||||
} else {
|
||||
err = OxError(1, "Type mismatch");
|
||||
}
|
||||
return OxError(1, "Type mismatch");
|
||||
}
|
||||
++m_fieldIt;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
template<typename Key>
|
||||
Error OrganicClawReader<Key>::field(Key key, uint8_t *val) {
|
||||
Error OrganicClawReader::field(const char *key, uint8_t *val) {
|
||||
auto err = OxError(0);
|
||||
if (targetValid()) {
|
||||
const auto &jv = value(key);
|
||||
++m_fieldIt;
|
||||
if (jv.empty()) {
|
||||
return OxError(0);
|
||||
}
|
||||
if (jv.isUInt()) {
|
||||
*val = 0;
|
||||
} else if (jv.isUInt()) {
|
||||
*val = static_cast<uint8_t>(jv.asUInt());
|
||||
return OxError(0);
|
||||
} else {
|
||||
err = OxError(1, "Type mismatch");
|
||||
}
|
||||
return OxError(1, "Type mismatch");
|
||||
}
|
||||
++m_fieldIt;
|
||||
return err;
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
Error OrganicClawReader<Key>::field(Key key, uint16_t *val) {
|
||||
Error OrganicClawReader::field(const char *key, uint16_t *val) {
|
||||
auto err = OxError(0);
|
||||
if (targetValid()) {
|
||||
const auto &jv = value(key);
|
||||
++m_fieldIt;
|
||||
if (jv.empty()) {
|
||||
return OxError(0);
|
||||
}
|
||||
if (jv.isUInt()) {
|
||||
*val = 0;
|
||||
} else if (jv.isUInt()) {
|
||||
*val = static_cast<uint16_t>(jv.asUInt());
|
||||
return OxError(0);
|
||||
} else {
|
||||
err = OxError(1, "Type mismatch");
|
||||
}
|
||||
return OxError(1, "Type mismatch");
|
||||
}
|
||||
++m_fieldIt;
|
||||
return err;
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
Error OrganicClawReader<Key>::field(Key key, uint32_t *val) {
|
||||
Error OrganicClawReader::field(const char *key, uint32_t *val) {
|
||||
auto err = OxError(0);
|
||||
if (targetValid()) {
|
||||
const auto &jv = value(key);
|
||||
++m_fieldIt;
|
||||
if (jv.empty()) {
|
||||
return OxError(0);
|
||||
}
|
||||
if (jv.isUInt()) {
|
||||
*val = 0;
|
||||
} else if (jv.isUInt()) {
|
||||
*val = static_cast<uint32_t>(jv.asUInt());
|
||||
return OxError(0);
|
||||
} else {
|
||||
err = OxError(1, "Type mismatch");
|
||||
}
|
||||
return OxError(1, "Type mismatch");
|
||||
}
|
||||
++m_fieldIt;
|
||||
return err;
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
Error OrganicClawReader<Key>::field(Key key, uint64_t *val) {
|
||||
Error OrganicClawReader::field(const char *key, uint64_t *val) {
|
||||
auto err = OxError(0);
|
||||
if (targetValid()) {
|
||||
const auto &jv = value(key);
|
||||
++m_fieldIt;
|
||||
if (jv.empty()) {
|
||||
return OxError(0);
|
||||
}
|
||||
if (jv.isUInt() || jv.isUInt64()) {
|
||||
*val = 0;
|
||||
} else if (jv.isUInt() || jv.isUInt64()) {
|
||||
*val = static_cast<uint64_t>(jv.asUInt64());
|
||||
return OxError(0);
|
||||
} else {
|
||||
err = OxError(1, "Type mismatch");
|
||||
}
|
||||
}
|
||||
return OxError(1, "Type mismatch");
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
Error OrganicClawReader<Key>::field(Key key, bool *val) {
|
||||
const auto &jv = value(key);
|
||||
++m_fieldIt;
|
||||
if (jv.empty()) {
|
||||
return OxError(0);
|
||||
}
|
||||
if (jv.isBool()) {
|
||||
*val = jv.asBool();
|
||||
return OxError(0);
|
||||
}
|
||||
return OxError(1, "Type mismatch");
|
||||
return err;
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
Error OrganicClawReader<Key>::field(Key key, SerStr val) {
|
||||
Error OrganicClawReader::field(const char *key, bool *val) {
|
||||
auto err = OxError(0);
|
||||
if (targetValid()) {
|
||||
const auto &jv = value(key);
|
||||
if (jv.empty()) {
|
||||
*val = false;
|
||||
} else if (jv.isBool()) {
|
||||
*val = jv.asBool();
|
||||
} else {
|
||||
err = OxError(1, "Type mismatch");
|
||||
}
|
||||
}
|
||||
++m_fieldIt;
|
||||
return err;
|
||||
}
|
||||
|
||||
Error OrganicClawReader::field(const char *key, SerStr val) {
|
||||
auto err = OxError(0);
|
||||
const char *begin = nullptr, *end = nullptr;
|
||||
const auto &jv = value(key);
|
||||
++m_fieldIt;
|
||||
if (targetValid()) {
|
||||
if (jv.empty()) {
|
||||
return OxError(0);
|
||||
}
|
||||
if (jv.isString()) {
|
||||
val.data()[0] = 0;
|
||||
} else if (jv.isString()) {
|
||||
jv.getString(&begin, &end);
|
||||
auto strSize = end - begin;
|
||||
if (strSize >= val.cap()) {
|
||||
return OxError(1, "String size exceeds capacity of destination");
|
||||
}
|
||||
err = OxError(1, "String size exceeds capacity of destination");
|
||||
} else {
|
||||
ox_memcpy(val.data(), begin, static_cast<std::size_t>(strSize));
|
||||
val.data()[strSize] = 0;
|
||||
return OxError(0);
|
||||
}
|
||||
return OxError(1, "Type mismatch");
|
||||
} else {
|
||||
err = OxError(1, "Type mismatch");
|
||||
}
|
||||
}
|
||||
++m_fieldIt;
|
||||
return err;
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
[[nodiscard]] ValErr<std::size_t> OrganicClawReader<Key>::arrayLength(Key key, bool) {
|
||||
[[nodiscard]] ValErr<std::size_t> OrganicClawReader::arrayLength(const char *key, bool) {
|
||||
const auto &jv = value(key);
|
||||
++m_fieldIt;
|
||||
if (jv.empty()) {
|
||||
return 0;
|
||||
}
|
||||
@ -198,11 +215,9 @@ template<typename Key>
|
||||
return OxError(1, "Type mismatch");
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
[[nodiscard]] std::size_t OrganicClawReader<Key>::stringLength(Key key) {
|
||||
[[nodiscard]] std::size_t OrganicClawReader::stringLength(const char *key) {
|
||||
const char *begin = nullptr, *end = nullptr;
|
||||
const auto &jv = value(key);
|
||||
++m_fieldIt;
|
||||
if (jv.empty()) {
|
||||
return 0;
|
||||
}
|
||||
@ -213,22 +228,15 @@ template<typename Key>
|
||||
return OxError(1, "Type mismatch");
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
void OrganicClawReader<Key>::setTypeInfo(const char*, int) {
|
||||
OrganicClawReader OrganicClawReader::child(const char *key, int unionIdx) {
|
||||
return OrganicClawReader(m_json[key], unionIdx);
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
OrganicClawReader<Key> OrganicClawReader<Key>::child(Key key) {
|
||||
return OrganicClawReader<Key>(m_json[key]);
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
bool OrganicClawReader<Key>::fieldPresent(Key key) {
|
||||
bool OrganicClawReader::fieldPresent(const char *key) {
|
||||
return !m_json[key].empty();
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
Json::Value &OrganicClawReader<Key>::value(Key key) {
|
||||
Json::Value &OrganicClawReader::value(const char *key) {
|
||||
if (m_json.isArray()) {
|
||||
return m_json[m_fieldIt];
|
||||
} else {
|
||||
@ -236,7 +244,8 @@ Json::Value &OrganicClawReader<Key>::value(Key key) {
|
||||
}
|
||||
}
|
||||
|
||||
template class OrganicClawReader<const char*>;
|
||||
template class OrganicClawReader<Json::ArrayIndex>;
|
||||
bool OrganicClawReader::targetValid() noexcept {
|
||||
return static_cast<int>(m_fieldIt) == m_unionIdx || m_unionIdx == -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
99
deps/ox/src/ox/oc/read.hpp
vendored
99
deps/ox/src/ox/oc/read.hpp
vendored
@ -18,12 +18,12 @@
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename Key>
|
||||
class OrganicClawReader {
|
||||
|
||||
private:
|
||||
Json::Value m_json;
|
||||
Json::ArrayIndex m_fieldIt = 0;
|
||||
int m_unionIdx = -1;
|
||||
|
||||
public:
|
||||
OrganicClawReader() = default;
|
||||
@ -32,57 +32,62 @@ class OrganicClawReader {
|
||||
|
||||
OrganicClawReader(const char *json, std::size_t buffSize);
|
||||
|
||||
OrganicClawReader(const Json::Value &json);
|
||||
OrganicClawReader(const Json::Value &json, int unionIdx = -1);
|
||||
|
||||
[[nodiscard]] Error field(Key key, int8_t *val);
|
||||
[[nodiscard]] Error field(Key key, int16_t *val);
|
||||
[[nodiscard]] Error field(Key key, int32_t *val);
|
||||
[[nodiscard]] Error field(Key key, int64_t *val);
|
||||
[[nodiscard]] Error field(const char *key, int8_t *val);
|
||||
[[nodiscard]] Error field(const char *key, int16_t *val);
|
||||
[[nodiscard]] Error field(const char *key, int32_t *val);
|
||||
[[nodiscard]] Error field(const char *key, int64_t *val);
|
||||
|
||||
[[nodiscard]] Error field(Key key, uint8_t *val);
|
||||
[[nodiscard]] Error field(Key key, uint16_t *val);
|
||||
[[nodiscard]] Error field(Key key, uint32_t *val);
|
||||
[[nodiscard]] Error field(Key key, uint64_t *val);
|
||||
[[nodiscard]] Error field(const char *key, uint8_t *val);
|
||||
[[nodiscard]] Error field(const char *key, uint16_t *val);
|
||||
[[nodiscard]] Error field(const char *key, uint32_t *val);
|
||||
[[nodiscard]] Error field(const char *key, uint64_t *val);
|
||||
|
||||
[[nodiscard]] Error field(Key key, bool *val);
|
||||
[[nodiscard]] Error field(const char *key, bool *val);
|
||||
|
||||
// array handler
|
||||
template<typename T>
|
||||
[[nodiscard]] Error field(Key key, T *val, std::size_t len);
|
||||
[[nodiscard]] Error field(const char *key, T *val, std::size_t len);
|
||||
|
||||
template<typename T>
|
||||
[[nodiscard]] Error field(Key key, ox::Vector<T> *val);
|
||||
[[nodiscard]] Error field(const char *key, ox::Vector<T> *val);
|
||||
|
||||
template<typename T>
|
||||
[[nodiscard]] Error field(Key key, T *val);
|
||||
[[nodiscard]] Error field(const char *key, T *val);
|
||||
|
||||
template<typename U>
|
||||
[[nodiscard]] Error field(const char *key, UnionView<U> val);
|
||||
|
||||
template<std::size_t L>
|
||||
[[nodiscard]] Error field(Key key, ox::BString<L> *val);
|
||||
[[nodiscard]] Error field(const char *key, ox::BString<L> *val);
|
||||
|
||||
[[nodiscard]] Error field(Key key, SerStr val);
|
||||
[[nodiscard]] Error field(const char *key, SerStr val);
|
||||
|
||||
/**
|
||||
* Reads an array length from the current location in the buffer.
|
||||
* @param pass indicates that the parsing should iterate past the array length
|
||||
*/
|
||||
[[nodiscard]] ValErr<std::size_t> arrayLength(Key key, bool pass = true);
|
||||
[[nodiscard]] ValErr<std::size_t> arrayLength(const char *key, bool pass = true);
|
||||
|
||||
/**
|
||||
* Reads an string length from the current location in the buffer.
|
||||
*/
|
||||
[[nodiscard]] std::size_t stringLength(Key name);
|
||||
[[nodiscard]] std::size_t stringLength(const char *name);
|
||||
|
||||
void setTypeInfo(const char *name, int fields);
|
||||
template<typename T = void>
|
||||
constexpr void setTypeInfo(const char* = T::TypeName, int = T::Fields) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a OrganicClawReader to parse a child object.
|
||||
*/
|
||||
[[nodiscard]] OrganicClawReader child(Key key);
|
||||
[[nodiscard]] OrganicClawReader child(const char *key, int unionIdx = -1);
|
||||
|
||||
// compatibility stub
|
||||
constexpr void nextField() noexcept {}
|
||||
|
||||
bool fieldPresent(Key key);
|
||||
bool fieldPresent(const char *key);
|
||||
|
||||
static constexpr auto opType() {
|
||||
return OpType::Read;
|
||||
@ -90,52 +95,66 @@ class OrganicClawReader {
|
||||
|
||||
private:
|
||||
|
||||
Json::Value &value(Key key);
|
||||
Json::Value &value(const char *key);
|
||||
|
||||
bool targetValid() noexcept;
|
||||
|
||||
};
|
||||
|
||||
template<typename Key>
|
||||
template<typename T>
|
||||
Error OrganicClawReader<Key>::field(Key key, T *val) {
|
||||
if (val) {
|
||||
Error OrganicClawReader::field(const char *key, T *val) {
|
||||
auto err = OxError(0);
|
||||
if (targetValid()) {
|
||||
const auto &jv = value(key);
|
||||
++m_fieldIt;
|
||||
if (jv.empty()) {
|
||||
return OxError(0);
|
||||
}
|
||||
if (jv.isObject()) {
|
||||
if (jv.empty() || jv.isObject()) {
|
||||
auto reader = child(key);
|
||||
return model(&reader, val);
|
||||
} else {
|
||||
err = OxError(1, "Type mismatch");
|
||||
}
|
||||
}
|
||||
return OxError(0);
|
||||
++m_fieldIt;
|
||||
return err;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
Error OrganicClawReader::field(const char *key, UnionView<U> val) {
|
||||
auto err = OxError(0);
|
||||
if (targetValid()) {
|
||||
const auto &jv = value(key);
|
||||
if (jv.empty() || jv.isObject()) {
|
||||
auto reader = child(key, val.idx());
|
||||
return model(&reader, val.get());
|
||||
} else {
|
||||
err = OxError(1, "Type mismatch");
|
||||
}
|
||||
}
|
||||
++m_fieldIt;
|
||||
return err;
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
template<std::size_t L>
|
||||
Error OrganicClawReader<Key>::field(Key name, ox::BString<L> *val) {
|
||||
Error OrganicClawReader::field(const char *name, ox::BString<L> *val) {
|
||||
return field(name, SerStr(val->data(), val->cap()));
|
||||
}
|
||||
|
||||
// array handler
|
||||
template<typename Key>
|
||||
template<typename T>
|
||||
Error OrganicClawReader<Key>::field(Key key, T *val, std::size_t valLen) {
|
||||
const auto &srcVal = m_json[key];
|
||||
Error OrganicClawReader::field(const char *key, T *val, std::size_t valLen) {
|
||||
const auto &srcVal = value(key);
|
||||
auto srcSize = srcVal.size();
|
||||
if (srcSize > valLen) {
|
||||
return OxError(1);
|
||||
}
|
||||
OrganicClawReader<const char*> r(srcVal);
|
||||
OrganicClawReader r(srcVal);
|
||||
for (decltype(srcSize) i = 0; i < srcSize; ++i) {
|
||||
oxReturnError(r.field("", &val[i]));
|
||||
}
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
template<typename T>
|
||||
Error OrganicClawReader<Key>::field(Key key, ox::Vector<T> *val) {
|
||||
Error OrganicClawReader::field(const char *key, ox::Vector<T> *val) {
|
||||
return field(nullptr, val->data(), val->size());
|
||||
}
|
||||
|
||||
@ -149,7 +168,7 @@ Error readOC(const char *json, std::size_t jsonSize, T *val) noexcept {
|
||||
if (!parser->parse(json, json + jsonSize, &doc, nullptr)) {
|
||||
return OxError(1, "Could not parse JSON");
|
||||
}
|
||||
OrganicClawReader<const char*> reader(json, jsonSize);
|
||||
OrganicClawReader reader(json, jsonSize);
|
||||
return model(&reader, val);
|
||||
} catch (Error err) {
|
||||
return err;
|
||||
|
34
deps/ox/src/ox/oc/test/tests.cpp
vendored
34
deps/ox/src/ox/oc/test/tests.cpp
vendored
@ -16,6 +16,14 @@
|
||||
#include <ox/oc/oc.hpp>
|
||||
#include <ox/std/std.hpp>
|
||||
|
||||
union TestUnion {
|
||||
static constexpr auto TypeName = "TestUnion";
|
||||
static constexpr auto Fields = 3;
|
||||
bool Bool;
|
||||
uint32_t Int = 5;
|
||||
char String[32];
|
||||
};
|
||||
|
||||
struct TestStructNest {
|
||||
bool Bool = false;
|
||||
uint32_t Int = 0;
|
||||
@ -33,20 +41,29 @@ struct TestStruct {
|
||||
int32_t Int6 = 0;
|
||||
int32_t Int7 = 0;
|
||||
int32_t Int8 = 0;
|
||||
TestUnion Union;
|
||||
ox::BString<32> String = "";
|
||||
uint32_t List[4] = {0, 0, 0 , 0};
|
||||
TestStructNest EmptyStruct;
|
||||
TestStructNest Struct;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
ox::Error model(T *io, TestUnion *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)));
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ox::Error model(T *io, TestStructNest *obj) {
|
||||
auto err = OxError(0);
|
||||
io->setTypeInfo("TestStructNest", 3);
|
||||
err |= io->field("Bool", &obj->Bool);
|
||||
err |= io->field("Int", &obj->Int);
|
||||
err |= io->field("String", &obj->String);
|
||||
return err;
|
||||
oxReturnError(io->field("Bool", &obj->Bool));
|
||||
oxReturnError(io->field("Int", &obj->Int));
|
||||
oxReturnError(io->field("String", &obj->String));
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -62,6 +79,7 @@ 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}));
|
||||
oxReturnError(io->field("String", &obj->String));
|
||||
oxReturnError(io->field("List", obj->List, 4));
|
||||
oxReturnError(io->field("EmptyStruct", &obj->EmptyStruct));
|
||||
@ -86,6 +104,7 @@ std::map<std::string, ox::Error(*)()> tests = {
|
||||
TestStruct testIn;
|
||||
testIn.Bool = true;
|
||||
testIn.Int = 42;
|
||||
testIn.Union.Int = 52;
|
||||
testIn.String = "Test String 1";
|
||||
testIn.List[0] = 1;
|
||||
testIn.List[1] = 2;
|
||||
@ -111,6 +130,7 @@ std::map<std::string, ox::Error(*)()> tests = {
|
||||
oxAssert(testIn.Int6 == testOut.Int6, "Int6 value mismatch");
|
||||
oxAssert(testIn.Int7 == testOut.Int7, "Int7 value mismatch");
|
||||
oxAssert(testIn.Int8 == testOut.Int8, "Int8 value mismatch");
|
||||
oxAssert(testIn.Union.Int == testOut.Union.Int, "Union.Int value mismatch");
|
||||
oxAssert(testIn.String == testOut.String, "String value mismatch");
|
||||
oxAssert(testIn.List[0] == testOut.List[0], "List[0] value mismatch");
|
||||
oxAssert(testIn.List[1] == testOut.List[1], "List[1] value mismatch");
|
||||
@ -146,8 +166,8 @@ std::map<std::string, ox::Error(*)()> tests = {
|
||||
oxAssert(ocErr, "Data generation failed");
|
||||
auto type = ox::buildTypeDef(&testIn);
|
||||
oxAssert(type.error, "Descriptor write failed");
|
||||
ox::walkModel<ox::OrganicClawReader<const char*>>(type.value, ox::bit_cast<uint8_t*>(oc.c_str()), oc.len() + 1,
|
||||
[](const ox::Vector<ox::FieldName>&, const ox::Vector<ox::TypeName>&, const ox::DescriptorField &f, ox::OrganicClawReader<const char*> *rdr) -> ox::Error {
|
||||
ox::walkModel<ox::OrganicClawReader>(type.value, ox::bit_cast<uint8_t*>(oc.c_str()), oc.len() + 1,
|
||||
[](const ox::Vector<ox::FieldName>&, const ox::Vector<ox::TypeName>&, const ox::DescriptorField &f, ox::OrganicClawReader *rdr) -> ox::Error {
|
||||
//std::cout << f.fieldName.c_str() << '\n';
|
||||
auto fieldName = f.fieldName.c_str();
|
||||
switch (f.type->primitiveType) {
|
||||
|
98
deps/ox/src/ox/oc/write.cpp
vendored
98
deps/ox/src/ox/oc/write.cpp
vendored
@ -10,105 +10,109 @@
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename Key>
|
||||
OrganicClawWriter<Key>::OrganicClawWriter(Json::Value json) {
|
||||
m_json = json;
|
||||
OrganicClawWriter::OrganicClawWriter(int unionIdx): m_unionIdx(unionIdx) {
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
Error OrganicClawWriter<Key>::field(Key key, int8_t *val) {
|
||||
OrganicClawWriter::OrganicClawWriter(Json::Value json, int unionIdx):
|
||||
m_json(json),
|
||||
m_unionIdx(unionIdx) {
|
||||
}
|
||||
|
||||
Error OrganicClawWriter::field(const char *key, int8_t *val) {
|
||||
if (*val) {
|
||||
m_json[key] = *val;
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
Error OrganicClawWriter<Key>::field(Key key, int16_t *val) {
|
||||
Error OrganicClawWriter::field(const char *key, int16_t *val) {
|
||||
if (*val) {
|
||||
m_json[key] = *val;
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
Error OrganicClawWriter<Key>::field(Key key, int32_t *val) {
|
||||
Error OrganicClawWriter::field(const char *key, int32_t *val) {
|
||||
if (*val) {
|
||||
m_json[key] = *val;
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
Error OrganicClawWriter<Key>::field(Key key, int64_t *val) {
|
||||
Error OrganicClawWriter::field(const char *key, int64_t *val) {
|
||||
if (*val) {
|
||||
m_json[key] = *val;
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
|
||||
template<typename Key>
|
||||
Error OrganicClawWriter<Key>::field(Key key, uint8_t *val) {
|
||||
Error OrganicClawWriter::field(const char *key, uint8_t *val) {
|
||||
if (*val) {
|
||||
m_json[key] = *val;
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
Error OrganicClawWriter<Key>::field(Key key, uint16_t *val) {
|
||||
if (*val) {
|
||||
m_json[key] = *val;
|
||||
Error OrganicClawWriter::field(const char *key, uint16_t *val) {
|
||||
if (targetValid() && *val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
Error OrganicClawWriter<Key>::field(Key key, uint32_t *val) {
|
||||
if (*val) {
|
||||
m_json[key] = *val;
|
||||
Error OrganicClawWriter::field(const char *key, uint32_t *val) {
|
||||
if (targetValid() && *val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
Error OrganicClawWriter<Key>::field(Key key, uint64_t *val) {
|
||||
if (*val) {
|
||||
m_json[key] = *val;
|
||||
Error OrganicClawWriter::field(const char *key, uint64_t *val) {
|
||||
if (targetValid() && *val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
Error OrganicClawWriter<Key>::field(Key key, bool *val) {
|
||||
if (*val) {
|
||||
m_json[key] = *val;
|
||||
Error OrganicClawWriter::field(const char *key, bool *val) {
|
||||
if (targetValid() && *val) {
|
||||
value(key) = *val;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
Error OrganicClawWriter<Key>::field(Key key, ox::String val) {
|
||||
if (val.len()) {
|
||||
m_json[key] = val.c_str();
|
||||
Error OrganicClawWriter::field(const char *key, ox::String val) {
|
||||
if (targetValid() && val.len()) {
|
||||
value(key) = val.c_str();
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
Error OrganicClawWriter<Key>::field(Key key, SerStr val) {
|
||||
if (val.len()) {
|
||||
m_json[key] = val.c_str();
|
||||
Error OrganicClawWriter::field(const char *key, SerStr val) {
|
||||
if (targetValid() && val.len()) {
|
||||
value(key) = val.c_str();
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
void OrganicClawWriter<Key>::setTypeInfo(const char*, int) {
|
||||
Json::Value &OrganicClawWriter::value(const char *key) {
|
||||
if (m_json.isArray()) {
|
||||
return m_json[m_fieldIt];
|
||||
} else {
|
||||
return m_json[key];
|
||||
}
|
||||
}
|
||||
|
||||
template class OrganicClawWriter<const char*>;
|
||||
template class OrganicClawWriter<Json::ArrayIndex>;
|
||||
|
||||
}
|
||||
|
100
deps/ox/src/ox/oc/write.hpp
vendored
100
deps/ox/src/ox/oc/write.hpp
vendored
@ -17,101 +17,125 @@
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename Key>
|
||||
class OrganicClawWriter {
|
||||
friend OrganicClawWriter<const char*>;
|
||||
friend OrganicClawWriter<Json::ArrayIndex>;
|
||||
|
||||
template<typename T>
|
||||
friend ValErr<String> writeOC(T *val);
|
||||
|
||||
protected:
|
||||
Json::Value m_json;
|
||||
Json::ArrayIndex m_fieldIt = 0;
|
||||
int m_unionIdx = -1;
|
||||
|
||||
public:
|
||||
OrganicClawWriter() = default;
|
||||
OrganicClawWriter(int unionIdx = -1);
|
||||
|
||||
OrganicClawWriter(Json::Value json);
|
||||
OrganicClawWriter(Json::Value json, int unionIdx = -1);
|
||||
|
||||
Error field(Key, int8_t *val);
|
||||
Error field(Key, int16_t *val);
|
||||
Error field(Key, int32_t *val);
|
||||
Error field(Key, int64_t *val);
|
||||
[[nodiscard]] Error field(const char*, int8_t *val);
|
||||
[[nodiscard]] Error field(const char*, int16_t *val);
|
||||
[[nodiscard]] Error field(const char*, int32_t *val);
|
||||
[[nodiscard]] Error field(const char*, int64_t *val);
|
||||
|
||||
Error field(Key, uint8_t *val);
|
||||
Error field(Key, uint16_t *val);
|
||||
Error field(Key, uint32_t *val);
|
||||
Error field(Key, uint64_t *val);
|
||||
[[nodiscard]] Error field(const char*, uint8_t *val);
|
||||
[[nodiscard]] Error field(const char*, uint16_t *val);
|
||||
[[nodiscard]] Error field(const char*, uint32_t *val);
|
||||
[[nodiscard]] Error field(const char*, uint64_t *val);
|
||||
|
||||
Error field(Key, bool *val);
|
||||
[[nodiscard]] Error field(const char*, bool *val);
|
||||
|
||||
template<typename T>
|
||||
Error field(Key, T *val, std::size_t len);
|
||||
[[nodiscard]] Error field(const char*, T *val, std::size_t len);
|
||||
|
||||
template<typename U>
|
||||
[[nodiscard]] Error field(const char*, UnionView<U> val);
|
||||
|
||||
template<typename T>
|
||||
Error field(Key, ox::Vector<T> *val);
|
||||
[[nodiscard]] Error field(const char*, ox::Vector<T> *val);
|
||||
|
||||
template<std::size_t L>
|
||||
Error field(Key, ox::BString<L> *val);
|
||||
[[nodiscard]] Error field(const char*, ox::BString<L> *val);
|
||||
|
||||
Error field(Key, ox::String val);
|
||||
[[nodiscard]] Error field(const char*, ox::String val);
|
||||
|
||||
Error field(Key, SerStr val);
|
||||
[[nodiscard]] Error field(const char*, SerStr val);
|
||||
|
||||
template<typename T>
|
||||
Error field(Key, T *val);
|
||||
[[nodiscard]] Error field(const char*, T *val);
|
||||
|
||||
void setTypeInfo(const char *name, int fields);
|
||||
template<typename T = void>
|
||||
constexpr void setTypeInfo(const char* = T::TypeName, int = T::Fields) {
|
||||
}
|
||||
|
||||
static constexpr auto opType() {
|
||||
return OpType::Write;
|
||||
}
|
||||
|
||||
private:
|
||||
constexpr bool targetValid() noexcept {
|
||||
return static_cast<int>(m_fieldIt) == m_unionIdx || m_unionIdx == -1;
|
||||
}
|
||||
|
||||
Json::Value &value(const char *key);
|
||||
|
||||
};
|
||||
|
||||
template<typename Key>
|
||||
template<typename T>
|
||||
Error OrganicClawWriter<Key>::field(Key key, T *val, std::size_t len) {
|
||||
OrganicClawWriter<Json::ArrayIndex> w;
|
||||
Error OrganicClawWriter::field(const char *key, T *val, std::size_t len) {
|
||||
if (targetValid()) {
|
||||
OrganicClawWriter w(Json::Value(Json::arrayValue));
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
oxReturnError(w.field(i, &val[i]));
|
||||
oxReturnError(w.field("", &val[i]));
|
||||
}
|
||||
m_json[key] = w.m_json;
|
||||
value(key) = w.m_json;
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
template<std::size_t L>
|
||||
Error OrganicClawWriter<Key>::field(Key key, ox::BString<L> *val) {
|
||||
Error OrganicClawWriter::field(const char *key, ox::BString<L> *val) {
|
||||
return field(key, SerStr(val->data(), val->cap()));
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
template<typename T>
|
||||
Error OrganicClawWriter<Key>::field(Key key, T *val) {
|
||||
OrganicClawWriter<const char*> w;
|
||||
Error OrganicClawWriter::field(const char *key, T *val) {
|
||||
if (targetValid()) {
|
||||
OrganicClawWriter w;
|
||||
oxReturnError(model(&w, val));
|
||||
if (!w.m_json.isNull()) {
|
||||
m_json[key] = w.m_json;
|
||||
value(key) = w.m_json;
|
||||
}
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
Error OrganicClawWriter::field(const char *key, UnionView<U> val) {
|
||||
if (targetValid()) {
|
||||
OrganicClawWriter w(val.idx());
|
||||
oxReturnError(model(&w, val.get()));
|
||||
if (!w.m_json.isNull()) {
|
||||
value(key) = w.m_json;
|
||||
}
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
template<typename T>
|
||||
Error OrganicClawWriter<Key>::field(Key key, ox::Vector<T> *val) {
|
||||
Error OrganicClawWriter::field(const char *key, ox::Vector<T> *val) {
|
||||
return field(key, val->data(), val->size());
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
ValErr<String> writeOC(T *val) {
|
||||
OrganicClawWriter<const char*> writer;
|
||||
OrganicClawWriter writer;
|
||||
oxReturnError(model(&writer, val));
|
||||
Json::StreamWriterBuilder jsonBuilder;
|
||||
return String(Json::writeString(jsonBuilder, writer.m_json).c_str());
|
||||
}
|
||||
|
||||
extern template class OrganicClawWriter<const char*>;
|
||||
extern template class OrganicClawWriter<Json::ArrayIndex>;
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user