Compare commits
7 Commits
d0579014d8
...
23054c9f6f
| Author | SHA1 | Date | |
|---|---|---|---|
| 23054c9f6f | |||
| e0289ee7e0 | |||
| 2c8e073172 | |||
| 6f5f2c7219 | |||
| ce4dcdcd18 | |||
| ae3f0bb5db | |||
| f5b1da09b5 |
10
deps/ox/src/ox/claw/test/tests.cpp
vendored
10
deps/ox/src/ox/claw/test/tests.cpp
vendored
@@ -139,7 +139,7 @@ static std::map<std::string_view, ox::Error(*)()> tests = {
|
||||
// This test doesn't confirm much, but it does show that the writer
|
||||
// doesn't segfault
|
||||
TestStruct ts;
|
||||
oxReturnError(ox::writeClaw(&ts, ox::ClawFormat::Metal));
|
||||
oxReturnError(ox::writeClaw(ts, ox::ClawFormat::Metal));
|
||||
return OxError(0);
|
||||
}
|
||||
},
|
||||
@@ -158,12 +158,10 @@ static std::map<std::string_view, ox::Error(*)()> tests = {
|
||||
testIn.Struct.Bool = false;
|
||||
testIn.Struct.Int = 300;
|
||||
testIn.Struct.String = "Test String 2";
|
||||
|
||||
auto [buff, err] = ox::writeClaw(&testIn, ox::ClawFormat::Metal);
|
||||
oxAssert(err, "writeMC failed");
|
||||
oxAssert(ox::readClaw(buff.data(), buff.size(), &testOut), "readMC failed");
|
||||
const auto [buff, err] = ox::writeMC(&testIn);
|
||||
oxAssert(err, "writeClaw failed");
|
||||
oxAssert(ox::readMC(buff.data(), buff.size(), &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");
|
||||
|
||||
50
deps/ox/src/ox/claw/write.hpp
vendored
50
deps/ox/src/ox/claw/write.hpp
vendored
@@ -14,6 +14,7 @@
|
||||
#endif
|
||||
#include <ox/std/buffer.hpp>
|
||||
#include <ox/std/string.hpp>
|
||||
#include <ox/std/stringview.hpp>
|
||||
|
||||
#include "format.hpp"
|
||||
|
||||
@@ -27,7 +28,11 @@ struct TypeInfoCatcher {
|
||||
int version = 0;
|
||||
|
||||
template<typename T = void>
|
||||
constexpr void setTypeInfo(const char *name = T::TypeName, int v = T::TypeVersion, const Vector<String>& = {}, std::size_t = 0) noexcept {
|
||||
constexpr void setTypeInfo(
|
||||
const char *name = T::TypeName,
|
||||
int v = T::TypeVersion,
|
||||
const Vector<String>& = {},
|
||||
std::size_t = 0) noexcept {
|
||||
this->name = name;
|
||||
this->version = v;
|
||||
}
|
||||
@@ -53,57 +58,64 @@ struct type_version<T, decltype((void) T::TypeVersion, -1)> {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
constexpr const char *getTypeName(T *t) noexcept {
|
||||
constexpr const char *getTypeName(const T *t) noexcept {
|
||||
TypeInfoCatcher tnc;
|
||||
oxIgnoreError(model(&tnc, t));
|
||||
return tnc.name;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr int getTypeVersion(T *t) noexcept {
|
||||
constexpr int getTypeVersion(const T *t) noexcept {
|
||||
TypeInfoCatcher tnc;
|
||||
oxIgnoreError(model(&tnc, t));
|
||||
return tnc.version;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Result<String> writeClawHeader(T *t, ClawFormat fmt) noexcept {
|
||||
String out;
|
||||
ox::Error writeClawHeader(Writer_c auto &writer, T *t, ClawFormat fmt) noexcept {
|
||||
switch (fmt) {
|
||||
case ClawFormat::Metal:
|
||||
out += "M2;";
|
||||
oxReturnError(write(&writer, "M2;"));
|
||||
break;
|
||||
case ClawFormat::Organic:
|
||||
out += "O1;";
|
||||
oxReturnError(write(&writer, "O1;"));
|
||||
break;
|
||||
default:
|
||||
return OxError(1);
|
||||
}
|
||||
out += detail::getTypeName(t);
|
||||
out += ";";
|
||||
oxReturnError(write(&writer, detail::getTypeName(t)));
|
||||
oxReturnError(writer.put(';'));
|
||||
const auto tn = detail::getTypeVersion(t);
|
||||
if (tn > -1) {
|
||||
out += tn;
|
||||
oxReturnError(ox::itoa(tn, writer));
|
||||
}
|
||||
out += ";";
|
||||
return out;
|
||||
oxReturnError(writer.put(';'));
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Result<Buffer> writeClaw(auto *t, ClawFormat fmt = ClawFormat::Metal) {
|
||||
oxRequire(header, detail::writeClawHeader(t, fmt));
|
||||
Result<Buffer> writeClaw(
|
||||
auto &t,
|
||||
ClawFormat fmt = ClawFormat::Metal,
|
||||
std::size_t buffReserveSz = 2 * units::KB) noexcept {
|
||||
Buffer out(buffReserveSz);
|
||||
BufferWriter bw(&out, 0);
|
||||
oxReturnError(detail::writeClawHeader(bw, &t, fmt));
|
||||
#ifdef OX_USE_STDLIB
|
||||
oxRequire(data, fmt == ClawFormat::Metal ? writeMC(t) : writeOC(t));
|
||||
if (fmt == ClawFormat::Metal) {
|
||||
oxReturnError(writeMC(bw, t));
|
||||
} else if (fmt == ClawFormat::Organic) {
|
||||
oxRequire(data, writeOC(t));
|
||||
oxReturnError(bw.write(data.data(), data.size()));
|
||||
}
|
||||
#else
|
||||
if (fmt != ClawFormat::Metal) {
|
||||
return OxError(1, "OC is not supported in this build");
|
||||
}
|
||||
oxRequire(data, writeMC(t));
|
||||
oxReturnError(writeMC(bw, t));
|
||||
#endif
|
||||
Buffer out(header.len() + data.size());
|
||||
memcpy(out.data(), header.data(), header.len());
|
||||
memcpy(out.data() + header.len(), data.data(), data.size());
|
||||
out.resize(bw.tellp());
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
8
deps/ox/src/ox/mc/presenceindicator.hpp
vendored
8
deps/ox/src/ox/mc/presenceindicator.hpp
vendored
@@ -24,6 +24,8 @@ class FieldBitmapReader {
|
||||
public:
|
||||
constexpr FieldBitmapReader(T map, std::size_t maxLen) noexcept;
|
||||
|
||||
constexpr auto setBuffer(T map, std::size_t maxLen) noexcept;
|
||||
|
||||
constexpr Result<bool> get(std::size_t i) const noexcept;
|
||||
|
||||
constexpr void setFields(int) noexcept;
|
||||
@@ -41,6 +43,12 @@ constexpr FieldBitmapReader<T>::FieldBitmapReader(T map, std::size_t maxLen) noe
|
||||
m_mapLen = maxLen;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr auto FieldBitmapReader<T>::setBuffer(T map, std::size_t maxLen) noexcept {
|
||||
m_map = map;
|
||||
m_mapLen = maxLen;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr Result<bool> FieldBitmapReader<T>::get(std::size_t i) const noexcept {
|
||||
if (i / 8 < m_mapLen) {
|
||||
|
||||
7
deps/ox/src/ox/mc/test/tests.cpp
vendored
7
deps/ox/src/ox/mc/test/tests.cpp
vendored
@@ -122,8 +122,6 @@ std::map<ox::String, ox::Error(*)()> tests = {
|
||||
"MetalClawReader",
|
||||
[] {
|
||||
// setup for tests
|
||||
static constexpr size_t buffLen = 1024;
|
||||
char buff[buffLen];
|
||||
TestStruct testIn, testOut;
|
||||
testIn.Bool = true;
|
||||
testIn.Int = 42;
|
||||
@@ -140,8 +138,9 @@ std::map<ox::String, ox::Error(*)()> tests = {
|
||||
testIn.Struct.Int = 300;
|
||||
testIn.Struct.BString = "Test String 2";
|
||||
// run tests
|
||||
oxAssert(ox::writeMC(buff, buffLen, &testIn), "writeMC failed");
|
||||
oxAssert(ox::readMC(buff, buffLen, &testOut), "readMC failed");
|
||||
const auto [buff, err] = ox::writeMC(&testIn);
|
||||
oxAssert(err, "writeMC failed");
|
||||
oxAssert(ox::readMC(buff.data(), buff.size(), &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");
|
||||
|
||||
3
deps/ox/src/ox/mc/write.cpp
vendored
3
deps/ox/src/ox/mc/write.cpp
vendored
@@ -15,6 +15,7 @@
|
||||
|
||||
namespace ox {
|
||||
|
||||
template class ModelHandlerInterface<MetalClawWriter>;
|
||||
template class ModelHandlerInterface<MetalClawWriter<BufferWriter>>;
|
||||
template class ModelHandlerInterface<MetalClawWriter<CharBuffWriter>>;
|
||||
|
||||
}
|
||||
|
||||
257
deps/ox/src/ox/mc/write.hpp
vendored
257
deps/ox/src/ox/mc/write.hpp
vendored
@@ -27,19 +27,19 @@
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<Writer_c Writer>
|
||||
class MetalClawWriter {
|
||||
|
||||
private:
|
||||
ox::Vector<uint8_t, 16> m_presenceMapBuff{};
|
||||
FieldBitmap m_fieldPresence;
|
||||
int m_fields = 0;
|
||||
int m_field = 0;
|
||||
int m_unionIdx = -1;
|
||||
std::size_t m_buffIt = 0;
|
||||
std::size_t m_buffLen = 0;
|
||||
uint8_t *m_buff = nullptr;
|
||||
std::size_t m_writerBeginP{};
|
||||
Writer &m_writer;
|
||||
|
||||
public:
|
||||
constexpr MetalClawWriter(uint8_t *buff, std::size_t buffLen, int unionIdx = -1) noexcept;
|
||||
constexpr explicit MetalClawWriter(Writer &writer, int unionIdx = -1) noexcept;
|
||||
|
||||
constexpr ~MetalClawWriter() noexcept = default;
|
||||
|
||||
@@ -122,77 +122,81 @@ class MetalClawWriter {
|
||||
return 0;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr std::size_t size() const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr auto opType() noexcept {
|
||||
return OpType::Write;
|
||||
}
|
||||
|
||||
ox::Error finalize() noexcept;
|
||||
|
||||
private:
|
||||
constexpr Error appendInteger(Integer_c auto val) noexcept {
|
||||
bool fieldSet = false;
|
||||
if (val && (m_unionIdx == -1 || m_unionIdx == m_field)) {
|
||||
auto mi = mc::encodeInteger(val);
|
||||
if (mi.length < m_buffLen) {
|
||||
fieldSet = true;
|
||||
ox_memcpy(&m_buff[m_buffIt], mi.data, mi.length);
|
||||
m_buffIt += mi.length;
|
||||
} else {
|
||||
return OxError(MC_BUFFENDED);
|
||||
}
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(mi.data), mi.length));
|
||||
fieldSet = true;
|
||||
}
|
||||
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||
m_field++;
|
||||
++m_field;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
extern template class ModelHandlerInterface<MetalClawWriter>;
|
||||
extern template class ModelHandlerInterface<MetalClawWriter<BufferWriter>>;
|
||||
extern template class ModelHandlerInterface<MetalClawWriter<CharBuffWriter>>;
|
||||
|
||||
constexpr MetalClawWriter::MetalClawWriter(uint8_t *buff, std::size_t buffLen, int unionIdx) noexcept:
|
||||
m_fieldPresence(buff, buffLen),
|
||||
template<Writer_c Writer>
|
||||
constexpr MetalClawWriter<Writer>::MetalClawWriter(Writer &writer, int unionIdx) noexcept:
|
||||
m_fieldPresence(m_presenceMapBuff.data(), m_presenceMapBuff.size()),
|
||||
m_unionIdx(unionIdx),
|
||||
m_buffLen(buffLen),
|
||||
m_buff(buff) {
|
||||
m_writerBeginP(writer.tellp()),
|
||||
m_writer(writer) {
|
||||
}
|
||||
|
||||
constexpr Error MetalClawWriter::field(const char*, CommonPtrWith<int8_t> auto *val) noexcept {
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, CommonPtrWith<int8_t> auto *val) noexcept {
|
||||
return appendInteger(*val);
|
||||
}
|
||||
|
||||
constexpr Error MetalClawWriter::field(const char*, CommonPtrWith<int16_t> auto *val) noexcept {
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, CommonPtrWith<int16_t> auto *val) noexcept {
|
||||
return appendInteger(*val);
|
||||
}
|
||||
|
||||
constexpr Error MetalClawWriter::field(const char*, CommonPtrWith<int32_t> auto *val) noexcept {
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, CommonPtrWith<int32_t> auto *val) noexcept {
|
||||
return appendInteger(*val);
|
||||
}
|
||||
|
||||
constexpr Error MetalClawWriter::field(const char*, CommonPtrWith<int64_t> auto *val) noexcept {
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, CommonPtrWith<int64_t> auto *val) noexcept {
|
||||
return appendInteger(*val);
|
||||
}
|
||||
|
||||
|
||||
constexpr Error MetalClawWriter::field(const char*, CommonPtrWith<uint8_t> auto *val) noexcept {
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, CommonPtrWith<uint8_t> auto *val) noexcept {
|
||||
return appendInteger(*val);
|
||||
}
|
||||
|
||||
constexpr Error MetalClawWriter::field(const char*, CommonPtrWith<uint16_t> auto *val) noexcept {
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, CommonPtrWith<uint16_t> auto *val) noexcept {
|
||||
return appendInteger(*val);
|
||||
}
|
||||
|
||||
constexpr Error MetalClawWriter::field(const char*, CommonPtrWith<uint32_t> auto *val) noexcept {
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, CommonPtrWith<uint32_t> auto *val) noexcept {
|
||||
return appendInteger(*val);
|
||||
}
|
||||
|
||||
constexpr Error MetalClawWriter::field(const char*, CommonPtrWith<uint64_t> auto *val) noexcept {
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, CommonPtrWith<uint64_t> auto *val) noexcept {
|
||||
return appendInteger(*val);
|
||||
}
|
||||
|
||||
constexpr Error MetalClawWriter::field(const char*, CommonPtrWith<bool> auto *val) noexcept {
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, CommonPtrWith<bool> auto *val) noexcept {
|
||||
if (m_unionIdx == -1 || m_unionIdx == m_field) {
|
||||
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), *val));
|
||||
}
|
||||
@@ -200,108 +204,97 @@ constexpr Error MetalClawWriter::field(const char*, CommonPtrWith<bool> auto *va
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
template<std::size_t SmallStringSize>
|
||||
constexpr Error MetalClawWriter::field(const char*, const BasicString<SmallStringSize> *val) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, const BasicString<SmallStringSize> *val) noexcept {
|
||||
bool fieldSet = false;
|
||||
if (val->len() && (m_unionIdx == -1 || m_unionIdx == m_field)) {
|
||||
// write the length
|
||||
const auto strLen = mc::encodeInteger(val->len());
|
||||
if (m_buffIt + strLen.length + static_cast<std::size_t>(val->len()) < m_buffLen) {
|
||||
memcpy(&m_buff[m_buffIt], strLen.data, strLen.length);
|
||||
m_buffIt += strLen.length;
|
||||
// write the string
|
||||
memcpy(&m_buff[m_buffIt], val->c_str(), static_cast<std::size_t>(val->len()));
|
||||
m_buffIt += static_cast<std::size_t>(val->len());
|
||||
fieldSet = true;
|
||||
} else {
|
||||
return OxError(MC_BUFFENDED);
|
||||
}
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLen.data), strLen.length));
|
||||
// write the string
|
||||
oxReturnError(m_writer.write(val->c_str(), static_cast<std::size_t>(val->len())));
|
||||
fieldSet = true;
|
||||
}
|
||||
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||
++m_field;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
template<std::size_t L>
|
||||
constexpr Error MetalClawWriter::field(const char *name, const BString<L> *val) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char *name, const BString<L> *val) noexcept {
|
||||
return fieldCString(name, val->data(), val->cap());
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
template<std::size_t SmallStringSize>
|
||||
constexpr Error MetalClawWriter::field(const char *name, BasicString<SmallStringSize> *val) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char *name, BasicString<SmallStringSize> *val) noexcept {
|
||||
return field(name, const_cast<const BasicString<SmallStringSize>*>(val));
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
template<std::size_t L>
|
||||
constexpr Error MetalClawWriter::field(const char *name, BString<L> *val) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char *name, BString<L> *val) noexcept {
|
||||
return fieldCString(name, val->data(), val->cap());
|
||||
}
|
||||
|
||||
constexpr Error MetalClawWriter::fieldCString(const char*, const char *const*val, std::size_t) noexcept {
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *const*val, std::size_t) noexcept {
|
||||
bool fieldSet = false;
|
||||
if (m_unionIdx == -1 || m_unionIdx == m_field) {
|
||||
const auto strLen = *val ? ox_strlen(*val) : 0;
|
||||
// write the length
|
||||
const auto strLenBuff = mc::encodeInteger(strLen);
|
||||
if (m_buffIt + strLenBuff.length + static_cast<std::size_t>(strLen) < m_buffLen) {
|
||||
ox_memcpy(&m_buff[m_buffIt], strLenBuff.data, strLenBuff.length);
|
||||
m_buffIt += strLenBuff.length;
|
||||
// write the string
|
||||
ox_memcpy(&m_buff[m_buffIt], *val, static_cast<std::size_t>(strLen));
|
||||
m_buffIt += static_cast<std::size_t>(strLen);
|
||||
fieldSet = true;
|
||||
} else {
|
||||
return OxError(MC_BUFFENDED);
|
||||
}
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data), strLenBuff.length));
|
||||
// write the string
|
||||
oxReturnError(m_writer.write(*val, static_cast<std::size_t>(strLen)));
|
||||
fieldSet = true;
|
||||
}
|
||||
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||
++m_field;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
constexpr Error MetalClawWriter::fieldCString(const char *name, const char **val) noexcept {
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::fieldCString(const char *name, const char **val) noexcept {
|
||||
return fieldCString(name, val, {});
|
||||
}
|
||||
|
||||
constexpr Error MetalClawWriter::fieldCString(const char *name, const char *const*val) noexcept {
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::fieldCString(const char *name, const char *const*val) noexcept {
|
||||
return fieldCString(name, val, {});
|
||||
}
|
||||
|
||||
constexpr Error MetalClawWriter::fieldCString(const char*, const char *val, std::size_t strLen) noexcept {
|
||||
template<Writer_c Writer>
|
||||
constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *val, std::size_t strLen) noexcept {
|
||||
bool fieldSet = false;
|
||||
if (strLen && (m_unionIdx == -1 || m_unionIdx == m_field)) {
|
||||
// write the length
|
||||
const auto strLenBuff = mc::encodeInteger(strLen);
|
||||
if (m_buffIt + strLenBuff.length + static_cast<std::size_t>(strLen) < m_buffLen) {
|
||||
ox_memcpy(&m_buff[m_buffIt], strLenBuff.data, strLenBuff.length);
|
||||
m_buffIt += strLenBuff.length;
|
||||
// write the string
|
||||
ox_memcpy(&m_buff[m_buffIt], val, static_cast<std::size_t>(strLen));
|
||||
m_buffIt += static_cast<std::size_t>(strLen);
|
||||
fieldSet = true;
|
||||
} else {
|
||||
return OxError(MC_BUFFENDED);
|
||||
}
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data), strLenBuff.length));
|
||||
// write the string
|
||||
oxReturnError(m_writer.write(val, static_cast<std::size_t>(strLen)));
|
||||
fieldSet = true;
|
||||
}
|
||||
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||
++m_field;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
template<typename T>
|
||||
constexpr Error MetalClawWriter::field(const char*, T *val) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, T *val) noexcept {
|
||||
if constexpr(isVector_v<T> || isArray_v<T>) {
|
||||
return field(nullptr, val->data(), val->size());
|
||||
} else {
|
||||
bool fieldSet = false;
|
||||
if (val && (m_unionIdx == -1 || m_unionIdx == m_field)) {
|
||||
MetalClawWriter writer(m_buff + m_buffIt, m_buffLen - m_buffIt);
|
||||
ModelHandlerInterface<MetalClawWriter> handler{&writer};
|
||||
MetalClawWriter<Writer> writer(m_writer);
|
||||
ModelHandlerInterface<MetalClawWriter<Writer>> handler{&writer};
|
||||
oxReturnError(model(&handler, val));
|
||||
if (static_cast<std::size_t>(writer.m_fieldPresence.getMaxLen()) < writer.m_buffIt) {
|
||||
m_buffIt += writer.m_buffIt;
|
||||
fieldSet = true;
|
||||
}
|
||||
oxReturnError(writer.finalize());
|
||||
fieldSet = true;
|
||||
}
|
||||
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||
++m_field;
|
||||
@@ -309,70 +302,57 @@ constexpr Error MetalClawWriter::field(const char*, T *val) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
template<typename U, bool force>
|
||||
constexpr Error MetalClawWriter::field(const char*, UnionView<U, force> val) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, UnionView<U, force> val) noexcept {
|
||||
bool fieldSet = false;
|
||||
if (val.get() && (m_unionIdx == -1 || m_unionIdx == m_field)) {
|
||||
MetalClawWriter writer(m_buff + m_buffIt, m_buffLen - m_buffIt, val.idx());
|
||||
MetalClawWriter<Writer> writer(m_writer, val.idx());
|
||||
ModelHandlerInterface handler{&writer};
|
||||
oxReturnError(model(&handler, val.get()));
|
||||
if (static_cast<std::size_t>(writer.m_fieldPresence.getMaxLen()) < writer.m_buffIt) {
|
||||
m_buffIt += writer.m_buffIt;
|
||||
fieldSet = true;
|
||||
}
|
||||
oxReturnError(writer.finalize());
|
||||
fieldSet = true;
|
||||
}
|
||||
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||
m_field++;
|
||||
++m_field;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
template<typename T>
|
||||
constexpr Error MetalClawWriter::field(const char*, T *val, std::size_t len) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, T *val, std::size_t len) noexcept {
|
||||
bool fieldSet = false;
|
||||
|
||||
if (len && (m_unionIdx == -1 || m_unionIdx == m_field)) {
|
||||
// write the length
|
||||
const auto arrLen = mc::encodeInteger(len);
|
||||
if (m_buffIt + arrLen.length < m_buffLen) {
|
||||
ox_memcpy(&m_buff[m_buffIt], arrLen.data, arrLen.length);
|
||||
m_buffIt += arrLen.length;
|
||||
} else {
|
||||
return OxError(MC_BUFFENDED);
|
||||
}
|
||||
|
||||
MetalClawWriter writer(m_buff + m_buffIt, m_buffLen - m_buffIt);
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data), arrLen.length));
|
||||
MetalClawWriter<Writer> writer(m_writer);
|
||||
ModelHandlerInterface handler{&writer};
|
||||
handler.setTypeInfo<T>("List", 0, {}, static_cast<std::size_t>(len));
|
||||
|
||||
handler.template setTypeInfo<T>("List", 0, {}, static_cast<std::size_t>(len));
|
||||
// write the array
|
||||
for (std::size_t i = 0; i < len; i++) {
|
||||
oxReturnError(handler.field("", &val[i]));
|
||||
}
|
||||
|
||||
m_buffIt += writer.m_buffIt;
|
||||
oxReturnError(writer.finalize());
|
||||
fieldSet = true;
|
||||
}
|
||||
|
||||
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||
m_field++;
|
||||
++m_field;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
template<typename T>
|
||||
constexpr Error MetalClawWriter::field(const char*, const HashMap<String, T> *val) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char*, const HashMap<String, T> *val) noexcept {
|
||||
const auto &keys = val->keys();
|
||||
const auto len = keys.size();
|
||||
bool fieldSet = false;
|
||||
if (len && (m_unionIdx == -1 || m_unionIdx == m_field)) {
|
||||
// write the length
|
||||
const auto arrLen = mc::encodeInteger(len);
|
||||
if (m_buffIt + arrLen.length < m_buffLen) {
|
||||
ox_memcpy(&m_buff[m_buffIt], arrLen.data, arrLen.length);
|
||||
m_buffIt += arrLen.length;
|
||||
} else {
|
||||
return OxError(MC_BUFFENDED);
|
||||
}
|
||||
MetalClawWriter writer(m_buff + m_buffIt, m_buffLen - m_buffIt);
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data), arrLen.length));
|
||||
// write map
|
||||
MetalClawWriter<Writer> writer(m_writer);
|
||||
ModelHandlerInterface handler{&writer};
|
||||
// double len for both key and value
|
||||
handler.setTypeInfo("Map", 0, {}, len * 2);
|
||||
@@ -386,48 +366,69 @@ constexpr Error MetalClawWriter::field(const char*, const HashMap<String, T> *va
|
||||
oxRequireM(value, val->at(key));
|
||||
oxReturnError(handler.field("", value));
|
||||
}
|
||||
m_buffIt += writer.m_buffIt;
|
||||
oxReturnError(writer.finalize());
|
||||
fieldSet = true;
|
||||
}
|
||||
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||
m_field++;
|
||||
++m_field;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
template<typename T>
|
||||
constexpr Error MetalClawWriter::field(const char *name, HashMap<String, T> *val) noexcept {
|
||||
constexpr Error MetalClawWriter<Writer>::field(const char *name, HashMap<String, T> *val) noexcept {
|
||||
return field(name, const_cast<const HashMap<String, T>*>(val));
|
||||
}
|
||||
|
||||
template<Writer_c Writer>
|
||||
template<typename T>
|
||||
constexpr void MetalClawWriter::setTypeInfo(const char*, int, const Vector<String>&, std::size_t fields) noexcept {
|
||||
m_fields = static_cast<int>(fields);
|
||||
constexpr void MetalClawWriter<Writer>::setTypeInfo(
|
||||
const char*,
|
||||
int,
|
||||
const Vector<String>&,
|
||||
std::size_t fields) noexcept {
|
||||
// TODO: change all setTypeInfo signatures to return Errors
|
||||
const auto fieldPresenceLen = (fields - 1) / 8 + 1;
|
||||
oxIgnoreError(m_writer.write(nullptr, fieldPresenceLen));
|
||||
m_presenceMapBuff.resize(fieldPresenceLen);
|
||||
m_fieldPresence.setBuffer(m_presenceMapBuff.data(), m_presenceMapBuff.size());
|
||||
m_fieldPresence.setFields(static_cast<int>(fields));
|
||||
m_buffIt = static_cast<std::size_t>(m_fieldPresence.getMaxLen());
|
||||
ox_memset(m_buff, 0, m_buffIt);
|
||||
}
|
||||
|
||||
constexpr std::size_t MetalClawWriter::size() const noexcept {
|
||||
return m_buffIt;
|
||||
template<Writer_c Writer>
|
||||
ox::Error MetalClawWriter<Writer>::finalize() noexcept {
|
||||
const auto end = m_writer.tellp();
|
||||
oxReturnError(m_writer.seekp(m_writerBeginP));
|
||||
oxReturnError(m_writer.write(
|
||||
reinterpret_cast<const char*>(m_presenceMapBuff.data()),
|
||||
m_presenceMapBuff.size()));
|
||||
oxReturnError(m_writer.seekp(end));
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<Buffer> writeMC(auto *val) noexcept {
|
||||
Buffer buff(10 * units::MB);
|
||||
MetalClawWriter writer(reinterpret_cast<uint8_t*>(buff.data()), buff.size());
|
||||
ModelHandlerInterface handler{&writer};
|
||||
oxReturnError(model(&handler, val));
|
||||
buff.resize(writer.size());
|
||||
Result<Buffer> writeMC(Writer_c auto &writer, const auto &val) noexcept {
|
||||
MetalClawWriter mcWriter(writer);
|
||||
ModelHandlerInterface handler{&mcWriter};
|
||||
oxReturnError(model(&handler, &val));
|
||||
oxReturnError(mcWriter.finalize());
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<Buffer> writeMC(const auto *val, std::size_t buffReserveSz = 2 * units::KB) noexcept {
|
||||
Buffer buff(buffReserveSz);
|
||||
BufferWriter bw(&buff, 0);
|
||||
oxReturnError(writeMC(bw, *val));
|
||||
buff.resize(bw.tellp());
|
||||
return buff;
|
||||
}
|
||||
|
||||
Error writeMC(char *buff, std::size_t buffLen, auto *val, std::size_t *sizeOut = nullptr) noexcept {
|
||||
MetalClawWriter writer(reinterpret_cast<uint8_t*>(buff), buffLen);
|
||||
ModelHandlerInterface handler(&writer);
|
||||
auto err = model(&handler, val);
|
||||
Error writeMC(char *buff, std::size_t buffLen, const auto *val, std::size_t *sizeOut = nullptr) noexcept {
|
||||
CharBuffWriter bw(buff, buffLen);
|
||||
oxReturnError(writeMC(bw, *val));
|
||||
if (sizeOut) {
|
||||
*sizeOut = writer.size();
|
||||
*sizeOut = bw.tellp();
|
||||
}
|
||||
return err;
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
6
deps/ox/src/ox/model/desctypes.hpp
vendored
6
deps/ox/src/ox/model/desctypes.hpp
vendored
@@ -79,6 +79,9 @@ constexpr Error model(T *io, CommonPtrWith<Subscript> auto *type) noexcept {
|
||||
if constexpr(T::opType() == OpType::Reflect) {
|
||||
uint32_t st = 0;
|
||||
oxReturnError(io->field("subscriptType", &st));
|
||||
} else if constexpr(T::opType() == OpType::Write) {
|
||||
auto pt = type ? static_cast<uint8_t>(type->subscriptType) : 0;
|
||||
oxReturnError(io->field("subscriptType", &pt));
|
||||
} else {
|
||||
auto pt = type ? static_cast<uint32_t>(type->subscriptType) : 0;
|
||||
oxReturnError(io->field("subscriptType", &pt));
|
||||
@@ -186,6 +189,9 @@ constexpr Error model(T *io, CommonPtrWith<DescriptorType> auto *type) noexcept
|
||||
if constexpr(T::opType() == OpType::Reflect) {
|
||||
uint8_t pt = 0;
|
||||
oxReturnError(io->field("primitiveType", &pt));
|
||||
} else if constexpr(T::opType() == OpType::Write) {
|
||||
auto pt = type ? static_cast<uint8_t>(type->primitiveType) : 0;
|
||||
oxReturnError(io->field("primitiveType", &pt));
|
||||
} else {
|
||||
auto pt = type ? static_cast<uint8_t>(type->primitiveType) : 0;
|
||||
oxReturnError(io->field("primitiveType", &pt));
|
||||
|
||||
8
deps/ox/src/ox/model/descwrite.hpp
vendored
8
deps/ox/src/ox/model/descwrite.hpp
vendored
@@ -143,9 +143,6 @@ class TypeDescWriter {
|
||||
[[nodiscard]]
|
||||
constexpr const DescriptorType *type(const char *val) const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr const DescriptorType *type(SerStr val) const noexcept;
|
||||
|
||||
template<std::size_t SmallStrSz>
|
||||
[[nodiscard]]
|
||||
constexpr const DescriptorType *type(const BasicString<SmallStrSz>*) const noexcept {
|
||||
@@ -332,11 +329,6 @@ constexpr const DescriptorType *TypeDescWriter::type(const char*) const noexcept
|
||||
return getType(types::String, 0, PT, 0);
|
||||
}
|
||||
|
||||
constexpr const DescriptorType *TypeDescWriter::type(SerStr) const noexcept {
|
||||
constexpr auto PT = PrimitiveType::String;
|
||||
return getType(types::String, 0, PT, 0);
|
||||
}
|
||||
|
||||
template<std::size_t sz>
|
||||
constexpr const DescriptorType *TypeDescWriter::type(const BString<sz>*) const noexcept {
|
||||
constexpr auto PT = PrimitiveType::String;
|
||||
|
||||
24
deps/ox/src/ox/model/modelops.hpp
vendored
24
deps/ox/src/ox/model/modelops.hpp
vendored
@@ -71,10 +71,6 @@ class MemberList {
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
constexpr Error field(const char *name, SerStr s) noexcept {
|
||||
return field(name, s.target());
|
||||
}
|
||||
|
||||
template<typename T = void>
|
||||
constexpr void setTypeInfo(const char* = T::TypeName, int = ModelTypeVersion_v<T>,
|
||||
const Vector<String>& = {}, int = ModelFieldCount_v<T>) noexcept {
|
||||
@@ -131,10 +127,6 @@ class Copier {
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
constexpr Error field(const char *name, SerStr s) {
|
||||
return field(name, s.target());
|
||||
}
|
||||
|
||||
template<typename T = void>
|
||||
constexpr void setTypeInfo(const char* = T::TypeName, int = T::TypeVersion, const Vector<String>& = {}, int = ModelFieldCount_v<T>) noexcept {
|
||||
}
|
||||
@@ -192,10 +184,6 @@ class Mover {
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
constexpr Error field(const char *name, SerStr s) noexcept {
|
||||
return field(name, s.target());
|
||||
}
|
||||
|
||||
template<typename T = void>
|
||||
constexpr void setTypeInfo(const char* = T::TypeName, int = T::TypeVersion, const Vector<String>& = {}, int = ModelFieldCount_v<T>) noexcept {
|
||||
}
|
||||
@@ -260,18 +248,6 @@ class Equals {
|
||||
}
|
||||
}
|
||||
|
||||
constexpr Error field(const char*, SerStr s) noexcept {
|
||||
const auto a = s.c_str();
|
||||
const auto b = *cbit_cast<const char**>(m_other->vars[m_i]);
|
||||
++m_i;
|
||||
if (a && b && ox_strcmp(a, b) == 0) {
|
||||
return OxError(0);
|
||||
} else {
|
||||
this->value = false;
|
||||
return OxError(1);
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr auto opType() noexcept {
|
||||
return OpType::Read;
|
||||
|
||||
70
deps/ox/src/ox/model/types.hpp
vendored
70
deps/ox/src/ox/model/types.hpp
vendored
@@ -157,76 +157,6 @@ constexpr bool isSmartPtr_v<::std::unique_ptr<T>> = true;
|
||||
#endif
|
||||
|
||||
|
||||
class SerStr {
|
||||
|
||||
protected:
|
||||
int m_cap = 0;
|
||||
char *m_str = nullptr;
|
||||
char **m_tgt = nullptr;
|
||||
|
||||
public:
|
||||
template<std::size_t sz>
|
||||
explicit constexpr SerStr(BString<sz> *str) noexcept {
|
||||
m_str = str->data();
|
||||
m_cap = str->cap();
|
||||
}
|
||||
|
||||
constexpr SerStr(char *str, int cap) noexcept {
|
||||
m_str = str;
|
||||
m_cap = cap;
|
||||
}
|
||||
|
||||
explicit constexpr SerStr(char **tgt, int cap = -1) noexcept {
|
||||
m_tgt = tgt;
|
||||
m_str = const_cast<char*>(*tgt);
|
||||
m_cap = cap;
|
||||
}
|
||||
|
||||
explicit constexpr SerStr(char *str, char **tgt, int cap = -1) noexcept {
|
||||
m_tgt = tgt;
|
||||
m_str = str;
|
||||
m_cap = cap;
|
||||
}
|
||||
|
||||
template<std::size_t cap>
|
||||
explicit constexpr SerStr(char (&str)[cap]) noexcept {
|
||||
m_str = str;
|
||||
m_cap = cap;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr const char *c_str() const noexcept {
|
||||
return m_str;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr auto target() const noexcept {
|
||||
return m_tgt;
|
||||
}
|
||||
|
||||
constexpr char *data(std::size_t sz = 0) noexcept {
|
||||
if (m_tgt && sz) {
|
||||
if (!*m_tgt || sz > static_cast<std::size_t>(m_cap)) {
|
||||
*m_tgt = new char[sz];
|
||||
m_str = *m_tgt;
|
||||
m_cap = static_cast<int>(sz);
|
||||
}
|
||||
}
|
||||
return m_str;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr int len() const noexcept {
|
||||
return static_cast<int>(m_str ? ox_strlen(m_str) : 0);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr int cap() const noexcept {
|
||||
return m_cap;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename Union, bool force = false>
|
||||
class UnionView {
|
||||
|
||||
|
||||
28
deps/ox/src/ox/oc/read.cpp
vendored
28
deps/ox/src/ox/oc/read.cpp
vendored
@@ -181,34 +181,6 @@ Error OrganicClawReader::field(const char *key, bool *val) noexcept {
|
||||
return err;
|
||||
}
|
||||
|
||||
Error OrganicClawReader::field(const char *key, SerStr val) noexcept {
|
||||
auto err = OxError(0);
|
||||
const char *begin = nullptr, *end = nullptr;
|
||||
const auto &jv = value(key);
|
||||
if (targetValid()) {
|
||||
if (jv.empty()) {
|
||||
auto data = val.data();
|
||||
if (data) {
|
||||
data[0] = 0;
|
||||
}
|
||||
} else if (jv.isString()) {
|
||||
jv.getString(&begin, &end);
|
||||
auto strSize = end - begin;
|
||||
auto data = val.data(static_cast<std::size_t>(strSize) + 1);
|
||||
if (strSize >= val.cap()) {
|
||||
err = OxError(1, "String size exceeds capacity of destination");
|
||||
} else {
|
||||
ox_memcpy(data, begin, static_cast<std::size_t>(strSize));
|
||||
data[strSize] = 0;
|
||||
}
|
||||
} else {
|
||||
err = OxError(1, "Type mismatch");
|
||||
}
|
||||
}
|
||||
++m_fieldIt;
|
||||
return err;
|
||||
}
|
||||
|
||||
Error OrganicClawReader::fieldCString(const char *key, char *val, std::size_t buffLen) noexcept {
|
||||
auto err = OxError(0);
|
||||
const char *begin = nullptr, *end = nullptr;
|
||||
|
||||
4
deps/ox/src/ox/oc/read.hpp
vendored
4
deps/ox/src/ox/oc/read.hpp
vendored
@@ -72,8 +72,6 @@ class OrganicClawReader {
|
||||
template<std::size_t L>
|
||||
Error field(const char *key, BString<L> *val) noexcept;
|
||||
|
||||
Error field(const char *key, SerStr val) noexcept;
|
||||
|
||||
Error fieldCString(const char *key, char *val, std::size_t buffLen) noexcept;
|
||||
|
||||
Error fieldCString(const char *key, char **val) noexcept;
|
||||
@@ -205,7 +203,7 @@ Error OrganicClawReader::field(const char *key, BasicString<L> *val) noexcept {
|
||||
|
||||
template<std::size_t L>
|
||||
Error OrganicClawReader::field(const char *key, BString<L> *val) noexcept {
|
||||
return field(key, SerStr(val->data(), static_cast<int>(val->cap())));
|
||||
return fieldCString(key, val->data(), val->cap());
|
||||
}
|
||||
|
||||
// array handler
|
||||
|
||||
10
deps/ox/src/ox/oc/test/tests.cpp
vendored
10
deps/ox/src/ox/oc/test/tests.cpp
vendored
@@ -132,7 +132,7 @@ const std::map<std::string_view, ox::Error(*)()> tests = {
|
||||
// This test doesn't confirm much, but it does show that the writer
|
||||
// doesn't segfault
|
||||
TestStruct ts;
|
||||
return ox::writeOC(&ts).error;
|
||||
return ox::writeOC(ts).error;
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -153,7 +153,7 @@ const std::map<std::string_view, ox::Error(*)()> tests = {
|
||||
testIn.Struct.Int = 300;
|
||||
testIn.Struct.String = "Test String 2";
|
||||
|
||||
auto [oc, writeErr] = ox::writeOC(&testIn);
|
||||
auto [oc, writeErr] = ox::writeOC(testIn);
|
||||
oxAssert(writeErr, "writeOC failed");
|
||||
oxOutf("{}\n", oc.data());
|
||||
auto [testOut, readErr] = ox::readOC<TestStruct>(oc.data());
|
||||
@@ -205,7 +205,7 @@ const std::map<std::string_view, ox::Error(*)()> tests = {
|
||||
testIn.Struct.String = "Test String 2";
|
||||
testIn.unionIdx = 1;
|
||||
testIn.Union.Int = 93;
|
||||
oxAssert(ox::writeOC(&testIn).moveTo(&dataBuff), "Data generation failed");
|
||||
oxAssert(ox::writeOC(testIn).moveTo(&dataBuff), "Data generation failed");
|
||||
ox::TypeStore typeStore;
|
||||
auto type = ox::buildTypeDef(&typeStore, &testIn);
|
||||
oxAssert(type.error, "Descriptor write failed");
|
||||
@@ -254,7 +254,7 @@ const std::map<std::string_view, ox::Error(*)()> tests = {
|
||||
testIn.Struct.Int = 300;
|
||||
testIn.Struct.String = "Test String 2";
|
||||
|
||||
auto [oc, ocErr] = ox::writeOC(&testIn);
|
||||
auto [oc, ocErr] = ox::writeOC(testIn);
|
||||
oxAssert(ocErr, "Data generation failed");
|
||||
ox::TypeStore typeStore;
|
||||
auto type = ox::buildTypeDef(&typeStore, &testIn);
|
||||
@@ -332,7 +332,7 @@ const std::map<std::string_view, ox::Error(*)()> tests = {
|
||||
}
|
||||
case ox::PrimitiveType::String: {
|
||||
ox::Vector<char> v(rdr->stringLength(fieldName) + 1);
|
||||
oxAssert(rdr->field(fieldName, ox::SerStr(v.data(), static_cast<int>(v.size()))), "Walking model failed.");
|
||||
oxAssert(rdr->fieldCString(fieldName, v.data(), v.size()), "Walking model failed.");
|
||||
oxOutf("{}:\tstring:\t{}\n", fieldName, v.data());
|
||||
break;
|
||||
}
|
||||
|
||||
8
deps/ox/src/ox/oc/write.cpp
vendored
8
deps/ox/src/ox/oc/write.cpp
vendored
@@ -18,14 +18,6 @@ OrganicClawWriter::OrganicClawWriter(Json::Value json, int unionIdx) noexcept:
|
||||
m_unionIdx(unionIdx) {
|
||||
}
|
||||
|
||||
Error OrganicClawWriter::field(const char *key, SerStr val) noexcept {
|
||||
if (targetValid() && val.len()) {
|
||||
value(key) = val.c_str();
|
||||
}
|
||||
++m_fieldIt;
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
Error OrganicClawWriter::fieldCString(const char *key, const char *const*val, int len) noexcept {
|
||||
if (targetValid() && len) {
|
||||
value(key) = *val;
|
||||
|
||||
20
deps/ox/src/ox/oc/write.hpp
vendored
20
deps/ox/src/ox/oc/write.hpp
vendored
@@ -24,7 +24,7 @@ namespace ox {
|
||||
|
||||
class OrganicClawWriter {
|
||||
|
||||
friend Result<Buffer> writeOC(auto *val) noexcept;
|
||||
friend Result<Buffer> writeOC(auto &val) noexcept;
|
||||
|
||||
protected:
|
||||
Json::Value m_json;
|
||||
@@ -141,12 +141,20 @@ class OrganicClawWriter {
|
||||
|
||||
template<std::size_t L>
|
||||
Error field(const char *key, const BString<L> *val) noexcept {
|
||||
return field(key, SerStr(val->data(), val->cap()));
|
||||
if (targetValid() && val->len()) {
|
||||
value(key) = val->c_str();
|
||||
}
|
||||
++m_fieldIt;
|
||||
return {};
|
||||
}
|
||||
|
||||
template<std::size_t L>
|
||||
Error field(const char *key, BString<L> *val) noexcept {
|
||||
return field(key, SerStr(val->data(), static_cast<int>(val->cap())));
|
||||
if (targetValid() && val->len()) {
|
||||
value(key) = val->c_str();
|
||||
}
|
||||
++m_fieldIt;
|
||||
return {};
|
||||
}
|
||||
|
||||
template<std::size_t L>
|
||||
@@ -163,8 +171,6 @@ class OrganicClawWriter {
|
||||
return field(key, const_cast<const BasicString<L>*>(val));
|
||||
}
|
||||
|
||||
Error field(const char*, SerStr val) noexcept;
|
||||
|
||||
Error fieldCString(const char*, const char *const*val, int len) noexcept;
|
||||
|
||||
Error fieldCString(const char *name, char **val, int len) noexcept;
|
||||
@@ -242,10 +248,10 @@ Error OrganicClawWriter::field(const char *key, UnionView<U, force> val) noexcep
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
Result<Buffer> writeOC(auto *val) noexcept {
|
||||
Result<Buffer> writeOC(auto &val) noexcept {
|
||||
OrganicClawWriter writer;
|
||||
ModelHandlerInterface handler(&writer);
|
||||
oxReturnError(model(&handler, val));
|
||||
oxReturnError(model(&handler, &val));
|
||||
Json::StreamWriterBuilder jsonBuilder;
|
||||
const auto str = Json::writeString(jsonBuilder, writer.m_json);
|
||||
Buffer buff(str.size() + 1);
|
||||
|
||||
8
deps/ox/src/ox/std/buffer.hpp
vendored
8
deps/ox/src/ox/std/buffer.hpp
vendored
@@ -60,7 +60,7 @@ class BufferWriter {
|
||||
}
|
||||
|
||||
constexpr ox::Error put(char val) noexcept {
|
||||
if (m_it >= m_buff.size()) [[unlikely]] {
|
||||
if (m_it >= m_buff.size()) {
|
||||
m_buff.resize(m_buff.size() + 1);
|
||||
}
|
||||
m_buff[m_it] = val;
|
||||
@@ -98,9 +98,9 @@ class CharBuffWriter {
|
||||
|
||||
public:
|
||||
template<std::size_t sz>
|
||||
explicit constexpr CharBuffWriter(ox::Array<char, sz> *buff) noexcept:
|
||||
m_cap(buff->size()),
|
||||
m_buff(buff->data()) {
|
||||
explicit constexpr CharBuffWriter(ox::Array<char, sz> &buff) noexcept:
|
||||
m_cap(buff.size()),
|
||||
m_buff(buff.data()) {
|
||||
}
|
||||
|
||||
explicit constexpr CharBuffWriter(char *buff, std::size_t size) noexcept: m_cap(size), m_buff(buff) {
|
||||
|
||||
2
deps/ox/src/ox/std/serialize.hpp
vendored
2
deps/ox/src/ox/std/serialize.hpp
vendored
@@ -87,7 +87,7 @@ constexpr ox::Error serialize(Writer_c auto *buff, T val) noexcept requires(is_i
|
||||
template<typename T>
|
||||
constexpr ox::Result<ox::Array<char, sizeof(T)>> serialize(const T &in) noexcept {
|
||||
ox::Array<char, sizeof(T)> out = {};
|
||||
CharBuffWriter w(&out);
|
||||
CharBuffWriter w(out);
|
||||
oxReturnError(serialize(&w, in));
|
||||
return out;
|
||||
};
|
||||
|
||||
2
deps/ox/src/ox/std/stringview.hpp
vendored
2
deps/ox/src/ox/std/stringview.hpp
vendored
@@ -280,7 +280,7 @@ using CRStringView = const StringView&;
|
||||
[[nodiscard]]
|
||||
constexpr bool beginsWith(CRStringView base, CRStringView beginning) noexcept {
|
||||
const auto beginningLen = ox::min(beginning.len(), base.len());
|
||||
return ox_strncmp(base.data(), beginning, beginningLen) == 0;
|
||||
return base.len() >= beginning.len() && ox_strncmp(base.data(), beginning, beginningLen) == 0;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
|
||||
37
deps/ox/src/ox/std/strops.hpp
vendored
37
deps/ox/src/ox/std/strops.hpp
vendored
@@ -12,6 +12,7 @@
|
||||
#include "math.hpp"
|
||||
#include "types.hpp"
|
||||
#include "typetraits.hpp"
|
||||
#include "writer.hpp"
|
||||
|
||||
template<typename T1, typename T2>
|
||||
constexpr char *ox_strcpy(T1 dest, T2 src) noexcept {
|
||||
@@ -125,6 +126,42 @@ constexpr int ox_lastIndexOf(const auto &str, int character, std::size_t maxLen
|
||||
return retval;
|
||||
}
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename Integer>
|
||||
constexpr ox::Error itoa(Integer v, ox::Writer_c auto &writer) noexcept {
|
||||
if (v) {
|
||||
ox::ResizedInt_t<Integer, 64> mod = 1000000000000000000;
|
||||
ox::ResizedInt_t<Integer, 64> val = v;
|
||||
constexpr auto base = 10;
|
||||
auto it = 0;
|
||||
if (val < 0) {
|
||||
oxReturnError(writer.put('-'));
|
||||
++it;
|
||||
}
|
||||
while (mod) {
|
||||
auto digit = val / mod;
|
||||
val %= mod;
|
||||
mod /= base;
|
||||
if (it || digit) {
|
||||
ox::ResizedInt_t<Integer, 64> start = '0';
|
||||
if (digit >= 10) {
|
||||
start = 'a';
|
||||
digit -= 10;
|
||||
}
|
||||
oxReturnError(writer.put(static_cast<char>(start + digit)));
|
||||
++it;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 0 is a special case
|
||||
oxReturnError(writer.put('0'));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<typename Integer, typename T>
|
||||
constexpr T ox_itoa(Integer v, T str) noexcept {
|
||||
if (v) {
|
||||
|
||||
1
deps/ox/src/ox/std/test/CMakeLists.txt
vendored
1
deps/ox/src/ox/std/test/CMakeLists.txt
vendored
@@ -11,6 +11,7 @@ add_test("[ox/std] ox_memcmp ABCDEFG != HIJKLMN" StdTest "ABCDEFG != HIJKLMN")
|
||||
add_test("[ox/std] ox_memcmp HIJKLMN != ABCDEFG" StdTest "HIJKLMN != ABCDEFG")
|
||||
add_test("[ox/std] ox_memcmp ABCDEFG == ABCDEFG" StdTest "ABCDEFG == ABCDEFG")
|
||||
add_test("[ox/std] ox_memcmp ABCDEFGHI == ABCDEFG" StdTest "ABCDEFGHI == ABCDEFG")
|
||||
add_test("[ox/std] itoa" StdTest "itoa")
|
||||
add_test("[ox/std] BString" StdTest "BString")
|
||||
add_test("[ox/std] String" StdTest "String")
|
||||
add_test("[ox/std] Vector" StdTest "Vector")
|
||||
|
||||
16
deps/ox/src/ox/std/test/tests.cpp
vendored
16
deps/ox/src/ox/std/test/tests.cpp
vendored
@@ -25,6 +25,22 @@ static std::map<ox::String, ox::Error(*)()> tests = {
|
||||
return OxError(0);
|
||||
}
|
||||
},
|
||||
{
|
||||
"itoa",
|
||||
[]() {
|
||||
ox::Array<char, 10> buff;
|
||||
ox::CharBuffWriter bw(buff);
|
||||
oxAssert(ox::itoa(5, bw), "ox::itoa returned Error");
|
||||
oxExpect(ox::StringView(buff.data()), ox::StringView("5"));
|
||||
oxReturnError(bw.seekp(0));
|
||||
oxAssert(ox::itoa(50, bw), "ox::itoa returned Error");
|
||||
oxExpect(ox::StringView(buff.data()), ox::StringView("50"));
|
||||
oxReturnError(bw.seekp(0));
|
||||
oxAssert(ox::itoa(500, bw), "ox::itoa returned Error");
|
||||
oxExpect(ox::StringView(buff.data()), ox::StringView("500"));
|
||||
return ox::Error{};
|
||||
}
|
||||
},
|
||||
{
|
||||
"ABCDEFG != HIJKLMN",
|
||||
[]() {
|
||||
|
||||
6
deps/ox/src/ox/std/writer.hpp
vendored
6
deps/ox/src/ox/std/writer.hpp
vendored
@@ -66,6 +66,12 @@ class WriterT: public Writer_v {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Allocates the specified amount of data at the end of the current write stream.
|
||||
* @param writer
|
||||
* @param sz
|
||||
* @return
|
||||
*/
|
||||
constexpr ox::Result<std::size_t> allocate(Writer_c auto *writer, std::size_t sz) noexcept {
|
||||
const auto p = writer->tellp();
|
||||
oxReturnError(writer->seekp(0, ios_base::end));
|
||||
|
||||
6
deps/teagba/include/teagba/registers.hpp
vendored
6
deps/teagba/include/teagba/registers.hpp
vendored
@@ -9,7 +9,7 @@
|
||||
namespace teagba {
|
||||
|
||||
inline auto bgSetSbb(volatile BgCtl *bgCtl, unsigned sbb) noexcept {
|
||||
*bgCtl = (*bgCtl & ~0b11111'0000'0000u) | (sbb << 8);
|
||||
*bgCtl = static_cast<BgCtl>(*bgCtl & ~0b11111'0000'0000u) | static_cast<BgCtl>(sbb << 8);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@@ -24,7 +24,7 @@ inline auto bgPri(const volatile BgCtl *bgCtl) noexcept {
|
||||
|
||||
inline auto bgSetPri(volatile BgCtl *bgCtl, unsigned pri) noexcept {
|
||||
pri = pri & 0b1;
|
||||
*bgCtl = (*bgCtl & ~0b1u) | (pri << 0);
|
||||
*bgCtl = static_cast<BgCtl>(*bgCtl & ~0b1u) | static_cast<BgCtl>(pri << 0);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@@ -58,7 +58,7 @@ inline auto bgCbb(const volatile BgCtl *bgCtl) noexcept {
|
||||
|
||||
inline auto bgSetCbb(volatile BgCtl *bgCtl, unsigned cbb) noexcept {
|
||||
cbb = cbb & 0b11;
|
||||
*bgCtl = (*bgCtl & ~0b1100u) | (cbb << 2);
|
||||
*bgCtl = static_cast<BgCtl>(*bgCtl & ~0b1100u) | static_cast<BgCtl>(cbb << 2);
|
||||
}
|
||||
|
||||
constexpr void iterateBgCtl(auto cb) noexcept {
|
||||
|
||||
7
deps/teagba/src/CMakeLists.txt
vendored
7
deps/teagba/src/CMakeLists.txt
vendored
@@ -10,6 +10,11 @@ add_library(
|
||||
gfx.cpp
|
||||
)
|
||||
|
||||
if(NOT MSVC)
|
||||
target_compile_options(TeaGBA PRIVATE -Wsign-conversion)
|
||||
target_compile_options(TeaGBA PRIVATE -Wconversion)
|
||||
endif()
|
||||
|
||||
target_include_directories(
|
||||
TeaGBA PUBLIC
|
||||
../include
|
||||
@@ -26,4 +31,4 @@ install(
|
||||
DESTINATION
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
)
|
||||
)
|
||||
|
||||
@@ -131,7 +131,7 @@ ox::Error writeObj(
|
||||
const ox::FileAddress &file,
|
||||
const T &obj,
|
||||
ox::ClawFormat fmt = ox::ClawFormat::Metal) noexcept {
|
||||
oxRequire(objBuff, ox::writeClaw(&obj, fmt));
|
||||
oxRequire(objBuff, ox::writeClaw(obj, fmt));
|
||||
return ctx->rom->write(file, objBuff.data(), objBuff.size());
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ static ox::Error doTransformations(keel::Context *ctx, ox::TypeStore *ts, ox::Fi
|
||||
// transform FileAddresses
|
||||
oxRequireM(obj, keel::readAsset(ts, buff));
|
||||
oxReturnError(transformFileAddressesObj(ctx, dest, &obj));
|
||||
oxReturnError(ox::writeClaw(&obj).moveTo(&buff));
|
||||
oxReturnError(ox::writeClaw(obj).moveTo(&buff));
|
||||
// write file to dest
|
||||
oxReturnError(dest->write(s.inode, buff.data(), buff.size()));
|
||||
return {};
|
||||
|
||||
@@ -172,7 +172,7 @@ ox::Result<ox::Buffer> convertBuffToBuff(keel::Context *ctx, const ox::Buffer &s
|
||||
static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>();
|
||||
static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>();
|
||||
oxRequire(out, convert(ctx, srcBuffer, DstTypeName, DstTypeVersion));
|
||||
return ox::writeClaw<DstType>(wrapCast<DstType>(out.get()), fmt);
|
||||
return ox::writeClaw<DstType>(*wrapCast<DstType>(out.get()), fmt);
|
||||
}
|
||||
|
||||
template<typename From, typename To, ox::ClawFormat fmt = ox::ClawFormat::Metal>
|
||||
|
||||
@@ -421,7 +421,7 @@ uint8_t bgStatus(Context *ctx) noexcept {
|
||||
const auto &gctx = static_cast<GlContext&>(*ctx);
|
||||
uint8_t out = 0;
|
||||
for (unsigned i = 0; i < gctx.cbbs.size(); ++i) {
|
||||
out |= gctx.backgrounds[i].enabled << i;
|
||||
out |= static_cast<uint8_t>(static_cast<unsigned>(gctx.backgrounds[i].enabled) << i);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -558,4 +558,4 @@ void drawMainView(core::Context *ctx, ox::Size const&renderSz) noexcept {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ ox::Error writeConfig(keel::Context *ctx, ox::CRStringView name, T *data) noexce
|
||||
oxErrf("Could not create config directory: {}\n", toStr(err));
|
||||
return err;
|
||||
}
|
||||
oxRequireM(buff, ox::writeOC(data));
|
||||
oxRequireM(buff, ox::writeOC(*data));
|
||||
buff.back().value = '\n';
|
||||
if (const auto err = fs.write(path, buff.data(), buff.size())) {
|
||||
oxErrf("Could not read config file: {}\n", toStr(err));
|
||||
|
||||
@@ -59,10 +59,13 @@ class Project {
|
||||
* Writes a MetalClaw object to the project at the given path.
|
||||
*/
|
||||
template<typename T>
|
||||
ox::Error writeObj(const ox::String &path, const T *obj, ox::ClawFormat fmt = ox::ClawFormat::Metal) noexcept;
|
||||
ox::Error writeObj(
|
||||
const ox::StringView &path,
|
||||
const T *obj,
|
||||
ox::ClawFormat fmt = ox::ClawFormat::Metal) noexcept;
|
||||
|
||||
template<typename T>
|
||||
ox::Result<T> loadObj(const ox::String &path) const noexcept;
|
||||
ox::Result<T> loadObj(const ox::StringView &path) const noexcept;
|
||||
|
||||
ox::Result<ox::FileStat> stat(ox::CRStringView path) const noexcept;
|
||||
|
||||
@@ -82,7 +85,7 @@ class Project {
|
||||
|
||||
ox::Error writeBuff(const ox::StringView &path, const ox::Buffer &buff) noexcept;
|
||||
|
||||
ox::Result<ox::Buffer> loadBuff(const ox::String &path) const noexcept;
|
||||
ox::Result<ox::Buffer> loadBuff(const ox::StringView &path) const noexcept;
|
||||
|
||||
ox::Error lsProcDir(ox::Vector<ox::String> *paths, ox::CRStringView path) const noexcept;
|
||||
|
||||
@@ -102,9 +105,9 @@ class Project {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
ox::Error Project::writeObj(const ox::String &path, const T *obj, ox::ClawFormat fmt) noexcept {
|
||||
ox::Error Project::writeObj(const ox::StringView &path, const T *obj, ox::ClawFormat fmt) noexcept {
|
||||
// write MetalClaw
|
||||
oxRequireM(buff, ox::writeClaw(obj, fmt));
|
||||
oxRequireM(buff, ox::writeClaw(*obj, fmt));
|
||||
// write to FS
|
||||
oxReturnError(writeBuff(path, buff));
|
||||
// write type descriptor
|
||||
@@ -115,7 +118,7 @@ ox::Error Project::writeObj(const ox::String &path, const T *obj, ox::ClawFormat
|
||||
const auto descPath = ox::sfmt("/.{}/type_descriptors", m_projectDataDir);
|
||||
oxReturnError(mkdir(descPath));
|
||||
for (const auto &t : m_typeStore.typeList()) {
|
||||
oxRequireM(typeOut, ox::writeClaw(t, ox::ClawFormat::Organic));
|
||||
oxRequireM(typeOut, ox::writeClaw(*t, ox::ClawFormat::Organic));
|
||||
// replace garbage last character with new line
|
||||
typeOut.back().value = '\n';
|
||||
// write to FS
|
||||
@@ -127,7 +130,7 @@ ox::Error Project::writeObj(const ox::String &path, const T *obj, ox::ClawFormat
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ox::Result<T> Project::loadObj(const ox::String &path) const noexcept {
|
||||
ox::Result<T> Project::loadObj(const ox::StringView &path) const noexcept {
|
||||
oxRequire(buff, loadBuff(path));
|
||||
if constexpr (ox::is_same_v<T, ox::ModelObject>) {
|
||||
return keel::readAsset(&m_typeStore, buff);
|
||||
|
||||
@@ -104,7 +104,7 @@ ox::Error Project::writeBuff(const ox::StringView &path, const ox::Buffer &buff)
|
||||
return {};
|
||||
}
|
||||
|
||||
ox::Result<ox::Buffer> Project::loadBuff(const ox::String &path) const noexcept {
|
||||
ox::Result<ox::Buffer> Project::loadBuff(const ox::StringView &path) const noexcept {
|
||||
return m_fs->read(path);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user