mirror of https://github.com/libAthena/athena.git
1188 lines
70 KiB
C++
1188 lines
70 KiB
C++
#pragma once
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <type_traits>
|
|
#include <vector>
|
|
|
|
#include "athena/ChecksumsLiterals.hpp"
|
|
#include "athena/IStreamReader.hpp"
|
|
#include "athena/IStreamWriter.hpp"
|
|
#include "athena/YAMLDocReader.hpp"
|
|
#include "athena/YAMLDocWriter.hpp"
|
|
|
|
namespace athena::io {
|
|
|
|
struct PropId {
|
|
std::string_view name;
|
|
uint32_t rcrc32 = 0xffffffff;
|
|
uint64_t crc64 = 0x0;
|
|
template <class T>
|
|
constexpr T opget() const;
|
|
constexpr PropId() = default;
|
|
constexpr explicit PropId(std::string_view name, uint32_t rcrc32, uint64_t crc64)
|
|
: name(name), rcrc32(rcrc32), crc64(crc64) {}
|
|
constexpr explicit PropId(std::string_view name)
|
|
: name(name)
|
|
, rcrc32(athena::checksums::literals::rcrc32_rec(0xFFFFFFFF, name.data()))
|
|
, crc64(athena::checksums::literals::crc64_rec(0xFFFFFFFFFFFFFFFF, name.data())) {}
|
|
constexpr PropId(std::string_view name, uint32_t rcrc32)
|
|
: name(name), rcrc32(rcrc32), crc64(athena::checksums::literals::crc64_rec(0xFFFFFFFFFFFFFFFF, name.data())) {}
|
|
};
|
|
|
|
template <>
|
|
constexpr uint32_t PropId::opget<uint32_t>() const {
|
|
return rcrc32;
|
|
}
|
|
|
|
template <>
|
|
constexpr uint64_t PropId::opget<uint64_t>() const {
|
|
return crc64;
|
|
}
|
|
|
|
namespace literals {
|
|
constexpr PropId operator"" _propid(const char* s, size_t len) { return PropId{s}; }
|
|
} // namespace literals
|
|
|
|
#define AT_PROP_CASE(...) case athena::io::PropId(__VA_ARGS__).opget<typename Op::PropT>()
|
|
|
|
#if defined(__atdna__)
|
|
#define AT_OVERRIDE_RCRC32(rcrc32) __attribute__((annotate("rcrc32=" #rcrc32)))
|
|
#else
|
|
#define AT_OVERRIDE_RCRC32(rcrc32)
|
|
#endif
|
|
|
|
#if defined(__atdna__)
|
|
#define AT_SPECIALIZE_PARMS(...) __attribute__((annotate("specparms=" #__VA_ARGS__)))
|
|
#else
|
|
#define AT_SPECIALIZE_PARMS(...)
|
|
#endif
|
|
|
|
enum class PropType { None, CRC32, CRC64 };
|
|
|
|
template <class T>
|
|
using __IsPODType = std::disjunction<
|
|
std::is_arithmetic<std::remove_cv_t<T>>, std::is_convertible<std::remove_cv_t<T>&, atVec2f&>,
|
|
std::is_convertible<std::remove_cv_t<T>&, atVec3f&>, std::is_convertible<std::remove_cv_t<T>&, atVec4f&>,
|
|
std::is_convertible<std::remove_cv_t<T>&, atVec2d&>, std::is_convertible<std::remove_cv_t<T>&, atVec3d&>,
|
|
std::is_convertible<std::remove_cv_t<T>&, atVec4d&>>;
|
|
template <class T>
|
|
constexpr bool __IsPODType_v = __IsPODType<T>::value;
|
|
|
|
template <class T>
|
|
using __CastPODType = std::conditional_t<
|
|
std::is_convertible_v<std::remove_cv_t<T>&, atVec2f&>, atVec2f,
|
|
std::conditional_t<
|
|
std::is_convertible_v<std::remove_cv_t<T>&, atVec3f&>, atVec3f,
|
|
std::conditional_t<
|
|
std::is_convertible_v<std::remove_cv_t<T>&, atVec4f&>, atVec4f,
|
|
std::conditional_t<
|
|
std::is_convertible_v<std::remove_cv_t<T>&, atVec2d&>, atVec2d,
|
|
std::conditional_t<std::is_convertible_v<std::remove_cv_t<T>&, atVec3d&>, atVec3d,
|
|
std::conditional_t<std::is_convertible_v<std::remove_cv_t<T>&, atVec4d&>, atVec4d,
|
|
std::remove_cv_t<T>>>>>>>;
|
|
|
|
template <Endian DNAE>
|
|
uint16_t __Read16(IStreamReader& r) {
|
|
return DNAE == Endian::Big ? r.readUint16Big() : r.readUint16Little();
|
|
}
|
|
|
|
template <Endian DNAE>
|
|
void __Write16(IStreamWriter& w, uint16_t v) {
|
|
DNAE == Endian::Big ? w.writeUint16Big(v) : w.writeUint16Little(v);
|
|
}
|
|
|
|
template <Endian DNAE>
|
|
uint32_t __Read32(IStreamReader& r) {
|
|
return DNAE == Endian::Big ? r.readUint32Big() : r.readUint32Little();
|
|
}
|
|
|
|
template <Endian DNAE>
|
|
void __Write32(IStreamWriter& w, uint32_t v) {
|
|
DNAE == Endian::Big ? w.writeUint32Big(v) : w.writeUint32Little(v);
|
|
}
|
|
|
|
template <Endian DNAE>
|
|
uint64_t __Read64(IStreamReader& r) {
|
|
return DNAE == Endian::Big ? r.readUint64Big() : r.readUint64Little();
|
|
}
|
|
|
|
template <Endian DNAE>
|
|
void __Write64(IStreamWriter& w, uint64_t v) {
|
|
DNAE == Endian::Big ? w.writeUint64Big(v) : w.writeUint64Little(v);
|
|
}
|
|
|
|
template <PropType PropOp>
|
|
struct BinarySize {
|
|
using PropT = std::conditional_t<PropOp == PropType::CRC64, uint64_t, uint32_t>;
|
|
using StreamT = size_t;
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_enum_v<T>> Do(const PropId& id, T& var, StreamT& s) {
|
|
if (PropOp != PropType::None) {
|
|
/* Accessed via Enumerate, header */
|
|
s += 6;
|
|
}
|
|
using PODType = std::underlying_type_t<T>;
|
|
BinarySize<PropType::None>::Do<PODType, DNAE>(id, *reinterpret_cast<PODType*>(&var), s);
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<__IsPODType_v<T>> Do(const PropId& id, T& var, StreamT& s) {
|
|
if (PropOp != PropType::None) {
|
|
/* Accessed via Enumerate, header */
|
|
s += 6;
|
|
}
|
|
using CastT = __CastPODType<T>;
|
|
BinarySize<PropType::None>::Do<CastT, DNAE>(id, static_cast<CastT&>(const_cast<std::remove_cv_t<T>&>(var)), s);
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<__IsDNARecord_v<T> && PropOp != PropType::None> Do(const PropId& id, T& var, StreamT& s) {
|
|
/* Accessed via Enumerate, header */
|
|
s += 6;
|
|
var.template Enumerate<BinarySize<PropOp>>(s);
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<__IsDNARecord_v<T> && PropOp == PropType::None> Do(const PropId& id, T& var, StreamT& s) {
|
|
var.template Enumerate<BinarySize<PropType::None>>(s);
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_array_v<T>> Do(const PropId& id, T& var, StreamT& s) {
|
|
for (auto& v : var) {
|
|
BinarySize<PropOp>::template Do<std::remove_reference_t<decltype(v)>, DNAE>(id, v, s);
|
|
}
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static void DoSize(const PropId& id, T& var, StreamT& s) {
|
|
BinarySize<PropOp>::template Do<T, DNAE>(id, var, s);
|
|
}
|
|
template <class T, class S, Endian DNAE>
|
|
static std::enable_if_t<!std::is_same_v<T, bool>> Do(const PropId& id, std::vector<T>& vector, const S& count,
|
|
StreamT& s) {
|
|
for (T& v : vector) {
|
|
BinarySize<PropOp>::template Do<T, DNAE>(id, v, s);
|
|
}
|
|
}
|
|
template <class T, class S, Endian DNAE>
|
|
static std::enable_if_t<std::is_same_v<T, bool>> Do(const PropId& id, std::vector<T>& vector, const S& count,
|
|
StreamT& s) {
|
|
/* libc++ specializes vector<bool> as a bitstream */
|
|
s += vector.size();
|
|
}
|
|
static void Do(const PropId& id, std::unique_ptr<atUint8[]>& buf, size_t count, StreamT& s) {
|
|
if (buf)
|
|
s += count;
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_same_v<T, std::string>> Do(const PropId& id, T& str, StreamT& s) {
|
|
s += str.size() + 1;
|
|
}
|
|
static void Do(const PropId& id, std::string& str, atInt32 count, StreamT& s) {
|
|
if (count < 0)
|
|
s += str.size() + 1;
|
|
else
|
|
s += count;
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_same_v<T, std::wstring>> Do(const PropId& id, T& str, StreamT& s) {
|
|
s += str.size() * 2 + 2;
|
|
}
|
|
template <Endian DNAE>
|
|
static void Do(const PropId& id, std::wstring& str, atInt32 count, StreamT& s) {
|
|
if (count < 0)
|
|
s += str.size() * 2 + 2;
|
|
else
|
|
s += count * 2;
|
|
}
|
|
static void DoSeek(atInt64 amount, SeekOrigin whence, StreamT& s) {
|
|
switch (whence) {
|
|
case SeekOrigin::Begin:
|
|
s = amount;
|
|
break;
|
|
case SeekOrigin::Current:
|
|
s += amount;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
static void DoAlign(atInt64 amount, StreamT& s) { s = (s + amount - 1) / amount * amount; }
|
|
};
|
|
#define __BINARY_SIZE_S(type, endian) \
|
|
template <> \
|
|
template <> \
|
|
inline void BinarySize<PropType::None>::Do<type, endian>(const PropId& id, type& var, BinarySize::StreamT& s)
|
|
__BINARY_SIZE_S(bool, Endian::Big) { s += 1; }
|
|
__BINARY_SIZE_S(atInt8, Endian::Big) { s += 1; }
|
|
__BINARY_SIZE_S(atUint8, Endian::Big) { s += 1; }
|
|
__BINARY_SIZE_S(atInt16, Endian::Big) { s += 2; }
|
|
__BINARY_SIZE_S(atUint16, Endian::Big) { s += 2; }
|
|
__BINARY_SIZE_S(atInt32, Endian::Big) { s += 4; }
|
|
__BINARY_SIZE_S(atUint32, Endian::Big) { s += 4; }
|
|
__BINARY_SIZE_S(atInt64, Endian::Big) { s += 8; }
|
|
__BINARY_SIZE_S(atUint64, Endian::Big) { s += 8; }
|
|
__BINARY_SIZE_S(float, Endian::Big) { s += 4; }
|
|
__BINARY_SIZE_S(double, Endian::Big) { s += 8; }
|
|
__BINARY_SIZE_S(atVec2f, Endian::Big) { s += 8; }
|
|
__BINARY_SIZE_S(atVec2d, Endian::Big) { s += 16; }
|
|
__BINARY_SIZE_S(atVec3f, Endian::Big) { s += 12; }
|
|
__BINARY_SIZE_S(atVec3d, Endian::Big) { s += 24; }
|
|
__BINARY_SIZE_S(atVec4f, Endian::Big) { s += 16; }
|
|
__BINARY_SIZE_S(atVec4d, Endian::Big) { s += 32; }
|
|
__BINARY_SIZE_S(bool, Endian::Little) { s += 1; }
|
|
__BINARY_SIZE_S(atInt8, Endian::Little) { s += 1; }
|
|
__BINARY_SIZE_S(atUint8, Endian::Little) { s += 1; }
|
|
__BINARY_SIZE_S(atInt16, Endian::Little) { s += 2; }
|
|
__BINARY_SIZE_S(atUint16, Endian::Little) { s += 2; }
|
|
__BINARY_SIZE_S(atInt32, Endian::Little) { s += 4; }
|
|
__BINARY_SIZE_S(atUint32, Endian::Little) { s += 4; }
|
|
__BINARY_SIZE_S(atInt64, Endian::Little) { s += 8; }
|
|
__BINARY_SIZE_S(atUint64, Endian::Little) { s += 8; }
|
|
__BINARY_SIZE_S(float, Endian::Little) { s += 4; }
|
|
__BINARY_SIZE_S(double, Endian::Little) { s += 8; }
|
|
__BINARY_SIZE_S(atVec2f, Endian::Little) { s += 8; }
|
|
__BINARY_SIZE_S(atVec2d, Endian::Little) { s += 16; }
|
|
__BINARY_SIZE_S(atVec3f, Endian::Little) { s += 12; }
|
|
__BINARY_SIZE_S(atVec3d, Endian::Little) { s += 24; }
|
|
__BINARY_SIZE_S(atVec4f, Endian::Little) { s += 16; }
|
|
__BINARY_SIZE_S(atVec4d, Endian::Little) { s += 32; }
|
|
|
|
template <PropType PropOp>
|
|
struct PropCount {
|
|
using PropT = std::conditional_t<PropOp == PropType::CRC64, uint64_t, uint32_t>;
|
|
using StreamT = size_t;
|
|
template <class T, Endian DNAE>
|
|
static void Do(const PropId& id, T& var, StreamT& s) {
|
|
/* Only reports one level of properties */
|
|
s += 1;
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static void DoSize(const PropId& id, T& var, StreamT& s) {
|
|
PropCount<PropOp>::template Do<T, DNAE>(id, var, s);
|
|
}
|
|
template <class T, class S, Endian DNAE>
|
|
static void Do(const PropId& id, std::vector<T>& vector, const S& count, StreamT& s) {
|
|
/* Only reports one level of properties */
|
|
s += 1;
|
|
}
|
|
static void Do(const PropId& id, std::unique_ptr<atUint8[]>& buf, size_t count, StreamT& s) {
|
|
/* Only reports one level of properties */
|
|
s += 1;
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_same_v<T, std::string>> Do(const PropId& id, T& str, StreamT& s) {
|
|
/* Only reports one level of properties */
|
|
s += 1;
|
|
}
|
|
static void Do(const PropId& id, std::string& str, atInt32 count, StreamT& s) {
|
|
/* Only reports one level of properties */
|
|
s += 1;
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_same_v<T, std::wstring>> Do(const PropId& id, T& str, StreamT& s) {
|
|
/* Only reports one level of properties */
|
|
s += 1;
|
|
}
|
|
template <Endian DNAE>
|
|
static void Do(const PropId& id, std::wstring& str, atInt32 count, StreamT& s) {
|
|
/* Only reports one level of properties */
|
|
s += 1;
|
|
}
|
|
static void DoSeek(atInt64 amount, SeekOrigin whence, StreamT& s) {}
|
|
static void DoAlign(atInt64 amount, StreamT& s) {}
|
|
};
|
|
|
|
template <PropType PropOp>
|
|
struct Read {
|
|
using PropT = std::conditional_t<PropOp == PropType::CRC64, uint64_t, uint32_t>;
|
|
using StreamT = IStreamReader;
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_enum_v<T>> Do(const PropId& id, T& var, StreamT& r) {
|
|
using PODType = std::underlying_type_t<T>;
|
|
Read<PropType::None>::Do<PODType, DNAE>(id, *reinterpret_cast<PODType*>(&var), r);
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<__IsPODType_v<T>> Do(const PropId& id, T& var, StreamT& r) {
|
|
using CastT = __CastPODType<T>;
|
|
Read<PropType::None>::Do<CastT, DNAE>(id, static_cast<CastT&>(var), r);
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<__IsDNARecord<T>() && PropOp == PropType::None> Do(const PropId& id, T& var, StreamT& r) {
|
|
var.template Enumerate<Read<PropType::None>>(r);
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<__IsDNARecord<T>() && PropOp != PropType::None> Do(const PropId& id, T& var, StreamT& r) {
|
|
/* Accessed via Lookup, no header */
|
|
atUint16 propCount = __Read16<T::DNAEndian>(r);
|
|
for (atUint32 i = 0; i < propCount; ++i) {
|
|
atUint64 hash;
|
|
if (PropOp == PropType::CRC64)
|
|
hash = __Read64<T::DNAEndian>(r);
|
|
else
|
|
hash = __Read32<T::DNAEndian>(r);
|
|
atInt64 size = __Read16<T::DNAEndian>(r);
|
|
atInt64 start = r.position();
|
|
var.template Lookup<Read<PropOp>>(hash, r);
|
|
atInt64 actualRead = r.position() - start;
|
|
if (actualRead != size)
|
|
r.seek(size - actualRead);
|
|
}
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_array_v<T>> Do(const PropId& id, T& var, StreamT& s) {
|
|
for (auto& v : var) {
|
|
Read<PropOp>::template Do<std::remove_reference_t<decltype(v)>, DNAE>(id, v, s);
|
|
}
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static void DoSize(const PropId& id, T& var, StreamT& s) {
|
|
Read<PropOp>::template Do<T, DNAE>(id, var, s);
|
|
}
|
|
template <class T, class S, Endian DNAE>
|
|
static std::enable_if_t<!std::is_same_v<T, bool>> Do(const PropId& id, std::vector<T>& vector, const S& count,
|
|
StreamT& r) {
|
|
vector.clear();
|
|
vector.reserve(count);
|
|
for (size_t i = 0; i < static_cast<size_t>(count); ++i) {
|
|
vector.emplace_back();
|
|
Read<PropOp>::template Do<T, DNAE>(id, vector.back(), r);
|
|
}
|
|
}
|
|
template <class T, class S, Endian DNAE>
|
|
static std::enable_if_t<std::is_same_v<T, bool>> Do(const PropId& id, std::vector<T>& vector, const S& count,
|
|
StreamT& r) {
|
|
/* libc++ specializes vector<bool> as a bitstream */
|
|
vector.clear();
|
|
vector.reserve(count);
|
|
for (size_t i = 0; i < count; ++i)
|
|
vector.push_back(r.readBool());
|
|
}
|
|
static void Do(const PropId& id, std::unique_ptr<atUint8[]>& buf, size_t count, StreamT& r) {
|
|
buf.reset(new atUint8[count]);
|
|
r.readUBytesToBuf(buf.get(), count);
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_same_v<T, std::string>> Do(const PropId& id, T& str, StreamT& r) {
|
|
str = r.readString();
|
|
}
|
|
static void Do(const PropId& id, std::string& str, atInt32 count, StreamT& r) { str = r.readString(count); }
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_same_v<T, std::wstring>> Do(const PropId& id, T& str, StreamT& r) {
|
|
Read<PropType::None>::Do<DNAE>(id, str, r);
|
|
}
|
|
template <Endian DNAE>
|
|
static void Do(const PropId& id, std::wstring& str, atInt32 count, StreamT& r) {
|
|
Read<PropType::None>::Do<DNAE>(id, str, count, r);
|
|
}
|
|
static void DoSeek(atInt64 amount, SeekOrigin whence, StreamT& r) { r.seek(amount, whence); }
|
|
static void DoAlign(atInt64 amount, StreamT& r) {
|
|
r.seek((r.position() + amount - 1) / amount * amount, athena::SeekOrigin::Begin);
|
|
}
|
|
};
|
|
#define __READ_S(type, endian) \
|
|
template <> \
|
|
template <> \
|
|
inline void Read<PropType::None>::Do<type, endian>(const PropId& id, type& var, Read::StreamT& r)
|
|
#define __READ_WSTR_S(endian) \
|
|
template <> \
|
|
template <> \
|
|
inline void Read<PropType::None>::Do<std::wstring, endian>(const PropId& id, std::wstring& str, Read::StreamT& r)
|
|
#define __READ_WSTRC_S(endian) \
|
|
template <> \
|
|
template <> \
|
|
inline void Read<PropType::None>::Do<endian>(const PropId& id, std::wstring& str, atInt32 count, Read::StreamT& r)
|
|
__READ_S(bool, Endian::Big) { var = r.readBool(); }
|
|
__READ_S(atInt8, Endian::Big) { var = r.readByte(); }
|
|
__READ_S(atUint8, Endian::Big) { var = r.readUByte(); }
|
|
__READ_S(atInt16, Endian::Big) { var = r.readInt16Big(); }
|
|
__READ_S(atUint16, Endian::Big) { var = r.readUint16Big(); }
|
|
__READ_S(atInt32, Endian::Big) { var = r.readInt32Big(); }
|
|
__READ_S(atUint32, Endian::Big) { var = r.readUint32Big(); }
|
|
__READ_S(atInt64, Endian::Big) { var = r.readInt64Big(); }
|
|
__READ_S(atUint64, Endian::Big) { var = r.readUint64Big(); }
|
|
__READ_S(float, Endian::Big) { var = r.readFloatBig(); }
|
|
__READ_S(double, Endian::Big) { var = r.readDoubleBig(); }
|
|
__READ_S(atVec2f, Endian::Big) { var = r.readVec2fBig(); }
|
|
__READ_S(atVec2d, Endian::Big) { var = r.readVec2dBig(); }
|
|
__READ_S(atVec3f, Endian::Big) { var = r.readVec3fBig(); }
|
|
__READ_S(atVec3d, Endian::Big) { var = r.readVec3dBig(); }
|
|
__READ_S(atVec4f, Endian::Big) { var = r.readVec4fBig(); }
|
|
__READ_S(atVec4d, Endian::Big) { var = r.readVec4dBig(); }
|
|
__READ_WSTR_S(Endian::Big) { str = r.readWStringBig(); }
|
|
__READ_WSTRC_S(Endian::Big) { str = r.readWStringBig(count); }
|
|
__READ_S(bool, Endian::Little) { var = r.readBool(); }
|
|
__READ_S(atInt8, Endian::Little) { var = r.readByte(); }
|
|
__READ_S(atUint8, Endian::Little) { var = r.readUByte(); }
|
|
__READ_S(atInt16, Endian::Little) { var = r.readInt16Little(); }
|
|
__READ_S(atUint16, Endian::Little) { var = r.readUint16Little(); }
|
|
__READ_S(atInt32, Endian::Little) { var = r.readInt32Little(); }
|
|
__READ_S(atUint32, Endian::Little) { var = r.readUint32Little(); }
|
|
__READ_S(atInt64, Endian::Little) { var = r.readInt64Little(); }
|
|
__READ_S(atUint64, Endian::Little) { var = r.readUint64Little(); }
|
|
__READ_S(float, Endian::Little) { var = r.readFloatLittle(); }
|
|
__READ_S(double, Endian::Little) { var = r.readDoubleLittle(); }
|
|
__READ_S(atVec2f, Endian::Little) { var = r.readVec2fLittle(); }
|
|
__READ_S(atVec2d, Endian::Little) { var = r.readVec2dLittle(); }
|
|
__READ_S(atVec3f, Endian::Little) { var = r.readVec3fLittle(); }
|
|
__READ_S(atVec3d, Endian::Little) { var = r.readVec3dLittle(); }
|
|
__READ_S(atVec4f, Endian::Little) { var = r.readVec4fLittle(); }
|
|
__READ_S(atVec4d, Endian::Little) { var = r.readVec4dLittle(); }
|
|
__READ_WSTR_S(Endian::Little) { str = r.readWStringLittle(); }
|
|
__READ_WSTRC_S(Endian::Little) { str = r.readWStringLittle(count); }
|
|
|
|
template <PropType PropOp>
|
|
struct Write {
|
|
using PropT = std::conditional_t<PropOp == PropType::CRC64, uint64_t, uint32_t>;
|
|
using StreamT = IStreamWriter;
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_enum_v<T>> Do(const PropId& id, T& var, StreamT& w) {
|
|
if (PropOp != PropType::None) {
|
|
/* Accessed via Enumerate, header */
|
|
if (PropOp == PropType::CRC64)
|
|
__Write64<DNAE>(w, id.crc64);
|
|
else
|
|
__Write32<DNAE>(w, id.rcrc32);
|
|
size_t binarySize = 0;
|
|
BinarySize<PropType::None>::Do<T, DNAE>(id, var, binarySize);
|
|
DNAE == Endian::Big ? w.writeUint16Big(atUint16(binarySize)) : w.writeUint16Little(atUint16(binarySize));
|
|
}
|
|
using PODType = std::underlying_type_t<T>;
|
|
Write<PropType::None>::Do<PODType, DNAE>(id, *reinterpret_cast<PODType*>(&var), w);
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<__IsPODType_v<T>> Do(const PropId& id, T& var, StreamT& w) {
|
|
using CastT = __CastPODType<T>;
|
|
if (PropOp != PropType::None) {
|
|
/* Accessed via Enumerate, header */
|
|
if (PropOp == PropType::CRC64)
|
|
__Write64<DNAE>(w, id.crc64);
|
|
else
|
|
__Write32<DNAE>(w, id.rcrc32);
|
|
size_t binarySize = 0;
|
|
BinarySize<PropType::None>::Do<CastT, DNAE>(id, static_cast<CastT&>(const_cast<std::remove_cv_t<T>&>(var)),
|
|
binarySize);
|
|
__Write16<DNAE>(w, atUint16(binarySize));
|
|
}
|
|
Write<PropType::None>::Do<CastT, DNAE>(id, static_cast<CastT&>(const_cast<std::remove_cv_t<T>&>(var)), w);
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<__IsDNARecord<T>() && PropOp != PropType::None> Do(const PropId& id, T& var, StreamT& w) {
|
|
/* Accessed via Enumerate, header */
|
|
if (PropOp == PropType::CRC64)
|
|
__Write64<T::DNAEndian>(w, id.crc64);
|
|
else
|
|
__Write32<T::DNAEndian>(w, id.rcrc32);
|
|
size_t binarySize = 0;
|
|
var.template Enumerate<BinarySize<PropOp>>(binarySize);
|
|
__Write16<T::DNAEndian>(w, atUint16(binarySize));
|
|
|
|
size_t propCount = 0;
|
|
var.template Enumerate<PropCount<PropOp>>(propCount);
|
|
__Write16<T::DNAEndian>(w, atUint16(propCount));
|
|
var.template Enumerate<Write<PropOp>>(w);
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<__IsDNARecord<T>() && PropOp == PropType::None> Do(const PropId& id, T& var, StreamT& w) {
|
|
var.template Enumerate<Write<PropType::None>>(w);
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_array_v<T>> Do(const PropId& id, T& var, StreamT& s) {
|
|
for (auto& v : var) {
|
|
Write<PropOp>::template Do<std::remove_reference_t<decltype(v)>, DNAE>(id, v, s);
|
|
}
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static void DoSize(const PropId& id, T& var, StreamT& s) {
|
|
Write<PropOp>::template Do<T, DNAE>(id, var, s);
|
|
}
|
|
template <class T, class S, Endian DNAE>
|
|
static std::enable_if_t<!std::is_same_v<T, bool>> Do(const PropId& id, std::vector<T>& vector, const S& count,
|
|
StreamT& w) {
|
|
for (T& v : vector) {
|
|
Write<PropOp>::template Do<T, DNAE>(id, v, w);
|
|
}
|
|
}
|
|
template <class T, class S, Endian DNAE>
|
|
static std::enable_if_t<std::is_same_v<T, bool>> Do(const PropId& id, std::vector<T>& vector, const S& count,
|
|
StreamT& w) {
|
|
/* libc++ specializes vector<bool> as a bitstream */
|
|
for (const T v : vector)
|
|
w.writeBool(v);
|
|
}
|
|
static void Do(const PropId& id, std::unique_ptr<atUint8[]>& buf, size_t count, StreamT& w) {
|
|
if (buf)
|
|
w.writeUBytes(buf.get(), count);
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_same_v<T, std::string>> Do(const PropId& id, std::string& str, StreamT& w) {
|
|
w.writeString(str);
|
|
}
|
|
static void Do(const PropId& id, std::string& str, atInt32 count, StreamT& w) { w.writeString(str, count); }
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_same_v<T, std::wstring>> Do(const PropId& id, std::wstring& str, StreamT& w) {
|
|
Write<PropType::None>::Do<DNAE>(id, str, w);
|
|
}
|
|
template <Endian DNAE>
|
|
static void Do(const PropId& id, std::wstring& str, atInt32 count, StreamT& w) {
|
|
Write<PropType::None>::Do<DNAE>(id, str, count, w);
|
|
}
|
|
static void DoSeek(atInt64 amount, SeekOrigin whence, StreamT& w) { w.seek(amount, whence); }
|
|
static void DoAlign(atInt64 amount, StreamT& w) { w.writeZeroTo((w.position() + amount - 1) / amount * amount); }
|
|
};
|
|
#define __WRITE_S(type, endian) \
|
|
template <> \
|
|
template <> \
|
|
inline void Write<PropType::None>::Do<type, endian>(const PropId& id, type& var, Write::StreamT& w)
|
|
#define __WRITE_WSTR_S(endian) \
|
|
template <> \
|
|
template <> \
|
|
inline void Write<PropType::None>::Do<std::wstring, endian>(const PropId& id, std::wstring& str, Write::StreamT& w)
|
|
#define __WRITE_WSTRC_S(endian) \
|
|
template <> \
|
|
template <> \
|
|
inline void Write<PropType::None>::Do<endian>(const PropId& id, std::wstring& str, atInt32 count, Write::StreamT& w)
|
|
__WRITE_S(bool, Endian::Big) { w.writeBool(var); }
|
|
__WRITE_S(atInt8, Endian::Big) { w.writeByte(var); }
|
|
__WRITE_S(atUint8, Endian::Big) { w.writeUByte(var); }
|
|
__WRITE_S(atInt16, Endian::Big) { w.writeInt16Big(var); }
|
|
__WRITE_S(atUint16, Endian::Big) { w.writeUint16Big(var); }
|
|
__WRITE_S(atInt32, Endian::Big) { w.writeInt32Big(var); }
|
|
__WRITE_S(atUint32, Endian::Big) { w.writeUint32Big(var); }
|
|
__WRITE_S(atInt64, Endian::Big) { w.writeInt64Big(var); }
|
|
__WRITE_S(atUint64, Endian::Big) { w.writeUint64Big(var); }
|
|
__WRITE_S(float, Endian::Big) { w.writeFloatBig(var); }
|
|
__WRITE_S(double, Endian::Big) { w.writeDoubleBig(var); }
|
|
__WRITE_S(atVec2f, Endian::Big) { w.writeVec2fBig(var); }
|
|
__WRITE_S(atVec2d, Endian::Big) { w.writeVec2dBig(var); }
|
|
__WRITE_S(atVec3f, Endian::Big) { w.writeVec3fBig(var); }
|
|
__WRITE_S(atVec3d, Endian::Big) { w.writeVec3dBig(var); }
|
|
__WRITE_S(atVec4f, Endian::Big) { w.writeVec4fBig(var); }
|
|
__WRITE_S(atVec4d, Endian::Big) { w.writeVec4dBig(var); }
|
|
__WRITE_WSTR_S(Endian::Big) { w.writeWStringBig(str); }
|
|
__WRITE_WSTRC_S(Endian::Big) { w.writeWStringBig(str, count); }
|
|
__WRITE_S(bool, Endian::Little) { w.writeBool(var); }
|
|
__WRITE_S(atInt8, Endian::Little) { w.writeByte(var); }
|
|
__WRITE_S(atUint8, Endian::Little) { w.writeUByte(var); }
|
|
__WRITE_S(atInt16, Endian::Little) { w.writeInt16Little(var); }
|
|
__WRITE_S(atUint16, Endian::Little) { w.writeUint16Little(var); }
|
|
__WRITE_S(atInt32, Endian::Little) { w.writeInt32Little(var); }
|
|
__WRITE_S(atUint32, Endian::Little) { w.writeUint32Little(var); }
|
|
__WRITE_S(atInt64, Endian::Little) { w.writeInt64Little(var); }
|
|
__WRITE_S(atUint64, Endian::Little) { w.writeUint64Little(var); }
|
|
__WRITE_S(float, Endian::Little) { w.writeFloatLittle(var); }
|
|
__WRITE_S(double, Endian::Little) { w.writeDoubleLittle(var); }
|
|
__WRITE_S(atVec2f, Endian::Little) { w.writeVec2fLittle(var); }
|
|
__WRITE_S(atVec2d, Endian::Little) { w.writeVec2dLittle(var); }
|
|
__WRITE_S(atVec3f, Endian::Little) { w.writeVec3fLittle(var); }
|
|
__WRITE_S(atVec3d, Endian::Little) { w.writeVec3dLittle(var); }
|
|
__WRITE_S(atVec4f, Endian::Little) { w.writeVec4fLittle(var); }
|
|
__WRITE_S(atVec4d, Endian::Little) { w.writeVec4dLittle(var); }
|
|
__WRITE_WSTR_S(Endian::Little) { w.writeWStringLittle(str); }
|
|
__WRITE_WSTRC_S(Endian::Little) { w.writeWStringLittle(str, count); }
|
|
|
|
template <PropType PropOp>
|
|
struct ReadYaml {
|
|
using PropT = std::conditional_t<PropOp == PropType::CRC64, uint64_t, uint32_t>;
|
|
using StreamT = YAMLDocReader;
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_enum_v<T>> Do(const PropId& id, T& var, StreamT& r) {
|
|
using PODType = std::underlying_type_t<T>;
|
|
ReadYaml<PropType::None>::Do<PODType, DNAE>(id, *reinterpret_cast<PODType*>(&var), r);
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<__IsPODType_v<T>> Do(const PropId& id, T& var, StreamT& r) {
|
|
using CastT = __CastPODType<T>;
|
|
ReadYaml<PropType::None>::Do<CastT, DNAE>(id, static_cast<CastT&>(var), r);
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<__IsDNARecord_v<T>> Do(const PropId& id, T& var, StreamT& r) {
|
|
if (auto rec = r.enterSubRecord(id.name))
|
|
var.template Enumerate<ReadYaml<PropOp>>(r);
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_array_v<T>> Do(const PropId& id, T& var, StreamT& r) {
|
|
size_t _count;
|
|
if (auto __v = r.enterSubVector(id.name, _count)) {
|
|
for (size_t i = 0; i < _count && i < std::extent_v<T>; ++i) {
|
|
ReadYaml<PropOp>::template Do<std::remove_reference_t<decltype(var[i])>, DNAE>({}, var[i], r);
|
|
}
|
|
}
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static void DoSize(const PropId& id, T& var, StreamT& s) {
|
|
/* Squelch size field access */
|
|
}
|
|
template <class T, class S, Endian DNAE>
|
|
static std::enable_if_t<!std::is_same_v<T, bool>> Do(const PropId& id, std::vector<T>& vector, const S& count,
|
|
StreamT& r) {
|
|
size_t _count;
|
|
vector.clear();
|
|
if (auto __v = r.enterSubVector(id.name, _count)) {
|
|
vector.reserve(_count);
|
|
for (size_t i = 0; i < _count; ++i) {
|
|
vector.emplace_back();
|
|
ReadYaml<PropOp>::template Do<T, DNAE>({}, vector.back(), r);
|
|
}
|
|
}
|
|
/* Horrible reference abuse (but it works) */
|
|
const_cast<S&>(count) = vector.size();
|
|
}
|
|
template <class T, class S, Endian DNAE>
|
|
static std::enable_if_t<std::is_same_v<T, bool>> Do(const PropId& id, std::vector<T>& vector, const S& count,
|
|
StreamT& r) {
|
|
/* libc++ specializes vector<bool> as a bitstream */
|
|
size_t _count;
|
|
vector.clear();
|
|
if (auto __v = r.enterSubVector(id.name, _count)) {
|
|
vector.reserve(_count);
|
|
for (size_t i = 0; i < _count; ++i)
|
|
vector.push_back(r.readBool());
|
|
}
|
|
/* Horrible reference abuse (but it works) */
|
|
const_cast<S&>(count) = vector.size();
|
|
}
|
|
static void Do(const PropId& id, std::unique_ptr<atUint8[]>& buf, size_t count, StreamT& r) {
|
|
buf = r.readUBytes(id.name);
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_same_v<T, std::string>> Do(const PropId& id, T& str, StreamT& r) {
|
|
str = r.readString(id.name);
|
|
}
|
|
static void Do(const PropId& id, std::string& str, atInt32 count, StreamT& r) { str = r.readString(id.name); }
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_same_v<T, std::wstring>> Do(const PropId& id, T& str, StreamT& r) {
|
|
str = r.readWString(id.name);
|
|
}
|
|
template <Endian DNAE>
|
|
static void Do(const PropId& id, std::wstring& str, atInt32 count, StreamT& r) {
|
|
str = r.readWString(id.name);
|
|
}
|
|
static void DoSeek(atInt64 amount, SeekOrigin whence, StreamT& r) {}
|
|
static void DoAlign(atInt64 amount, StreamT& r) {}
|
|
};
|
|
#define __READ_YAML_S(type, endian) \
|
|
template <> \
|
|
template <> \
|
|
inline void ReadYaml<PropType::None>::Do<type, endian>(const PropId& id, type& var, ReadYaml::StreamT& r)
|
|
__READ_YAML_S(bool, Endian::Big) { var = r.readBool(id.name); }
|
|
__READ_YAML_S(atInt8, Endian::Big) { var = r.readByte(id.name); }
|
|
__READ_YAML_S(atUint8, Endian::Big) { var = r.readUByte(id.name); }
|
|
__READ_YAML_S(atInt16, Endian::Big) { var = r.readInt16(id.name); }
|
|
__READ_YAML_S(atUint16, Endian::Big) { var = r.readUint16(id.name); }
|
|
__READ_YAML_S(atInt32, Endian::Big) { var = r.readInt32(id.name); }
|
|
__READ_YAML_S(atUint32, Endian::Big) { var = r.readUint32(id.name); }
|
|
__READ_YAML_S(atInt64, Endian::Big) { var = r.readInt64(id.name); }
|
|
__READ_YAML_S(atUint64, Endian::Big) { var = r.readUint64(id.name); }
|
|
__READ_YAML_S(float, Endian::Big) { var = r.readFloat(id.name); }
|
|
__READ_YAML_S(double, Endian::Big) { var = r.readDouble(id.name); }
|
|
__READ_YAML_S(atVec2f, Endian::Big) { var = r.readVec2f(id.name); }
|
|
__READ_YAML_S(atVec2d, Endian::Big) { var = r.readVec2d(id.name); }
|
|
__READ_YAML_S(atVec3f, Endian::Big) { var = r.readVec3f(id.name); }
|
|
__READ_YAML_S(atVec3d, Endian::Big) { var = r.readVec3d(id.name); }
|
|
__READ_YAML_S(atVec4f, Endian::Big) { var = r.readVec4f(id.name); }
|
|
__READ_YAML_S(atVec4d, Endian::Big) { var = r.readVec4d(id.name); }
|
|
__READ_YAML_S(bool, Endian::Little) { var = r.readBool(id.name); }
|
|
__READ_YAML_S(atInt8, Endian::Little) { var = r.readByte(id.name); }
|
|
__READ_YAML_S(atUint8, Endian::Little) { var = r.readUByte(id.name); }
|
|
__READ_YAML_S(atInt16, Endian::Little) { var = r.readInt16(id.name); }
|
|
__READ_YAML_S(atUint16, Endian::Little) { var = r.readUint16(id.name); }
|
|
__READ_YAML_S(atInt32, Endian::Little) { var = r.readInt32(id.name); }
|
|
__READ_YAML_S(atUint32, Endian::Little) { var = r.readUint32(id.name); }
|
|
__READ_YAML_S(atInt64, Endian::Little) { var = r.readInt64(id.name); }
|
|
__READ_YAML_S(atUint64, Endian::Little) { var = r.readUint64(id.name); }
|
|
__READ_YAML_S(float, Endian::Little) { var = r.readFloat(id.name); }
|
|
__READ_YAML_S(double, Endian::Little) { var = r.readDouble(id.name); }
|
|
__READ_YAML_S(atVec2f, Endian::Little) { var = r.readVec2f(id.name); }
|
|
__READ_YAML_S(atVec2d, Endian::Little) { var = r.readVec2d(id.name); }
|
|
__READ_YAML_S(atVec3f, Endian::Little) { var = r.readVec3f(id.name); }
|
|
__READ_YAML_S(atVec3d, Endian::Little) { var = r.readVec3d(id.name); }
|
|
__READ_YAML_S(atVec4f, Endian::Little) { var = r.readVec4f(id.name); }
|
|
__READ_YAML_S(atVec4d, Endian::Little) { var = r.readVec4d(id.name); }
|
|
|
|
template <PropType PropOp>
|
|
struct WriteYaml {
|
|
using PropT = std::conditional_t<PropOp == PropType::CRC64, uint64_t, uint32_t>;
|
|
using StreamT = YAMLDocWriter;
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_enum_v<T>> Do(const PropId& id, T& var, StreamT& w) {
|
|
using PODType = std::underlying_type_t<T>;
|
|
WriteYaml<PropType::None>::Do<PODType, DNAE>(id, *reinterpret_cast<PODType*>(&var), w);
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<__IsPODType_v<T>> Do(const PropId& id, T& var, StreamT& w) {
|
|
using CastT = __CastPODType<T>;
|
|
WriteYaml<PropType::None>::Do<CastT, DNAE>(id, static_cast<CastT&>(const_cast<std::remove_cv_t<T>&>(var)), w);
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<__IsDNARecord_v<T>> Do(const PropId& id, T& var, StreamT& w) {
|
|
if (auto rec = w.enterSubRecord(id.name))
|
|
var.template Enumerate<WriteYaml<PropOp>>(w);
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_array_v<T>> Do(const PropId& id, T& var, StreamT& w) {
|
|
if (auto __v = w.enterSubVector(id.name)) {
|
|
for (auto& v : var) {
|
|
WriteYaml<PropOp>::template Do<std::remove_reference_t<decltype(v)>, DNAE>({}, v, w);
|
|
}
|
|
}
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static void DoSize(const PropId& id, T& var, StreamT& s) {
|
|
/* Squelch size field access */
|
|
}
|
|
template <class T, class S, Endian DNAE>
|
|
static std::enable_if_t<!std::is_same_v<T, bool>> Do(const PropId& id, std::vector<T>& vector, const S& count,
|
|
StreamT& w) {
|
|
if (auto __v = w.enterSubVector(id.name)) {
|
|
for (T& v : vector) {
|
|
WriteYaml<PropOp>::template Do<T, DNAE>(id, v, w);
|
|
}
|
|
}
|
|
}
|
|
template <class T, class S, Endian DNAE>
|
|
static std::enable_if_t<std::is_same_v<T, bool>> Do(const PropId& id, std::vector<T>& vector, const S& count,
|
|
StreamT& w) {
|
|
/* libc++ specializes vector<bool> as a bitstream */
|
|
if (auto __v = w.enterSubVector(id.name))
|
|
for (const T v : vector)
|
|
w.writeBool(v);
|
|
}
|
|
static void Do(const PropId& id, std::unique_ptr<atUint8[]>& buf, size_t count, StreamT& w) {
|
|
w.writeUBytes(id.name, buf, count);
|
|
}
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_same_v<T, std::string>> Do(const PropId& id, T& str, StreamT& w) {
|
|
w.writeString(id.name, str);
|
|
}
|
|
static void Do(const PropId& id, std::string& str, atInt32 count, StreamT& w) { w.writeString(id.name, str); }
|
|
template <class T, Endian DNAE>
|
|
static std::enable_if_t<std::is_same_v<T, std::wstring>> Do(const PropId& id, T& str, StreamT& w) {
|
|
w.writeWString(id.name, str);
|
|
}
|
|
template <Endian DNAE>
|
|
static void Do(const PropId& id, std::wstring& str, atInt32 count, StreamT& w) {
|
|
w.writeWString(id.name, str);
|
|
}
|
|
static void DoSeek(atInt64 amount, SeekOrigin whence, StreamT& w) {}
|
|
static void DoAlign(atInt64 amount, StreamT& w) {}
|
|
};
|
|
#define __WRITE_YAML_S(type, endian) \
|
|
template <> \
|
|
template <> \
|
|
inline void WriteYaml<PropType::None>::Do<type, endian>(const PropId& id, type& var, WriteYaml::StreamT& w)
|
|
__WRITE_YAML_S(bool, Endian::Big) { w.writeBool(id.name, var); }
|
|
__WRITE_YAML_S(atInt8, Endian::Big) { w.writeByte(id.name, var); }
|
|
__WRITE_YAML_S(atUint8, Endian::Big) { w.writeUByte(id.name, var); }
|
|
__WRITE_YAML_S(atInt16, Endian::Big) { w.writeInt16(id.name, var); }
|
|
__WRITE_YAML_S(atUint16, Endian::Big) { w.writeUint16(id.name, var); }
|
|
__WRITE_YAML_S(atInt32, Endian::Big) { w.writeInt32(id.name, var); }
|
|
__WRITE_YAML_S(atUint32, Endian::Big) { w.writeUint32(id.name, var); }
|
|
__WRITE_YAML_S(atInt64, Endian::Big) { w.writeInt64(id.name, var); }
|
|
__WRITE_YAML_S(atUint64, Endian::Big) { w.writeUint64(id.name, var); }
|
|
__WRITE_YAML_S(float, Endian::Big) { w.writeFloat(id.name, var); }
|
|
__WRITE_YAML_S(double, Endian::Big) { w.writeDouble(id.name, var); }
|
|
__WRITE_YAML_S(atVec2f, Endian::Big) { w.writeVec2f(id.name, var); }
|
|
__WRITE_YAML_S(atVec2d, Endian::Big) { w.writeVec2d(id.name, var); }
|
|
__WRITE_YAML_S(atVec3f, Endian::Big) { w.writeVec3f(id.name, var); }
|
|
__WRITE_YAML_S(atVec3d, Endian::Big) { w.writeVec3d(id.name, var); }
|
|
__WRITE_YAML_S(atVec4f, Endian::Big) { w.writeVec4f(id.name, var); }
|
|
__WRITE_YAML_S(atVec4d, Endian::Big) { w.writeVec4d(id.name, var); }
|
|
__WRITE_YAML_S(bool, Endian::Little) { w.writeBool(id.name, var); }
|
|
__WRITE_YAML_S(atInt8, Endian::Little) { w.writeByte(id.name, var); }
|
|
__WRITE_YAML_S(atUint8, Endian::Little) { w.writeUByte(id.name, var); }
|
|
__WRITE_YAML_S(atInt16, Endian::Little) { w.writeInt16(id.name, var); }
|
|
__WRITE_YAML_S(atUint16, Endian::Little) { w.writeUint16(id.name, var); }
|
|
__WRITE_YAML_S(atInt32, Endian::Little) { w.writeInt32(id.name, var); }
|
|
__WRITE_YAML_S(atUint32, Endian::Little) { w.writeUint32(id.name, var); }
|
|
__WRITE_YAML_S(atInt64, Endian::Little) { w.writeInt64(id.name, var); }
|
|
__WRITE_YAML_S(atUint64, Endian::Little) { w.writeUint64(id.name, var); }
|
|
__WRITE_YAML_S(float, Endian::Little) { w.writeFloat(id.name, var); }
|
|
__WRITE_YAML_S(double, Endian::Little) { w.writeDouble(id.name, var); }
|
|
__WRITE_YAML_S(atVec2f, Endian::Little) { w.writeVec2f(id.name, var); }
|
|
__WRITE_YAML_S(atVec2d, Endian::Little) { w.writeVec2d(id.name, var); }
|
|
__WRITE_YAML_S(atVec3f, Endian::Little) { w.writeVec3f(id.name, var); }
|
|
__WRITE_YAML_S(atVec3d, Endian::Little) { w.writeVec3d(id.name, var); }
|
|
__WRITE_YAML_S(atVec4f, Endian::Little) { w.writeVec4f(id.name, var); }
|
|
__WRITE_YAML_S(atVec4d, Endian::Little) { w.writeVec4d(id.name, var); }
|
|
|
|
template <class Op, class T, Endian DNAE>
|
|
void __Do(const PropId& id, T& var, typename Op::StreamT& s) {
|
|
Op::template Do<T, DNAE>(id, var, s);
|
|
}
|
|
|
|
template <class Op, class T, Endian DNAE>
|
|
void __DoSize(const PropId& id, T& var, typename Op::StreamT& s) {
|
|
Op::template DoSize<T, DNAE>(id, var, s);
|
|
}
|
|
|
|
template <class Op, class T, class S, Endian DNAE>
|
|
void __Do(const PropId& id, std::vector<T>& vector, const S& count, typename Op::StreamT& s) {
|
|
Op::template Do<T, S, DNAE>(id, vector, count, s);
|
|
}
|
|
|
|
template <class Op>
|
|
void __Do(const PropId& id, std::unique_ptr<atUint8[]>& buf, size_t count, typename Op::StreamT& s) {
|
|
Op::Do(id, buf, count, s);
|
|
}
|
|
|
|
template <class Op>
|
|
void __Do(const PropId& id, std::string& str, atInt32 count, typename Op::StreamT& s) {
|
|
Op::Do(id, str, count, s);
|
|
}
|
|
|
|
template <class Op, Endian DNAE>
|
|
void __Do(const PropId& id, std::wstring& str, atInt32 count, typename Op::StreamT& s) {
|
|
Op::template Do<DNAE>(id, str, count, s);
|
|
}
|
|
|
|
template <class Op>
|
|
void __DoSeek(atInt64 delta, athena::SeekOrigin whence, typename Op::StreamT& s) {
|
|
Op::DoSeek(delta, whence, s);
|
|
}
|
|
|
|
template <class Op>
|
|
void __DoAlign(atInt64 amount, typename Op::StreamT& s) {
|
|
Op::DoAlign(amount, s);
|
|
}
|
|
|
|
template <class T>
|
|
void __Read(T& obj, athena::io::IStreamReader& r) {
|
|
__Do<Read<PropType::None>, T, T::DNAEndian>({}, obj, r);
|
|
}
|
|
|
|
template <class T>
|
|
void __Write(const T& obj, athena::io::IStreamWriter& w) {
|
|
__Do<Write<PropType::None>, T, T::DNAEndian>({}, const_cast<T&>(obj), w);
|
|
}
|
|
|
|
template <class T>
|
|
void __BinarySize(const T& obj, size_t& s) {
|
|
__Do<BinarySize<PropType::None>, T, T::DNAEndian>({}, const_cast<T&>(obj), s);
|
|
}
|
|
|
|
template <class T>
|
|
void __PropCount(const T& obj, size_t& s) {
|
|
const_cast<T&>(obj).template Enumerate<PropCount<PropType::None>>(s);
|
|
}
|
|
|
|
template <class T>
|
|
void __ReadYaml(T& obj, athena::io::YAMLDocReader& r) {
|
|
obj.template Enumerate<ReadYaml<PropType::None>>(r);
|
|
}
|
|
|
|
template <class T>
|
|
void __WriteYaml(const T& obj, athena::io::YAMLDocWriter& w) {
|
|
const_cast<T&>(obj).template Enumerate<WriteYaml<PropType::None>>(w);
|
|
}
|
|
|
|
template <class T>
|
|
void __ReadProp(T& obj, athena::io::IStreamReader& r) {
|
|
/* Read root 0xffffffff hash (hashed empty string) */
|
|
T::DNAEndian == Endian::Big ? r.readUint32Big() : r.readUint32Little();
|
|
atInt64 size = T::DNAEndian == Endian::Big ? r.readUint16Big() : r.readUint16Little();
|
|
atInt64 start = r.position();
|
|
__Do<Read<PropType::CRC32>, T, T::DNAEndian>({}, obj, r);
|
|
atInt64 actualRead = r.position() - start;
|
|
if (actualRead != size)
|
|
r.seek(size - actualRead);
|
|
}
|
|
|
|
template <class T>
|
|
void __WriteProp(const T& obj, athena::io::IStreamWriter& w) {
|
|
__Do<Write<PropType::CRC32>, T, T::DNAEndian>({}, const_cast<T&>(obj), w);
|
|
}
|
|
|
|
template <class T>
|
|
void __BinarySizeProp(const T& obj, size_t& s) {
|
|
__Do<BinarySize<PropType::CRC32>, T, T::DNAEndian>({}, const_cast<T&>(obj), s);
|
|
}
|
|
|
|
template <class T>
|
|
void __ReadProp64(T& obj, athena::io::IStreamReader& r) {
|
|
/* Read root 0x0 hash (hashed empty string) */
|
|
T::DNAEndian == Endian::Big ? r.readUint64Big() : r.readUint64Little();
|
|
atInt64 size = T::DNAEndian == Endian::Big ? r.readUint16Big() : r.readUint16Little();
|
|
atInt64 start = r.position();
|
|
__Do<Read<PropType::CRC64>, T, T::DNAEndian>({}, obj, r);
|
|
atInt64 actualRead = r.position() - start;
|
|
if (actualRead != size)
|
|
r.seek(size - actualRead);
|
|
}
|
|
|
|
template <class T>
|
|
void __WriteProp64(const T& obj, athena::io::IStreamWriter& w) {
|
|
__Do<Write<PropType::CRC64>, T, T::DNAEndian>({}, const_cast<T&>(obj), w);
|
|
}
|
|
|
|
template <class T>
|
|
void __BinarySizeProp64(const T& obj, size_t& s) {
|
|
__Do<BinarySize<PropType::CRC64>, T, T::DNAEndian>({}, const_cast<T&>(obj), s);
|
|
}
|
|
|
|
} // namespace athena::io
|
|
|
|
#define AT_DECL_DNA_DO \
|
|
template <class Op, athena::Endian DNAE = DNAEndian, class T> \
|
|
void Do(const athena::io::PropId& _id, T& var, typename Op::StreamT& s) { \
|
|
athena::io::__Do<Op, T, DNAE>(_id, var, s); \
|
|
} \
|
|
template <class Op, athena::Endian DNAE = DNAEndian, class T> \
|
|
void DoSize(const athena::io::PropId& _id, T& var, typename Op::StreamT& s) { \
|
|
athena::io::__DoSize<Op, T, DNAE>(_id, var, s); \
|
|
} \
|
|
template <class Op, athena::Endian DNAE = DNAEndian, class T, class S> \
|
|
void Do(const athena::io::PropId& _id, std::vector<T>& var, const S& count, typename Op::StreamT& s) { \
|
|
athena::io::__Do<Op, T, S, DNAE>(_id, var, count, s); \
|
|
} \
|
|
template <class Op> \
|
|
void Do(const athena::io::PropId& _id, std::unique_ptr<atUint8[]>& buf, size_t count, typename Op::StreamT& s) { \
|
|
athena::io::__Do<Op>(_id, buf, count, s); \
|
|
} \
|
|
template <class Op> \
|
|
void Do(const athena::io::PropId& _id, std::string& str, atInt32 count, typename Op::StreamT& s) { \
|
|
athena::io::__Do<Op>(_id, str, count, s); \
|
|
} \
|
|
template <class Op, athena::Endian DNAE = DNAEndian> \
|
|
void Do(const athena::io::PropId& _id, std::wstring& str, atInt32 count, typename Op::StreamT& s) { \
|
|
athena::io::__Do<Op, DNAE>(_id, str, count, s); \
|
|
} \
|
|
template <class Op> \
|
|
void DoSeek(atInt64 delta, athena::SeekOrigin whence, typename Op::StreamT& s) { \
|
|
athena::io::__DoSeek<Op>(delta, whence, s); \
|
|
} \
|
|
template <class Op> \
|
|
void DoAlign(atInt64 amount, typename Op::StreamT& s) { \
|
|
athena::io::__DoAlign<Op>(amount, s); \
|
|
} \
|
|
template <class Op> \
|
|
void Enumerate(typename Op::StreamT& s); \
|
|
static std::string_view DNAType();
|
|
|
|
#define AT_DECL_DNA \
|
|
AT_DECL_DNA_DO \
|
|
void read(athena::io::IStreamReader& r) { athena::io::__Read(*this, r); } \
|
|
void write(athena::io::IStreamWriter& w) const { athena::io::__Write(*this, w); } \
|
|
void binarySize(size_t& s) const { athena::io::__BinarySize(*this, s); }
|
|
|
|
#define AT_DECL_DNA_YAML \
|
|
AT_DECL_DNA \
|
|
void read(athena::io::YAMLDocReader& r) { athena::io::__ReadYaml(*this, r); } \
|
|
void write(athena::io::YAMLDocWriter& w) const { athena::io::__WriteYaml(*this, w); }
|
|
|
|
#define AT_DECL_EXPLICIT_DNA \
|
|
AT_DECL_DNA \
|
|
Delete __d;
|
|
|
|
#define AT_DECL_EXPLICIT_DNAV \
|
|
AT_DECL_DNAV \
|
|
Delete __d;
|
|
|
|
#define AT_DECL_EXPLICIT_DNAV_NO_TYPE \
|
|
AT_DECL_DNAV_NO_TYPE \
|
|
Delete __d;
|
|
|
|
#define AT_DECL_EXPLICIT_DNA_YAML \
|
|
AT_DECL_DNA_YAML \
|
|
Delete __d;
|
|
|
|
#define AT_DECL_EXPLICIT_DNA_YAMLV \
|
|
AT_DECL_DNA_YAMLV \
|
|
Delete __d;
|
|
|
|
#define AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE \
|
|
AT_DECL_DNA_YAMLV_NO_TYPE \
|
|
Delete __d;
|
|
#define AT_DECL_DNAV \
|
|
AT_DECL_DNA_DO \
|
|
void read(athena::io::IStreamReader& r) override { athena::io::__Read(*this, r); } \
|
|
void write(athena::io::IStreamWriter& w) const override { athena::io::__Write(*this, w); } \
|
|
void binarySize(size_t& s) const override { athena::io::__BinarySize(*this, s); } \
|
|
std::string_view DNATypeV() const override { return DNAType(); }
|
|
|
|
#define AT_DECL_DNAV_NO_TYPE \
|
|
AT_DECL_DNA_DO \
|
|
void read(athena::io::IStreamReader& r) override { athena::io::__Read(*this, r); } \
|
|
void write(athena::io::IStreamWriter& w) const override { athena::io::__Write(*this, w); } \
|
|
void binarySize(size_t& s) const override { athena::io::__BinarySize(*this, s); }
|
|
|
|
#define AT_DECL_DNA_YAMLV \
|
|
AT_DECL_DNAV \
|
|
void read(athena::io::YAMLDocReader& r) override { athena::io::__ReadYaml(*this, r); } \
|
|
void write(athena::io::YAMLDocWriter& w) const override { athena::io::__WriteYaml(*this, w); }
|
|
|
|
#define AT_DECL_DNA_YAMLV_NO_TYPE \
|
|
AT_DECL_DNAV_NO_TYPE \
|
|
void read(athena::io::YAMLDocReader& r) override { athena::io::__ReadYaml(*this, r); } \
|
|
void write(athena::io::YAMLDocWriter& w) const override { athena::io::__WriteYaml(*this, w); }
|
|
|
|
#define AT_SPECIALIZE_DNA(...) \
|
|
template void __VA_ARGS__::Enumerate<athena::io::Read<athena::io::PropType::None>>( \
|
|
athena::io::Read<athena::io::PropType::None>::StreamT & s); \
|
|
template void __VA_ARGS__::Enumerate<athena::io::Write<athena::io::PropType::None>>( \
|
|
athena::io::Write<athena::io::PropType::None>::StreamT & s); \
|
|
template void __VA_ARGS__::Enumerate<athena::io::BinarySize<athena::io::PropType::None>>( \
|
|
athena::io::BinarySize<athena::io::PropType::None>::StreamT & s);
|
|
|
|
#define AT_SPECIALIZE_DNA_YAML(...) \
|
|
AT_SPECIALIZE_DNA(__VA_ARGS__) \
|
|
template void __VA_ARGS__::Enumerate<athena::io::ReadYaml<athena::io::PropType::None>>( \
|
|
athena::io::ReadYaml<athena::io::PropType::None>::StreamT & s); \
|
|
template void __VA_ARGS__::Enumerate<athena::io::WriteYaml<athena::io::PropType::None>>( \
|
|
athena::io::WriteYaml<athena::io::PropType::None>::StreamT & s);
|
|
|
|
#define AT_DECL_PROPDNA \
|
|
template <class Op, athena::Endian DNAE = DNAEndian, class T> \
|
|
void Do(const athena::io::PropId& _id, T& var, typename Op::StreamT& s) { \
|
|
athena::io::__Do<Op, T, DNAE>(_id, var, s); \
|
|
} \
|
|
template <class Op, athena::Endian DNAE = DNAEndian, class T> \
|
|
void DoSize(const athena::io::PropId& _id, T& var, typename Op::StreamT& s) { \
|
|
athena::io::__DoSize<Op, T, DNAE>(_id, var, s); \
|
|
} \
|
|
template <class Op, athena::Endian DNAE = DNAEndian, class T, class S> \
|
|
void Do(const athena::io::PropId& _id, std::vector<T>& var, const S& count, typename Op::StreamT& s) { \
|
|
athena::io::__Do<Op, T, S, DNAE>(_id, var, count, s); \
|
|
} \
|
|
template <class Op> \
|
|
void Do(const athena::io::PropId& _id, std::unique_ptr<atUint8[]>& buf, size_t count, typename Op::StreamT& s) { \
|
|
athena::io::__Do<Op>(_id, buf, count, s); \
|
|
} \
|
|
template <class Op> \
|
|
void Do(const athena::io::PropId& _id, std::string& str, atInt32 count, typename Op::StreamT& s) { \
|
|
athena::io::__Do<Op>(_id, str, count, s); \
|
|
} \
|
|
template <class Op, athena::Endian DNAE = DNAEndian> \
|
|
void Do(const athena::io::PropId& _id, std::wstring& str, atInt32 count, typename Op::StreamT& s) { \
|
|
athena::io::__Do<Op, DNAE>(_id, str, count, s); \
|
|
} \
|
|
template <class Op> \
|
|
void DoSeek(atInt64 delta, athena::SeekOrigin whence, typename Op::StreamT& s) { \
|
|
athena::io::__DoSeek<Op>(delta, whence, s); \
|
|
} \
|
|
template <class Op> \
|
|
void DoAlign(atInt64 amount, typename Op::StreamT& s) { \
|
|
athena::io::__DoAlign<Op>(amount, s); \
|
|
} \
|
|
template <class Op> \
|
|
void Enumerate(typename Op::StreamT& s); \
|
|
template <class Op> \
|
|
bool Lookup(uint64_t hash, typename Op::StreamT& s); \
|
|
static std::string_view DNAType(); \
|
|
void read(athena::io::IStreamReader& r) { athena::io::__Read(*this, r); } \
|
|
void write(athena::io::IStreamWriter& w) const { athena::io::__Write(*this, w); } \
|
|
void binarySize(size_t& s) const { athena::io::__BinarySize(*this, s); } \
|
|
void read(athena::io::YAMLDocReader& r) { athena::io::__ReadYaml(*this, r); } \
|
|
void write(athena::io::YAMLDocWriter& w) const { athena::io::__WriteYaml(*this, w); } \
|
|
void readProp(athena::io::IStreamReader& r) { athena::io::__ReadProp(*this, r); } \
|
|
void writeProp(athena::io::IStreamWriter& w) const { athena::io::__WriteProp(*this, w); } \
|
|
void binarySizeProp(size_t& s) const { athena::io::__BinarySizeProp(*this, s); } \
|
|
void propCount(size_t& s) const { athena::io::__PropCount(*this, s); } \
|
|
void readProp64(athena::io::IStreamReader& r) { athena::io::__ReadProp64(*this, r); } \
|
|
void writeProp64(athena::io::IStreamWriter& w) const { athena::io::__WriteProp64(*this, w); } \
|
|
void binarySizeProp64(size_t& s) const { athena::io::__BinarySizeProp64(*this, s); }
|
|
|
|
#define AT_DECL_EXPLICIT_PROPDNA \
|
|
AT_DECL_PROPDNA \
|
|
Delete __d;
|
|
|
|
#define AT_SPECIALIZE_PROPDNA(...) \
|
|
template void __VA_ARGS__::Enumerate<athena::io::Read<athena::io::PropType::None>>( \
|
|
athena::io::Read<athena::io::PropType::None>::StreamT & s); \
|
|
template void __VA_ARGS__::Enumerate<athena::io::Write<athena::io::PropType::None>>( \
|
|
athena::io::Write<athena::io::PropType::None>::StreamT & s); \
|
|
template void __VA_ARGS__::Enumerate<athena::io::BinarySize<athena::io::PropType::None>>( \
|
|
athena::io::BinarySize<athena::io::PropType::None>::StreamT & s); \
|
|
template void __VA_ARGS__::Enumerate<athena::io::ReadYaml<athena::io::PropType::None>>( \
|
|
athena::io::ReadYaml<athena::io::PropType::None>::StreamT & s); \
|
|
template void __VA_ARGS__::Enumerate<athena::io::WriteYaml<athena::io::PropType::None>>( \
|
|
athena::io::WriteYaml<athena::io::PropType::None>::StreamT & s); \
|
|
template bool __VA_ARGS__::Lookup<athena::io::Read<athena::io::PropType::CRC32>>( \
|
|
uint64_t hash, athena::io::Read<athena::io::PropType::CRC32>::StreamT & s); \
|
|
template void __VA_ARGS__::Enumerate<athena::io::Read<athena::io::PropType::CRC32>>( \
|
|
athena::io::Read<athena::io::PropType::CRC32>::StreamT & s); \
|
|
template bool __VA_ARGS__::Lookup<athena::io::Write<athena::io::PropType::CRC32>>( \
|
|
uint64_t hash, athena::io::Write<athena::io::PropType::CRC32>::StreamT & s); \
|
|
template void __VA_ARGS__::Enumerate<athena::io::Write<athena::io::PropType::CRC32>>( \
|
|
athena::io::Write<athena::io::PropType::CRC32>::StreamT & s); \
|
|
template bool __VA_ARGS__::Lookup<athena::io::BinarySize<athena::io::PropType::CRC32>>( \
|
|
uint64_t hash, athena::io::BinarySize<athena::io::PropType::CRC32>::StreamT & s); \
|
|
template void __VA_ARGS__::Enumerate<athena::io::BinarySize<athena::io::PropType::CRC32>>( \
|
|
athena::io::BinarySize<athena::io::PropType::CRC32>::StreamT & s); \
|
|
template bool __VA_ARGS__::Lookup<athena::io::PropCount<athena::io::PropType::CRC32>>( \
|
|
uint64_t hash, athena::io::PropCount<athena::io::PropType::CRC32>::StreamT & s); \
|
|
template void __VA_ARGS__::Enumerate<athena::io::PropCount<athena::io::PropType::CRC32>>( \
|
|
athena::io::PropCount<athena::io::PropType::CRC32>::StreamT & s); \
|
|
template bool __VA_ARGS__::Lookup<athena::io::ReadYaml<athena::io::PropType::CRC32>>( \
|
|
uint64_t hash, athena::io::ReadYaml<athena::io::PropType::CRC32>::StreamT & s); \
|
|
template void __VA_ARGS__::Enumerate<athena::io::ReadYaml<athena::io::PropType::CRC32>>( \
|
|
athena::io::ReadYaml<athena::io::PropType::CRC32>::StreamT & s); \
|
|
template bool __VA_ARGS__::Lookup<athena::io::WriteYaml<athena::io::PropType::CRC32>>( \
|
|
uint64_t hash, athena::io::WriteYaml<athena::io::PropType::CRC32>::StreamT & s); \
|
|
template void __VA_ARGS__::Enumerate<athena::io::WriteYaml<athena::io::PropType::CRC32>>( \
|
|
athena::io::WriteYaml<athena::io::PropType::CRC32>::StreamT & s); \
|
|
template bool __VA_ARGS__::Lookup<athena::io::Read<athena::io::PropType::CRC64>>( \
|
|
uint64_t hash, athena::io::Read<athena::io::PropType::CRC64>::StreamT & s); \
|
|
template void __VA_ARGS__::Enumerate<athena::io::Read<athena::io::PropType::CRC64>>( \
|
|
athena::io::Read<athena::io::PropType::CRC64>::StreamT & s); \
|
|
template bool __VA_ARGS__::Lookup<athena::io::Write<athena::io::PropType::CRC64>>( \
|
|
uint64_t hash, athena::io::Write<athena::io::PropType::CRC64>::StreamT & s); \
|
|
template void __VA_ARGS__::Enumerate<athena::io::Write<athena::io::PropType::CRC64>>( \
|
|
athena::io::Write<athena::io::PropType::CRC64>::StreamT & s); \
|
|
template bool __VA_ARGS__::Lookup<athena::io::BinarySize<athena::io::PropType::CRC64>>( \
|
|
uint64_t hash, athena::io::BinarySize<athena::io::PropType::CRC64>::StreamT & s); \
|
|
template void __VA_ARGS__::Enumerate<athena::io::BinarySize<athena::io::PropType::CRC64>>( \
|
|
athena::io::BinarySize<athena::io::PropType::CRC64>::StreamT & s); \
|
|
template bool __VA_ARGS__::Lookup<athena::io::PropCount<athena::io::PropType::CRC64>>( \
|
|
uint64_t hash, athena::io::PropCount<athena::io::PropType::CRC64>::StreamT & s); \
|
|
template void __VA_ARGS__::Enumerate<athena::io::PropCount<athena::io::PropType::CRC64>>( \
|
|
athena::io::PropCount<athena::io::PropType::CRC64>::StreamT & s); \
|
|
template bool __VA_ARGS__::Lookup<athena::io::ReadYaml<athena::io::PropType::CRC64>>( \
|
|
uint64_t hash, athena::io::ReadYaml<athena::io::PropType::CRC64>::StreamT & s); \
|
|
template void __VA_ARGS__::Enumerate<athena::io::ReadYaml<athena::io::PropType::CRC64>>( \
|
|
athena::io::ReadYaml<athena::io::PropType::CRC64>::StreamT & s); \
|
|
template bool __VA_ARGS__::Lookup<athena::io::WriteYaml<athena::io::PropType::CRC64>>( \
|
|
uint64_t hash, athena::io::WriteYaml<athena::io::PropType::CRC64>::StreamT & s); \
|
|
template void __VA_ARGS__::Enumerate<athena::io::WriteYaml<athena::io::PropType::CRC64>>( \
|
|
athena::io::WriteYaml<athena::io::PropType::CRC64>::StreamT & s);
|
|
|
|
#define AT_SUBDECL_DNA \
|
|
void _read(athena::io::IStreamReader& r); \
|
|
void _write(athena::io::IStreamWriter& w) const; \
|
|
void _binarySize(size_t& s) const; \
|
|
void _read(athena::io::YAMLDocReader& r); \
|
|
void _write(athena::io::YAMLDocWriter& w) const;
|
|
|
|
#define AT_SUBDECL_DNA_YAML \
|
|
AT_SUBDECL_DNA \
|
|
void _read(athena::io::YAMLDocReader& r); \
|
|
void _write(athena::io::YAMLDocWriter& w) const;
|
|
|
|
#define AT_SUBSPECIALIZE_DNA(...) \
|
|
template <> \
|
|
template <> \
|
|
void __VA_ARGS__::Enumerate<athena::io::DNA<athena::Endian::Big>::BinarySize>(typename BinarySize::StreamT & s) { \
|
|
_binarySize(s); \
|
|
} \
|
|
template <> \
|
|
template <> \
|
|
void __VA_ARGS__::Enumerate<athena::io::DNA<athena::Endian::Big>::Read>(typename Read::StreamT & r) { \
|
|
_read(r); \
|
|
} \
|
|
template <> \
|
|
template <> \
|
|
void __VA_ARGS__::Enumerate<athena::io::DNA<athena::Endian::Big>::Write>(typename Write::StreamT & w) { \
|
|
_write(w); \
|
|
}
|
|
|
|
#define AT_SUBSPECIALIZE_DNA_YAML(...) \
|
|
template <> \
|
|
template <> \
|
|
void __VA_ARGS__::Enumerate<athena::io::DNA<athena::Endian::Big>::ReadYaml>(typename ReadYaml::StreamT & r) { \
|
|
_read(r); \
|
|
} \
|
|
template <> \
|
|
template <> \
|
|
void __VA_ARGS__::Enumerate<athena::io::DNA<athena::Endian::Big>::WriteYaml>(typename WriteYaml::StreamT & w) { \
|
|
_write(w); \
|
|
} \
|
|
AT_SUBSPECIALIZE_DNA(__VA_ARGS__)
|