Merge commit '69fcd7ad1056940166a5d9524b4f03578f680834' as 'deps/oxlib'
This commit is contained in:
Vendored
+50
@@ -0,0 +1,50 @@
|
||||
|
||||
add_library(
|
||||
OxClaw
|
||||
src/read.cpp
|
||||
src/write.cpp
|
||||
)
|
||||
|
||||
if(NOT MSVC)
|
||||
target_compile_options(OxClaw PRIVATE -Wsign-conversion)
|
||||
target_compile_options(OxClaw PRIVATE -Wconversion)
|
||||
endif()
|
||||
|
||||
target_link_libraries(
|
||||
OxClaw PUBLIC
|
||||
OxMetalClaw
|
||||
$<$<BOOL:${OX_USE_STDLIB}>:OxOrganicClaw>
|
||||
)
|
||||
|
||||
#if(OX_USE_STDLIB)
|
||||
# add_executable(
|
||||
# readclaw
|
||||
# readclaw.cpp
|
||||
# )
|
||||
# target_link_libraries(
|
||||
# readclaw PUBLIC
|
||||
# OxClaw
|
||||
# )
|
||||
#endif()
|
||||
|
||||
target_include_directories(
|
||||
OxClaw PUBLIC
|
||||
include
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY
|
||||
include/ox
|
||||
DESTINATION
|
||||
include
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS OxClaw
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
)
|
||||
|
||||
if(OX_RUN_TESTS)
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright 2015 - 2025 gary@drinkingtea.net
|
||||
*
|
||||
* 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 https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "read.hpp"
|
||||
#include "write.hpp"
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2015 - 2025 gary@drinkingtea.net
|
||||
*
|
||||
* 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 https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ox {
|
||||
|
||||
enum class ClawFormat {
|
||||
None,
|
||||
Metal,
|
||||
Organic,
|
||||
};
|
||||
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2015 - 2025 gary@drinkingtea.net
|
||||
*
|
||||
* 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 https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/std/span.hpp>
|
||||
#include <ox/mc/read.hpp>
|
||||
#ifdef OX_USE_STDLIB
|
||||
#include <ox/oc/read.hpp>
|
||||
#endif
|
||||
#include <ox/std/buffer.hpp>
|
||||
#include <ox/std/string.hpp>
|
||||
|
||||
#include "format.hpp"
|
||||
|
||||
namespace ox {
|
||||
|
||||
constexpr auto Error_ClawTypeMismatch = 200;
|
||||
constexpr auto Error_ClawTypeVersionMismatch = 201;
|
||||
|
||||
struct ClawHeader {
|
||||
String typeName;
|
||||
int typeVersion = -1;
|
||||
TypeParamPack typeParams;
|
||||
ClawFormat fmt = ClawFormat::None;
|
||||
const char *data = nullptr;
|
||||
std::size_t dataSize = 0;
|
||||
};
|
||||
|
||||
ox::Result<ox::StringView> readClawTypeId(ox::BufferView buff) noexcept;
|
||||
|
||||
Result<ClawHeader> readClawHeader(ox::BufferView buff) noexcept;
|
||||
|
||||
Result<BufferView> stripClawHeader(ox::BufferView buff) noexcept;
|
||||
|
||||
template<typename T>
|
||||
Error readClaw(ox::BufferView buff, T &val) {
|
||||
OX_REQUIRE(header, readClawHeader(buff));
|
||||
if (header.typeName != getModelTypeName<T>()) {
|
||||
return ox::Error(Error_ClawTypeMismatch, "Claw Read: Type mismatch");
|
||||
}
|
||||
if (header.typeVersion != getModelTypeVersion<T>()) {
|
||||
return ox::Error(Error_ClawTypeVersionMismatch, "Claw Read: Type Version mismatch");
|
||||
}
|
||||
switch (header.fmt) {
|
||||
case ClawFormat::Metal:
|
||||
{
|
||||
ox::BufferReader br({header.data, header.dataSize});
|
||||
MetalClawReader reader(br);
|
||||
return model(reader.interface(), &val);
|
||||
}
|
||||
case ClawFormat::Organic:
|
||||
{
|
||||
#ifdef OX_USE_STDLIB
|
||||
OrganicClawReader reader(header.data, header.dataSize);
|
||||
return model(&reader, &val);
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
case ClawFormat::None:
|
||||
return ox::Error(1);
|
||||
}
|
||||
return ox::Error(1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Result<T> readClaw(ox::BufferView buff) {
|
||||
Result<T> val;
|
||||
OX_RETURN_ERROR(readClaw(buff, val.value));
|
||||
return val;
|
||||
}
|
||||
|
||||
Result<ModelObject> readClaw(TypeStore &ts, BufferView buff) noexcept;
|
||||
|
||||
}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2015 - 2025 gary@drinkingtea.net
|
||||
*
|
||||
* 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 https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/mc/write.hpp>
|
||||
#ifdef OX_USE_STDLIB
|
||||
#include <ox/oc/write.hpp>
|
||||
#endif
|
||||
#include <ox/std/buffer.hpp>
|
||||
#include <ox/std/string.hpp>
|
||||
#include <ox/std/stringview.hpp>
|
||||
|
||||
#include "format.hpp"
|
||||
|
||||
namespace ox {
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct TypeInfoCatcher {
|
||||
|
||||
const char *name = nullptr;
|
||||
int version = 0;
|
||||
|
||||
template<typename T>
|
||||
constexpr ox::Error setTypeInfo(
|
||||
const char *pName = T::TypeName,
|
||||
int pVersion = T::TypeVersion,
|
||||
const Vector<String>& = {},
|
||||
std::size_t = 0) noexcept {
|
||||
this->name = pName;
|
||||
this->version = pVersion;
|
||||
return {};
|
||||
}
|
||||
|
||||
constexpr Error field(...) noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
static constexpr auto opType() {
|
||||
return OpType::Write;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename T, typename = int>
|
||||
struct type_version {
|
||||
static constexpr auto value = -1;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct type_version<T, decltype((void) T::TypeVersion, -1)> {
|
||||
static constexpr auto value = T::TypeVersion;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
constexpr const char *getTypeName(const T *t) noexcept {
|
||||
TypeInfoCatcher tnc;
|
||||
std::ignore = model(&tnc, t);
|
||||
return tnc.name;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr int getTypeVersion(const T *t) noexcept {
|
||||
TypeInfoCatcher tnc;
|
||||
std::ignore = model(&tnc, t);
|
||||
return tnc.version;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ox::Error writeClawHeader(Writer_c auto &writer, const T *t, ClawFormat fmt) noexcept {
|
||||
switch (fmt) {
|
||||
case ClawFormat::Metal:
|
||||
OX_RETURN_ERROR(write(writer, "M2;"));
|
||||
break;
|
||||
case ClawFormat::Organic:
|
||||
OX_RETURN_ERROR(write(writer, "O1;"));
|
||||
break;
|
||||
default:
|
||||
return ox::Error(1);
|
||||
}
|
||||
OX_RETURN_ERROR(write(writer, detail::getTypeName(t)));
|
||||
OX_RETURN_ERROR(writer.put(';'));
|
||||
const auto tn = detail::getTypeVersion(t);
|
||||
if (tn > -1) {
|
||||
OX_RETURN_ERROR(ox::writeItoa(tn, writer));
|
||||
}
|
||||
OX_RETURN_ERROR(writer.put(';'));
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Result<Buffer> writeClaw(
|
||||
const auto &t,
|
||||
ClawFormat fmt = ClawFormat::Metal,
|
||||
std::size_t buffReserveSz = 2 * units::KB) noexcept {
|
||||
Buffer out(buffReserveSz);
|
||||
BufferWriter bw(&out, 0);
|
||||
OX_RETURN_ERROR(detail::writeClawHeader(bw, &t, fmt));
|
||||
#ifdef OX_USE_STDLIB
|
||||
if (fmt == ClawFormat::Metal) {
|
||||
OX_RETURN_ERROR(writeMC(bw, t));
|
||||
} else if (fmt == ClawFormat::Organic) {
|
||||
OX_REQUIRE(data, writeOC(t));
|
||||
OX_RETURN_ERROR(bw.write(data.data(), data.size()));
|
||||
}
|
||||
#else
|
||||
if (fmt != ClawFormat::Metal) {
|
||||
return ox::Error(1, "OC is not supported in this build");
|
||||
}
|
||||
OX_RETURN_ERROR(writeMC(bw, t));
|
||||
#endif
|
||||
out.resize(bw.tellp());
|
||||
return out;
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+129
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright 2015 - 2025 gary@drinkingtea.net
|
||||
*
|
||||
* 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 https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <ox/std/buffer.hpp>
|
||||
|
||||
#include <ox/claw/read.hpp>
|
||||
|
||||
namespace ox {
|
||||
|
||||
Result<StringView> readClawTypeId(BufferView const buff) noexcept {
|
||||
auto buffRaw = buff.data();
|
||||
auto buffLen = buff.size();
|
||||
size_t outSz{};
|
||||
const auto s1End = ox::strchr(buffRaw, ';', buffLen);
|
||||
if (!s1End) {
|
||||
return ox::Error(1, "Could not read Claw header");
|
||||
}
|
||||
auto const fmtSz = static_cast<std::size_t>(s1End - buffRaw) + 1;
|
||||
buffRaw += fmtSz;
|
||||
buffLen -= fmtSz;
|
||||
outSz += fmtSz;
|
||||
auto const s2End = ox::strchr(buffRaw, ';', buffLen);
|
||||
if (!s2End) {
|
||||
return ox::Error(2, "Could not read Claw header");
|
||||
}
|
||||
auto const s2Size = static_cast<std::size_t>(s2End - buffRaw) + 1;
|
||||
buffRaw += s2Size;
|
||||
buffLen -= s2Size;
|
||||
outSz += s2Size;
|
||||
auto const s3End = ox::strchr(buffRaw, ';', buffLen) + 1;
|
||||
if (!s3End) {
|
||||
return ox::Error(3, "Could not read Claw header");
|
||||
}
|
||||
auto const s3Size = static_cast<std::size_t>(s3End - buffRaw);
|
||||
buffRaw += s3Size;
|
||||
buffLen -= s3Size;
|
||||
outSz += s3Size;
|
||||
return {{buff.data() + fmtSz, outSz - fmtSz - 1}};
|
||||
}
|
||||
|
||||
Result<ClawHeader> readClawHeader(BufferView const buff) noexcept {
|
||||
auto buffRaw = buff.data();
|
||||
auto buffLen = buff.size();
|
||||
const auto s1End = ox::strchr(buffRaw, ';', buffLen);
|
||||
if (!s1End) {
|
||||
return ox::Error(1, "Could not read Claw header");
|
||||
}
|
||||
auto const s1Size = static_cast<std::size_t>(s1End - buffRaw);
|
||||
StringView const fmt(buffRaw, s1Size);
|
||||
buffRaw += s1Size + 1;
|
||||
buffLen -= s1Size + 1;
|
||||
|
||||
auto const s2End = ox::strchr(buffRaw, ';', buffLen);
|
||||
if (!s2End) {
|
||||
return ox::Error(2, "Could not read Claw header");
|
||||
}
|
||||
auto const s2Size = static_cast<std::size_t>(s2End - buffRaw);
|
||||
StringView const typeName(buffRaw, s2Size);
|
||||
buffRaw += s2Size + 1;
|
||||
buffLen -= s2Size + 1;
|
||||
|
||||
auto const s3End = ox::strchr(buffRaw, ';', buffLen);
|
||||
if (!s3End) {
|
||||
return ox::Error(3, "Could not read Claw header");
|
||||
}
|
||||
auto const s3Size = static_cast<std::size_t>(s3End - buffRaw);
|
||||
StringView const versionStr(buffRaw, s3Size);
|
||||
buffRaw += s3Size + 1;
|
||||
buffLen -= s3Size + 1;
|
||||
ClawHeader hdr;
|
||||
if (fmt == "M2") {
|
||||
hdr.fmt = ClawFormat::Metal;
|
||||
} else if (fmt == "O1") {
|
||||
hdr.fmt = ClawFormat::Organic;
|
||||
} else {
|
||||
return ox::Error(4, "Claw format does not match any supported format/version combo");
|
||||
}
|
||||
hdr.typeName = typeName;
|
||||
std::ignore = ox::strToInt(versionStr).copyTo(hdr.typeVersion);
|
||||
hdr.data = buffRaw;
|
||||
hdr.dataSize = buffLen;
|
||||
return hdr;
|
||||
}
|
||||
|
||||
Result<BufferView> stripClawHeader(BufferView const buff) noexcept {
|
||||
OX_REQUIRE(header, readClawHeader(buff));
|
||||
return {{header.data, header.dataSize}};
|
||||
}
|
||||
|
||||
Result<ModelObject> readClaw(TypeStore &ts, BufferView buff) noexcept {
|
||||
OX_REQUIRE(header, readClawHeader(buff));
|
||||
auto const [t, tdErr] = ts.getLoad(
|
||||
header.typeName, header.typeVersion, header.typeParams);
|
||||
if (tdErr) {
|
||||
return ox::Error(3, "Could not load type descriptor");
|
||||
}
|
||||
ModelObject obj;
|
||||
OX_RETURN_ERROR(obj.setType(t));
|
||||
switch (header.fmt) {
|
||||
case ClawFormat::Metal:
|
||||
{
|
||||
ox::BufferReader br({header.data, header.dataSize});
|
||||
MetalClawReader reader(br);
|
||||
OX_RETURN_ERROR(model(reader.interface(), &obj));
|
||||
return obj;
|
||||
}
|
||||
case ClawFormat::Organic:
|
||||
{
|
||||
#ifdef OX_USE_STDLIB
|
||||
OrganicClawReader reader({header.data, header.dataSize});
|
||||
ModelHandlerInterface handler(reader);
|
||||
OX_RETURN_ERROR(model(&handler, &obj));
|
||||
return obj;
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
case ClawFormat::None:
|
||||
return ox::Error(1);
|
||||
}
|
||||
return ox::Error(1);
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2015 - 2025 gary@drinkingtea.net
|
||||
*
|
||||
* 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 https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include <ox/std/reader.hpp>
|
||||
#include <ox/std/trace.hpp>
|
||||
|
||||
#include "claw.hpp"
|
||||
|
||||
|
||||
int main(int argc, char **args) {
|
||||
if (argc > 2) {
|
||||
oxErr("Too many arguments");
|
||||
return -1;
|
||||
}
|
||||
auto const file = argc == 1 ? stdin : fopen(args[1], "r");
|
||||
if (fseek(file, 0, SEEK_END)) {
|
||||
oxErr("Could not get file size\n");
|
||||
return -2;
|
||||
}
|
||||
auto const size = static_cast<std::size_t>(ftell(file));
|
||||
oxDebugf("{}", size);
|
||||
return 0;
|
||||
}
|
||||
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2015 - 2025 gary@drinkingtea.net
|
||||
*
|
||||
* 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 https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <ox/claw/write.hpp>
|
||||
|
||||
namespace ox::detail {
|
||||
|
||||
struct versioned_type {
|
||||
static constexpr int TypeVersion = 4;
|
||||
};
|
||||
|
||||
struct unversioned_type {
|
||||
};
|
||||
|
||||
static_assert(type_version<versioned_type>::value == 4);
|
||||
static_assert(type_version<unversioned_type>::value == -1);
|
||||
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
add_executable(
|
||||
ClawTest
|
||||
tests.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
ClawTest
|
||||
OxClaw
|
||||
)
|
||||
|
||||
add_test("[ox/claw] ClawHeaderReader" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ClawTest ClawHeaderReader)
|
||||
add_test("[ox/claw] ClawHeaderReader2" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ClawTest ClawHeaderReader2)
|
||||
add_test("[ox/claw] ClawHeaderReadTypeId" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ClawTest ClawHeaderReadTypeId)
|
||||
add_test("[ox/claw] ClawWriter" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ClawTest ClawWriter)
|
||||
add_test("[ox/claw] ClawReader" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ClawTest ClawReader)
|
||||
Vendored
+211
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright 2015 - 2025 gary@drinkingtea.net
|
||||
*
|
||||
* 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 https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#undef NDEBUG
|
||||
|
||||
#include <map>
|
||||
#include <ox/claw/format.hpp>
|
||||
#include <ox/claw/read.hpp>
|
||||
#include <ox/claw/write.hpp>
|
||||
#include <ox/mc/mc.hpp>
|
||||
#include <ox/model/model.hpp>
|
||||
#include <ox/std/std.hpp>
|
||||
|
||||
union TestUnion {
|
||||
static constexpr auto TypeName = "TestUnion";
|
||||
static constexpr auto TypeVersion = 1;
|
||||
bool Bool;
|
||||
uint32_t Int = 5;
|
||||
char *String;
|
||||
};
|
||||
|
||||
struct TestStructNest {
|
||||
static constexpr auto TypeName = "TestStructNest";
|
||||
static constexpr auto TypeVersion = 1;
|
||||
bool Bool = false;
|
||||
uint32_t Int = 0;
|
||||
ox::IString<32> String = "";
|
||||
};
|
||||
|
||||
struct TestStruct {
|
||||
static constexpr auto TypeName = "TestStruct";
|
||||
static constexpr auto TypeVersion = 1;
|
||||
bool Bool = false;
|
||||
int32_t Int = 0;
|
||||
int32_t Int1 = 0;
|
||||
int32_t Int2 = 0;
|
||||
int32_t Int3 = 0;
|
||||
int32_t Int4 = 0;
|
||||
int32_t Int5 = 0;
|
||||
int32_t Int6 = 0;
|
||||
int32_t Int7 = 0;
|
||||
int32_t Int8 = 0;
|
||||
int unionIdx = 1;
|
||||
TestUnion Union;
|
||||
ox::IString<32> String = "";
|
||||
uint32_t List[4] = {0, 0, 0, 0};
|
||||
TestStructNest EmptyStruct;
|
||||
TestStructNest Struct;
|
||||
|
||||
~TestStruct() {
|
||||
if (unionIdx == 2) {
|
||||
ox::safeDelete(Union.String);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestUnion> auto *obj) {
|
||||
OX_RETURN_ERROR(io->template setTypeInfo<TestUnion>());
|
||||
OX_RETURN_ERROR(io->field("Bool", &obj->Bool));
|
||||
OX_RETURN_ERROR(io->field("Int", &obj->Int));
|
||||
OX_RETURN_ERROR(io->fieldCString("String", &obj->String));
|
||||
return ox::Error(0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStructNest> auto *obj) {
|
||||
OX_RETURN_ERROR(io->template setTypeInfo<TestStructNest>());
|
||||
OX_RETURN_ERROR(io->field("Bool", &obj->Bool));
|
||||
OX_RETURN_ERROR(io->field("Int", &obj->Int));
|
||||
OX_RETURN_ERROR(io->field("String", &obj->String));
|
||||
return ox::Error(0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStruct> auto *obj) {
|
||||
OX_RETURN_ERROR(io->template setTypeInfo<TestStruct>());
|
||||
OX_RETURN_ERROR(io->field("Bool", &obj->Bool));
|
||||
OX_RETURN_ERROR(io->field("Int", &obj->Int));
|
||||
OX_RETURN_ERROR(io->field("Int1", &obj->Int1));
|
||||
OX_RETURN_ERROR(io->field("Int2", &obj->Int2));
|
||||
OX_RETURN_ERROR(io->field("Int3", &obj->Int3));
|
||||
OX_RETURN_ERROR(io->field("Int4", &obj->Int4));
|
||||
OX_RETURN_ERROR(io->field("Int5", &obj->Int5));
|
||||
OX_RETURN_ERROR(io->field("Int6", &obj->Int6));
|
||||
OX_RETURN_ERROR(io->field("Int7", &obj->Int7));
|
||||
OX_RETURN_ERROR(io->field("Int8", &obj->Int8));
|
||||
int unionIdx = 0;
|
||||
if constexpr(T::opType() != ox::OpType::Reflect) {
|
||||
unionIdx = obj->unionIdx;
|
||||
}
|
||||
OX_RETURN_ERROR(io->field("Union", ox::UnionView{&obj->Union, unionIdx}));
|
||||
OX_RETURN_ERROR(io->field("String", &obj->String));
|
||||
OX_RETURN_ERROR(io->field("List", obj->List, 4));
|
||||
OX_RETURN_ERROR(io->field("EmptyStruct", &obj->EmptyStruct));
|
||||
OX_RETURN_ERROR(io->field("Struct", &obj->Struct));
|
||||
return ox::Error(0);
|
||||
}
|
||||
|
||||
static std::map<ox::StringView, ox::Error(*)()> tests = {
|
||||
{
|
||||
{
|
||||
"ClawHeaderReader",
|
||||
[] {
|
||||
constexpr auto hdr = ox::StringLiteral("O1;com.drinkingtea.ox.claw.test.Header;2;");
|
||||
auto [ch, err] = ox::readClawHeader({hdr.c_str(), hdr.size() + 1});
|
||||
oxAssert(err, "Error parsing header");
|
||||
oxAssert(ch.fmt == ox::ClawFormat::Organic, "Format wrong");
|
||||
oxAssert(ch.typeName == "com.drinkingtea.ox.claw.test.Header", "Type name wrong");
|
||||
oxAssert(ch.typeVersion == 2, "Type version wrong");
|
||||
return ox::Error(0);
|
||||
}
|
||||
},
|
||||
{
|
||||
"ClawHeaderReader2",
|
||||
[] {
|
||||
constexpr auto hdr = ox::StringLiteral("M2;com.drinkingtea.ox.claw.test.Header2;3;");
|
||||
auto [ch, err] = ox::readClawHeader({hdr.c_str(), hdr.size() + 1});
|
||||
oxAssert(err, "Error parsing header");
|
||||
oxAssert(ch.fmt == ox::ClawFormat::Metal, "Format wrong");
|
||||
oxAssert(ch.typeName == "com.drinkingtea.ox.claw.test.Header2", "Type name wrong");
|
||||
oxAssert(ch.typeVersion == 3, "Type version wrong");
|
||||
return ox::Error(0);
|
||||
}
|
||||
},
|
||||
{
|
||||
"ClawHeaderReadTypeId",
|
||||
[] {
|
||||
constexpr auto hdr = ox::StringLiteral("M2;com.drinkingtea.ox.claw.test.Header2;3;awefawf");
|
||||
constexpr auto expected = ox::StringLiteral("com.drinkingtea.ox.claw.test.Header2;3");
|
||||
OX_REQUIRE(actual, ox::readClawTypeId({hdr.data(), hdr.size() + 1}));
|
||||
ox::expect(actual, expected);
|
||||
return ox::Error{};
|
||||
}
|
||||
},
|
||||
{
|
||||
"ClawWriter",
|
||||
[] {
|
||||
// This test doesn't confirm much, but it does show that the writer
|
||||
// doesn't segfault
|
||||
TestStruct ts;
|
||||
OX_RETURN_ERROR(ox::writeClaw(ts, ox::ClawFormat::Metal));
|
||||
return ox::Error(0);
|
||||
}
|
||||
},
|
||||
{
|
||||
"ClawReader",
|
||||
[] {
|
||||
TestStruct testIn, testOut;
|
||||
testIn.Bool = true;
|
||||
testIn.Int = 42;
|
||||
testIn.Union.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";
|
||||
const auto [buff, err] = ox::writeMC(testIn);
|
||||
oxAssert(err, "writeClaw failed");
|
||||
oxAssert(ox::readMC(buff, testOut), "readClaw failed");
|
||||
//std::cout << testIn.Union.Int << "|" << testOut.Union.Int << "|\n";
|
||||
oxAssert(testIn.Bool == testOut.Bool, "Bool value mismatch");
|
||||
oxAssert(testIn.Int == testOut.Int, "Int value mismatch");
|
||||
oxAssert(testIn.Int1 == testOut.Int1, "Int1 value mismatch");
|
||||
oxAssert(testIn.Int2 == testOut.Int2, "Int2 value mismatch");
|
||||
oxAssert(testIn.Int3 == testOut.Int3, "Int3 value mismatch");
|
||||
oxAssert(testIn.Int4 == testOut.Int4, "Int4 value mismatch");
|
||||
oxAssert(testIn.Int5 == testOut.Int5, "Int5 value mismatch");
|
||||
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");
|
||||
oxAssert(testIn.List[2] == testOut.List[2], "List[2] value mismatch");
|
||||
oxAssert(testIn.List[3] == testOut.List[3], "List[3] 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.String == testOut.EmptyStruct.String, "EmptyStruct.String value mismatch");
|
||||
oxAssert(testIn.Struct.Int == testOut.Struct.Int, "Struct.Int value mismatch");
|
||||
oxAssert(testIn.Struct.String == testOut.Struct.String, "Struct.String value mismatch");
|
||||
oxAssert(testIn.Struct.Bool == testOut.Struct.Bool, "Struct.Bool value mismatch");
|
||||
|
||||
return ox::Error(0);
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, const char **args) {
|
||||
if (argc < 2) {
|
||||
oxError("Must specify test to run");
|
||||
}
|
||||
auto const testName = args[1];
|
||||
auto const func = tests.find(testName);
|
||||
if (func != tests.end()) {
|
||||
oxAssert(func->second(), "Test returned Error");
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
Reference in New Issue
Block a user