wowlib 0.0.0
Read & write World of Warcraft client files — a C++26 core
Loading...
Searching...
No Matches
wowlib::formats::m2::M2OffsetBlock< Derived > Struct Template Reference

The serialization face of an offset block, mixed in CRTP-style: an entity struct E : M2OffsetBlock<E> gains read()/write() plus the imageSize() and memberOffset() layout queries. More...

#include <wowlib/formats/m2/offset_block.hpp>

Inheritance diagram for wowlib::formats::m2::M2OffsetBlock< Derived >:

Classes

struct  M2ArrayRef
 The on-disk shape of an offset-array reference: element count and the byte offset of the data block, relative to the entity image base. More...

Public Member Functions

Result< void > read (std::span< const std::byte > data)
 Deserialize file bytes into this entity, replacing its contents.
Result< void > read (std::span< const std::byte > data, const OffsetReadContext &ctx)
 Deserialize data with external sequence data resolved through ctx (the M2 .anim baking path).
Result< FileBuffer > write () const
 Serialize this entity in wowlib's canonical layout (an offset format has no byte-perfect round-trip guarantee; a written entity re-reads equal instead).
Result< FileBuffer > write (const OffsetWriteContext &ctx) const
 Serialize with external sequence data routed through ctx (the M2 .anim splitting path).
Result< void > write (FileBuffer &out) const
 Append this entity's serialized image to out (the chunk serializer's SelfSerializing write hook — offsets are relative to the start of the appended image).
bool empty () const
 Never empty: an offset block always has a header image worth writing (the SelfSerializing engagement hook — an MD21-style carrier chunk is always emitted).
ValidationReport validate () const
Result< void > ensureValid () const
 Validate and raise on the first error instead of returning a report — the assert-style face of validate().
std::size_t imageSize () const
 The entity's image footprint in bytes for Derived's version: every version-active member's layoutSize, plus any engaged gatedBy member.
bool operator== (const M2OffsetBlock &) const =default
Public Member Functions inherited from wowlib::formats::m2::M2OffsetBase
bool operator== (const M2OffsetBase &) const =default

Static Public Member Functions

static consteval std::size_t memberOffset (std::string_view name)
 The positional byte offset of member name within this entity's image, for Derived's version: the version-active members' layoutSize summed in layout order up to (not including) name.

Static Protected Member Functions

static consteval std::optional< formats::detail::OffsetAfterSpec > _offsetAnchorOf (std::meta::info member)
 The first offsetAfter positional anchor on member, or nullopt.
template<typename T>
static consteval auto _memberOrder ()
 The member indices (into membersOf<T>) in positional (layout) order: T's OWN members in declaration order, each followed by the trait-base members anchored to it with =offsetAfter("name").
template<std::meta::info Mem, typename T>
static bool _memberPresent (const T &rec)
 Whether member Mem occupies bytes in this instance of rec: always, unless it is gatedBy(mask) and none of those globalFlags bits are set.
template<bool IsSequenceData, typename T>
static bool _resolvesExternally (const T &rec)
 Whether a SequenceData member of rec resolves its per-element data through the external I/O context on this call.
template<typename T>
static Result< void > _readMembers (T &dst, const std::span< const std::byte > image, std::size_t &cursor, const std::span< const std::byte > base, const OffsetReadContext &ctx)
 Read every version-active member of record/entity dst from image at cursor, in layout order (own declaration order with trait members spliced at their offsetAfter anchors).
template<typename M>
static Result< void > _readMember (M &dst, const std::span< const std::byte > image, std::size_t &cursor, const std::span< const std::byte > base, const OffsetReadContext &ctx, const bool external, const std::string_view what)
 Read one member dst — an array/string reference, an inline sub-record, or an inline scalar — advancing cursor over its in-image bytes.
template<typename M>
static Result< void > _readScalar (M &dst, const std::span< const std::byte > image, std::size_t &cursor, const std::string_view what)
 Read a trivially-copyable scalar dst from image at cursor.
static Result< void > _readArrayRef (M2ArrayRef &ref, const std::span< const std::byte > image, std::size_t &cursor, const std::string_view what)
 Read and bounds-check the 8-byte M2Array{count, offset} slot at cursor into ref, advancing cursor past it.
template<typename M>
static Result< void > _readArrayMember (M &dst, const std::span< const std::byte > image, std::size_t &cursor, const std::span< const std::byte > base, const OffsetReadContext &ctx, const bool external, const std::string_view what)
 Read an M2Array-referenced member: take its slot, then decode the data block as a string or a vector.
