[ox/preloader] Fix alignment and add preload function

This commit is contained in:
Gary Talent 2022-12-01 01:59:27 -06:00
parent 0e0f43895a
commit 5be8ed533e

View File

@ -20,6 +20,12 @@
namespace ox {
template<typename PlatSpec>
class Preloader;
template<typename PlatSpec, typename T>
constexpr ox::Error preload(Preloader<PlatSpec> *pl, ox::CommonPtrWith<T> auto *obj) noexcept;
template<typename PlatSpec>
class Preloader: public ModelHandlerBase<Preloader<PlatSpec>> {
private:
@ -59,7 +65,7 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>> {
std::size_t sz = 0) noexcept;
template<typename T>
constexpr void setTypeInfo(const char* = T::TypeName, int = T::TypeVersion,
constexpr void setTypeInfo(ox::CRStringView = T::TypeName, int = T::TypeVersion,
const Vector<String>& = {}, int = ModelFieldCount_v<T>) noexcept {}
template<typename U, bool force>
@ -89,6 +95,9 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>> {
return ox::OpType::Write;
}
template<typename T>
constexpr ox::Error pad(const T*) noexcept;
private:
constexpr ox::Error fieldVector(CRStringView name, const ox::ModelValueVector *val) noexcept;
@ -97,8 +106,6 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>> {
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;
};
@ -126,7 +133,7 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const ox::UnionView
}
oxReturnError(pad(val.get()));
m_unionIdx.emplace_back(val.idx());
const auto err = model(this->interface(), val.get());
const auto err = preload<PlatSpec, U>(this, val.get());
m_unionIdx.pop_back();
return err;
}
@ -146,7 +153,7 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView name, const T *val)
return fieldVector(name, val);
} else {
m_unionIdx.emplace_back(-1);
const auto out = model(this->interface(), val);
const auto out = preload<PlatSpec, T>(this, val);
m_unionIdx.pop_back();
return out;
}
@ -219,6 +226,18 @@ constexpr ox::Error Preloader<PlatSpec>::offsetPtrs(std::size_t offset) noexcept
return {};
}
template<typename PlatSpec>
template<typename T>
constexpr ox::Error Preloader<PlatSpec>::pad(const T *v) noexcept {
const auto a = alignOf<PlatSpec>(*v);
const auto excess = m_writer.tellp() % a;
if (excess) {
return m_writer.write(nullptr, a - excess);
} else {
return {};
}
}
template<typename PlatSpec>
constexpr ox::Error Preloader<PlatSpec>::fieldVector(CRStringView name, const ox::ModelValueVector *val) noexcept {
// serialize the Vector
@ -266,25 +285,17 @@ constexpr ox::Error Preloader<PlatSpec>::fieldVector(CRStringView, const auto *v
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();
template<typename PlatSpec, typename T>
constexpr ox::Error preload(Preloader<PlatSpec> *pl, ox::CommonPtrWith<T> auto *obj) noexcept {
auto i = pl->interface();
oxReturnError(model(i, obj));
return pl->pad(obj);
}
}