From 63486c23d46412e7eacc8acf6e56fd699b3bca45 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Wed, 8 May 2024 23:35:05 -0500 Subject: [PATCH] [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}));