static Result< void > _readStringBlock (std::string &dst, const M2ArrayRef ref, const std::span< const std::byte > base, const std::string_view what)
 Decode a string data block referenced by ref out of base.
template<typename M>
static Result< void > _readVectorBlock (M &dst, const M2ArrayRef ref, const std::span< const std::byte > base, const OffsetReadContext &ctx, const bool external, const std::string_view what)
 Decode a vector data block referenced by ref out of base: ref.count element images of layoutSize<U> bytes.
template<typename M>
static Result< void > _readArrayElements (M &dst, const M2ArrayRef ref, const std::span< const std::byte > base, const OffsetReadContext &ctx, const bool external, const std::string_view what)
 Read the non-trivial elements of dst, each from its own element image inside base.
static void _putBytes (FileBuffer &image, const std::size_t imagePos, std::size_t &cursor, const void *bytes, const std::size_t n)
 Write n raw bytes into image at imagePos + cursor, advancing the cursor.
static std::size_t _allocBlock (FileBuffer &target, const std::size_t bytes)
 Reserve bytes at the (16-byte aligned, zero-filled) end of target and return the start index.
static Result< void > _writeImage (const Derived &self, FileBuffer &out, const OffsetWriteContext &ctx)
 Serialize self in canonical layout — the image first (pre-sized to imageSize()), then data blocks depth-first via _writeMembers — and append the result to out.
template<typename T>
static Result< void > _writeMembers (const T &src, FileBuffer &image, const std::size_t imagePos, std::size_t &cursor, FileBuffer &blocks, const OffsetWriteContext &ctx)
 Write every version-active member of record/entity src into image at imagePos + cursor, in layout order; data blocks append to blocks.
template<typename M>
static Result< void > _writeMember (const M &src, FileBuffer &image, const std::size_t imagePos, std::size_t &cursor, FileBuffer &blocks, const OffsetWriteContext &ctx, const bool external, const std::string_view what)
 Write one member src — an array/string reference, an inline sub-record, or an inline scalar — advancing cursor over its in-image bytes.
template<typename M>
static Result< void > _writeArrayMember (const M &src, FileBuffer &image, const std::size_t imagePos, std::size_t &cursor, FileBuffer &blocks, const OffsetWriteContext &ctx, const bool external, const std::string_view what)
 Write an M2Array-referenced member: allocate its data block, fill it, and emit the {count, offset} slot.
static Result< void > _writeStringBlock (const std::string &src, FileBuffer &image, const std::size_t imagePos, std::size_t &cursor, FileBuffer &blocks)
 Emit src as an M2Array<char> whose count includes the NUL terminator — the client reads these as buffer sizes and requires the terminator inside, so even the empty string writes {1, block}, never {0, 0}.
template<typename M>
static Result< void > _writeVectorBlock (const M &src, FileBuffer &image, const std::size_t imagePos, std::size_t &cursor, FileBuffer &blocks, const OffsetWriteContext &ctx, const bool external, const std::string_view what)
 Emit src as an M2Array: an empty vector writes {0, 0}; otherwise a count * layoutSize<U> element block is reserved, filled (bulk memcpy for trivially-copyable elements, else _writeArrayElements), and the slot emitted.
template<typename M>
static Result< void > _writeArrayElements (const M &src, const std::size_t blockAt, FileBuffer &blocks, const OffsetWriteContext &ctx, const bool external, const std::string_view what)
 Write the non-trivial elements of src into the block already reserved at blockAt in blocks.
static std::unexpected< Error > _offsetError (const ErrorCode code, const std::string_view member, const std::string_view what)
 Build an offset-scoped error naming the offending member.

Detailed Description

template<typename Derived>
struct wowlib::formats::m2::M2OffsetBlock< Derived >

The serialization face of an offset block, mixed in CRTP-style: an entity struct E : M2OffsetBlock<E> gains read()/write() plus the imageSize() and memberOffset() layout queries.

The whole read/write engine lives here as protected member functions — encapsulated with the type it serves rather than scattered through a detail namespace.

The read(span) / write(FileBuffer&) / empty() trio deliberately matches the chunk framework's SelfSerializing concept, so an offset block can sit directly behind a chunk member (the Legion+ MD21 chunk carries the whole MD20 image as its payload).

