wowlib 0.0.0
Read & write World of Warcraft client files — a C++26 core
Loading...
Searching...
No Matches
codec.hpp
Go to the documentation of this file.
1#pragma once
2
16
17#include <cstddef>
18#include <cstdint>
19#include <span>
20#include <string>
21#include <string_view>
22#include <vector>
23
24#include <welder/vocabulary.hpp>
25
27#include <wowlib/db/schema.hpp>
29
30namespace wowlib::db {
33 enum class [[
34 =welder::weld,
35 =welder::doc(R"(
36 How a client-database write handles keyless encrypted sections: Preserve
37 re-emits the file's original bytes verbatim (encrypted content intact,
38 edits to decoded rows NOT applied); Drop writes only the decoded rows as
39 a plain unencrypted table, discarding the rows behind missing keys.)")
41 Preserve,
43 };
48 struct [[
49 =welder::weld,
50 =welder::doc(
51 "An encrypted WDC section: its records are behind a TACT key "
52 "wowlib does not hold, so they are absent from records.")
54 [[=welder::doc(
55 "The section's TACT key lookup hash (names the missing key).")]]
56 std::uint64_t keyHash = 0;
57
58 [[=welder::doc("How many records the encrypted section holds.")]]
59 std::uint32_t recordCount = 0;
61 [[=welder::doc(
62 "The ids of the encrypted records, when the file lists them.")]]
63 std::vector<std::uint32_t> ids;
64 };
65
68 (diagnostics), and the runtime schema. Every other derived quantity —
69 record stride, field-slot count, inline column count, the id column's
70 inline index / non-inline flag — the codecs compute from @ref schema. */
71 struct TableInfo {
73 std::string_view name;
74 std::span<const Column> schema;
75 };
81 struct TableState {
82 std::uint32_t sourceMagic = 0;
83 std::uint32_t fieldCount = 0;
84 std::uint32_t recordSize = 0;
89 std::vector<std::uint32_t> stringOffsets;
90
91 std::vector<std::byte> wdb2Header;
92 std::vector<std::byte> wdb2Index;
93 std::vector<std::byte> wdb2Copy;
94
95 std::vector<EncryptedSection> encrypted;
96 std::uint32_t wdcTableHash = 0;
97 std::uint32_t wdcLayoutHash = 0;
98 std::uint32_t wdcLocale = 0;
99 std::vector<std::byte> wdcOriginal;
100 std::vector<std::uint8_t> wdcKinds;
101 std::vector<std::byte> wdc5Prefix;
102
103
104 void reset() {
105 strings = {};
106 stringOffsets.clear();
107 wdb2Header.clear();
108 wdb2Index.clear();
109 wdb2Copy.clear();
110 encrypted.clear();
111 wdcOriginal.clear();
112 wdcKinds.clear();
113 wdc5Prefix.clear();
115 };
124 public:
125 virtual ~RecordSink() = default;
126 virtual void clear() = 0;
127 virtual void reserve(std::size_t n) = 0;
128 virtual std::size_t add() = 0;
129 virtual std::size_t size() const = 0;
130 virtual std::uint32_t idOf(std::size_t record) const = 0;
131 virtual void setInt(std::size_t record, std::size_t column, std::size_t element, std::int64_t value) = 0;
132 virtual void setFloat(std::size_t record, std::size_t column, std::size_t element, float value) = 0;
133 virtual void setString(std::size_t record, std::size_t column, std::size_t element, std::string_view value) = 0;
135 (WDC copy-table materialization). */
136 virtual void cloneWithId(std::size_t src, std::uint32_t newId) = 0;
139 virtual std::size_t findById(std::uint32_t id) const = 0;
140 };
144
147 implements it over a const std::vector<Record>&. */
148 class RecordSource {
149 public:
150 virtual ~RecordSource() = default;
151 virtual std::size_t size() const = 0;
152 virtual std::uint32_t idOf(std::size_t record) const = 0;
153 virtual std::int64_t getInt(std::size_t record, std::size_t column, std::size_t element) const = 0;
154 virtual std::uint32_t getSlot(std::size_t record, std::size_t column, std::size_t element) const = 0;
155 virtual std::string_view getString(std::size_t record, std::size_t column, std::size_t element) const = 0;
156 };
157
158 namespace detail {
159
160 inline std::size_t recordStride(std::span<const Column> schema) {
161 std::size_t bytes = 0;
162 for (const Column& col : schema) bytes += col.inlineBytes();
163 return bytes;
164 }
165
166
167 inline std::uint32_t fieldSlotCount(std::span<const Column> schema) {
168 std::uint32_t slots = 0;
169 for (const Column& col : schema) slots += col.fieldSlots();
170 return slots;
171 }
172
173
174 inline std::size_t stringSlotCount(std::span<const Column> schema) {
175 std::size_t slots = 0;
176 for (const Column& col : schema) slots += col.stringSlots();
177 return slots;
178 }
179
180
181 inline std::size_t inlineColumnCount(std::span<const Column> schema) {
182 std::size_t n = 0;
183 for (const Column& col : schema) n += col.noninline ? 0 : 1;
184 return n;
185 }
186
188 inline bool idIsNoninline(std::span<const Column> schema) {
189 for (const Column& col : schema)
190 if (col.isId) return col.noninline;
191 return false;
192 }
193
195 inline std::uint16_t idFieldIndex(std::span<const Column> schema) {
196 std::uint16_t idx = 0;
197 for (const Column& col : schema) {
198 if (col.noninline) continue;
199 if (col.isId) return idx;
200 ++idx;
201 }
202 return 0;
203 }
204 }
205}
The decode target: the codecs build the record vector through this, one field at a time.
Definition codec.hpp:110
virtual void cloneWithId(std::size_t src, std::uint32_t newId)=0
Clone record src into a fresh record and set its id column to newId (WDC copy-table materialization).
virtual void setFloat(std::size_t record, std::size_t column, std::size_t element, float value)=0
virtual std::size_t add()=0
virtual std::size_t size() const =0
virtual std::uint32_t idOf(std::size_t record) const =0
virtual void setString(std::size_t record, std::size_t column, std::size_t element, std::string_view value)=0
virtual void setInt(std::size_t record, std::size_t column, std::size_t element, std::int64_t value)=0
virtual void reserve(std::size_t n)=0
virtual void clear()=0
virtual std::size_t findById(std::uint32_t id) const =0
The first record whose id equals id, or size() when none (copy source lookup).
virtual ~RecordSink()=default
The encode source: the codecs read the record vector through this.
Definition codec.hpp:135
virtual std::size_t size() const =0
virtual std::int64_t getInt(std::size_t record, std::size_t column, std::size_t element) const =0
virtual std::uint32_t getSlot(std::size_t record, std::size_t column, std::size_t element) const =0
virtual ~RecordSource()=default
virtual std::uint32_t idOf(std::size_t record) const =0
virtual std::string_view getString(std::size_t record, std::size_t column, std::size_t element) const =0
Client version identity, the flavor axis that separates a client's CONTENT version from the engine ge...
std::uint16_t idFieldIndex(std::span< const Column > schema)
The inline field index of an inline id column (0 when non-inline).
Definition codec.hpp:182
bool idIsNoninline(std::span< const Column > schema)
Whether the id column is stored outside the record ($noninline$ id).
Definition codec.hpp:175
std::size_t inlineColumnCount(std::span< const Column > schema)
The number of INLINE columns (everything not $noninline$).
Definition codec.hpp:168
consteval std::size_t recordStride()
The fixed record stride of Record inside a WDBC/WDB2 record block.
Definition schema.hpp:239
consteval std::uint32_t fieldSlotCount()
The expanded on-disk field slot count of Record (the WDBC/WDB2 header fieldCount a fresh write derive...
Definition schema.hpp:250
EncryptedPolicy
How write() treats a table that still holds keyless (undecryptable) encrypted sections.
Definition codec.hpp:33
@ Drop
Write only decoded rows as plaintext; keyless rows are dropped.
Definition codec.hpp:35
@ Preserve
Re-emit the original image verbatim; edits are not applied.
Definition codec.hpp:34
consteval std::size_t stringSlotCount()
The string-block references one record of Record stores — the width of the engine's per-record origin...
Definition schema.hpp:261
Schema reflection over generated client-database record structs: the column list, record stride and f...
StringBlock — the decoded representation of a chunk of zero-terminated strings (MOTX,...
One column of a record schema, derived from a record member by reflection (typed records) or from the...
Definition schema.hpp:46
One WDC section whose records could not be decoded because they are encrypted under a TACT key wowlib...
Definition codec.hpp:42
std::uint64_t keyHash
The section's TACT key lookup hash (names the missing key).
Definition codec.hpp:44
std::uint32_t recordCount
How many records the encrypted section holds.
Definition codec.hpp:47
std::vector< std::uint32_t > ids
The ids of the encrypted records, when the file lists them.
Definition codec.hpp:50
The per-table identity a codec needs beyond the record data: the client version (format selection,...
Definition codec.hpp:58
ClientVersion version
The record's client version.
Definition codec.hpp:59
std::span< const Column > schema
The record schema (schemaOf<Record>()).
Definition codec.hpp:61
std::string_view name
The WoWDBDefs table name.
Definition codec.hpp:60
The preserved decode state a table carries between read() and write() so a WDBC/WDB2 write is byte-pe...
Definition codec.hpp:68
std::vector< std::byte > wdb2Copy
Preserved WDB2 copy table, verbatim.
Definition codec.hpp:80
std::vector< std::uint8_t > wdcKinds
Original per-inline-column compression (WdcCompression).
Definition codec.hpp:87
formats::StringBlock strings
Preserved string block; offsets never move.
Definition codec.hpp:72
void reset()
Reset the per-read state before decoding a fresh image.
Definition codec.hpp:91
std::vector< std::byte > wdb2Header
Preserved WDB2 header identity bytes.
Definition codec.hpp:78
std::vector< std::uint32_t > stringOffsets
The original string-block offset of every string field, row-major in record then schema order — the b...
Definition codec.hpp:76
std::vector< std::byte > wdb2Index
Preserved WDB2 id-index block, verbatim.
Definition codec.hpp:79
std::vector< std::byte > wdcOriginal
Raw image kept when the file has encrypted sections.
Definition codec.hpp:86
std::uint32_t wdcTableHash
Preserved WDC3 header tableHash.
Definition codec.hpp:83
std::uint32_t recordSize
Preserved header recordSize.
Definition codec.hpp:71
std::uint32_t fieldCount
Preserved header fieldCount (not always derivable).
Definition codec.hpp:70
std::uint32_t wdcLocale
Preserved WDC3 header locale.
Definition codec.hpp:85
std::vector< EncryptedSection > encrypted
Encrypted WDC sections skipped on read.
Definition codec.hpp:82
std::uint32_t sourceMagic
The magic read() sniffed; 0 for a fresh table.
Definition codec.hpp:69
std::uint32_t wdcLayoutHash
Preserved WDC3 header layoutHash.
Definition codec.hpp:84
std::vector< std::byte > wdc5Prefix
Preserved WDC5 {version, schema string} header prefix.
Definition codec.hpp:88