Class CatalogSerializer
Turns a Catalog into the canonical bytes that travel in WELCOME, into the digest a returning client offers back to skip them, and
back from bytes into a catalog.
public static class CatalogSerializer
- Inheritance
-
CatalogSerializer
- Inherited Members
Remarks
Canonical means declaration-order-independent. Canonicalize(Catalog) sorts every named collection ordinally and assigns each entry's
idx from that order — except built-in commands and metrics, whose indices are reserved and never move, so enabling one cannot renumber the
application's entries (W27). Sorting alone would not be enough: idx is the wire index, so if it came from declaration order, reordering two
archetypes in registration code would change what the bytes mean. A grid's archetype list is remapped along with the archetypes it names.
Field order is wire order (W11). A record body is a concatenation of independently encoded sections — the onEnter section, then one per change group in canonical order — because a state record is assembled per session from group bodies encoded once. Within a section, packed fields come first (they share the section's leading pack, W12), then byte-aligned fields, each by ordinal name. The catalog's field array is exactly that order, so no client ever sorts.
The digest is FNV-1a 64 over the canonical bytes (03-wire-protocol § 4). Hashing the bytes rather than folding the structure means nothing that reaches the wire can be left out of the digest by forgetting to fold it, and two catalogs that serialize identically cannot differ in digest. The price is that a change to how the serializer formats a value moves every digest once — one catalog resend per client, which the golden vectors make visible.
Methods
Canonicalize(Catalog)
Validates catalog and returns an equivalent catalog in canonical form: every named collection sorted, indices assigned, fields in
wire order.
public static Catalog Canonicalize(Catalog catalog)
Parameters
catalogCatalogThe catalog as the application declared it.
Returns
- Catalog
A new catalog; the input is not modified, though leaf values (codecs, positions, label arrays) are shared with it.
Exceptions
- ArgumentNullException
catalogis null.- CatalogException
The catalog breaks a wire rule.
ComputeHash(Catalog)
Canonicalizes catalog and returns the digest of its canonical bytes, which a client presents to skip the catalog.
public static ulong ComputeHash(Catalog catalog)
Parameters
catalogCatalogThe catalog to digest.
Returns
- ulong
The digest; on the wire it travels as eight little-endian bytes (W20).
Export(Catalog)
Canonicalizes catalog once and returns the canonical form, its bytes and their digest together — what a server serves, computed
in one pass so the bytes and the digest cannot describe two different declarations.
public static CatalogExport Export(Catalog catalog)
Parameters
catalogCatalogThe catalog as the application declared it.
Returns
- CatalogExport
The export.
FromUtf8(ReadOnlySpan<byte>)
Parses catalog JSON received from a server, validates it, and refuses it unless it is canonical — indices, order and reserved ranges exactly as
Canonicalize(Catalog) would produce them. A decode plan built from a non-canonical catalog would silently map mask bits and indices to the
wrong fields, so this is a refusal at WELCOME, never a repair.
public static Catalog FromUtf8(ReadOnlySpan<byte> utf8Json)
Parameters
utf8JsonReadOnlySpan<byte>The catalog bytes from
WELCOME.
Returns
- Catalog
The catalog.
Exceptions
- CatalogException
The JSON is not a catalog, breaks a wire rule, or is not canonical.
HashBytes(ReadOnlySpan<byte>)
The FNV-1a 64 digest of catalog bytes.
public static ulong HashBytes(ReadOnlySpan<byte> utf8)
Parameters
utf8ReadOnlySpan<byte>Canonical catalog bytes.
Returns
- ulong
The digest.
IsPacked(CodecKind)
Whether a codec kind is packed into its section's leading bit pack rather than byte-aligned (W12).
public static bool IsPacked(CodecKind kind)
Parameters
kindCodecKindThe codec kind.
Returns
ToCanonicalUtf8(Catalog)
Canonicalizes catalog and serializes it to the UTF-8 bytes that travel in WELCOME: no insignificant whitespace, camelCase
names, and defaulted parameters omitted.
public static byte[] ToCanonicalUtf8(Catalog catalog)
Parameters
catalogCatalogThe catalog to serialize.
Returns
- byte[]
The canonical UTF-8 bytes.
ToHex(ulong)
The digest's display form: sixteen lower-case hex digits, most significant first.
public static string ToHex(ulong hash)
Parameters
hashulongThe digest.
Returns
- string
The hex string.
WriteHash(ulong, Span<byte>)
Writes the digest's wire form, eight little-endian bytes, into destination.
public static void WriteHash(ulong hash, Span<byte> destination)