Template Parameters
Derivedthe entity itself (the CRTP pattern); it must declare a static constexpr ClientVersion version.

Definition at line 165 of file offset_block.hpp.

Member Function Documentation

◆ _allocBlock()

template<typename Derived>
std::size_t wowlib::formats::m2::M2OffsetBlock< Derived >::_allocBlock ( FileBuffer & target,
const std::size_t bytes )
inlinestaticprotected

Reserve bytes at the (16-byte aligned, zero-filled) end of target and return the start index.

Blizzard aligns every data block to 16 bytes; an index (not a pointer) is returned because the buffer reallocates as it grows.

Parameters
targetthe buffer to grow.
bytesthe block size to reserve.
Returns
the byte index of the reserved block.

Definition at line 636 of file offset_block.hpp.

Referenced by _writeStringBlock(), and _writeVectorBlock().

◆ _memberOrder()

template<typename Derived>
template<typename T>
consteval auto wowlib::formats::m2::M2OffsetBlock< Derived >::_memberOrder ( )
inlinestaticconstevalprotected

The member indices (into membersOf<T>) in positional (layout) order: T's OWN members in declaration order, each followed by the trait-base members anchored to it with =offsetAfter("name").

A member flattened in from a (conditionally-inherited version-trait) base cannot keep its flatten position — bases flatten by-base, never the interleaved layout order — so each names the own member it follows and is spliced right after it (several members on one anchor keep their flatten order; in practice they are mutually exclusive version twins). Consteval-checked both ways: a trait-base member without an anchor, and an anchor naming no own member, are errors.

Template Parameters
Tthe record/entity type to order.
Returns
a static array of member indices in layout order.
Exceptions
(consteval)if a trait member lacks an anchor, or an anchor is unmatched.

Definition at line 329 of file offset_block.hpp.

References _offsetAnchorOf(), and wowlib::formats::detail::membersOf().

Referenced by _readMembers(), _writeMembers(), and memberOffset().

◆ _memberPresent()

template<typename Derived>
template<std::meta::info Mem, typename T>
bool wowlib::formats::m2::M2OffsetBlock< Derived >::_memberPresent ( const T & rec)
inlinestaticprotected

Whether member Mem occupies bytes in this instance of rec: always, unless it is gatedBy(mask) and none of those globalFlags bits are set.

Shared by read, write and imageSize so the gate has one definition.

Template Parameters
Memthe reflected member.
Tthe containing record/entity type.
Parameters
recthe record instance whose globalFlags gate the member.
Returns
true when the member occupies bytes in the layout.

Definition at line 364 of file offset_block.hpp.

References wowlib::formats::detail::annotation().

Referenced by _readMembers(), _writeMembers(), and imageSize().

◆ _offsetAnchorOf()

template<typename Derived>
consteval std::optional< formats::detail::OffsetAfterSpec > wowlib::formats::m2::M2OffsetBlock< Derived >::_offsetAnchorOf ( std::meta::info member)
inlinestaticconstevalprotected

The first offsetAfter positional anchor on member, or nullopt.

Parameters
memberthe reflected member to inspect.
Returns
the anchor spec, or nullopt when the member carries none.

Definition at line 308 of file offset_block.hpp.

Referenced by _memberOrder().

◆ _offsetError()

template<typename Derived>
std::unexpected< Error > wowlib::formats::m2::M2OffsetBlock< Derived >::_offsetError ( const ErrorCode code,
const std::string_view member,
const std::string_view what )
inlinestaticprotected

Build an offset-scoped error naming the offending member.

Parameters
codethe error category (typically OffsetOutOfBounds).
memberthe entity member being transferred.
whatthe failure description.
Returns
the error, ready to return from a Result function.

Definition at line 853 of file offset_block.hpp.

References wowlib::makeError().

Referenced by _readArrayRef(), _readScalar(), _readStringBlock(), and _readVectorBlock().

◆ _putBytes()

template<typename Derived>
void wowlib::formats::m2::M2OffsetBlock< Derived >::_putBytes ( FileBuffer & image,
const std::size_t imagePos,
std::size_t & cursor,
const void * bytes,
const std::size_t n )
inlinestaticprotected

Write n raw bytes into image at imagePos + cursor, advancing the cursor.

The image is pre-sized to the entity footprint, so this write stays within bounds.

