[ox] Add StringView, Writer system, Preloader system
This commit is contained in:
24
deps/ox/src/ox/preloader/CMakeLists.txt
vendored
Normal file
24
deps/ox/src/ox/preloader/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
add_library(
|
||||
OxPreloader
|
||||
preload.cpp
|
||||
preloader.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
OxPreloader PUBLIC
|
||||
OxClaw
|
||||
OxModel
|
||||
OxStd
|
||||
)
|
||||
|
||||
install(
|
||||
FILES
|
||||
alignmentcatcher.hpp
|
||||
platspecs.hpp
|
||||
preload.hpp
|
||||
preloader.hpp
|
||||
unionsizecatcher.hpp
|
||||
DESTINATION
|
||||
include/nostalgia/preloader
|
||||
)
|
62
deps/ox/src/ox/preloader/alignmentcatcher.hpp
vendored
Normal file
62
deps/ox/src/ox/preloader/alignmentcatcher.hpp
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/model/modelhandleradaptor.hpp>
|
||||
#include <ox/model/optype.hpp>
|
||||
#include <ox/model/types.hpp>
|
||||
#include <ox/std/error.hpp>
|
||||
#include <ox/std/string.hpp>
|
||||
#include <ox/std/types.hpp>
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename PlatSpec, typename T>
|
||||
[[nodiscard]]
|
||||
constexpr std::size_t alignOf(const T &t) noexcept;
|
||||
|
||||
template<typename PlatSpec, typename T>
|
||||
[[nodiscard]]
|
||||
constexpr std::size_t sizeOf(const T *t) noexcept;
|
||||
|
||||
template<typename PlatSpec>
|
||||
struct AlignmentCatcher: public ModelHandlerBase<AlignmentCatcher<PlatSpec>> {
|
||||
std::size_t biggestAlignment = 1;
|
||||
|
||||
template<typename ...T>
|
||||
constexpr void setTypeInfo(T&&...) const noexcept {
|
||||
}
|
||||
|
||||
template<typename T, bool force>
|
||||
constexpr ox::Error field(CRStringView name, const UnionView<T, force> val) noexcept {
|
||||
return field(name, val.get());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr ox::Error field(CRStringView, const T *val) noexcept {
|
||||
if constexpr(ox::is_integer_v<T>) {
|
||||
biggestAlignment = ox::max(biggestAlignment, PlatSpec::alignOf(*val));
|
||||
} else {
|
||||
biggestAlignment = ox::max(biggestAlignment, alignOf<PlatSpec>(*val));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr ox::Error field(CRStringView, const T *val, std::size_t cnt) noexcept {
|
||||
for (std::size_t i = 0; i < cnt; ++i) {
|
||||
oxReturnError(field(nullptr, &val[i]));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr auto opType() noexcept {
|
||||
return ox::OpType::Reflect;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
126
deps/ox/src/ox/preloader/platspecs.hpp
vendored
Normal file
126
deps/ox/src/ox/preloader/platspecs.hpp
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/std/serialize.hpp>
|
||||
#include <ox/std/typetraits.hpp>
|
||||
|
||||
#include "alignmentcatcher.hpp"
|
||||
#include "sizecatcher.hpp"
|
||||
|
||||
namespace ox {
|
||||
|
||||
struct NativePlatSpec {
|
||||
using PtrType = uintptr_t;
|
||||
using size_t = std::size_t;
|
||||
|
||||
static constexpr auto PtrAlign = alignof(void*);
|
||||
static constexpr PtrType RomStart = 0x08000000;
|
||||
|
||||
template<typename T>
|
||||
[[nodiscard]]
|
||||
static constexpr auto alignOf(const T &v) noexcept {
|
||||
if constexpr(ox::is_integral_v<T>) {
|
||||
return alignof(T);
|
||||
} else if constexpr(ox::is_pointer_v<T>) {
|
||||
return PtrAlign;
|
||||
} else {
|
||||
AlignmentCatcher<NativePlatSpec> c;
|
||||
oxAssert(model(c.interface(), &v), "Could not get alignment for type");
|
||||
return c.biggestAlignment;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr auto correctEndianness(auto v) noexcept {
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
struct GbaPlatSpec {
|
||||
using PtrType = uint32_t;
|
||||
using size_t = uint32_t;
|
||||
|
||||
static constexpr auto PtrAlign = 4;
|
||||
static constexpr PtrType RomStart = 0x08000000;
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr std::size_t alignOf(const bool) noexcept {
|
||||
return 1;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr std::size_t alignOf(const uint8_t) noexcept {
|
||||
return 1;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr std::size_t alignOf(const uint16_t) noexcept {
|
||||
return 2;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr std::size_t alignOf(const uint32_t) noexcept {
|
||||
return 4;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr std::size_t alignOf(const uint64_t) noexcept {
|
||||
return 8;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr std::size_t alignOf(const int8_t) noexcept {
|
||||
return 1;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr std::size_t alignOf(const int16_t) noexcept {
|
||||
return 2;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr std::size_t alignOf(const int32_t) noexcept {
|
||||
return 4;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr std::size_t alignOf(const int64_t) noexcept {
|
||||
return 8;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr std::size_t alignOf(auto*) noexcept {
|
||||
return 4;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr std::size_t alignOf(const auto*) noexcept {
|
||||
return 4;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr std::size_t alignOf(const auto &v) noexcept {
|
||||
AlignmentCatcher<GbaPlatSpec> c;
|
||||
oxAssert(model(c.interface(), &v), "Could not get alignment for type");
|
||||
return c.biggestAlignment;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr auto correctEndianness(auto v) noexcept {
|
||||
return ox::toLittleEndian(v);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename PlatSpec, typename T>
|
||||
[[nodiscard]]
|
||||
constexpr std::size_t alignOf(const T &t) noexcept {
|
||||
return PlatSpec::alignOf(t);
|
||||
}
|
||||
|
||||
template<typename PlatSpec, typename T>
|
||||
constexpr auto alignOf_v = alignOf<PlatSpec>(static_cast<T*>(nullptr));
|
||||
|
||||
}
|
33
deps/ox/src/ox/preloader/preload.cpp
vendored
Normal file
33
deps/ox/src/ox/preloader/preload.cpp
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <ox/claw/claw.hpp>
|
||||
|
||||
#include "preload.hpp"
|
||||
|
||||
namespace ox {
|
||||
|
||||
static ox::Error buildPreloadBuffer(ox::Buffer *buff, std::size_t buffStart, ox::FileSystem *fs,
|
||||
ox::TypeStore *ts, const char *path) noexcept {
|
||||
oxRequire(files, fs->ls(path));
|
||||
for (const auto &f : files) {
|
||||
oxRequire(stat, fs->stat(f));
|
||||
if (stat.fileType == ox::FileType::NormalFile) {
|
||||
oxRequire(fileBuff, fs->read(path));
|
||||
oxRequire(obj, ox::readClaw(ts, fileBuff));
|
||||
} else if (stat.fileType == ox::FileType::Directory) {
|
||||
const auto childPath = ox::sfmt("{}/{}", path, f);
|
||||
oxReturnError(buildPreloadBuffer(buff, buffStart, fs, ts, childPath.c_str()));
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
ox::Result<ox::Buffer> buildPreloadBuffer(std::size_t buffStart, ox::FileSystem *fs, ox::TypeStore *ts) noexcept {
|
||||
ox::Buffer buff;
|
||||
oxReturnError(buildPreloadBuffer(&buff, buffStart, fs, ts, "/"));
|
||||
return buff;
|
||||
}
|
||||
|
||||
}
|
21
deps/ox/src/ox/preloader/preload.hpp
vendored
Normal file
21
deps/ox/src/ox/preloader/preload.hpp
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/fs/fs.hpp>
|
||||
#include <ox/std/buffer.hpp>
|
||||
|
||||
namespace ox {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param buffStart where the preload buffer will start in ROM
|
||||
* @param fs an ox::FileSystem containing the contents to be preloaded
|
||||
* @return preload buffer or error
|
||||
*/
|
||||
[[maybe_unused]]
|
||||
ox::Result<ox::Buffer> buildPreloadBuffer(std::size_t buffStart, ox::FileSystem *fs) noexcept;
|
||||
|
||||
}
|
33
deps/ox/src/ox/preloader/preloader.cpp
vendored
Normal file
33
deps/ox/src/ox/preloader/preloader.cpp
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <ox/std/error.hpp>
|
||||
|
||||
#include "platspecs.hpp"
|
||||
#include "preloader.hpp"
|
||||
|
||||
namespace ox {
|
||||
|
||||
struct TestType {
|
||||
static constexpr auto TypeName = "net.drinkingtea.nostalgia.preloader.TestType";
|
||||
static constexpr auto TypeVersion = 1;
|
||||
uint32_t field1 = 0;
|
||||
uint32_t *field2 = nullptr;
|
||||
ox::Vector<uint32_t> field3;
|
||||
};
|
||||
|
||||
oxModelBegin(TestType)
|
||||
oxModelField(field1)
|
||||
oxModelField(field2)
|
||||
oxModelField(field3)
|
||||
oxModelEnd()
|
||||
|
||||
constexpr ox::Error asdf() noexcept {
|
||||
const TestType t;
|
||||
return preload<NativePlatSpec>(&t).error;
|
||||
}
|
||||
|
||||
//static_assert(asdf().errCode == 0);
|
||||
|
||||
}
|
287
deps/ox/src/ox/preloader/preloader.hpp
vendored
Normal file
287
deps/ox/src/ox/preloader/preloader.hpp
vendored
Normal file
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/std/array.hpp>
|
||||
#include <ox/std/buffer.hpp>
|
||||
#include <ox/std/byteswap.hpp>
|
||||
#include <ox/std/error.hpp>
|
||||
#include <ox/std/memops.hpp>
|
||||
#include <ox/std/memory.hpp>
|
||||
#include <ox/std/types.hpp>
|
||||
#include <ox/std/typetraits.hpp>
|
||||
#include <ox/std/units.hpp>
|
||||
#include <ox/model/modelhandleradaptor.hpp>
|
||||
|
||||
#include "preloader.hpp"
|
||||
#include "platspecs.hpp"
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename PlatSpec>
|
||||
class Preloader: public ModelHandlerBase<Preloader<PlatSpec>> {
|
||||
private:
|
||||
class UnionIdxTracker {
|
||||
private:
|
||||
int m_unionIdx = -1;
|
||||
int m_it = 0;
|
||||
public:
|
||||
constexpr UnionIdxTracker() noexcept = default;
|
||||
constexpr explicit UnionIdxTracker(int idx) noexcept: m_unionIdx(idx) {}
|
||||
constexpr auto checkAndIterate() noexcept {
|
||||
return m_unionIdx == -1 || m_it++ == m_unionIdx;
|
||||
}
|
||||
};
|
||||
ox::Buffer m_buff;
|
||||
ox::BufferWriter m_writer;
|
||||
// list of all the places where ptrs were written to buffer
|
||||
struct PtrPair {
|
||||
std::size_t loc = 0;
|
||||
typename PlatSpec::PtrType value = 0;
|
||||
constexpr PtrPair() noexcept = default;
|
||||
constexpr PtrPair(std::size_t pLoc, typename PlatSpec::PtrType pValue) noexcept:
|
||||
loc(pLoc), value(pValue) {}
|
||||
};
|
||||
ox::Vector<PtrPair> m_ptrs;
|
||||
ox::Vector<UnionIdxTracker, 8> m_unionIdx = {{}};
|
||||
|
||||
constexpr Preloader() noexcept: m_writer(&m_buff) {}
|
||||
|
||||
Preloader(const Preloader &src) = delete;
|
||||
Preloader(Preloader &&src) = delete;
|
||||
const Preloader &operator=(const Preloader &src) = delete;
|
||||
const Preloader &operator=(Preloader &&src) = delete;
|
||||
|
||||
public:
|
||||
constexpr static ox::Result<ox::UniquePtr<Preloader>> make(ox::ios_base::seekdir anchor = ox::ios_base::cur,
|
||||
std::size_t sz = 0) noexcept;
|
||||
|
||||
constexpr void setTypeInfo(CRStringView, int, const ox::Vector<String>& = {}, int = 0) noexcept {}
|
||||
|
||||
template<typename U, bool force>
|
||||
constexpr ox::Error field(CRStringView, const ox::UnionView<U, force> val) noexcept;
|
||||
|
||||
template<typename T>
|
||||
constexpr ox::Error field(CRStringView, const T *val) noexcept;
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
constexpr ox::Error field(CRStringView, const ox::BasicString<SmallStringSize> *val) noexcept;
|
||||
|
||||
template<typename T, std::size_t sz>
|
||||
constexpr ox::Error field(CRStringView, const ox::Array<T, sz> *valArray) noexcept;
|
||||
|
||||
template<typename T>
|
||||
constexpr ox::Error field(CRStringView, const T **val, std::size_t cnt) noexcept;
|
||||
|
||||
constexpr ox::Error offsetPtrs(std::size_t offset) noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr auto &buff() const noexcept {
|
||||
return m_buff;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr auto opType() noexcept {
|
||||
return ox::OpType::Write;
|
||||
}
|
||||
|
||||
private:
|
||||
constexpr ox::Error fieldVector(CRStringView name, const ox::ModelValueVector *val) noexcept;
|
||||
|
||||
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||
constexpr ox::Error fieldVector(CRStringView, const ox::Vector<T, SmallVectorSize, Allocator> *val) noexcept;
|
||||
|
||||
constexpr ox::Error fieldVector(CRStringView, const auto *val, ox::VectorMemMap<PlatSpec> vecVal) noexcept;
|
||||
|
||||
constexpr ox::Error pad(const auto *val) noexcept;
|
||||
|
||||
constexpr bool unionCheckAndIt() noexcept;
|
||||
};
|
||||
|
||||
template<typename PlatSpec>
|
||||
constexpr ox::Result<ox::UniquePtr<Preloader<PlatSpec>>>
|
||||
Preloader<PlatSpec>::make(ox::ios_base::seekdir anchor, std::size_t sz) noexcept {
|
||||
auto p = ox::UniquePtr<Preloader>(new Preloader);
|
||||
if (const auto err = p->m_writer.seekp(0, anchor)) {
|
||||
return {std::move(p), err};
|
||||
}
|
||||
if (const auto err = p->m_writer.write(nullptr, sz)) {
|
||||
return {std::move(p), err};
|
||||
}
|
||||
if (const auto err = p->m_writer.seekp(p->m_writer.tellp() - sz)) {
|
||||
return {std::move(p), err};
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
template<typename PlatSpec>
|
||||
template<typename U, bool force>
|
||||
constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const ox::UnionView<U, force> val) noexcept {
|
||||
if (!unionCheckAndIt()) {
|
||||
return {};
|
||||
}
|
||||
oxReturnError(pad(val.get()));
|
||||
m_unionIdx.emplace_back(val.idx());
|
||||
const auto err = model(this->interface(), val.get());
|
||||
m_unionIdx.pop_back();
|
||||
return err;
|
||||
}
|
||||
|
||||
template<typename PlatSpec>
|
||||
template<typename T>
|
||||
constexpr ox::Error Preloader<PlatSpec>::field(CRStringView name, const T *val) noexcept {
|
||||
if (!unionCheckAndIt()) {
|
||||
return {};
|
||||
}
|
||||
oxReturnError(pad(val));
|
||||
if constexpr(ox::is_integral_v<T>) {
|
||||
return ox::serialize(&m_writer, PlatSpec::correctEndianness(*val));
|
||||
} else if constexpr(ox::is_pointer_v<T>) {
|
||||
return {};
|
||||
} else if constexpr(ox::isVector_v<T> || ox::is_same_v<T, ox::ModelValueVector>) {
|
||||
return fieldVector(name, val);
|
||||
} else {
|
||||
m_unionIdx.emplace_back(-1);
|
||||
const auto out = model(this->interface(), val);
|
||||
m_unionIdx.pop_back();
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename PlatSpec>
|
||||
template<std::size_t SmallStringSize>
|
||||
constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const ox::BasicString<SmallStringSize> *val) noexcept {
|
||||
if (!unionCheckAndIt()) {
|
||||
return {};
|
||||
}
|
||||
using VecMap = ox::VectorMemMap<PlatSpec>;
|
||||
const auto sz = val->bytes();
|
||||
oxRequire(a, ox::allocate(&m_writer, sz));
|
||||
const VecMap vecVal{
|
||||
.smallVecSize = SmallStringSize,
|
||||
.size = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(sz)),
|
||||
.cap = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(sz)),
|
||||
.items = sz ? PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(a) + PlatSpec::RomStart) : 0,
|
||||
};
|
||||
oxReturnError(pad(&vecVal));
|
||||
const auto restore = m_writer.tellp();
|
||||
oxReturnError(m_writer.seekp(a));
|
||||
oxReturnError(m_writer.write(val->data(), sz));
|
||||
oxReturnError(m_writer.seekp(restore));
|
||||
oxReturnError(serialize(&m_writer, vecVal));
|
||||
m_ptrs.emplace_back(restore + offsetof(VecMap, items), vecVal.items);
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename PlatSpec>
|
||||
template<typename T, std::size_t sz>
|
||||
constexpr ox::Error Preloader<PlatSpec>::field(CRStringView name, const ox::Array<T, sz> *val) noexcept {
|
||||
if (!unionCheckAndIt()) {
|
||||
return {};
|
||||
}
|
||||
// serialize the Array elements
|
||||
if constexpr(sz) {
|
||||
m_unionIdx.emplace_back(-1);
|
||||
for (std::size_t i = 0; i < val->size(); ++i) {
|
||||
oxReturnError(this->interface()->field(name, &(*val)[i]));
|
||||
}
|
||||
m_unionIdx.pop_back();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename PlatSpec>
|
||||
template<typename T>
|
||||
constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const T **val, std::size_t cnt) noexcept {
|
||||
if (!unionCheckAndIt()) {
|
||||
return {};
|
||||
}
|
||||
// serialize the array
|
||||
m_unionIdx.emplace_back(-1);
|
||||
for (std::size_t i = 0; i < cnt; ++i) {
|
||||
oxReturnError(this->interface()->field(nullptr, &val[i]));
|
||||
}
|
||||
m_unionIdx.pop_back();
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename PlatSpec>
|
||||
constexpr ox::Error Preloader<PlatSpec>::offsetPtrs(std::size_t offset) noexcept {
|
||||
for (const auto &p : m_ptrs) {
|
||||
oxReturnError(m_writer.seekp(p.loc));
|
||||
oxReturnError(ox::serialize(&m_writer, PlatSpec::correctEndianness(p.value + offset)));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename PlatSpec>
|
||||
constexpr ox::Error Preloader<PlatSpec>::fieldVector(CRStringView name, const ox::ModelValueVector *val) noexcept {
|
||||
// serialize the Vector
|
||||
ox::VectorMemMap<PlatSpec> vecVal{
|
||||
.size = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(val->size())),
|
||||
.cap = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(val->size())),
|
||||
};
|
||||
return fieldVector(name, val, vecVal);
|
||||
}
|
||||
|
||||
template<typename PlatSpec>
|
||||
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||
constexpr ox::Error Preloader<PlatSpec>::fieldVector(CRStringView name, const ox::Vector<T, SmallVectorSize, Allocator> *val) noexcept {
|
||||
// serialize the Vector
|
||||
ox::VectorMemMap<PlatSpec> vecVal{
|
||||
.smallVecSize = SmallVectorSize * sizeOf<PlatSpec>(static_cast<T*>(nullptr)),
|
||||
.size = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(val->size())),
|
||||
.cap = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(val->size())),
|
||||
};
|
||||
return fieldVector(name, val, vecVal);
|
||||
}
|
||||
|
||||
template<typename PlatSpec>
|
||||
constexpr ox::Error Preloader<PlatSpec>::fieldVector(CRStringView, const auto *val, ox::VectorMemMap<PlatSpec> vecVal) noexcept {
|
||||
oxReturnError(pad(&vecVal));
|
||||
const auto vecValPt = m_writer.tellp();
|
||||
// serialize the Vector elements
|
||||
if (val->size()) {
|
||||
const auto sz = sizeOf<PlatSpec>(&(*val)[0]) * val->size();
|
||||
oxRequire(p, ox::allocate(&m_writer, sz));
|
||||
oxReturnError(m_writer.seekp(p));
|
||||
m_unionIdx.emplace_back(-1);
|
||||
for (std::size_t i = 0; i < val->size(); ++i) {
|
||||
oxReturnError(this->interface()->field(nullptr, &val->operator[](i)));
|
||||
}
|
||||
m_unionIdx.pop_back();
|
||||
vecVal.items = PlatSpec::correctEndianness(p + PlatSpec::RomStart);
|
||||
oxReturnError(m_writer.seekp(vecValPt));
|
||||
} else {
|
||||
vecVal.items = 0;
|
||||
}
|
||||
// serialize the Vector
|
||||
oxReturnError(serialize(&m_writer, vecVal));
|
||||
m_ptrs.emplace_back(vecValPt + offsetof(ox::VectorMemMap<PlatSpec>, items), vecVal.items);
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename PlatSpec>
|
||||
constexpr ox::Error Preloader<PlatSpec>::pad(const auto *val) noexcept {
|
||||
constexpr auto a = alignOf_v<PlatSpec, decltype(val)>;
|
||||
const auto padding = a - m_writer.tellp() % a;
|
||||
return m_writer.write(nullptr, padding);
|
||||
}
|
||||
|
||||
template<typename PlatSpec>
|
||||
constexpr bool Preloader<PlatSpec>::unionCheckAndIt() noexcept {
|
||||
auto &u = m_unionIdx.back().unwrap();
|
||||
return u.checkAndIterate();
|
||||
}
|
||||
|
||||
template<typename PlatSpec>
|
||||
constexpr ox::Result<ox::Buffer> preload(const auto *obj) noexcept {
|
||||
using Pl = Preloader<PlatSpec>;
|
||||
oxRequireM(preloader, Pl::make(ox::ios_base::end));
|
||||
oxReturnError(model(preloader->interface(), obj));
|
||||
return preloader->buff();
|
||||
}
|
||||
|
||||
}
|
109
deps/ox/src/ox/preloader/sizecatcher.hpp
vendored
Normal file
109
deps/ox/src/ox/preloader/sizecatcher.hpp
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/model/modelhandleradaptor.hpp>
|
||||
#include <ox/model/optype.hpp>
|
||||
#include <ox/model/types.hpp>
|
||||
#include <ox/std/error.hpp>
|
||||
#include <ox/std/string.hpp>
|
||||
#include <ox/std/types.hpp>
|
||||
|
||||
#include "unionsizecatcher.hpp"
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename PlatSpec, typename T>
|
||||
[[nodiscard]]
|
||||
constexpr std::size_t alignOf(const T &t) noexcept;
|
||||
|
||||
template<typename PlatSpec, typename T>
|
||||
[[nodiscard]]
|
||||
constexpr std::size_t sizeOf(const T *t) noexcept;
|
||||
|
||||
template<typename PlatSpec>
|
||||
class SizeCatcher: public ModelHandlerBase<SizeCatcher<PlatSpec>> {
|
||||
private:
|
||||
std::size_t m_size = 0;
|
||||
|
||||
public:
|
||||
constexpr explicit SizeCatcher() noexcept = default;
|
||||
|
||||
template<typename ...T>
|
||||
constexpr void setTypeInfo(T&&...) const noexcept {
|
||||
}
|
||||
|
||||
template<typename T, bool force>
|
||||
constexpr ox::Error field(const char*, UnionView<T, force>) noexcept;
|
||||
|
||||
template<typename T>
|
||||
constexpr ox::Error field(const char*, const T *val) noexcept;
|
||||
|
||||
template<typename T>
|
||||
constexpr ox::Error field(const char*, const T **val, std::size_t cnt) noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr auto size() const noexcept {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr auto opType() noexcept {
|
||||
return ox::OpType::Reflect;
|
||||
}
|
||||
|
||||
private:
|
||||
constexpr void pad(const auto *val) noexcept;
|
||||
};
|
||||
|
||||
template<typename PlatSpec>
|
||||
template<typename T, bool force>
|
||||
constexpr ox::Error SizeCatcher<PlatSpec>::field(const char*, const UnionView<T, force> val) noexcept {
|
||||
pad(val.get());
|
||||
UnionSizeCatcher<PlatSpec> sc;
|
||||
oxReturnError(model(sc.interface(), val.get()));
|
||||
m_size += sc.size();
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename PlatSpec>
|
||||
template<typename T>
|
||||
constexpr ox::Error SizeCatcher<PlatSpec>::field(const char*, const T *val) noexcept {
|
||||
pad(val);
|
||||
m_size += sizeOf<PlatSpec>(val);
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename PlatSpec>
|
||||
template<typename T>
|
||||
constexpr ox::Error SizeCatcher<PlatSpec>::field(const char*, const T **val, std::size_t cnt) noexcept {
|
||||
for (std::size_t i = 0; i < cnt; ++i) {
|
||||
oxReturnError(field("", &val[i]));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename PlatSpec>
|
||||
constexpr void SizeCatcher<PlatSpec>::pad(const auto *val) noexcept {
|
||||
const auto padding = m_size - m_size % alignOf<PlatSpec>(*val);
|
||||
m_size += padding;
|
||||
}
|
||||
|
||||
template<typename PlatSpec, typename T>
|
||||
[[nodiscard]]
|
||||
constexpr std::size_t sizeOf(const T *t) noexcept {
|
||||
if constexpr(ox::is_integral_v<T>) {
|
||||
return sizeof(T);
|
||||
} else if constexpr(ox::is_pointer_v<T>) {
|
||||
return sizeof(PlatSpec::PtrType);
|
||||
} else {
|
||||
SizeCatcher<PlatSpec> sc;
|
||||
const auto err = model(sc.interface(), t);
|
||||
oxAssert(err, "Could not get size of type");
|
||||
return sc.size();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
97
deps/ox/src/ox/preloader/unionsizecatcher.hpp
vendored
Normal file
97
deps/ox/src/ox/preloader/unionsizecatcher.hpp
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/model/modelhandleradaptor.hpp>
|
||||
#include <ox/model/optype.hpp>
|
||||
#include <ox/model/types.hpp>
|
||||
#include <ox/std/error.hpp>
|
||||
#include <ox/std/string.hpp>
|
||||
#include <ox/std/types.hpp>
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename PlatSpec>
|
||||
class UnionSizeCatcher: public ModelHandlerBase<UnionSizeCatcher<PlatSpec>> {
|
||||
private:
|
||||
std::size_t m_size = 0;
|
||||
|
||||
public:
|
||||
template<typename ...T>
|
||||
constexpr void setTypeInfo(T&&...) const noexcept {
|
||||
}
|
||||
|
||||
template<typename T, bool force>
|
||||
constexpr ox::Error field(CRStringView, const UnionView<T, force> val) noexcept {
|
||||
UnionSizeCatcher<PlatSpec> sc;
|
||||
oxReturnError(model(sc.interface(), val.get()));
|
||||
m_size += sc.size();
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr ox::Error field(CRStringView, const T *val) noexcept;
|
||||
|
||||
template<typename T>
|
||||
constexpr ox::Error field(CRStringView, const T **val, std::size_t cnt) noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr auto size() const noexcept {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr auto opType() noexcept {
|
||||
return ox::OpType::Reflect;
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename T, std::size_t SmallVecSize>
|
||||
constexpr ox::Error fieldStr(CRStringView, const ox::BasicString<SmallVecSize> *val) noexcept;
|
||||
|
||||
template<typename T, std::size_t SmallVecSize>
|
||||
constexpr ox::Error fieldVector(CRStringView, const ox::Vector<T, SmallVecSize> *val) noexcept;
|
||||
|
||||
constexpr void setSize(std::size_t sz) noexcept;
|
||||
};
|
||||
|
||||
template<typename PlatSpec>
|
||||
template<typename T>
|
||||
constexpr ox::Error UnionSizeCatcher<PlatSpec>::field(CRStringView, const T *val) noexcept {
|
||||
setSize(sizeOf<PlatSpec>(val));
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename PlatSpec>
|
||||
template<typename T>
|
||||
constexpr ox::Error UnionSizeCatcher<PlatSpec>::field(CRStringView, const T **val, std::size_t cnt) noexcept {
|
||||
for (std::size_t i = 0; i < cnt; ++i) {
|
||||
oxReturnError(field("", &val[i]));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename PlatSpec>
|
||||
template<typename T, std::size_t SmallStrSize>
|
||||
constexpr ox::Error UnionSizeCatcher<PlatSpec>::fieldStr(CRStringView, const ox::BasicString<SmallStrSize>*) noexcept {
|
||||
ox::VectorMemMap<PlatSpec> v;
|
||||
setSize(sizeOf<PlatSpec>(v));
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename PlatSpec>
|
||||
template<typename T, std::size_t SmallVecSize>
|
||||
constexpr ox::Error UnionSizeCatcher<PlatSpec>::fieldVector(CRStringView, const ox::Vector<T, SmallVecSize>*) noexcept {
|
||||
ox::VectorMemMap<PlatSpec> v;
|
||||
setSize(sizeOf<PlatSpec>(v));
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename PlatSpec>
|
||||
constexpr void UnionSizeCatcher<PlatSpec>::setSize(std::size_t sz) noexcept {
|
||||
m_size = ox::max(m_size, sz);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user