[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 { 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> template<typename PlatSpec>
class Preloader: public ModelHandlerBase<Preloader<PlatSpec>> { class Preloader: public ModelHandlerBase<Preloader<PlatSpec>> {
private: private:
@ -59,7 +65,7 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>> {
std::size_t sz = 0) noexcept; std::size_t sz = 0) noexcept;
template<typename T> 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 {} const Vector<String>& = {}, int = ModelFieldCount_v<T>) noexcept {}
template<typename U, bool force> template<typename U, bool force>
@ -89,6 +95,9 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>> {
return ox::OpType::Write; return ox::OpType::Write;
} }
template<typename T>
constexpr ox::Error pad(const T*) noexcept;
private: private:
constexpr ox::Error fieldVector(CRStringView name, const ox::ModelValueVector *val) noexcept; 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 fieldVector(CRStringView, const auto *val, ox::VectorMemMap<PlatSpec> vecVal) noexcept;
constexpr ox::Error pad(const auto *val) noexcept;
constexpr bool unionCheckAndIt() noexcept; constexpr bool unionCheckAndIt() noexcept;
}; };
@ -126,7 +133,7 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const ox::UnionView
} }
oxReturnError(pad(val.get())); oxReturnError(pad(val.get()));
m_unionIdx.emplace_back(val.idx()); 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(); m_unionIdx.pop_back();
return err; return err;
} }
@ -146,7 +153,7 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView name, const T *val)
return fieldVector(name, val); return fieldVector(name, val);
} else { } else {
m_unionIdx.emplace_back(-1); m_unionIdx.emplace_back(-1);
const auto out = model(this->interface(), val); const auto out = preload<PlatSpec, T>(this, val);
m_unionIdx.pop_back(); m_unionIdx.pop_back();
return out; return out;
} }
@ -219,6 +226,18 @@ constexpr ox::Error Preloader<PlatSpec>::offsetPtrs(std::size_t offset) noexcept
return {}; 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> template<typename PlatSpec>
constexpr ox::Error Preloader<PlatSpec>::fieldVector(CRStringView name, const ox::ModelValueVector *val) noexcept { constexpr ox::Error Preloader<PlatSpec>::fieldVector(CRStringView name, const ox::ModelValueVector *val) noexcept {
// serialize the Vector // serialize the Vector
@ -266,25 +285,17 @@ constexpr ox::Error Preloader<PlatSpec>::fieldVector(CRStringView, const auto *v
return {}; 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> template<typename PlatSpec>
constexpr bool Preloader<PlatSpec>::unionCheckAndIt() noexcept { constexpr bool Preloader<PlatSpec>::unionCheckAndIt() noexcept {
auto &u = m_unionIdx.back().unwrap(); auto &u = m_unionIdx.back().unwrap();
return u.checkAndIterate(); return u.checkAndIterate();
} }
template<typename PlatSpec> template<typename PlatSpec, typename T>
constexpr ox::Result<ox::Buffer> preload(const auto *obj) noexcept { constexpr ox::Error preload(Preloader<PlatSpec> *pl, ox::CommonPtrWith<T> auto *obj) noexcept {
using Pl = Preloader<PlatSpec>; auto i = pl->interface();
oxRequireM(preloader, Pl::make(ox::ios_base::end)); oxReturnError(model(i, obj));
oxReturnError(model(preloader->interface(), obj)); return pl->pad(obj);
return preloader->buff();
} }
} }