Parameters
imagethe pre-sized image buffer.
imagePosthe base offset of the record being written within image.
cursorthe position within the record; advanced by n.
bytesthe source bytes.
nthe byte count.

Definition at line 619 of file offset_block.hpp.

Referenced by _writeMember(), _writeStringBlock(), and _writeVectorBlock().

◆ _readArrayElements()

template<typename Derived>
template<typename M>
Result< void > wowlib::formats::m2::M2OffsetBlock< Derived >::_readArrayElements ( M & dst,
const M2ArrayRef ref,
const std::span< const std::byte > base,
const OffsetReadContext & ctx,
const bool external,
const std::string_view what )
inlinestaticprotected

Read the non-trivial elements of dst, each from its own element image inside base.

For an externally-resolved SequenceData array, element i reads its nested blocks from ctx.sequenceBase(i) (the matching .anim bytes) instead of base.

Template Parameters
Mthe vector type (already sized to the element count).
Parameters
dstthe destination vector, pre-resized.
refthe {count, offset} slot locating the element images.
basethe buffer the element images live in.
ctxper-sequence base resolution.
externalwhether this is an externally-resolved sequence array.
whatthe member name, for diagnostics.
Returns
nothing, or the first structural error.

Definition at line 592 of file offset_block.hpp.

References _readMember(), wowlib::formats::m2::layoutSize(), wowlib::formats::m2::M2OffsetBlock< Derived >::M2ArrayRef::offset, and wowlib::formats::m2::OffsetReadContext::sequenceBase.

Referenced by _readVectorBlock().

◆ _readArrayMember()

template<typename Derived>
template<typename M>
Result< void > wowlib::formats::m2::M2OffsetBlock< Derived >::_readArrayMember ( M & dst,
const std::span< const std::byte > image,
std::size_t & cursor,
const std::span< const std::byte > base,
const OffsetReadContext & ctx,
const bool external,
const std::string_view what )
inlinestaticprotected

Read an M2Array-referenced member: take its slot, then decode the data block as a string or a vector.

Template Parameters
Mthe member type (std::string or std::vector).
Parameters
dst the destination member.
image the inline image bytes.
cursor the read position; advanced past the slot.
base the buffer the slot offset resolves against.
ctx per-sequence base resolution.
externalset for an externally-resolved SequenceData array.
what the member name, for diagnostics.
Returns
nothing, or the first structural error.

Definition at line 503 of file offset_block.hpp.

References _readArrayRef(), _readStringBlock(), and _readVectorBlock().

Referenced by _readMember().

◆ _readArrayRef()

template<typename Derived>
Result< void > wowlib::formats::m2::M2OffsetBlock< Derived >::_readArrayRef ( M2ArrayRef & ref,
const std::span< const std::byte > image,
std::size_t & cursor,
const std::string_view what )
inlinestaticprotected

Read and bounds-check the 8-byte M2Array{count, offset} slot at cursor into ref, advancing cursor past it.

Parameters
refthe destination reference.
imagethe inline image bytes.
cursorthe read position; advanced by 8.
whatthe member name, for diagnostics.
Returns
nothing, or OffsetOutOfBounds if the slot overruns image.

Definition at line 480 of file offset_block.hpp.

References _offsetError(), and wowlib::OffsetOutOfBounds.

Referenced by _readArrayMember().

◆ _readMember()

template<typename Derived>
template<typename M>
Result< void > wowlib::formats::m2::M2OffsetBlock< Derived >::_readMember ( M & dst,
const std::span< const std::byte > image,
std::size_t & cursor,
const std::span< const std::byte > base,
const OffsetReadContext & ctx,
const bool external,
const std::string_view what )
inlinestaticprotected

Read one member dst — an array/string reference, an inline sub-record, or an inline scalar — advancing cursor over its in-image bytes.

Template Parameters
Mthe member type; the concept it satisfies picks the branch.
Parameters
dstthe destination member.
imagethe inline image bytes.
cursorthe read position within image; advanced.
basethe buffer array/string offsets resolve against.
ctxper-sequence base resolution.
externalset only for a SequenceData array resolving through ctx.
whatthe member name, for diagnostics.
Returns
nothing, or the first structural error.

Definition at line 437 of file offset_block.hpp.

References _readArrayMember(), _readMembers(), and _readScalar().

Referenced by _readArrayElements(), and _readMembers().

◆ _readMembers()

