[ox] Add HashMap<String, T> to serializaton handlers
This commit is contained in:
parent
0698353fbf
commit
b6f8c9e242
4
deps/ox/src/ox/mc/read.cpp
vendored
4
deps/ox/src/ox/mc/read.cpp
vendored
@ -26,7 +26,9 @@ MetalClawReader::~MetalClawReader() noexcept {
|
|||||||
if (m_parent) {
|
if (m_parent) {
|
||||||
m_parent->m_buffIt += m_buffIt;
|
m_parent->m_buffIt += m_buffIt;
|
||||||
}
|
}
|
||||||
oxAssert(m_field == m_fields, "MetalClawReader: incorrect fields number given");
|
if (m_field != m_fields) {
|
||||||
|
oxTrace("ox::mc::MetalClawReader::error") << "MetalClawReader: incorrect fields number given";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Error MetalClawReader::field(const char*, int8_t *val) {
|
Error MetalClawReader::field(const char*, int8_t *val) {
|
||||||
|
32
deps/ox/src/ox/mc/read.hpp
vendored
32
deps/ox/src/ox/mc/read.hpp
vendored
@ -55,6 +55,10 @@ class MetalClawReader {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]] Error field(const char*, T *val, std::size_t len);
|
[[nodiscard]] Error field(const char*, T *val, std::size_t len);
|
||||||
|
|
||||||
|
// map handler
|
||||||
|
template<typename T>
|
||||||
|
[[nodiscard]] Error field(const char*, HashMap<String, T> *val);
|
||||||
|
|
||||||
// array handler, with callback to allow handling individual elements
|
// array handler, with callback to allow handling individual elements
|
||||||
template<typename T, typename Handler>
|
template<typename T, typename Handler>
|
||||||
[[nodiscard]] Error field(const char*, Handler handler);
|
[[nodiscard]] Error field(const char*, Handler handler);
|
||||||
@ -191,6 +195,34 @@ Error MetalClawReader::field(const char *name, T *val, std::size_t valLen) {
|
|||||||
return OxError(0);
|
return OxError(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Error MetalClawReader::field(const char*, HashMap<String, T> *val) {
|
||||||
|
if (m_unionIdx == -1 || m_unionIdx == m_field) {
|
||||||
|
if (m_fieldPresence.get(m_field)) {
|
||||||
|
// read the length
|
||||||
|
if (m_buffIt >= m_buffLen) {
|
||||||
|
return OxError(MC_BUFFENDED);
|
||||||
|
}
|
||||||
|
std::size_t bytesRead = 0;
|
||||||
|
auto len = mc::decodeInteger<ArrayLength>(&m_buff[m_buffIt], m_buffLen - m_buffIt, &bytesRead);
|
||||||
|
m_buffIt += bytesRead;
|
||||||
|
oxReturnError(len.error);
|
||||||
|
|
||||||
|
// read the list
|
||||||
|
auto reader = child("");
|
||||||
|
reader.setTypeInfo("List", len.value);
|
||||||
|
for (std::size_t i = 0; i < len.value; i++) {
|
||||||
|
auto keyLen = reader.stringLength(nullptr);
|
||||||
|
auto wkey = ox_malloca(keyLen + 1, char, 0);
|
||||||
|
oxReturnError(reader.field("", SerStr(wkey.get(), keyLen)));
|
||||||
|
oxReturnError(reader.field("", &val->at(wkey.get())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++m_field;
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T, typename Handler>
|
template<typename T, typename Handler>
|
||||||
Error MetalClawReader::field(const char*, Handler handler) {
|
Error MetalClawReader::field(const char*, Handler handler) {
|
||||||
if (m_unionIdx == -1 || m_unionIdx == m_field) {
|
if (m_unionIdx == -1 || m_unionIdx == m_field) {
|
||||||
|
9
deps/ox/src/ox/mc/test/tests.cpp
vendored
9
deps/ox/src/ox/mc/test/tests.cpp
vendored
@ -6,6 +6,7 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "ox/std/hashmap.hpp"
|
||||||
#undef NDEBUG
|
#undef NDEBUG
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -36,7 +37,7 @@ struct TestStructNest {
|
|||||||
|
|
||||||
struct TestStruct {
|
struct TestStruct {
|
||||||
static constexpr auto TypeName = "TestStruct";
|
static constexpr auto TypeName = "TestStruct";
|
||||||
static constexpr auto Fields = 16;
|
static constexpr auto Fields = 17;
|
||||||
bool Bool = false;
|
bool Bool = false;
|
||||||
int32_t Int = 0;
|
int32_t Int = 0;
|
||||||
int32_t Int1 = 0;
|
int32_t Int1 = 0;
|
||||||
@ -51,6 +52,7 @@ struct TestStruct {
|
|||||||
char *CString = nullptr;
|
char *CString = nullptr;
|
||||||
ox::BString<32> String = "";
|
ox::BString<32> String = "";
|
||||||
uint32_t List[4] = {0, 0, 0, 0};
|
uint32_t List[4] = {0, 0, 0, 0};
|
||||||
|
ox::HashMap<ox::String, int> Map;
|
||||||
TestStructNest EmptyStruct;
|
TestStructNest EmptyStruct;
|
||||||
TestStructNest Struct;
|
TestStructNest Struct;
|
||||||
|
|
||||||
@ -95,6 +97,7 @@ ox::Error model(T *io, TestStruct *obj) {
|
|||||||
oxReturnError(io->field("CString", ox::SerStr(&obj->CString)));
|
oxReturnError(io->field("CString", ox::SerStr(&obj->CString)));
|
||||||
oxReturnError(io->field("String", &obj->String));
|
oxReturnError(io->field("String", &obj->String));
|
||||||
oxReturnError(io->field("List", obj->List, 4));
|
oxReturnError(io->field("List", obj->List, 4));
|
||||||
|
oxReturnError(io->field("Map", &obj->Map));
|
||||||
oxReturnError(io->field("EmptyStruct", &obj->EmptyStruct));
|
oxReturnError(io->field("EmptyStruct", &obj->EmptyStruct));
|
||||||
oxReturnError(io->field("Struct", &obj->Struct));
|
oxReturnError(io->field("Struct", &obj->Struct));
|
||||||
return OxError(0);
|
return OxError(0);
|
||||||
@ -133,6 +136,8 @@ std::map<std::string, ox::Error(*)()> tests = {
|
|||||||
testIn.List[1] = 2;
|
testIn.List[1] = 2;
|
||||||
testIn.List[2] = 3;
|
testIn.List[2] = 3;
|
||||||
testIn.List[3] = 4;
|
testIn.List[3] = 4;
|
||||||
|
testIn.Map["asdf"] = 93;
|
||||||
|
testIn.Map["aoeu"] = 94;
|
||||||
testIn.Struct.Bool = false;
|
testIn.Struct.Bool = false;
|
||||||
testIn.Struct.Int = 300;
|
testIn.Struct.Int = 300;
|
||||||
testIn.Struct.String = "Test String 2";
|
testIn.Struct.String = "Test String 2";
|
||||||
@ -158,6 +163,8 @@ std::map<std::string, ox::Error(*)()> tests = {
|
|||||||
oxAssert(testIn.List[1] == testOut.List[1], "List[1] value mismatch");
|
oxAssert(testIn.List[1] == testOut.List[1], "List[1] value mismatch");
|
||||||
oxAssert(testIn.List[2] == testOut.List[2], "List[2] value mismatch");
|
oxAssert(testIn.List[2] == testOut.List[2], "List[2] value mismatch");
|
||||||
oxAssert(testIn.List[3] == testOut.List[3], "List[3] value mismatch");
|
oxAssert(testIn.List[3] == testOut.List[3], "List[3] value mismatch");
|
||||||
|
oxAssert(testIn.Map["asdf"] == testOut.Map["asdf"], "Map[\"asdf\"] value mismatch");
|
||||||
|
oxAssert(testIn.Map["aoeu"] == testOut.Map["aoeu"], "Map[\"aoeu\"] value mismatch");
|
||||||
oxAssert(testIn.EmptyStruct.Bool == testOut.EmptyStruct.Bool, "EmptyStruct.Bool value mismatch");
|
oxAssert(testIn.EmptyStruct.Bool == testOut.EmptyStruct.Bool, "EmptyStruct.Bool value mismatch");
|
||||||
oxAssert(testIn.EmptyStruct.Int == testOut.EmptyStruct.Int, "EmptyStruct.Int value mismatch");
|
oxAssert(testIn.EmptyStruct.Int == testOut.EmptyStruct.Int, "EmptyStruct.Int value mismatch");
|
||||||
oxAssert(testIn.EmptyStruct.String == testOut.EmptyStruct.String, "EmptyStruct.String value mismatch");
|
oxAssert(testIn.EmptyStruct.String == testOut.EmptyStruct.String, "EmptyStruct.String value mismatch");
|
||||||
|
5
deps/ox/src/ox/mc/write.cpp
vendored
5
deps/ox/src/ox/mc/write.cpp
vendored
@ -9,6 +9,7 @@
|
|||||||
#include <ox/std/assert.hpp>
|
#include <ox/std/assert.hpp>
|
||||||
#include <ox/std/byteswap.hpp>
|
#include <ox/std/byteswap.hpp>
|
||||||
#include <ox/std/memops.hpp>
|
#include <ox/std/memops.hpp>
|
||||||
|
#include <ox/std/trace.hpp>
|
||||||
|
|
||||||
#include "write.hpp"
|
#include "write.hpp"
|
||||||
|
|
||||||
@ -22,7 +23,9 @@ MetalClawWriter::MetalClawWriter(uint8_t *buff, std::size_t buffLen, int unionId
|
|||||||
}
|
}
|
||||||
|
|
||||||
MetalClawWriter::~MetalClawWriter() noexcept {
|
MetalClawWriter::~MetalClawWriter() noexcept {
|
||||||
oxAssert(m_field == m_fields, "MetalClawWriter: incorrect fields number given");
|
if (m_field != m_fields) {
|
||||||
|
oxTrace("ox::mc::MetalClawWriter::error") << "MetalClawReader: incorrect fields number given";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Error MetalClawWriter::field(const char*, int8_t *val) noexcept {
|
Error MetalClawWriter::field(const char*, int8_t *val) noexcept {
|
||||||
|
47
deps/ox/src/ox/mc/write.hpp
vendored
47
deps/ox/src/ox/mc/write.hpp
vendored
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "intops.hpp"
|
#include "intops.hpp"
|
||||||
#include "err.hpp"
|
#include "err.hpp"
|
||||||
|
#include "ox/std/hashmap.hpp"
|
||||||
#include "presenceindicator.hpp"
|
#include "presenceindicator.hpp"
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
|
|
||||||
@ -56,7 +57,10 @@ class MetalClawWriter {
|
|||||||
[[nodiscard]] Error field(const char*, T *val, std::size_t len);
|
[[nodiscard]] Error field(const char*, T *val, std::size_t len);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]] Error field(const char*, ox::Vector<T> *val);
|
[[nodiscard]] Error field(const char*, Vector<T> *val);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
[[nodiscard]] Error field(const char*, HashMap<String, T> *val);
|
||||||
|
|
||||||
template<std::size_t L>
|
template<std::size_t L>
|
||||||
[[nodiscard]] Error field(const char*, ox::BString<L> *val) noexcept;
|
[[nodiscard]] Error field(const char*, ox::BString<L> *val) noexcept;
|
||||||
@ -153,10 +157,49 @@ Error MetalClawWriter::field(const char*, T *val, std::size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Error MetalClawWriter::field(const char*, ox::Vector<T> *val) {
|
Error MetalClawWriter::field(const char*, Vector<T> *val) {
|
||||||
return field(nullptr, val->data(), val->size());
|
return field(nullptr, val->data(), val->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
[[nodiscard]] Error MetalClawWriter::field(const char*, HashMap<String, T> *val) {
|
||||||
|
auto &keys = val->keys();
|
||||||
|
auto len = keys.size();
|
||||||
|
bool fieldSet = false;
|
||||||
|
|
||||||
|
if (len && (m_unionIdx == -1 || m_unionIdx == m_field)) {
|
||||||
|
// write the length
|
||||||
|
const auto arrLen = mc::encodeInteger(len);
|
||||||
|
if (m_buffIt + arrLen.length < m_buffLen) {
|
||||||
|
ox_memcpy(&m_buff[m_buffIt], arrLen.data, arrLen.length);
|
||||||
|
m_buffIt += arrLen.length;
|
||||||
|
} else {
|
||||||
|
return OxError(MC_BUFFENDED);
|
||||||
|
}
|
||||||
|
|
||||||
|
MetalClawWriter writer(m_buff + m_buffIt, m_buffLen - m_buffIt);
|
||||||
|
// double len for both key and value
|
||||||
|
writer.setTypeInfo("Map", len * 2);
|
||||||
|
|
||||||
|
// write the array
|
||||||
|
for (std::size_t i = 0; i < len; i++) {
|
||||||
|
auto &key = keys[i];
|
||||||
|
const auto keyLen = ox_strlen(key);
|
||||||
|
auto wkey = static_cast<char*>(ox_alloca(keyLen));
|
||||||
|
memcpy(wkey, key.c_str(), keyLen + 1);
|
||||||
|
oxReturnError(writer.field("", SerStr(&wkey, keyLen)));
|
||||||
|
oxReturnError(writer.field("", &(*val)[key]));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_buffIt += writer.m_buffIt;
|
||||||
|
fieldSet = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
oxReturnError(m_fieldPresence.set(m_field, fieldSet));
|
||||||
|
m_field++;
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename I>
|
template<typename I>
|
||||||
Error MetalClawWriter::appendInteger(I val) noexcept {
|
Error MetalClawWriter::appendInteger(I val) noexcept {
|
||||||
bool fieldSet = false;
|
bool fieldSet = false;
|
||||||
|
8
deps/ox/src/ox/model/descwrite.hpp
vendored
8
deps/ox/src/ox/model/descwrite.hpp
vendored
@ -132,6 +132,9 @@ class TypeDescWriter {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
DescriptorType *type(Vector<T> *val, bool *alreadyExisted);
|
DescriptorType *type(Vector<T> *val, bool *alreadyExisted);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
DescriptorType *type(HashMap<String, T> *val, bool *alreadyExisted);
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
DescriptorType *type(UnionView<U> val, bool *alreadyExisted);
|
DescriptorType *type(UnionView<U> val, bool *alreadyExisted);
|
||||||
|
|
||||||
@ -204,6 +207,11 @@ DescriptorType *TypeDescWriter::type(Vector<T> *val, bool *alreadyExisted) {
|
|||||||
return type(val->data(), alreadyExisted);
|
return type(val->data(), alreadyExisted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
DescriptorType *TypeDescWriter::type(HashMap<String, T>*, bool *alreadyExisted) {
|
||||||
|
return type(static_cast<T*>(nullptr), alreadyExisted);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
DescriptorType *TypeDescWriter::type(UnionView<U> val, bool *alreadyExisted) {
|
DescriptorType *TypeDescWriter::type(UnionView<U> val, bool *alreadyExisted) {
|
||||||
return type(val.get(), alreadyExisted);
|
return type(val.get(), alreadyExisted);
|
||||||
|
19
deps/ox/src/ox/oc/read.hpp
vendored
19
deps/ox/src/ox/oc/read.hpp
vendored
@ -12,6 +12,7 @@
|
|||||||
#include <ox/model/optype.hpp>
|
#include <ox/model/optype.hpp>
|
||||||
#include <ox/model/types.hpp>
|
#include <ox/model/types.hpp>
|
||||||
#include <ox/std/byteswap.hpp>
|
#include <ox/std/byteswap.hpp>
|
||||||
|
#include <ox/std/hashmap.hpp>
|
||||||
#include <ox/std/memops.hpp>
|
#include <ox/std/memops.hpp>
|
||||||
#include <ox/std/string.hpp>
|
#include <ox/std/string.hpp>
|
||||||
#include <ox/std/vector.hpp>
|
#include <ox/std/vector.hpp>
|
||||||
@ -51,7 +52,10 @@ class OrganicClawReader {
|
|||||||
[[nodiscard]] Error field(const char *key, T *val, std::size_t len);
|
[[nodiscard]] Error field(const char *key, T *val, std::size_t len);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]] Error field(const char *key, ox::Vector<T> *val);
|
[[nodiscard]] Error field(const char *key, Vector<T> *val);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
[[nodiscard]] Error field(const char*, HashMap<String, T> *val);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]] Error field(const char *key, T *val);
|
[[nodiscard]] Error field(const char *key, T *val);
|
||||||
@ -158,6 +162,19 @@ Error OrganicClawReader::field(const char *key, ox::Vector<T> *val) {
|
|||||||
return field(key, val->data(), val->size());
|
return field(key, val->data(), val->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
[[nodiscard]] Error OrganicClawReader::field(const char *key, HashMap<String, T> *val) {
|
||||||
|
const auto &srcVal = value(key);
|
||||||
|
auto keys = srcVal.getMemberNames();
|
||||||
|
auto srcSize = srcVal.size();
|
||||||
|
OrganicClawReader r(srcVal);
|
||||||
|
for (decltype(srcSize) i = 0; i < srcSize; ++i) {
|
||||||
|
auto k = keys[i].c_str();
|
||||||
|
oxReturnError(r.field(k, &val->at(k)));
|
||||||
|
}
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Error readOC(const char *json, std::size_t jsonSize, T *val) noexcept {
|
Error readOC(const char *json, std::size_t jsonSize, T *val) noexcept {
|
||||||
// OrganicClawReader constructor can throw, but readOC should return its errors.
|
// OrganicClawReader constructor can throw, but readOC should return its errors.
|
||||||
|
8
deps/ox/src/ox/oc/test/tests.cpp
vendored
8
deps/ox/src/ox/oc/test/tests.cpp
vendored
@ -45,6 +45,7 @@ struct TestStruct {
|
|||||||
char *CString = nullptr;
|
char *CString = nullptr;
|
||||||
ox::BString<32> String = "";
|
ox::BString<32> String = "";
|
||||||
uint32_t List[4] = {0, 0, 0, 0};
|
uint32_t List[4] = {0, 0, 0, 0};
|
||||||
|
ox::HashMap<ox::String, int> Map;
|
||||||
TestStructNest EmptyStruct;
|
TestStructNest EmptyStruct;
|
||||||
TestStructNest Struct;
|
TestStructNest Struct;
|
||||||
|
|
||||||
@ -74,7 +75,7 @@ ox::Error model(T *io, TestStructNest *obj) {
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ox::Error model(T *io, TestStruct *obj) {
|
ox::Error model(T *io, TestStruct *obj) {
|
||||||
io->setTypeInfo("TestStruct", 16);
|
io->setTypeInfo("TestStruct", 17);
|
||||||
oxReturnError(io->field("Bool", &obj->Bool));
|
oxReturnError(io->field("Bool", &obj->Bool));
|
||||||
oxReturnError(io->field("Int", &obj->Int));
|
oxReturnError(io->field("Int", &obj->Int));
|
||||||
oxReturnError(io->field("Int1", &obj->Int1));
|
oxReturnError(io->field("Int1", &obj->Int1));
|
||||||
@ -89,6 +90,7 @@ ox::Error model(T *io, TestStruct *obj) {
|
|||||||
oxReturnError(io->field("CString", ox::SerStr(&obj->CString)));
|
oxReturnError(io->field("CString", ox::SerStr(&obj->CString)));
|
||||||
oxReturnError(io->field("String", &obj->String));
|
oxReturnError(io->field("String", &obj->String));
|
||||||
oxReturnError(io->field("List", obj->List, 4));
|
oxReturnError(io->field("List", obj->List, 4));
|
||||||
|
oxReturnError(io->field("Map", &obj->Map));
|
||||||
oxReturnError(io->field("EmptyStruct", &obj->EmptyStruct));
|
oxReturnError(io->field("EmptyStruct", &obj->EmptyStruct));
|
||||||
oxReturnError(io->field("Struct", &obj->Struct));
|
oxReturnError(io->field("Struct", &obj->Struct));
|
||||||
return OxError(0);
|
return OxError(0);
|
||||||
@ -119,6 +121,8 @@ std::map<std::string, ox::Error(*)()> tests = {
|
|||||||
testIn.List[1] = 2;
|
testIn.List[1] = 2;
|
||||||
testIn.List[2] = 3;
|
testIn.List[2] = 3;
|
||||||
testIn.List[3] = 4;
|
testIn.List[3] = 4;
|
||||||
|
testIn.Map["asdf"] = 93;
|
||||||
|
testIn.Map["aoeu"] = 94;
|
||||||
testIn.Struct.Bool = false;
|
testIn.Struct.Bool = false;
|
||||||
testIn.Struct.Int = 300;
|
testIn.Struct.Int = 300;
|
||||||
testIn.Struct.String = "Test String 2";
|
testIn.Struct.String = "Test String 2";
|
||||||
@ -146,6 +150,8 @@ std::map<std::string, ox::Error(*)()> tests = {
|
|||||||
oxAssert(testIn.List[1] == testOut->List[1], "List[1] value mismatch");
|
oxAssert(testIn.List[1] == testOut->List[1], "List[1] value mismatch");
|
||||||
oxAssert(testIn.List[2] == testOut->List[2], "List[2] value mismatch");
|
oxAssert(testIn.List[2] == testOut->List[2], "List[2] value mismatch");
|
||||||
oxAssert(testIn.List[3] == testOut->List[3], "List[3] value mismatch");
|
oxAssert(testIn.List[3] == testOut->List[3], "List[3] value mismatch");
|
||||||
|
oxAssert(testIn.Map["asdf"] == testOut->Map["asdf"], "Map[\"asdf\"] value mismatch");
|
||||||
|
oxAssert(testIn.Map["aoeu"] == testOut->Map["aoeu"], "Map[\"aoeu\"] value mismatch");
|
||||||
oxAssert(testIn.EmptyStruct.Bool == testOut->EmptyStruct.Bool, "EmptyStruct.Bool value mismatch");
|
oxAssert(testIn.EmptyStruct.Bool == testOut->EmptyStruct.Bool, "EmptyStruct.Bool value mismatch");
|
||||||
oxAssert(testIn.EmptyStruct.Int == testOut->EmptyStruct.Int, "EmptyStruct.Int value mismatch");
|
oxAssert(testIn.EmptyStruct.Int == testOut->EmptyStruct.Int, "EmptyStruct.Int value mismatch");
|
||||||
oxAssert(testIn.EmptyStruct.String == testOut->EmptyStruct.String, "EmptyStruct.String value mismatch");
|
oxAssert(testIn.EmptyStruct.String == testOut->EmptyStruct.String, "EmptyStruct.String value mismatch");
|
||||||
|
18
deps/ox/src/ox/oc/write.hpp
vendored
18
deps/ox/src/ox/oc/write.hpp
vendored
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <ox/model/optype.hpp>
|
#include <ox/model/optype.hpp>
|
||||||
#include <ox/model/types.hpp>
|
#include <ox/model/types.hpp>
|
||||||
|
#include <ox/std/hashmap.hpp>
|
||||||
#include <ox/std/string.hpp>
|
#include <ox/std/string.hpp>
|
||||||
#include <ox/std/vector.hpp>
|
#include <ox/std/vector.hpp>
|
||||||
|
|
||||||
@ -53,6 +54,9 @@ class OrganicClawWriter {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]] Error field(const char*, ox::Vector<T> *val);
|
[[nodiscard]] Error field(const char*, ox::Vector<T> *val);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
[[nodiscard]] Error field(const char*, HashMap<String, T> *val);
|
||||||
|
|
||||||
template<std::size_t L>
|
template<std::size_t L>
|
||||||
[[nodiscard]] Error field(const char*, ox::BString<L> *val);
|
[[nodiscard]] Error field(const char*, ox::BString<L> *val);
|
||||||
|
|
||||||
@ -129,6 +133,20 @@ Error OrganicClawWriter::field(const char *key, ox::Vector<T> *val) {
|
|||||||
return field(key, val->data(), val->size());
|
return field(key, val->data(), val->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
[[nodiscard]] Error OrganicClawWriter::field(const char *key, ox::HashMap<String, T> *val) {
|
||||||
|
if (targetValid()) {
|
||||||
|
auto &keys = val->keys();
|
||||||
|
OrganicClawWriter w;
|
||||||
|
for (std::size_t i = 0; i < keys.size(); ++i) {
|
||||||
|
auto k = keys[i].c_str();
|
||||||
|
oxReturnError(w.field(k, &val->at(k)));
|
||||||
|
}
|
||||||
|
value(key) = w.m_json;
|
||||||
|
}
|
||||||
|
++m_fieldIt;
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ValErr<Vector<char>> writeOC(T *val) {
|
ValErr<Vector<char>> writeOC(T *val) {
|
||||||
|
26
deps/ox/src/ox/std/hashmap.hpp
vendored
26
deps/ox/src/ox/std/hashmap.hpp
vendored
@ -16,6 +16,9 @@ namespace ox {
|
|||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
class HashMap {
|
class HashMap {
|
||||||
|
|
||||||
|
using key_t = K;
|
||||||
|
using value_t = T;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Pair {
|
struct Pair {
|
||||||
K key = {};
|
K key = {};
|
||||||
@ -31,6 +34,8 @@ class HashMap {
|
|||||||
|
|
||||||
~HashMap();
|
~HashMap();
|
||||||
|
|
||||||
|
bool operator==(const HashMap &other) const;
|
||||||
|
|
||||||
HashMap &operator=(HashMap &other);
|
HashMap &operator=(HashMap &other);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,6 +52,8 @@ class HashMap {
|
|||||||
|
|
||||||
std::size_t size() const noexcept;
|
std::size_t size() const noexcept;
|
||||||
|
|
||||||
|
const Vector<K> &keys() const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void expand();
|
void expand();
|
||||||
|
|
||||||
@ -78,6 +85,20 @@ HashMap<K, T>::~HashMap() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename K, typename T>
|
||||||
|
bool HashMap<K, T>::operator==(const HashMap &other) const {
|
||||||
|
if (m_keys != other.m_keys) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < m_keys.size(); i++) {
|
||||||
|
auto &k = m_keys[i];
|
||||||
|
if (at(k) != other.at(k)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
HashMap<K, T> &HashMap<K, T>::operator=(HashMap<K, T> &other) {
|
HashMap<K, T> &HashMap<K, T>::operator=(HashMap<K, T> &other) {
|
||||||
this->~HashMap<K, T>();
|
this->~HashMap<K, T>();
|
||||||
@ -115,6 +136,11 @@ std::size_t HashMap<K, T>::size() const noexcept {
|
|||||||
return m_keys.size();
|
return m_keys.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename K, typename T>
|
||||||
|
const Vector<K> &HashMap<K, T>::keys() const noexcept {
|
||||||
|
return m_keys;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
void HashMap<K, T>::expand() {
|
void HashMap<K, T>::expand() {
|
||||||
Vector<Pair*> r;
|
Vector<Pair*> r;
|
||||||
|
2
deps/ox/src/ox/std/string.cpp
vendored
2
deps/ox/src/ox/std/string.cpp
vendored
@ -39,7 +39,7 @@ String::String(const char *str, std::size_t size) noexcept {
|
|||||||
m_buff[size] = 0;
|
m_buff[size] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
String::String(String &other) noexcept {
|
String::String(const String &other) noexcept {
|
||||||
m_buff = other.m_buff;
|
m_buff = other.m_buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
deps/ox/src/ox/std/string.hpp
vendored
2
deps/ox/src/ox/std/string.hpp
vendored
@ -29,7 +29,7 @@ class String {
|
|||||||
|
|
||||||
String(const char *str, std::size_t size) noexcept;
|
String(const char *str, std::size_t size) noexcept;
|
||||||
|
|
||||||
String(String&) noexcept;
|
String(const String&) noexcept;
|
||||||
|
|
||||||
String(String&&) noexcept;
|
String(String&&) noexcept;
|
||||||
|
|
||||||
|
8
deps/ox/src/ox/std/vector.hpp
vendored
8
deps/ox/src/ox/std/vector.hpp
vendored
@ -27,13 +27,13 @@ class Vector {
|
|||||||
|
|
||||||
explicit Vector(std::size_t size) noexcept;
|
explicit Vector(std::size_t size) noexcept;
|
||||||
|
|
||||||
Vector(Vector &other) noexcept;
|
Vector(const Vector &other) noexcept;
|
||||||
|
|
||||||
Vector(Vector &&other) noexcept;
|
Vector(Vector &&other) noexcept;
|
||||||
|
|
||||||
~Vector() noexcept;
|
~Vector() noexcept;
|
||||||
|
|
||||||
Vector &operator=(Vector &other) noexcept;
|
Vector &operator=(const Vector &other) noexcept;
|
||||||
|
|
||||||
Vector &operator=(Vector &&other) noexcept;
|
Vector &operator=(Vector &&other) noexcept;
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ Vector<T>::Vector(std::size_t size) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Vector<T>::Vector(Vector<T> &other) noexcept {
|
Vector<T>::Vector(const Vector<T> &other) noexcept {
|
||||||
m_size = other.m_size;
|
m_size = other.m_size;
|
||||||
m_cap = other.m_cap;
|
m_cap = other.m_cap;
|
||||||
m_items = reinterpret_cast<T*>(new AllocAlias<T>[m_cap]);
|
m_items = reinterpret_cast<T*>(new AllocAlias<T>[m_cap]);
|
||||||
@ -128,7 +128,7 @@ Vector<T>::~Vector() noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Vector<T> &Vector<T>::operator=(Vector<T> &other) noexcept {
|
Vector<T> &Vector<T>::operator=(const Vector<T> &other) noexcept {
|
||||||
this->~Vector<T>();
|
this->~Vector<T>();
|
||||||
m_size = other.m_size;
|
m_size = other.m_size;
|
||||||
m_cap = other.m_cap;
|
m_cap = other.m_cap;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user