From 63486c23d46412e7eacc8acf6e56fd699b3bca45 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Wed, 8 May 2024 23:35:05 -0500 Subject: [PATCH 1/6] [ox] Cleanup --- deps/ox/src/ox/claw/read.cpp | 105 +++++++++++++---------- deps/ox/src/ox/claw/read.hpp | 39 +++------ deps/ox/src/ox/claw/test/CMakeLists.txt | 1 + deps/ox/src/ox/claw/test/tests.cpp | 16 +++- deps/ox/src/ox/mc/intops.hpp | 2 +- deps/ox/src/ox/mc/read.hpp | 17 ++-- deps/ox/src/ox/mc/test/tests.cpp | 6 +- deps/ox/src/ox/model/desctypes.hpp | 4 +- deps/ox/src/ox/model/typenamecatcher.hpp | 7 ++ deps/ox/src/ox/model/typestore.hpp | 2 +- deps/ox/src/ox/oc/read.hpp | 23 ++--- deps/ox/src/ox/oc/test/tests.cpp | 2 +- deps/ox/src/ox/std/buffer.hpp | 7 +- deps/ox/src/ox/std/error.hpp | 16 ++++ deps/ox/src/ox/std/fmt.hpp | 9 +- deps/ox/src/ox/std/span.hpp | 14 ++- deps/ox/src/ox/std/strconv.hpp | 15 ++++ deps/ox/src/ox/std/string.hpp | 4 + deps/ox/src/ox/std/test/CMakeLists.txt | 1 + deps/ox/src/ox/std/test/tests.cpp | 22 ++++- 20 files changed, 195 insertions(+), 117 deletions(-) diff --git a/deps/ox/src/ox/claw/read.cpp b/deps/ox/src/ox/claw/read.cpp index 439ae517..eb489be6 100644 --- a/deps/ox/src/ox/claw/read.cpp +++ b/deps/ox/src/ox/claw/read.cpp @@ -12,34 +12,66 @@ namespace ox { -Result readClawHeader(const char *buff, std::size_t buffLen) noexcept { - const auto s1End = ox::strchr(buff, ';', buffLen); +ox::Result readClawTypeId(ox::BufferView buff) noexcept { + auto buffRaw = buff.data(); + auto buffLen = buff.size(); + size_t outSz{}; + const auto s1End = ox::strchr(buffRaw, ';', buffLen); if (!s1End) { return OxError(1, "Could not read Claw header"); } - const auto s1Size = static_cast(s1End - buff); - const String fmt(buff, s1Size); - buff += s1Size + 1; - buffLen -= s1Size + 1; - - const auto s2End = ox::strchr(buff, ';', buffLen); + auto const fmtSz = static_cast(s1End - buffRaw) + 1; + buffRaw += fmtSz; + buffLen -= fmtSz; + outSz += fmtSz; + auto const s2End = ox::strchr(buffRaw, ';', buffLen); if (!s2End) { return OxError(2, "Could not read Claw header"); } - const auto s2Size = static_cast(s2End - buff); - const String typeName(buff, s2Size); - buff += s2Size + 1; - buffLen -= s2Size + 1; - - const auto s3End = ox::strchr(buff, ';', buffLen); + auto const s2Size = static_cast(s2End - buffRaw) + 1; + buffRaw += s2Size; + buffLen -= s2Size; + outSz += s2Size; + auto const s3End = ox::strchr(buffRaw, ';', buffLen) + 1; if (!s3End) { return OxError(3, "Could not read Claw header"); } - const auto s3Size = static_cast(s3End - buff); - const String versionStr(buff, s3Size); - buff += s3Size + 1; - buffLen -= s3Size + 1; + auto const s3Size = static_cast(s3End - buffRaw); + buffRaw += s3Size; + buffLen -= s3Size; + outSz += s3Size; + return {{buff.data() + fmtSz, outSz - fmtSz - 1}}; +} +Result readClawHeader(ox::BufferView buff) noexcept { + auto buffRaw = buff.data(); + auto buffLen = buff.size(); + const auto s1End = ox::strchr(buffRaw, ';', buffLen); + if (!s1End) { + return OxError(1, "Could not read Claw header"); + } + auto const s1Size = static_cast(s1End - buffRaw); + StringView const fmt(buffRaw, s1Size); + buffRaw += s1Size + 1; + buffLen -= s1Size + 1; + + auto const s2End = ox::strchr(buffRaw, ';', buffLen); + if (!s2End) { + return OxError(2, "Could not read Claw header"); + } + auto const s2Size = static_cast(s2End - buffRaw); + StringView const typeName(buffRaw, s2Size); + buffRaw += s2Size + 1; + buffLen -= s2Size + 1; + + auto const s3End = ox::strchr(buffRaw, ';', buffLen); + if (!s3End) { + return OxError(3, "Could not read Claw header"); + } + auto const s3Size = static_cast(s3End - buffRaw); + StringView const versionStr(buffRaw, s3Size); + buffRaw += s3Size + 1; + buffLen -= s3Size + 1; ClawHeader hdr; if (fmt == "M2") { hdr.fmt = ClawFormat::Metal; @@ -49,32 +81,21 @@ Result readClawHeader(const char *buff, std::size_t buffLen) noexcep return OxError(4, "Claw format does not match any supported format/version combo"); } hdr.typeName = typeName; - if (auto r = ox::atoi(versionStr.c_str()); r.error == 0) { - hdr.typeVersion = r.value; - } - hdr.data = buff; + std::ignore = ox::atoi(versionStr).copyTo(hdr.typeVersion); + hdr.data = buffRaw; hdr.dataSize = buffLen; return hdr; } -Result readClawHeader(const ox::Buffer &buff) noexcept { - return readClawHeader(buff.data(), buff.size()); +Result stripClawHeader(ox::BufferView buff) noexcept { + oxRequire(header, readClawHeader(buff)); + return {{header.data, header.dataSize}}; } -Result stripClawHeader(const char *buff, std::size_t buffLen) noexcept { - oxRequire(header, readClawHeader(buff, buffLen)); - Buffer out(header.dataSize); - ox::listcpy(out.data(), header.data, out.size()); - return out; -} - -Result stripClawHeader(const ox::Buffer &buff) noexcept { - return stripClawHeader(buff.data(), buff.size()); -} - -Result readClaw(TypeStore &ts, const char *buff, std::size_t buffSz) noexcept { - oxRequire(header, readClawHeader(buff, buffSz)); - auto const [t, tdErr] = ts.getLoad(header.typeName, header.typeVersion, header.typeParams); +Result readClaw(TypeStore &ts, BufferView buff) noexcept { + oxRequire(header, readClawHeader(buff)); + auto const [t, tdErr] = ts.getLoad( + header.typeName, header.typeVersion, header.typeParams); if (tdErr) { return OxError(3, "Could not load type descriptor"); } @@ -83,7 +104,7 @@ Result readClaw(TypeStore &ts, const char *buff, std::size_t buffSz switch (header.fmt) { case ClawFormat::Metal: { - ox::BufferReader br(header.data, header.dataSize); + ox::BufferReader br({header.data, header.dataSize}); MetalClawReader reader(br); ModelHandlerInterface handler(&reader); oxReturnError(model(&handler, &obj)); @@ -92,7 +113,7 @@ Result readClaw(TypeStore &ts, const char *buff, std::size_t buffSz case ClawFormat::Organic: { #ifdef OX_USE_STDLIB - OrganicClawReader reader(header.data, header.dataSize); + OrganicClawReader reader({header.data, header.dataSize}); ModelHandlerInterface handler(&reader); oxReturnError(model(&handler, &obj)); return obj; @@ -106,8 +127,4 @@ Result readClaw(TypeStore &ts, const char *buff, std::size_t buffSz return OxError(1); } -Result readClaw(TypeStore &ts, const Buffer &buff) noexcept { - return readClaw(ts, buff.data(), buff.size()); -} - } diff --git a/deps/ox/src/ox/claw/read.hpp b/deps/ox/src/ox/claw/read.hpp index 37d624eb..c625ee22 100644 --- a/deps/ox/src/ox/claw/read.hpp +++ b/deps/ox/src/ox/claw/read.hpp @@ -8,6 +8,7 @@ #pragma once +#include #include #ifdef OX_USE_STDLIB #include @@ -31,17 +32,15 @@ struct ClawHeader { std::size_t dataSize = 0; }; -Result readClawHeader(const char *buff, std::size_t buffLen) noexcept; +ox::Result readClawTypeId(ox::BufferView buff) noexcept; -Result readClawHeader(const ox::Buffer &buff) noexcept; +Result readClawHeader(ox::BufferView buff) noexcept; -Result stripClawHeader(const char *buff, std::size_t buffLen) noexcept; - -Result stripClawHeader(const ox::Buffer &buff) noexcept; +Result stripClawHeader(ox::BufferView buff) noexcept; template -Error readClaw(const char *buff, std::size_t buffLen, T *val) { - oxRequire(header, readClawHeader(buff, buffLen)); +Error readClaw(ox::BufferView buff, T &val) { + oxRequire(header, readClawHeader(buff)); if (header.typeName != getModelTypeName()) { return OxError(Error_ClawTypeMismatch, "Claw Read: Type mismatch"); } @@ -51,16 +50,16 @@ Error readClaw(const char *buff, std::size_t buffLen, T *val) { switch (header.fmt) { case ClawFormat::Metal: { - ox::BufferReader br(header.data, header.dataSize); + ox::BufferReader br({header.data, header.dataSize}); MetalClawReader reader(br); ModelHandlerInterface handler(&reader); - return model(&handler, val); + return model(&handler, &val); } case ClawFormat::Organic: { #ifdef OX_USE_STDLIB OrganicClawReader reader(header.data, header.dataSize); - return model(&reader, val); + return model(&reader, &val); #else break; #endif @@ -72,24 +71,12 @@ Error readClaw(const char *buff, std::size_t buffLen, T *val) { } template -Result readClaw(const char *buff, std::size_t buffLen) { - T val; - oxReturnError(readClaw(buff, buffLen, &val)); +Result readClaw(ox::BufferView buff) { + Result val; + oxReturnError(readClaw(buff, val.value)); return val; } -template -Error readClaw(const Buffer &buff, T *val) { - return readClaw(buff.data(), buff.size(), val); -} - -template -Result readClaw(const Buffer &buff) { - return readClaw(buff.data(), buff.size()); -} - -Result readClaw(TypeStore &ts, const char *buff, std::size_t buffSz) noexcept; - -Result readClaw(TypeStore &ts, const Buffer &buff) noexcept; +Result readClaw(TypeStore &ts, BufferView buff) noexcept; } diff --git a/deps/ox/src/ox/claw/test/CMakeLists.txt b/deps/ox/src/ox/claw/test/CMakeLists.txt index ddf2ae7e..d33bec47 100644 --- a/deps/ox/src/ox/claw/test/CMakeLists.txt +++ b/deps/ox/src/ox/claw/test/CMakeLists.txt @@ -10,5 +10,6 @@ target_link_libraries( 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) diff --git a/deps/ox/src/ox/claw/test/tests.cpp b/deps/ox/src/ox/claw/test/tests.cpp index 17a801c7..90c1bffd 100644 --- a/deps/ox/src/ox/claw/test/tests.cpp +++ b/deps/ox/src/ox/claw/test/tests.cpp @@ -109,7 +109,7 @@ static std::map tests = { "ClawHeaderReader", [] { constexpr auto hdr = ox::StringLiteral("O1;com.drinkingtea.ox.claw.test.Header;2;"); - auto [ch, err] = ox::readClawHeader(hdr.c_str(), hdr.len() + 1); + auto [ch, err] = ox::readClawHeader({hdr.c_str(), hdr.len() + 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"); @@ -121,7 +121,7 @@ static std::map tests = { "ClawHeaderReader2", [] { constexpr auto hdr = ox::StringLiteral("M2;com.drinkingtea.ox.claw.test.Header2;3;"); - auto [ch, err] = ox::readClawHeader(hdr.c_str(), hdr.len() + 1); + auto [ch, err] = ox::readClawHeader({hdr.c_str(), hdr.len() + 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"); @@ -129,6 +129,16 @@ static std::map tests = { return OxError(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"); + oxRequire(actual, ox::readClawTypeId({hdr.data(), hdr.len() + 1})); + oxExpect(actual, expected); + return ox::Error{}; + } + }, { "ClawWriter", [] { @@ -156,7 +166,7 @@ static std::map tests = { testIn.Struct.String = "Test String 2"; const auto [buff, err] = ox::writeMC(testIn); oxAssert(err, "writeClaw failed"); - oxAssert(ox::readMC(buff.data(), buff.size(), &testOut), "readClaw 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"); diff --git a/deps/ox/src/ox/mc/intops.hpp b/deps/ox/src/ox/mc/intops.hpp index 2376cdd8..501cda87 100644 --- a/deps/ox/src/ox/mc/intops.hpp +++ b/deps/ox/src/ox/mc/intops.hpp @@ -185,7 +185,7 @@ constexpr Result decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noe template Result decodeInteger(McInt m) noexcept { std::size_t bytesRead{}; - BufferReader br(reinterpret_cast(m.data), 9); + BufferReader br({reinterpret_cast(m.data), 9}); return decodeInteger(br, &bytesRead); } diff --git a/deps/ox/src/ox/mc/read.hpp b/deps/ox/src/ox/mc/read.hpp index 5133f11c..3cebd2a9 100644 --- a/deps/ox/src/ox/mc/read.hpp +++ b/deps/ox/src/ox/mc/read.hpp @@ -524,25 +524,20 @@ constexpr void MetalClawReaderTemplate::nextField() noexcept { using MetalClawReader = MetalClawReaderTemplate; template -Error readMC(const char *buff, std::size_t buffLen, T *val) noexcept { - BufferReader br(buff, buffLen); +Error readMC(ox::BufferView buff, T &val) noexcept { + BufferReader br(buff); MetalClawReader reader(br); ModelHandlerInterface handler(&reader); - return model(&handler, val); + return model(&handler, &val); } template -Result readMC(const char *buff, std::size_t buffLen) noexcept { - T val; - oxReturnError(readMC(buff, buffLen, &val)); +Result readMC(ox::BufferView buff) noexcept { + Result val; + oxReturnError(readMC(buff, val.value)); return val; } -template -Result readMC(const Buffer &buff) noexcept { - return readMC(buff.data(), buff.size()); -} - extern template class ModelHandlerInterface>; } diff --git a/deps/ox/src/ox/mc/test/tests.cpp b/deps/ox/src/ox/mc/test/tests.cpp index 24b66dc8..456a6bd1 100644 --- a/deps/ox/src/ox/mc/test/tests.cpp +++ b/deps/ox/src/ox/mc/test/tests.cpp @@ -143,7 +143,7 @@ std::map tests = { // run tests const auto [buff, err] = ox::writeMC(testIn); oxAssert(err, "writeMC failed"); - oxAssert(ox::readMC(buff.data(), buff.size(), &testOut), "readMC failed"); + oxAssert(ox::readMC(buff, testOut), "readMC 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"); @@ -319,7 +319,7 @@ std::map tests = { oxAssert(typeErr, "Descriptor write failed"); ox::ModelObject testOut; oxReturnError(testOut.setType(type)); - oxAssert(ox::readMC(dataBuff.data(), dataBuff.size(), &testOut), "Data read failed"); + oxAssert(ox::readMC(dataBuff, testOut), "Data read failed"); oxAssert(testOut.at("Int").unwrap()->get() == testIn.Int, "testOut.Int failed"); oxAssert(testOut.at("Bool").unwrap()->get() == testIn.Bool, "testOut.Bool failed"); oxAssert(testOut.at("IString").unwrap()->get() == testIn.IString.c_str(), "testOut.String failed"); @@ -369,7 +369,7 @@ std::map tests = { ox::TypeStore typeStore; const auto [type, typeErr] = ox::buildTypeDef(&typeStore, &testIn); oxAssert(typeErr, "Descriptor write failed"); - ox::BufferReader br(dataBuff, dataBuffLen); + ox::BufferReader br({dataBuff, dataBuffLen}); oxReturnError(ox::walkModel(type, br, [](const ox::Vector&, const ox::Vector&, const ox::DescriptorField &f, ox::MetalClawReader *rdr) -> ox::Error { //std::cout << f.fieldName.c_str() << '\n'; diff --git a/deps/ox/src/ox/model/desctypes.hpp b/deps/ox/src/ox/model/desctypes.hpp index e2924d25..9eb2af7a 100644 --- a/deps/ox/src/ox/model/desctypes.hpp +++ b/deps/ox/src/ox/model/desctypes.hpp @@ -37,12 +37,12 @@ constexpr auto buildTypeId() noexcept { static constexpr auto buildTypeId(CRStringView name, int version, const TypeParamPack &typeParams = {}) noexcept { String tp; - if (typeParams.size()) { + if (!typeParams.empty()) { tp = "#"; for (const auto &p : typeParams) { tp += p + ","; } - tp = tp.substr(0, tp.len() - 1); + tp.resize(tp.len() - 1); tp += "#"; } return ox::sfmt("{}{};{}", name, tp, version); diff --git a/deps/ox/src/ox/model/typenamecatcher.hpp b/deps/ox/src/ox/model/typenamecatcher.hpp index 14cef239..0a4b49a2 100644 --- a/deps/ox/src/ox/model/typenamecatcher.hpp +++ b/deps/ox/src/ox/model/typenamecatcher.hpp @@ -97,6 +97,7 @@ struct TypeInfoCatcher { }; template +[[nodiscard]] constexpr int getModelTypeVersion(T *val) noexcept { TypeInfoCatcher nc; std::ignore = model(&nc, val); @@ -104,6 +105,7 @@ constexpr int getModelTypeVersion(T *val) noexcept { } template +[[nodiscard]] constexpr int getModelTypeVersion() noexcept { std::allocator a; const auto t = a.allocate(1); @@ -113,6 +115,7 @@ constexpr int getModelTypeVersion() noexcept { } template +[[nodiscard]] consteval int requireModelTypeVersion() noexcept { constexpr auto version = getModelTypeVersion(); static_assert(version != 0, "TypeVersion is required"); @@ -120,6 +123,7 @@ consteval int requireModelTypeVersion() noexcept { } template +[[nodiscard]] constexpr Str getModelTypeName(T *val) noexcept { TypeNameCatcher nc; std::ignore = model(&nc, val); @@ -127,6 +131,7 @@ constexpr Str getModelTypeName(T *val) noexcept { } template +[[nodiscard]] constexpr Str getModelTypeName() noexcept { std::allocator a; auto t = a.allocate(1); @@ -136,8 +141,10 @@ constexpr Str getModelTypeName() noexcept { } template +[[nodiscard]] consteval auto requireModelTypeName() noexcept { constexpr auto name = getModelTypeName(); + static_assert(ox::StringView{name}.len(), "Type lacks required TypeName"); return name; } diff --git a/deps/ox/src/ox/model/typestore.hpp b/deps/ox/src/ox/model/typestore.hpp index 2a8f1e1c..298a71d8 100644 --- a/deps/ox/src/ox/model/typestore.hpp +++ b/deps/ox/src/ox/model/typestore.hpp @@ -101,7 +101,7 @@ class TypeStore { } protected: - virtual Result> loadDescriptor(ox::CRStringView) noexcept { + virtual Result> loadDescriptor(ox::StringView) noexcept { return OxError(1); } diff --git a/deps/ox/src/ox/oc/read.hpp b/deps/ox/src/ox/oc/read.hpp index aa7b66c3..eebf50a4 100644 --- a/deps/ox/src/ox/oc/read.hpp +++ b/deps/ox/src/ox/oc/read.hpp @@ -246,18 +246,18 @@ Error OrganicClawReader::field(const char *key, HashMap *val) noexcep return OxError(0); } -Error readOC(const char *buff, std::size_t buffSize, auto *val) noexcept { +Error readOC(BufferView buff, auto &val) noexcept { // OrganicClawReader constructor can throw, but readOC should return its errors. try { Json::Value doc; Json::CharReaderBuilder parserBuilder; auto parser = UniquePtr(parserBuilder.newCharReader()); - if (!parser->parse(buff, buff + buffSize, &doc, nullptr)) { + if (!parser->parse(buff.data(), buff.data() + buff.size(), &doc, nullptr)) { return OxError(1, "Could not parse JSON"); } - OrganicClawReader reader(buff, buffSize); + OrganicClawReader reader(buff.data(), buff.size()); ModelHandlerInterface handler(&reader); - return model(&handler, val); + return model(&handler, &val); } catch (const Error &err) { return err; } catch (...) { @@ -266,20 +266,15 @@ Error readOC(const char *buff, std::size_t buffSize, auto *val) noexcept { } template -Result readOC(const char *json, std::size_t jsonLen) noexcept { - T val; - oxReturnError(readOC(json, jsonLen, &val)); +Result readOC(BufferView buff) noexcept { + Result val; + oxReturnError(readOC(buff, val.value)); return val; } template -Result readOC(const char *json) noexcept { - return readOC(json, ox::strlen(json)); -} - -template -Result readOC(const Buffer &buff) noexcept { - return readOC(buff.data(), buff.size()); +Result readOC(ox::StringView json) noexcept { + return readOC(ox::BufferView{json.data(), json.len()}); } } diff --git a/deps/ox/src/ox/oc/test/tests.cpp b/deps/ox/src/ox/oc/test/tests.cpp index ec33c37a..e6597dc6 100644 --- a/deps/ox/src/ox/oc/test/tests.cpp +++ b/deps/ox/src/ox/oc/test/tests.cpp @@ -211,7 +211,7 @@ const std::map tests = { 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(ox::readOC(dataBuff, testOut), "Data read failed"); oxAssert(testOut.get("Int").unwrap()->get() == testIn.Int, "testOut.Int failed"); oxAssert(testOut.get("Bool").unwrap()->get() == testIn.Bool, "testOut.Bool failed"); oxAssert(testOut.get("String").unwrap()->get() == testIn.String, "testOut.String failed"); diff --git a/deps/ox/src/ox/std/buffer.hpp b/deps/ox/src/ox/std/buffer.hpp index bcfccea6..b49d9eb9 100644 --- a/deps/ox/src/ox/std/buffer.hpp +++ b/deps/ox/src/ox/std/buffer.hpp @@ -10,6 +10,7 @@ #include "error.hpp" #include "reader.hpp" +#include "span.hpp" #include "vector.hpp" #include "writer.hpp" @@ -18,6 +19,7 @@ namespace ox { extern template class Vector; using Buffer = Vector; +using BufferView = SpanView; class BufferWriter { private: @@ -174,10 +176,7 @@ class BufferReader { char const* m_buff = nullptr; public: - constexpr explicit BufferReader(char const*buff, std::size_t sz) noexcept: - m_size(sz), m_buff(buff) {} - - constexpr explicit BufferReader(ox::Buffer const&buffer) noexcept: + constexpr explicit BufferReader(ox::BufferView buffer) noexcept: m_size(buffer.size()), m_buff(buffer.data()) {} constexpr ox::Result peek() const noexcept { diff --git a/deps/ox/src/ox/std/error.hpp b/deps/ox/src/ox/std/error.hpp index 1f53426a..6018971d 100644 --- a/deps/ox/src/ox/std/error.hpp +++ b/deps/ox/src/ox/std/error.hpp @@ -234,6 +234,22 @@ struct [[nodiscard]] Result { return value; } + template + constexpr ox::Result to() & noexcept { + if (error) [[unlikely]] { + return error; + } + return U(value); + } + + template + constexpr ox::Result to() && noexcept { + if (error) [[unlikely]] { + return error; + } + return U(std::move(value)); + } + template constexpr ox::Result to(auto const&f) & noexcept { if (error) [[unlikely]] { diff --git a/deps/ox/src/ox/std/fmt.hpp b/deps/ox/src/ox/std/fmt.hpp index 2cdab425..bc8d9a49 100644 --- a/deps/ox/src/ox/std/fmt.hpp +++ b/deps/ox/src/ox/std/fmt.hpp @@ -40,12 +40,17 @@ constexpr StringView toStringView(const char *s) noexcept { template constexpr StringView toStringView(const IString &s) noexcept { - return s.c_str(); + return s; +} + +template +constexpr StringView toStringView(ox::StringLiteral s) noexcept { + return s; } template constexpr StringView toStringView(const BasicString &s) noexcept { - return s.c_str(); + return s; } #if __has_include() diff --git a/deps/ox/src/ox/std/span.hpp b/deps/ox/src/ox/std/span.hpp index 40644586..542ac6d9 100644 --- a/deps/ox/src/ox/std/span.hpp +++ b/deps/ox/src/ox/std/span.hpp @@ -19,8 +19,8 @@ template class SpanView { private: - const T *m_items{}; - const std::size_t m_size{}; + T const*m_items{}; + std::size_t m_size{}; public: using value_type = T; @@ -106,6 +106,16 @@ class SpanView { return m_items[i]; } + constexpr SpanView operator+(size_t i) const noexcept { + return {m_items + i, m_size - i}; + } + + constexpr SpanView operator+=(size_t i) noexcept { + m_items += i; + m_size -= i; + return *this; + } + [[nodiscard]] constexpr T const*data() const noexcept { return m_items; diff --git a/deps/ox/src/ox/std/strconv.hpp b/deps/ox/src/ox/std/strconv.hpp index f976366e..2a18ec3d 100644 --- a/deps/ox/src/ox/std/strconv.hpp +++ b/deps/ox/src/ox/std/strconv.hpp @@ -1,7 +1,9 @@ #pragma once +#include "bit.hpp" #include "error.hpp" +#include "math.hpp" #include "types.hpp" #include "writer.hpp" @@ -39,6 +41,19 @@ constexpr ox::Error writeItoa(Integer v, ox::Writer_c auto &writer) noexcept { return {}; } +constexpr ox::Error writeF32toa(float const v, ox::Writer_c auto &writer) noexcept { + auto const raw = std::bit_cast(v); + if (raw >> 31) { + oxReturnError(writer.put('-')); + } + auto const mantissa = raw & onMask(23); + auto const exp = ((raw >> 23) & 0xff) - 126; + auto const p = ox::pow(2u, exp); + auto const out = p * mantissa; + oxReturnError(writeItoa(out, writer)); + return {}; +} + } #include "istring.hpp" diff --git a/deps/ox/src/ox/std/string.hpp b/deps/ox/src/ox/std/string.hpp index 90a71341..d5406bba 100644 --- a/deps/ox/src/ox/std/string.hpp +++ b/deps/ox/src/ox/std/string.hpp @@ -192,6 +192,10 @@ class BasicString { [[nodiscard]] constexpr BasicString substr(std::size_t begin, std::size_t end) const noexcept; + constexpr void resize(size_t sz) noexcept { + m_buff.resize(sz); + } + [[nodiscard]] constexpr const char *data() const noexcept { return m_buff.data(); diff --git a/deps/ox/src/ox/std/test/CMakeLists.txt b/deps/ox/src/ox/std/test/CMakeLists.txt index d0c7da23..567cf7db 100644 --- a/deps/ox/src/ox/std/test/CMakeLists.txt +++ b/deps/ox/src/ox/std/test/CMakeLists.txt @@ -11,6 +11,7 @@ add_test("[ox/std] ox_memcmp ABCDEFG != HIJKLMN" ${CMAKE_RUNTIME_OUTPUT_DIRECTOR add_test("[ox/std] ox_memcmp HIJKLMN != ABCDEFG" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "HIJKLMN != ABCDEFG") add_test("[ox/std] ox_memcmp ABCDEFG == ABCDEFG" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "ABCDEFG == ABCDEFG") add_test("[ox/std] ox_memcmp ABCDEFGHI == ABCDEFG" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "ABCDEFGHI == ABCDEFG") +#add_test("[ox/std] ftoa" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "ftoa") add_test("[ox/std] itoa" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "itoa") add_test("[ox/std] BString" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "BString") add_test("[ox/std] String" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "String") diff --git a/deps/ox/src/ox/std/test/tests.cpp b/deps/ox/src/ox/std/test/tests.cpp index 1af6c8f7..745ea2f8 100644 --- a/deps/ox/src/ox/std/test/tests.cpp +++ b/deps/ox/src/ox/std/test/tests.cpp @@ -26,6 +26,16 @@ static std::map tests = { return OxError(0); } }, + { + "ftoa", + []() { + ox::Array buff; + ox::CharBuffWriter bw(buff); + oxAssert(ox::writeF32toa(5, bw), "ox::writeItoa returned Error"); + oxExpect(ox::StringView(buff.data()), ox::StringView("5")); + return ox::Error{}; + } + }, { "itoa", []() { @@ -109,7 +119,9 @@ static std::map tests = { oxAssert(ox::StringView("Write") != ox::String(""), "String / StringView comparison broken"); oxAssert(ox::String("Write") != ox::StringView(""), "String / StringView comparison broken"); oxAssert(ox::String("Write") == ox::StringView("Write"), "String / StringView comparison broken"); - oxAssert(ox::String(ox::StringView("Write")) == ox::StringView("Write"), "String / StringView comparison broken"); + oxAssert( + ox::String(ox::StringView("Write")) == ox::StringView("Write"), + "String / StringView comparison broken"); return OxError(0); } }, @@ -119,7 +131,7 @@ static std::map tests = { ox::Vector v; oxAssert(v.size() == 0, "Initial Vector size not 0"); oxAssert(v.empty(), "Vector::empty() is broken"); - auto insertTest = [&v](int val, [[maybe_unused]] std::size_t size) { + auto insertTest = [&v](int val, std::size_t size) { v.push_back(val); oxReturnError(OxError(v.size() != size, "Vector size incorrect")); oxReturnError(OxError(v[v.size() - 1] != val, "Vector value wrong")); @@ -152,7 +164,11 @@ static std::map tests = { [] { using BA = ox::Array; const auto actual = ox::serialize(256).unwrap(); - oxOutf("[{}, {}, {}, {}]", static_cast(actual[0]), static_cast(actual[1]), static_cast(actual[2]), static_cast(actual[3])); + oxOutf("[{}, {}, {}, {}]", + static_cast(actual[0]), + static_cast(actual[1]), + static_cast(actual[2]), + static_cast(actual[3])); oxExpect(ox::serialize(4).unwrap(), BA({4, 0, 0, 0})); oxExpect(ox::serialize(256).unwrap(), BA({0, 1, 0, 0})); oxExpect(ox::serialize(257).unwrap(), BA({1, 1, 0, 0})); From 331f72129279b1d4dd10002ceaf8ce7b2a118869 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Wed, 8 May 2024 23:35:34 -0500 Subject: [PATCH 2/6] [olympic,nostalgia] Cleanup --- src/nostalgia/modules/core/src/gba/gfx.cpp | 6 +-- .../modules/core/src/keel/keelmodule.cpp | 18 +++----- .../modules/core/src/keel/typeconv.hpp | 12 ++--- src/olympic/keel/include/keel/asset.hpp | 14 +++--- src/olympic/keel/include/keel/context.hpp | 20 ++++++++- src/olympic/keel/include/keel/typeconv.hpp | 41 +++++++++-------- src/olympic/keel/include/keel/typestore.hpp | 2 +- src/olympic/keel/src/asset.cpp | 44 ++++++++++--------- src/olympic/keel/src/media.cpp | 13 +++--- src/olympic/keel/src/typeconv.cpp | 43 +++++++++--------- src/olympic/keel/src/typestore.cpp | 6 +-- src/olympic/studio/applib/src/main.cpp | 2 +- 12 files changed, 116 insertions(+), 105 deletions(-) diff --git a/src/nostalgia/modules/core/src/gba/gfx.cpp b/src/nostalgia/modules/core/src/gba/gfx.cpp index 308be953..e2404fd2 100644 --- a/src/nostalgia/modules/core/src/gba/gfx.cpp +++ b/src/nostalgia/modules/core/src/gba/gfx.cpp @@ -196,7 +196,7 @@ static ox::Error loadTileSheetSet( .targetBpp = static_cast(set.bpp), .setEntry = &entry, }; - oxReturnError(ox::readMC(ts, static_cast(tsStat.size), &target)); + oxReturnError(ox::readMC({ts, static_cast(tsStat.size)}, target)); tileWriteIdx += target.tileWriteIdx; } return {}; @@ -215,7 +215,7 @@ ox::Error loadBgTileSheet( .defaultPalette = {}, .tileMap = MEM_BG_TILES[cbb].data(), }; - oxReturnError(ox::readMC(ts, static_cast(tsStat.size), &target)); + oxReturnError(ox::readMC({ts, static_cast(tsStat.size)}, target)); // update bpp of all bgs with the updated cbb const auto bpp = ctx.cbbData[cbb].bpp; teagba::iterateBgCtl([bpp, cbb](volatile BgCtl &bgCtl) { @@ -267,7 +267,7 @@ ox::Error loadSpriteTileSheet( .defaultPalette = {}, .tileMap = MEM_SPRITE_TILES, }; - oxReturnError(ox::readMC(ts, static_cast(tsStat.size), &target)); + oxReturnError(ox::readMC({ts, static_cast(tsStat.size)}, target)); if (loadDefaultPalette && target.defaultPalette) { oxReturnError(loadSpritePalette(ctx, target.defaultPalette)); } diff --git a/src/nostalgia/modules/core/src/keel/keelmodule.cpp b/src/nostalgia/modules/core/src/keel/keelmodule.cpp index cc59d504..43221940 100644 --- a/src/nostalgia/modules/core/src/keel/keelmodule.cpp +++ b/src/nostalgia/modules/core/src/keel/keelmodule.cpp @@ -58,27 +58,21 @@ static class: public keel::Module { ox::Vector packTransforms() const noexcept final { return { // convert tilesheets to CompactTileSheets - [](keel::Context &ctx, ox::Buffer &buff) -> ox::Error { - oxRequire(hdr, keel::readAssetHeader(buff)); - auto const typeId = ox::buildTypeId( - hdr.clawHdr.typeName, hdr.clawHdr.typeVersion, hdr.clawHdr.typeParams); + [](keel::Context &ctx, ox::Buffer &buff, ox::StringView typeId) -> ox::Error { if (typeId == ox::ModelTypeId_v || typeId == ox::ModelTypeId_v || typeId == ox::ModelTypeId_v || typeId == ox::ModelTypeId_v) { - oxReturnError(keel::convertBuffToBuff( - ctx, buff, ox::ClawFormat::Metal).moveTo(buff)); + return keel::convertBuffToBuff( + ctx, buff, ox::ClawFormat::Metal).moveTo(buff); } return {}; }, - [](keel::Context &ctx, ox::Buffer &buff) -> ox::Error { - oxRequire(hdr, keel::readAssetHeader(buff)); - auto const typeId = ox::buildTypeId( - hdr.clawHdr.typeName, hdr.clawHdr.typeVersion, hdr.clawHdr.typeParams); + [](keel::Context &ctx, ox::Buffer &buff, ox::StringView typeId) -> ox::Error { if (typeId == ox::ModelTypeId_v || typeId == ox::ModelTypeId_v) { - oxReturnError(keel::convertBuffToBuff( - ctx, buff, ox::ClawFormat::Metal).moveTo(buff)); + return keel::convertBuffToBuff( + ctx, buff, ox::ClawFormat::Metal).moveTo(buff); } return {}; }, diff --git a/src/nostalgia/modules/core/src/keel/typeconv.hpp b/src/nostalgia/modules/core/src/keel/typeconv.hpp index 7c27fa7d..b7b47722 100644 --- a/src/nostalgia/modules/core/src/keel/typeconv.hpp +++ b/src/nostalgia/modules/core/src/keel/typeconv.hpp @@ -29,11 +29,11 @@ class TileSheetV1ToTileSheetV2Converter: public keel::Converter { - static void convertSubsheet( - TileSheetV2::SubSheet &src, - TileSheetV3::SubSheet &dst, - SubSheetId &idIt) noexcept; - ox::Error convert(keel::Context&, TileSheetV2 &src, TileSheetV3 &dst) const noexcept final; + static void convertSubsheet( + TileSheetV2::SubSheet &src, + TileSheetV3::SubSheet &dst, + SubSheetId &idIt) noexcept; + ox::Error convert(keel::Context&, TileSheetV2 &src, TileSheetV3 &dst) const noexcept final; }; class TileSheetV3ToTileSheetV4Converter: public keel::Converter { @@ -45,7 +45,7 @@ class TileSheetV3ToTileSheetV4Converter: public keel::Converter { - ox::Error convert(keel::Context&, TileSheet &src, CompactTileSheet &dst) const noexcept final; + ox::Error convert(keel::Context&, TileSheet &src, CompactTileSheet &dst) const noexcept final; }; } diff --git a/src/olympic/keel/include/keel/asset.hpp b/src/olympic/keel/include/keel/asset.hpp index f03b2a06..6fbd5584 100644 --- a/src/olympic/keel/include/keel/asset.hpp +++ b/src/olympic/keel/include/keel/asset.hpp @@ -11,9 +11,7 @@ namespace keel { constexpr auto K1HdrSz = 40; -ox::Result readUuidHeader(ox::Buffer const&buff) noexcept; - -ox::Result readUuidHeader(const char *buff, std::size_t buffLen) noexcept; +ox::Result readUuidHeader(ox::BufferView buff) noexcept; ox::Error writeUuidHeader(ox::Writer_c auto &writer, ox::UUID const&uuid) noexcept { oxReturnError(write(writer, "K1;")); @@ -22,24 +20,24 @@ ox::Error writeUuidHeader(ox::Writer_c auto &writer, ox::UUID const&uuid) noexce } template -ox::Result readAsset(ox::Buffer const&buff) noexcept { +ox::Result readAsset(ox::BufferView buff) noexcept { std::size_t offset = 0; const auto err = readUuidHeader(buff).error; if (!err) { offset = K1HdrSz; // the size of K1 headers } - return ox::readClaw(buff.data() + offset, buff.size() - offset); + return ox::readClaw(buff + offset); } -ox::Result readAsset(ox::TypeStore &ts, ox::Buffer const&buff) noexcept; +ox::Result readAsset(ox::TypeStore &ts, ox::BufferView buff) noexcept; struct AssetHdr { ox::UUID uuid; ox::ClawHeader clawHdr; }; -ox::Result readAssetHeader(char const*buff, std::size_t buffLen) noexcept; +ox::Result readAssetTypeId(ox::BufferView buff) noexcept; -ox::Result readAssetHeader(ox::Buffer const&buff) noexcept; +ox::Result readAssetHeader(ox::BufferView buff) noexcept; } diff --git a/src/olympic/keel/include/keel/context.hpp b/src/olympic/keel/include/keel/context.hpp index acc936c9..30847cb6 100644 --- a/src/olympic/keel/include/keel/context.hpp +++ b/src/olympic/keel/include/keel/context.hpp @@ -12,7 +12,7 @@ namespace keel { class Context; -using PackTransform = ox::Error(*)(Context&, ox::Buffer &clawData); +using PackTransform = ox::Error(*)(Context&, ox::Buffer &clawData, ox::StringView); class Context { public: @@ -36,4 +36,22 @@ class Context { constexpr virtual ~Context() noexcept = default; }; +constexpr ox::SpanView packTransforms( + [[maybe_unused]] Context const&ctx) noexcept { +#ifndef OX_BARE_METAL + return ctx.packTransforms; +#else + return {}; +#endif +} + +constexpr ox::SpanView converters( + [[maybe_unused]] Context const&ctx) noexcept { +#ifndef OX_BARE_METAL + return ctx.converters; +#else + return {}; +#endif +} + } diff --git a/src/olympic/keel/include/keel/typeconv.hpp b/src/olympic/keel/include/keel/typeconv.hpp index 35239488..2ece88c1 100644 --- a/src/olympic/keel/include/keel/typeconv.hpp +++ b/src/olympic/keel/include/keel/typeconv.hpp @@ -40,7 +40,7 @@ class WrapInline: public Wrap { }; template -constexpr auto makeWrap(Args &&...args) noexcept { +constexpr ox::UPtr makeWrap(Args &&...args) noexcept { return ox::make_unique>(ox::forward(args)...); } @@ -65,9 +65,10 @@ class BaseConverter { [[nodiscard]] virtual bool dstMatches(ox::CRStringView dstTypeName, int dstTypeVersion) const noexcept = 0; - virtual ox::Result> convertPtrToPtr(keel::Context &ctx, Wrap &src) const noexcept = 0; + virtual ox::Result> convertPtrToPtr(keel::Context &ctx, Wrap &src) const noexcept = 0; - virtual ox::Result> convertBuffToPtr(keel::Context &ctx, ox::Buffer const&srcBuff) const noexcept = 0; + virtual ox::Result> convertBuffToPtr( + keel::Context &ctx, ox::Buffer const&srcBuff) const noexcept = 0; [[nodiscard]] inline bool matches( @@ -84,12 +85,12 @@ class Converter: public BaseConverter { public: [[nodiscard]] ox::StringView srcTypeName() const noexcept final { - return ox::requireModelTypeName(); + return ox::ModelTypeName_v; } [[nodiscard]] int srcTypeVersion() const noexcept final { - return ox::requireModelTypeVersion(); + return ox::ModelTypeVersion_v; } [[nodiscard]] @@ -97,7 +98,7 @@ class Converter: public BaseConverter { constexpr auto SrcTypeName = ox::requireModelTypeName(); constexpr auto SrcTypeVersion = ox::requireModelTypeVersion(); return pSrcTypeName == SrcTypeName - && pSrcTypeVersion == SrcTypeVersion; + && pSrcTypeVersion == SrcTypeVersion; } [[nodiscard]] @@ -105,20 +106,22 @@ class Converter: public BaseConverter { constexpr auto DstTypeName = ox::StringView(ox::requireModelTypeName()); constexpr auto DstTypeVersion = ox::requireModelTypeVersion(); return dstTypeName == DstTypeName - && dstTypeVersion == DstTypeVersion; + && dstTypeVersion == DstTypeVersion; } - ox::Result> convertPtrToPtr(keel::Context &ctx, Wrap &src) const noexcept final { + ox::Result> convertPtrToPtr( + keel::Context &ctx, Wrap &src) const noexcept final { auto dst = makeWrap(); oxReturnError(convert(ctx, wrapCast(src), wrapCast(*dst))); - return ox::Result>(std::move(dst)); + return {std::move(dst)}; } - ox::Result> convertBuffToPtr(keel::Context &ctx, ox::Buffer const&srcBuff) const noexcept final { + ox::Result> convertBuffToPtr( + keel::Context &ctx, ox::Buffer const&srcBuff) const noexcept final { oxRequireM(src, readAsset(srcBuff)); auto dst = makeWrap(); oxReturnError(convert(ctx, src, wrapCast(*dst))); - return ox::Result>(std::move(dst)); + return {std::move(dst)}; } protected: @@ -126,9 +129,11 @@ class Converter: public BaseConverter { }; -ox::Result> convert( - keel::Context &ctx, ox::Buffer const&srcBuffer, - ox::CRStringView dstTypeName, int dstTypeVersion) noexcept; +ox::Result> convert( + keel::Context &ctx, + ox::Buffer const&srcBuffer, + ox::CRStringView dstTypeName, + int dstTypeVersion) noexcept; template ox::Result convert(keel::Context &ctx, ox::Buffer const&srcBuffer) noexcept { @@ -148,7 +153,8 @@ ox::Error convert(keel::Context &ctx, ox::Buffer const&buff, DstType *outObj) no } template -ox::Result convertBuffToBuff(keel::Context &ctx, ox::Buffer const&srcBuffer, ox::ClawFormat fmt) noexcept { +ox::Result convertBuffToBuff( + keel::Context &ctx, ox::Buffer const&srcBuffer, ox::ClawFormat fmt) noexcept { static constexpr auto DstTypeName = ox::requireModelTypeName(); static constexpr auto DstTypeVersion = ox::requireModelTypeVersion(); oxRequire(out, convert(ctx, srcBuffer, DstTypeName, DstTypeVersion)); @@ -156,10 +162,7 @@ ox::Result convertBuffToBuff(keel::Context &ctx, ox::Buffer const&sr } template -auto transformRule(keel::Context &ctx, ox::Buffer &buff) noexcept -> ox::Error { - oxRequire(hdr, readAssetHeader(buff)); - const auto typeId = ox::buildTypeId( - hdr.clawHdr.typeName, hdr.clawHdr.typeVersion, hdr.clawHdr.typeParams); +auto transformRule(keel::Context &ctx, ox::Buffer &buff, ox::StringView typeId) noexcept -> ox::Error { if (typeId == ox::ModelTypeId_v) { oxReturnError(keel::convertBuffToBuff(ctx, buff, fmt).moveTo(buff)); } diff --git a/src/olympic/keel/include/keel/typestore.hpp b/src/olympic/keel/include/keel/typestore.hpp index 699c569b..619c050b 100644 --- a/src/olympic/keel/include/keel/typestore.hpp +++ b/src/olympic/keel/include/keel/typestore.hpp @@ -19,7 +19,7 @@ class TypeStore: public ox::TypeStore { explicit TypeStore(ox::FileSystem &fs, ox::StringView descPath) noexcept; protected: - ox::Result> loadDescriptor(ox::CRStringView typeId) noexcept override; + ox::Result> loadDescriptor(ox::StringView typeId) noexcept override; }; } diff --git a/src/olympic/keel/src/asset.cpp b/src/olympic/keel/src/asset.cpp index 5caf6b2f..338ce25a 100644 --- a/src/olympic/keel/src/asset.cpp +++ b/src/olympic/keel/src/asset.cpp @@ -6,41 +6,45 @@ namespace keel { -ox::Result readUuidHeader(ox::Buffer const&buff) noexcept { - return readUuidHeader(buff.data(), buff.size()); -} - -ox::Result readUuidHeader(char const*buff, std::size_t buffLen) noexcept { - if (buffLen < K1HdrSz) { +ox::Result readUuidHeader(ox::BufferView buff) noexcept { + if (buff.size() < K1HdrSz) [[unlikely]] { return OxError(1, "Insufficient data to contain complete Keel header"); } constexpr ox::StringView k1Hdr = "K1;"; - if (k1Hdr != ox::StringView(buff, k1Hdr.bytes())) { + if (k1Hdr != ox::StringView(buff.data(), k1Hdr.bytes())) [[unlikely]] { return OxError(2, "No Keel asset header data"); } - return ox::UUID::fromString(ox::StringView(buff + k1Hdr.bytes(), 36)); + return ox::UUID::fromString(ox::StringView(buff.data() + k1Hdr.bytes(), 36)); } -ox::Result readAsset(ox::TypeStore &ts, ox::Buffer const&buff) noexcept { +ox::Result readAsset(ox::TypeStore &ts, ox::BufferView buff) noexcept { std::size_t offset = 0; if (!readUuidHeader(buff).error) { offset = K1HdrSz; } - return ox::readClaw(ts, buff.data() + offset, buff.size() - offset); + buff += offset; + return ox::readClaw(ts, buff); } -ox::Result readAssetHeader(char const*buff, std::size_t buffLen) noexcept { - AssetHdr out; - const auto err = readUuidHeader(buff, buffLen).moveTo(out.uuid); +ox::Result readAssetTypeId(ox::BufferView buff) noexcept { + const auto err = readUuidHeader(buff).error; const auto offset = err ? 0u : K1HdrSz; - buff = buff + offset; - buffLen = buffLen - offset; - oxReturnError(ox::readClawHeader(buff, buffLen).moveTo(out.clawHdr)); + if (offset >= buff.size()) [[unlikely]] { + return OxError(1, "Buffer too small for expected data"); + } + return ox::readClawTypeId(buff + offset); +} + +ox::Result readAssetHeader(ox::BufferView buff) noexcept { + ox::Result out; + const auto err = readUuidHeader(buff).moveTo(out.value.uuid); + const auto offset = err ? 0u : K1HdrSz; + if (offset >= buff.size()) [[unlikely]] { + return OxError(1, "Buffer too small for expected data"); + } + buff += offset; + oxReturnError(ox::readClawHeader(buff).moveTo(out.value.clawHdr)); return out; } -ox::Result readAssetHeader(ox::Buffer const&buff) noexcept { - return readAssetHeader(buff.data(), buff.size()); -} - } diff --git a/src/olympic/keel/src/media.cpp b/src/olympic/keel/src/media.cpp index 03a7e718..682f34a4 100644 --- a/src/olympic/keel/src/media.cpp +++ b/src/olympic/keel/src/media.cpp @@ -102,14 +102,11 @@ ox::Result uuidToPath(Context &ctx, ox::UUID const&uuid) noexcept { } ox::Error performPackTransforms(Context &ctx, ox::Buffer &clawData) noexcept { -#ifndef OX_BARE_METAL - for (auto tr : ctx.packTransforms) { - oxReturnError(tr(ctx, clawData)); + oxRequire(typeId, readAssetTypeId(clawData).to()); + for (auto const tr : packTransforms(ctx)) { + oxReturnError(tr(ctx, clawData, typeId)); } return {}; -#else - return OxError(1, "Transformations not supported on this platform"); -#endif } } @@ -153,7 +150,7 @@ ox::Result getPreloadAddr(keel::Context &ctx, ox::CRStringView path oxRequire(stat, ctx.rom->stat(path)); oxRequire(buff, static_cast(ctx.rom.get())->directAccess(path)); PreloadPtr p; - oxReturnError(ox::readMC(buff, static_cast(stat.size), &p)); + oxReturnError(ox::readMC({buff, static_cast(stat.size)}, p)); return static_cast(p.preloadAddr) + ctx.preloadSectionOffset; } @@ -161,7 +158,7 @@ ox::Result getPreloadAddr(keel::Context &ctx, ox::FileAddress const oxRequire(stat, ctx.rom->stat(file)); oxRequire(buff, static_cast(ctx.rom.get())->directAccess(file)); PreloadPtr p; - oxReturnError(ox::readMC(buff, static_cast(stat.size), &p)); + oxReturnError(ox::readMC({buff, static_cast(stat.size)}, p)); return static_cast(p.preloadAddr) + ctx.preloadSectionOffset; } diff --git a/src/olympic/keel/src/typeconv.cpp b/src/olympic/keel/src/typeconv.cpp index a53bea06..bb821797 100644 --- a/src/olympic/keel/src/typeconv.cpp +++ b/src/olympic/keel/src/typeconv.cpp @@ -10,13 +10,13 @@ namespace keel { [[nodiscard]] -static ox::Result findConverter( - ox::Vector const&converters, +static ox::Result findConverter( + ox::SpanView const&converters, ox::CRStringView srcTypeName, int srcTypeVersion, ox::CRStringView dstTypeName, int dstTypeVersion) noexcept { - for (auto &c : converters) { + for (auto const&c : converters) { if (c->matches(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion)) { return c; } @@ -24,21 +24,22 @@ static ox::Result findConverter( return OxError(1, "Could not find converter"); }; -static ox::Result> convert( - [[maybe_unused]] keel::Context &ctx, - ox::Vector const&converters, - [[maybe_unused]] ox::Buffer const&srcBuffer, - [[maybe_unused]] ox::CRStringView srcTypeName, - [[maybe_unused]] int srcTypeVersion, - [[maybe_unused]] ox::CRStringView dstTypeName, - [[maybe_unused]] int dstTypeVersion) noexcept { +static ox::Result> convert( + keel::Context &ctx, + ox::SpanView const&converters, + ox::Buffer const&srcBuffer, + ox::CRStringView srcTypeName, + int srcTypeVersion, + ox::CRStringView dstTypeName, + int dstTypeVersion) noexcept { // look for direct converter - auto [c, err] = findConverter(converters, srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion); + auto [c, err] = findConverter( + converters, srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion); if (!err) { return c->convertBuffToPtr(ctx, srcBuffer); } // try to chain multiple converters - for (const auto &subConverter : converters) { + for (auto const&subConverter : converters) { if (!subConverter->dstMatches(dstTypeName, dstTypeVersion)) { continue; } @@ -52,24 +53,20 @@ static ox::Result> convert( return OxError(1, "Could not convert between types"); } -ox::Result> convert( - [[maybe_unused]] keel::Context &ctx, - [[maybe_unused]] ox::Buffer const&srcBuffer, - [[maybe_unused]] ox::CRStringView dstTypeName, - [[maybe_unused]] int dstTypeVersion) noexcept { -#ifndef OX_BARE_METAL +ox::Result> convert( + keel::Context &ctx, + ox::Buffer const&srcBuffer, + ox::CRStringView dstTypeName, + int dstTypeVersion) noexcept { oxRequire(hdr, readAssetHeader(srcBuffer)); return convert( ctx, - ctx.converters, + converters(ctx), srcBuffer, hdr.clawHdr.typeName, hdr.clawHdr.typeVersion, dstTypeName, dstTypeVersion); -#else - return OxError(1, "Operation not supported on this platform"); -#endif } } diff --git a/src/olympic/keel/src/typestore.cpp b/src/olympic/keel/src/typestore.cpp index 7afcc6b1..b5a79c74 100644 --- a/src/olympic/keel/src/typestore.cpp +++ b/src/olympic/keel/src/typestore.cpp @@ -11,11 +11,11 @@ TypeStore::TypeStore(ox::FileSystem &fs, ox::StringView descPath) noexcept: m_descPath(descPath) { } -ox::Result> TypeStore::loadDescriptor(ox::CRStringView typeId) noexcept { - auto path = ox::sfmt("{}/{}", m_descPath, typeId); +ox::Result> TypeStore::loadDescriptor(ox::StringView const typeId) noexcept { + auto const path = ox::sfmt("{}/{}", m_descPath, typeId); oxRequire(buff, m_fs.read(path)); auto dt = ox::make_unique(); - oxReturnError(ox::readClaw(buff, dt.get())); + oxReturnError(ox::readClaw(buff, *dt)); return dt; } diff --git a/src/olympic/studio/applib/src/main.cpp b/src/olympic/studio/applib/src/main.cpp index be05412b..b38ec361 100644 --- a/src/olympic/studio/applib/src/main.cpp +++ b/src/olympic/studio/applib/src/main.cpp @@ -68,7 +68,7 @@ static ox::Error run( static_cast(time << 1) }); // run app - auto const err = runApp(appName, projectDataDir, ox::UniquePtr(nullptr)); + auto const err = runApp(appName, projectDataDir, ox::UPtr(nullptr)); oxAssert(err, "Something went wrong..."); return err; } From 74a8a7d7515d2a9f372b7cd3d2fefccf570da4c2 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Wed, 8 May 2024 23:43:12 -0500 Subject: [PATCH 3/6] [ox/std] Remove incomplete writeF32toa --- deps/ox/src/ox/std/smallmap.hpp | 238 +++++++++++++++++++++++++ deps/ox/src/ox/std/strconv.hpp | 13 -- deps/ox/src/ox/std/test/CMakeLists.txt | 1 - deps/ox/src/ox/std/test/tests.cpp | 10 -- 4 files changed, 238 insertions(+), 24 deletions(-) create mode 100644 deps/ox/src/ox/std/smallmap.hpp diff --git a/deps/ox/src/ox/std/smallmap.hpp b/deps/ox/src/ox/std/smallmap.hpp new file mode 100644 index 00000000..76ad9370 --- /dev/null +++ b/deps/ox/src/ox/std/smallmap.hpp @@ -0,0 +1,238 @@ +/* + * Copyright 2015 - 2024 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 "algorithm.hpp" +#include "hash.hpp" +#include "ignore.hpp" +#include "stringview.hpp" +#include "strops.hpp" +#include "vector.hpp" + +namespace ox { + +template +class SmallMap { + + public: + using key_t = K; + using value_t = T; + + private: + struct Pair { + K key = {}; + T value{}; + }; + Vector m_keys; + Vector m_pairs; + + public: + explicit constexpr SmallMap(std::size_t size = 127); + + constexpr SmallMap(SmallMap const&other); + + constexpr SmallMap(SmallMap &&other) noexcept; + + constexpr ~SmallMap(); + + constexpr bool operator==(SmallMap const&other) const; + + constexpr SmallMap &operator=(SmallMap const&other); + + constexpr SmallMap &operator=(SmallMap &&other) noexcept; + + constexpr T &operator[](MaybeView_t const&key); + + constexpr Result at(MaybeView_t const&key) noexcept; + + constexpr Result at(MaybeView_t const&key) const noexcept; + + constexpr void erase(MaybeView_t const&key); + + [[nodiscard]] + constexpr bool contains(MaybeView_t const&key) const noexcept; + + [[nodiscard]] + constexpr std::size_t size() const noexcept; + + [[nodiscard]] + constexpr Vector const&keys() const noexcept; + + constexpr void clear(); + + private: + constexpr void expand(); + + template + constexpr Pair *const&access(Vector const&pairs, KK const&key) const; + + template + constexpr Pair *&access(Vector &pairs, KK const&key); + +}; + +template +constexpr SmallMap::SmallMap(std::size_t size): m_pairs(size) { +} + +template +constexpr SmallMap::SmallMap(SmallMap const&other) { + m_pairs = other.m_pairs; +} + +template +constexpr SmallMap::SmallMap(SmallMap &&other) noexcept { + m_keys = std::move(other.m_keys); + m_pairs = std::move(other.m_pairs); +} + +template +constexpr SmallMap::~SmallMap() { + clear(); +} + +template +constexpr bool SmallMap::operator==(SmallMap const&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 +constexpr SmallMap &SmallMap::operator=(SmallMap const&other) { + if (this != &other) { + clear(); + m_keys = other.m_keys; + m_pairs = other.m_pairs; + } + return *this; +} + +template +constexpr SmallMap &SmallMap::operator=(SmallMap &&other) noexcept { + if (this != &other) { + clear(); + m_keys = std::move(other.m_keys); + m_pairs = std::move(other.m_pairs); + } + return *this; +} + +template +constexpr T &SmallMap::operator[](MaybeView_t const&k) { + auto &p = access(m_pairs, k); + if (p == nullptr) { + if (static_cast(m_pairs.size()) * 0.7 < + static_cast(m_keys.size())) { + expand(); + } + p = new Pair; + p->key = k; + m_keys.emplace_back(k); + } + return p->value; +} + +template +constexpr Result SmallMap::at(MaybeView_t const&k) noexcept { + auto p = access(m_pairs, k); + if (!p) { + return {nullptr, OxError(1, "value not found for given key")}; + } + return &p->value; +} + +template +constexpr Result SmallMap::at(MaybeView_t const&k) const noexcept { + auto p = access(m_pairs, k); + if (!p) { + return {nullptr, OxError(1, "value not found for given key")}; + } + return &p->value; +} + +template +constexpr void SmallMap::erase(MaybeView_t const&k) { + size_t i{}; + for (auto const&p : m_pairs) { + if (k == p.key) { + break; + } + ++i; + } + std::ignore = m_pairs.erase(i); + std::ignore = m_keys.erase(i); +} + +template +constexpr bool SmallMap::contains(MaybeView_t const&k) const noexcept { + return access(m_pairs, k) != nullptr; +} + +template +constexpr std::size_t SmallMap::size() const noexcept { + return m_keys.size(); +} + +template +constexpr Vector const&SmallMap::keys() const noexcept { + return m_keys; +} + +template +constexpr void SmallMap::clear() { + for (std::size_t i = 0; i < m_pairs.size(); i++) { + delete m_pairs[i]; + } + m_pairs.clear(); + m_pairs.resize(127); +} + +template +constexpr void SmallMap::expand() { + Vector r; + for (std::size_t i = 0; i < m_keys.size(); ++i) { + auto const&k = m_keys[i]; + access(r, k) = std::move(access(m_pairs, k)); + } + m_pairs = std::move(r); +} + +template +template +constexpr typename SmallMap::Pair *const&SmallMap::access( + Vector const&pairs, KK const&k) const { + for (auto const&p : pairs) { + if (p.key == k) { + return &p; + } + } + return nullptr; +} + +template +template +constexpr typename SmallMap::Pair *&SmallMap::access( + Vector &pairs, KK const&k) { + for (auto &p : pairs) { + if (p.key == k) { + return &p; + } + } + return nullptr; +} + +} diff --git a/deps/ox/src/ox/std/strconv.hpp b/deps/ox/src/ox/std/strconv.hpp index 2a18ec3d..6d8a25b3 100644 --- a/deps/ox/src/ox/std/strconv.hpp +++ b/deps/ox/src/ox/std/strconv.hpp @@ -41,19 +41,6 @@ constexpr ox::Error writeItoa(Integer v, ox::Writer_c auto &writer) noexcept { return {}; } -constexpr ox::Error writeF32toa(float const v, ox::Writer_c auto &writer) noexcept { - auto const raw = std::bit_cast(v); - if (raw >> 31) { - oxReturnError(writer.put('-')); - } - auto const mantissa = raw & onMask(23); - auto const exp = ((raw >> 23) & 0xff) - 126; - auto const p = ox::pow(2u, exp); - auto const out = p * mantissa; - oxReturnError(writeItoa(out, writer)); - return {}; -} - } #include "istring.hpp" diff --git a/deps/ox/src/ox/std/test/CMakeLists.txt b/deps/ox/src/ox/std/test/CMakeLists.txt index 567cf7db..d0c7da23 100644 --- a/deps/ox/src/ox/std/test/CMakeLists.txt +++ b/deps/ox/src/ox/std/test/CMakeLists.txt @@ -11,7 +11,6 @@ add_test("[ox/std] ox_memcmp ABCDEFG != HIJKLMN" ${CMAKE_RUNTIME_OUTPUT_DIRECTOR add_test("[ox/std] ox_memcmp HIJKLMN != ABCDEFG" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "HIJKLMN != ABCDEFG") add_test("[ox/std] ox_memcmp ABCDEFG == ABCDEFG" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "ABCDEFG == ABCDEFG") add_test("[ox/std] ox_memcmp ABCDEFGHI == ABCDEFG" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "ABCDEFGHI == ABCDEFG") -#add_test("[ox/std] ftoa" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "ftoa") add_test("[ox/std] itoa" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "itoa") add_test("[ox/std] BString" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "BString") add_test("[ox/std] String" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "String") diff --git a/deps/ox/src/ox/std/test/tests.cpp b/deps/ox/src/ox/std/test/tests.cpp index 745ea2f8..2a72f17a 100644 --- a/deps/ox/src/ox/std/test/tests.cpp +++ b/deps/ox/src/ox/std/test/tests.cpp @@ -26,16 +26,6 @@ static std::map tests = { return OxError(0); } }, - { - "ftoa", - []() { - ox::Array buff; - ox::CharBuffWriter bw(buff); - oxAssert(ox::writeF32toa(5, bw), "ox::writeItoa returned Error"); - oxExpect(ox::StringView(buff.data()), ox::StringView("5")); - return ox::Error{}; - } - }, { "itoa", []() { From 1ecf197a9ec5d7a903c5049f9ed6da01b18b62a3 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Wed, 8 May 2024 23:44:05 -0500 Subject: [PATCH 4/6] [nostalgia] Remove .idea directory --- .idea/.gitignore | 8 ------- .idea/codeStyles/Project.xml | 22 ----------------- .idea/codeStyles/codeStyleConfig.xml | 5 ---- .../fileTemplates/internal/C++ Class Header.h | 17 ------------- .idea/fileTemplates/internal/C++ Class.cc | 13 ---------- .idea/inspectionProfiles/Project_Default.xml | 24 ------------------- .idea/misc.xml | 17 ------------- .idea/nostalgia.iml | 8 ------- .idea/vcs.xml | 6 ----- 9 files changed, 120 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/codeStyles/Project.xml delete mode 100644 .idea/codeStyles/codeStyleConfig.xml delete mode 100644 .idea/fileTemplates/internal/C++ Class Header.h delete mode 100644 .idea/fileTemplates/internal/C++ Class.cc delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/nostalgia.iml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 73f69e09..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml -# Editor-based HTTP Client requests -/httpRequests/ diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index 7224b0cc..00000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index fea906c2..00000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/fileTemplates/internal/C++ Class Header.h b/.idea/fileTemplates/internal/C++ Class Header.h deleted file mode 100644 index 7eb10bd8..00000000 --- a/.idea/fileTemplates/internal/C++ Class Header.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2016 - 2021 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 http://mozilla.org/MPL/2.0/. - */ - -#[[#pragma]]# once - -${NAMESPACES_OPEN} - -class ${NAME} { - -}; - -${NAMESPACES_CLOSE} \ No newline at end of file diff --git a/.idea/fileTemplates/internal/C++ Class.cc b/.idea/fileTemplates/internal/C++ Class.cc deleted file mode 100644 index dab91b77..00000000 --- a/.idea/fileTemplates/internal/C++ Class.cc +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright 2016 - 2021 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 http://mozilla.org/MPL/2.0/. - */ - -#[[#include]]# "${HEADER_FILENAME}" - -${NAMESPACES_OPEN} - -${NAMESPACES_CLOSE} diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 37b0cba1..00000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 8067168a..00000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/nostalgia.iml b/.idea/nostalgia.iml deleted file mode 100644 index 57399c33..00000000 --- a/.idea/nostalgia.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7f..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From 204e5bbff4141a1d308bab2868673281db329a25 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Wed, 8 May 2024 23:46:12 -0500 Subject: [PATCH 5/6] [ox/std] Add SmallMap --- deps/ox/src/ox/std/CMakeLists.txt | 1 + deps/ox/src/ox/std/std.hpp | 1 + 2 files changed, 2 insertions(+) diff --git a/deps/ox/src/ox/std/CMakeLists.txt b/deps/ox/src/ox/std/CMakeLists.txt index 93dd0d75..ebc10c0f 100644 --- a/deps/ox/src/ox/std/CMakeLists.txt +++ b/deps/ox/src/ox/std/CMakeLists.txt @@ -117,6 +117,7 @@ install( ranges.hpp serialize.hpp size.hpp + smallmap.hpp stacktrace.hpp std.hpp stddef.hpp diff --git a/deps/ox/src/ox/std/std.hpp b/deps/ox/src/ox/std/std.hpp index be073120..6b95d6dd 100644 --- a/deps/ox/src/ox/std/std.hpp +++ b/deps/ox/src/ox/std/std.hpp @@ -39,6 +39,7 @@ #include "realstd.hpp" #include "serialize.hpp" #include "size.hpp" +#include "smallmap.hpp" #include "stacktrace.hpp" #include "stddef.hpp" #include "string.hpp" From f624c720f9dcc9b44943269adb54d32095bc0e04 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Wed, 8 May 2024 23:54:06 -0500 Subject: [PATCH 6/6] [studio] Fix broken readClaw call --- src/olympic/studio/modlib/include/studio/imguiutil.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/olympic/studio/modlib/include/studio/imguiutil.hpp b/src/olympic/studio/modlib/include/studio/imguiutil.hpp index 8038660f..4632b6ec 100644 --- a/src/olympic/studio/modlib/include/studio/imguiutil.hpp +++ b/src/olympic/studio/modlib/include/studio/imguiutil.hpp @@ -29,9 +29,9 @@ ox::Result getDragDropPayload(ox::CStringView name) noexcept { if (!payload) { return OxError(1, "No drag/drop payload"); } - return ox::readClaw( + return ox::readClaw({ reinterpret_cast(payload->Data), - static_cast(payload->DataSize)); + static_cast(payload->DataSize)}); } ox::Error setDragDropPayload(ox::CStringView name, auto const &obj) noexcept {