template<typename Derived>
template<typename T>
Result< void > wowlib::formats::m2::M2OffsetBlock< Derived >::_readMembers ( T & dst,
const std::span< const std::byte > image,
std::size_t & cursor,
const std::span< const std::byte > base,
const OffsetReadContext & ctx )
inlinestaticprotected

Read every version-active member of record/entity dst from image at cursor, in layout order (own declaration order with trait members spliced at their offsetAfter anchors).

Array/string data blocks resolve against base. The gatedBy check reads dst.globalFlags, valid because the flags precede any gated member in layout order.

Template Parameters
Tthe record/entity type.
Parameters
dstthe destination record, overwritten member-by-member.
imagethe inline image bytes to read members from.
cursorthe read position within image; advanced past the members.
basethe buffer array/string offsets resolve against.
ctxper-sequence base resolution for SequenceData members.
Returns
nothing, or the first structural error.

Definition at line 403 of file offset_block.hpp.

References _memberOrder(), _memberPresent(), _readMember(), _resolvesExternally(), wowlib::formats::detail::annotation(), wowlib::audit::RoundtripReport::error, wowlib::formats::detail::membersOf(), and wowlib::formats::detail::versionActive().

Referenced by _readMember(), read(), and read().

◆ _readScalar()

template<typename Derived>
template<typename M>
Result< void > wowlib::formats::m2::M2OffsetBlock< Derived >::_readScalar ( M & dst,
const std::span< const std::byte > image,
std::size_t & cursor,
const std::string_view what )
inlinestaticprotected

Read a trivially-copyable scalar dst from image at cursor.

Template Parameters
Mthe scalar type.
Parameters
dstthe destination value.
imagethe inline image bytes.
cursorthe read position; advanced by sizeof(M).
whatthe member name, for diagnostics.
Returns
nothing, or OffsetOutOfBounds if the value overruns image.

Definition at line 461 of file offset_block.hpp.

References _offsetError(), and wowlib::OffsetOutOfBounds.

Referenced by _readMember().

◆ _readStringBlock()

template<typename Derived>
Result< void > wowlib::formats::m2::M2OffsetBlock< Derived >::_readStringBlock ( std::string & dst,
const M2ArrayRef ref,
const std::span< const std::byte > base,
const std::string_view what )
inlinestaticprotected

Decode a string data block referenced by ref out of base.

The stored count includes the NUL terminator (client buffer-size semantics), so the string is truncated at the first NUL within it.

Parameters
dstthe destination string, cleared first.
refthe {count, offset} slot.
basethe buffer the offset resolves against.
whatthe member name, for diagnostics.
Returns
nothing, or OffsetOutOfBounds if the block overruns base.

Definition at line 524 of file offset_block.hpp.

References _offsetError(), wowlib::formats::m2::M2OffsetBlock< Derived >::M2ArrayRef::count, wowlib::formats::m2::M2OffsetBlock< Derived >::M2ArrayRef::offset, and wowlib::OffsetOutOfBounds.

Referenced by _readArrayMember().

◆ _readVectorBlock()

template<typename Derived>
template<typename M>
Result< void > wowlib::formats::m2::M2OffsetBlock< Derived >::_readVectorBlock ( M & dst,
const M2ArrayRef ref,
const std::span< const std::byte > base,
const OffsetReadContext & ctx,
const bool external,
const std::string_view what )
inlinestaticprotected

Decode a vector data block referenced by ref out of base: ref.count element images of layoutSize<U> bytes.

Trivially-copyable elements bulk-copy; non-trivial ones recurse through _readArrayElements. An externally-resolved sequence with an empty base (a missing .anim file) leaves the member empty rather than failing.

Template Parameters
Mthe vector type.
Parameters
dstthe destination vector, cleared first.
refthe {count, offset} slot.
basethe buffer the offset resolves against.
ctxper-sequence base resolution.
externalset for an externally-resolved SequenceData array.
whatthe member name, for diagnostics.
Returns
nothing, or OffsetOutOfBounds if the block overruns base.

Definition at line 554 of file offset_block.hpp.

References _offsetError(), _readArrayElements(), wowlib::formats::m2::M2OffsetBlock< Derived >::M2ArrayRef::count, wowlib::formats::m2::layoutSize(), wowlib::formats::m2::M2OffsetBlock< Derived >::M2ArrayRef::offset, and wowlib::OffsetOutOfBounds.

Referenced by _readArrayMember().

◆ _resolvesExternally()

