wowlib 0.0.0
Read & write World of Warcraft client files — a C++26 core
Loading...
Searching...
No Matches
offset_block.hpp File Reference

The offset-format storage vocabulary and serializer engine for the M2 family, in one header. More...

#include <meta>
#include <cstddef>
#include <cstring>
#include <format>
#include <functional>
#include <optional>
#include <span>
#include <string>
#include <type_traits>
#include <vector>
#include <welder/vocabulary.hpp>
#include <wowlib/core/buffer.hpp>
#include <wowlib/core/client_version.hpp>
#include <wowlib/core/error.hpp>
#include <wowlib/formats/common/annotations.hpp>
#include <wowlib/formats/common/chunked_file.hpp>
Include dependency graph for offset_block.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  wowlib::formats::m2::M2OffsetBase
 The non-template marker base every offset block carries (what the OffsetEntity concept detects). More...
struct  wowlib::formats::m2::OffsetReadContext
 Resolution of SequenceData members while reading: where each outer element's nested data lives. More...
struct  wowlib::formats::m2::OffsetWriteContext
 Resolution of SequenceData members while writing: which buffer each outer element's nested data blocks are appended to (offsets recorded relative to that buffer). More...
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. More...
struct  wowlib::formats::m2::M2OffsetBlock< Derived >::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...

Namespaces

namespace  wowlib
namespace  wowlib::formats
namespace  wowlib::formats::m2

Concepts

concept  wowlib::formats::m2::OffsetStringMember
 A member serialized as an M2Array<char>: its bytes (NUL included) live in a data block, referenced by an M2Array{count, offset} slot.
concept  wowlib::formats::m2::OffsetArrayMember
 A member serialized as an M2Array{count, offset} reference to a separate data block — a std::vector (the block holds its element images) or a std::string.
concept  wowlib::formats::m2::InlineRecordMember
 A member serialized inline as a nested record: a non-trivial class the walker recurses into member-by-member at the current cursor (M2Track and friends).
concept  wowlib::formats::m2::InlineScalarMember
 A member serialized as inline raw bytes: anything trivially copyable that is not an array/string reference (scalars, C3Vector, M2Range, …).
concept  wowlib::formats::m2::OffsetEntity
 A type the offset engine can read and write: it is an M2 offset block and declares the client version it is laid out for.

Functions

template<typename T, ClientVersion V>
consteval std::size_t wowlib::formats::m2::layoutSize ()
 The image footprint of T in an offset layout for client version V: the 8-byte M2Array slot for an array/string reference, sizeof for an inline scalar, and the version-active member sum for an inline record (client records have no implicit padding, so the sum IS the layout).

Detailed Description

The offset-format storage vocabulary and serializer engine for the M2 family, in one header.

This machinery is used ONLY by M2 and its satellite files (that is why it lives under m2/ rather than common/); the fourcc+size chunk streams every other format uses are handled by common/chunked_file.hpp.

Vocabulary. M2OffsetBlock is the CRTP mixin that gives an offset-addressed entity — M2Root (the MD20 body), Skin, the .skel chunk payloads — its read()/write() methods. An offset block is the in-memory face of a flat, positional layout made of inline scalars and M2Array{count, offset} references whose data lives elsewhere in the buffer. Members store std::vector<T> / std::string; the on-disk M2Array never surfaces as a user type. OffsetReadContext / OffsetWriteContext route a member's per-sequence data to and from an external buffer (the M2 .anim files).

Unlike the chunk framework there is NO byte-perfect round-trip guarantee: a write always produces wowlib's canonical relayout (user decision 2026-07-24, see .claude/context/m2-architecture.md); the tested guarantee is semantic — an entity written and re-read compares equal.

Engine. The read/write logic lives as documented member functions of M2OffsetBlock rather than loose free functions. It walks a block's members and maps each onto the offset layout, dispatching on member KIND through the named concepts below:

  • OffsetArrayMember (std::vector / std::string) -> an M2Array slot plus a data block of element images (recursing when the element is itself an array/string/record);
  • InlineRecordMember (a non-trivial class, e.g. M2Track) -> its members recurse inline at the current cursor;
  • InlineScalarMember (anything trivially copyable) -> raw inline bytes.

Layout order is the block's OWN member declaration order; a version-gated member living in a conditionally-inherited trait base carries =offsetAfter("member") naming the own member it follows, and is spliced in there (base flattening is by-base, never the interleaved layout order). Writes emit the image first, then data blocks depth-first, each 16-byte aligned with zero gap fill (Blizzard's preferred alignment).

Definition in file offset_block.hpp.