The MD20 model body for one client version: header scalars plus every offset-addressed block, decoded into vectors.
More...
|
| Result< void > | read (std::span< const std::byte > data) |
| | Deserialize file bytes into this entity, replacing its contents.
|
| 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).
|
| 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 |
| bool | operator== (const M2OffsetBase &) const =default |
| bool | operator== (const M2RootBase &) const =default |
| 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 consteval std::optional< formats::detail::OffsetAfterSpec > | _offsetAnchorOf (std::meta::info member) |
| | The first offsetAfter positional anchor on member, or nullopt.
|
| 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").
|
| 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.
|
| 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.
|
| 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).
|
| 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.
|
| 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.
|
| 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.
|
| 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.
|
| 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 M2Root< V > &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.
|
| 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.
|
| 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.
|
| 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}.
|
| 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.
|
| 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.
|
template<
ClientVersion V>
struct wowlib::formats::m2::root::M2Root< V >
The MD20 model body for one client version: header scalars plus every offset-addressed block, decoded into vectors.
This entity alone is a complete pre-WotLK model; later clients pull skins, low-priority sequence data, skeleton and physics from satellite files — the M2 assembly bakes those back in. Instantiate through the canonicalizing m2::M2Root alias, never directly.
- Template Parameters
-
| V | the canonical client version this body targets. |
- See also
- https://wowdev.wiki/M2
Definition at line 131 of file root.hpp.