template<typename Derived>
template<bool IsSequenceData, typename T>
bool wowlib::formats::m2::M2OffsetBlock< Derived >::_resolvesExternally ( const T & rec)
inlinestaticprotected

Whether a SequenceData member of rec resolves its per-element data through the external I/O context on this call.

A track bound to a global sequence keeps a single inline timeline even while other sequences live in .anim files, so it never resolves externally.

Template Parameters
IsSequenceDatawhether the member carries the SequenceData annotation.
Tthe containing record type.
Parameters
recthe record instance (its globalSequence, if any, is read).
Returns
true when element data should route through the I/O context.

Definition at line 382 of file offset_block.hpp.

Referenced by _readMembers(), and _writeMembers().

◆ _writeArrayElements()

template<typename Derived>
template<typename M>
Result< void > wowlib::formats::m2::M2OffsetBlock< Derived >::_writeArrayElements ( const M & src,
const std::size_t blockAt,
FileBuffer & blocks,
const OffsetWriteContext & ctx,
const bool external,
const std::string_view what )
inlinestaticprotected

Write the non-trivial elements of src into the block already reserved at blockAt in blocks.

Each element's inline image lands in that block; its own nested data blocks append to the sequence sink (ctx.sequenceSink(i), the .anim buffer) when this is an externally resolved SequenceData array, else to blocks.

Template Parameters
Mthe vector type.
Parameters
srcthe source vector.
blockAtthe byte index of the reserved element block in blocks.
blocksthe buffer holding the element images (and, by default, their nested data).
ctxper-sequence sink resolution.
externalwhether this is an externally-resolved sequence array.
whatthe member name, for diagnostics.
Returns
nothing, or the first error.

Definition at line 829 of file offset_block.hpp.

References _writeMember(), wowlib::formats::m2::layoutSize(), and wowlib::formats::m2::OffsetWriteContext::sequenceSink.

Referenced by _writeVectorBlock().

◆ _writeArrayMember()

template<typename Derived>
template<typename M>
Result< void > wowlib::formats::m2::M2OffsetBlock< Derived >::_writeArrayMember ( const M & src,
FileBuffer & image,
const std::size_t imagePos,
std::size_t & cursor,
FileBuffer & blocks,
const OffsetWriteContext & ctx,
const bool external,
const std::string_view what )
inlinestaticprotected

Write an M2Array-referenced member: allocate its data block, fill it, and emit the {count, offset} slot.

Template Parameters
Mthe member type (std::string or std::vector).
Parameters
src the source member.
image the pre-sized image buffer.
imagePosthe base offset of the containing record within image.
cursor the position within the record; advanced past the slot.
blocks the buffer receiving the data block.
ctx per-sequence sink resolution.
externalset for an externally-resolved SequenceData array.
what the member name, for diagnostics.
Returns
nothing, or the first error.

Definition at line 739 of file offset_block.hpp.

References _writeStringBlock(), and _writeVectorBlock().

Referenced by _writeMember().

◆ _writeImage()

template<typename Derived>
Result< void > wowlib::formats::m2::M2OffsetBlock< Derived >::_writeImage ( const Derived & self,
FileBuffer & out,
const OffsetWriteContext & ctx )
inlinestaticprotected

Serialize self in canonical layout — the image first (pre-sized to imageSize()), then data blocks depth-first via _writeMembers — and append the result to out.

Offsets are recorded relative to the image start, so the image is built into a fresh buffer before appending.

Parameters
selfthe entity to serialize.
outthe destination buffer (appended, not cleared).
ctxper-sequence sink resolution.
Returns
nothing, or the first error.

Definition at line 651 of file offset_block.hpp.

References _writeMembers().

Referenced by write(), and write().

◆ _writeMember()

template<typename Derived>
template<typename M>
Result< void > wowlib::formats::m2::M2OffsetBlock< Derived >::_writeMember ( const M & src,
FileBuffer & image,
const std::size_t imagePos,
std::size_t & cursor,
FileBuffer & blocks,
const OffsetWriteContext & ctx,
const bool external,
const std::string_view what )
inlinestaticprotected

Write one member src — an array/string reference, an inline sub-record, or an inline scalar — advancing cursor over its in-image bytes.

Template Parameters
Mthe member type; the concept it satisfies picks the branch.
Parameters
srcthe source member.
imagethe pre-sized image buffer.
imagePosthe base offset of the containing record within image.
cursorthe position within the record; advanced.
blocksthe buffer receiving data blocks.
ctxper-sequence sink resolution.
externalset only for a SequenceData array routing through ctx.
whatthe member name, for diagnostics.
Returns
nothing, or the first error.

