feat(editor): add --catalog-stats for single-file deep size analysis

Reports header bytes (magic + version + nameLen + name +
entryCount) vs entry-section bytes, average entry size, total
file size, the catalog's name string length, and the first
entry's id field. Useful for sizing analysis: "which catalogs
are biggest, where do the bytes go, what's the per-entry
overhead".

Goes deeper than --info-magic which just reports the magic +
version + name + count. The byte breakdown distinguishes:
  - headerBytes        — fixed-cost header
  - catalogNameBytes   — variable-length catalog label
  - entrySectionBytes  — total size of all entries combined
  - averageEntryBytes  — entrySectionBytes / entryCount

Only the first entry's id is sampled because entries have
variable-length name+description strings — multi-sampling
produces garbage for most formats. The single sampled id is
reliable because it sits at exactly headerBytes offset.

JSON sidecar via --json. Format metadata (description / category)
is included from the format table when the magic is recognized;
unknown magics still get the size breakdown but no metadata.

This is the 18th cross-format utility; the second per-file
single-target one (alongside --info-magic). CLI flag count
1033 -> 1034.
This commit is contained in:
Kelsi 2026-05-09 23:21:32 -07:00
parent 6abd3f5398
commit 69857eea18
6 changed files with 199 additions and 0 deletions

View file

@ -1381,6 +1381,8 @@ void printUsage(const char* argv0) {
std::printf(" Find .wXXX.json sidecars whose binary .wXXX is missing. Useful after deleting/moving binaries — orphan JSONs accumulate noise and may shadow re-imports. Exit 1 if any orphans found\n");
std::printf(" --list-by-magic <dir> <magic> [--json]\n");
std::printf(" List every file in a directory tree matching a 4-char magic (e.g. WSPL). Reports per-file size + entry count + catalog name + relative path. Exit 1 if no matches\n");
std::printf(" --catalog-stats <file> [--json]\n");
std::printf(" Single-file deep stats — header bytes vs entry-section bytes, average entry size, sampled entry IDs. Useful for sizing analysis (which catalogs are biggest, where do the bytes go)\n");
std::printf(" --gen-animations <wani-base> [name]\n");
std::printf(" Emit .wani starter: 5 essential animations (Stand / Walk / Run / Death / AttackUnarmed) with fallback chains\n");
std::printf(" --gen-animations-combat <wani-base> [name]\n");