Definition at line 708 of file offset_block.hpp.

References _putBytes(), _writeArrayMember(), and _writeMembers().

Referenced by _writeArrayElements(), and _writeMembers().

◆ _writeMembers()

template<typename Derived>
template<typename T>
Result< void > wowlib::formats::m2::M2OffsetBlock< Derived >::_writeMembers ( const T & src,
FileBuffer & image,
const std::size_t imagePos,
std::size_t & cursor,
FileBuffer & blocks,
const OffsetWriteContext & ctx )
inlinestaticprotected

Write every version-active member of record/entity src into image at imagePos + cursor, in layout order; data blocks append to blocks.

Mirrors _readMembers exactly.

Template Parameters
Tthe record/entity type.
Parameters
srcthe source record.
imagethe pre-sized image buffer.
imagePosthe base offset of src's image within image.
cursorthe position within the record; advanced past the members.
blocksthe buffer receiving array/string data blocks.
ctxper-sequence sink resolution.
Returns
nothing, or the first error.

Definition at line 672 of file offset_block.hpp.

References _memberOrder(), _memberPresent(), _resolvesExternally(), _writeMember(), wowlib::formats::detail::annotation(), wowlib::audit::RoundtripReport::error, wowlib::formats::detail::membersOf(), and wowlib::formats::detail::versionActive().

Referenced by _writeImage(), and _writeMember().

◆ _writeStringBlock()

template<typename Derived>
Result< void > wowlib::formats::m2::M2OffsetBlock< Derived >::_writeStringBlock ( const std::string & src,
FileBuffer & image,
const std::size_t imagePos,
std::size_t & cursor,
FileBuffer & blocks )
inlinestaticprotected

Emit src as an M2Array<char> whose count includes the NUL terminator — the client reads these as buffer sizes and requires the terminator inside, so even the empty string writes {1, block}, never {0, 0}.

Parameters
srcthe source string.
imagethe pre-sized image buffer.
imagePosthe base offset of the containing record within image.
cursorthe position within the record; advanced past the slot.
blocksthe buffer receiving the character block.
Returns
nothing (never fails).

Definition at line 761 of file offset_block.hpp.

References _allocBlock(), and _putBytes().

Referenced by _writeArrayMember().

◆ _writeVectorBlock()

template<typename Derived>
template<typename M>
Result< void > wowlib::formats::m2::M2OffsetBlock< Derived >::_writeVectorBlock ( const M & src,
FileBuffer & image,
const std::size_t imagePos,
std::size_t & cursor,
FileBuffer & blocks,
const OffsetWriteContext & ctx,
const bool external,
const std::string_view what )
inlinestaticprotected

Emit src as an M2Array: an empty vector writes {0, 0}; otherwise a count * layoutSize<U> element block is reserved, filled (bulk memcpy for trivially-copyable elements, else _writeArrayElements), and the slot emitted.

Template Parameters
Mthe vector type.
Parameters
srcthe source vector.
imagethe pre-sized image buffer.
imagePosthe base offset of the containing record within image.
cursorthe position within the record; advanced past the slot.
blocksthe buffer receiving the element block.
ctxper-sequence sink resolution.
externalset for an externally-resolved SequenceData array.
whatthe member name, for diagnostics.
Returns
nothing, or the first error.

Definition at line 789 of file offset_block.hpp.

References _allocBlock(), _putBytes(), _writeArrayElements(), empty(), and wowlib::formats::m2::layoutSize().

Referenced by _writeArrayMember().

◆ empty()

template<typename Derived>
bool wowlib::formats::m2::M2OffsetBlock< Derived >::empty ( ) const
inline

Never empty: an offset block always has a header image worth writing (the SelfSerializing engagement hook — an MD21-style carrier chunk is always emitted).

Returns
always false.

Definition at line 217 of file offset_block.hpp.

Referenced by _writeVectorBlock().

◆ ensureValid()

template<typename Derived>
Result< void > wowlib::formats::m2::M2OffsetBlock< Derived >::ensureValid ( ) const
inlinenodiscard

Validate and raise on the first error instead of returning a report — the assert-style face of validate().

Returns
nothing; raises when validate() finds any error

Definition at line 234 of file offset_block.hpp.

References validate().

◆ imageSize()

template<typename Derived>
std::size_t wowlib::formats::m2::M2OffsetBlock< Derived >::imageSize ( ) const
inline

The entity's image footprint in bytes for Derived's version: every version-active member's layoutSize, plus any engaged gatedBy member.

This is the exact size of the header/inline image that precedes the data blocks.

Returns
the image size in bytes.

Definition at line 243 of file offset_block.hpp.

References _memberPresent(), wowlib::formats::m2::layoutSize(), wowlib::formats::detail::membersOf(), and wowlib::formats::detail::versionActive().

◆ memberOffset()

template<typename Derived>
consteval std::size_t wowlib::formats::m2::M2OffsetBlock< Derived >::memberOffset ( std::string_view name)
inlinestaticconsteval

The positional byte offset of member name within this entity's image, for Derived's version: the version-active members' layoutSize summed in layout order up to (not including) name.

Lets a caller stamp a derived field into an already-serialized image (the M2 assembly stamps numSkinProfiles from its skins vector) without mutating entity state. Valid only while no gatedBy member precedes name — the offset would be runtime state then; both that and the member's existence are enforced at compile time.

Parameters
namethe member identifier.
Returns
the byte offset inside the entity's image.
Exceptions
(consteval)if name is unknown, or a gatedBy member precedes it.

Definition at line 268 of file offset_block.hpp.

References _memberOrder(), wowlib::formats::detail::annotation(), wowlib::formats::m2::layoutSize(), wowlib::formats::detail::membersOf(), and wowlib::formats::detail::versionActive().

◆ operator==()

template<typename Derived>
bool wowlib::formats::m2::M2OffsetBlock< Derived >::operator== ( const M2OffsetBlock< Derived > & ) const
default

◆ read() [1/2]

template<typename Derived>
Result< void > wowlib::formats::m2::M2OffsetBlock< Derived >::read ( std::span< const std::byte > data)
inline

Deserialize file bytes into this entity, replacing its contents.

Offsets resolve against the given buffer; sequence-gated data is read inline.

Parameters
datathe file (or containing-chunk payload) bytes

Definition at line 168 of file offset_block.hpp.

References _readMembers().

◆ read() [2/2]

template<typename Derived>
Result< void > wowlib::formats::m2::M2OffsetBlock< Derived >::read ( std::span< const std::byte > data,
const OffsetReadContext & ctx )
inline

Deserialize data with external sequence data resolved through ctx (the M2 .anim baking path).

Parameters
datathe file (or containing-chunk payload) bytes.
ctxper-sequence base resolution for SequenceData members.
Returns
nothing, or the first structural error.

Definition at line 179 of file offset_block.hpp.

References _readMembers().

◆ validate()

template<typename Derived>
ValidationReport wowlib::formats::m2::M2OffsetBlock< Derived >::validate ( ) const
inlinenodiscard
Returns
every violated contract, in member order

Definition at line 223 of file offset_block.hpp.

References wowlib::formats::detail::validateEntity().

Referenced by ensureValid().

◆ write() [1/3]

template<typename Derived>
Result< FileBuffer > wowlib::formats::m2::M2OffsetBlock< Derived >::write ( ) const
inlinenodiscard

Serialize this entity in wowlib's canonical layout (an offset format has no byte-perfect round-trip guarantee; a written entity re-reads equal instead).

Returns
the file bytes

Definition at line 190 of file offset_block.hpp.

References write().

Referenced by write().

◆ write() [2/3]

template<typename Derived>
Result< FileBuffer > wowlib::formats::m2::M2OffsetBlock< Derived >::write ( const OffsetWriteContext & ctx) const
inline

Serialize with external sequence data routed through ctx (the M2 .anim splitting path).

Parameters
ctxper-sequence sink resolution for SequenceData members.
Returns
the file bytes, or the first error.

Definition at line 198 of file offset_block.hpp.

References _writeImage().

◆ write() [3/3]

template<typename Derived>
Result< void > wowlib::formats::m2::M2OffsetBlock< Derived >::write ( FileBuffer & out) const
inline

Append this entity's serialized image to out (the chunk serializer's SelfSerializing write hook — offsets are relative to the start of the appended image).

Parameters
outthe destination buffer (appended, not cleared).
Returns
nothing, or the first error.

Definition at line 209 of file offset_block.hpp.

References _writeImage().


The documentation for this struct was generated from the following file: