whiteoutlib 0.2.0

Read and write Blizzard game assets from Rust: models (MDX, M2, M3), textures (BLP, DDS, PNG, JPEG, BMP, TGA, TIFF, GIF) and archives (CASC, MPQ).
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2026 Fernando Sahmkow
// AUTOGENERATED by tools/codegen/emit_c.py — do not edit.
// Regenerate via:  python -m tools.codegen.codegen casc --backend c-source

#include "whiteout_casc.h"

#include <cstring>
#include <new>
#include <span>
#include <string>
#include <vector>

#include <whiteout/storages/casc/types.h>
#include <whiteout/storages/casc/storage.h>
#include <whiteout/storages/casc/storage_writable.h>

namespace { using namespace whiteout; }

namespace {

// `whiteout::u8` is `std::uint8_t`, so a single overload suffices. We use
// the project's type so the reinterpret_cast is a no-op everywhere the
// codegen runs.
inline whiteout_Bytes wrapBytes(std::vector<whiteout::u8>&& v) {
    auto* owned = new std::vector<whiteout::u8>(std::move(v));
    return { reinterpret_cast<const uint8_t*>(owned->data()), owned->size(), owned };
}

inline whiteout_Bytes emptyBytes() {
    return { nullptr, 0, nullptr };
}

inline whiteout_CString wrapCString(std::string&& s) {
    auto* owned = new std::string(std::move(s));
    return { owned->c_str(), owned->size(), owned };
}

inline whiteout_CString emptyCString() {
    return { nullptr, 0, nullptr };
}

} // anonymous

size_t whiteout_casc_StringList_size(const whiteout_StringList* self) {
    return reinterpret_cast<const std::vector<std::string>*>(self)->size();
}

whiteout_CString whiteout_casc_StringList_at(whiteout_StringList* self, size_t index) {
    auto* v = reinterpret_cast<std::vector<std::string>*>(self);
    if (index >= v->size()) return emptyCString();
    const std::string& s = (*v)[index];
    return whiteout_CString{ s.c_str(), s.size(), nullptr };
}

void whiteout_casc_StringList_delete(whiteout_StringList* self) {
    delete reinterpret_cast<std::vector<std::string>*>(self);
}
// ── CascCreateOptions ─────────────────────────────────────────────────

extern "C" {

whiteout_CascCreateOptions* whiteout_casc_CascCreateOptions_new(void) {
    return reinterpret_cast<whiteout_CascCreateOptions*>(new whiteout::storages::casc::CreateOptions());
}

void whiteout_casc_CascCreateOptions_delete(whiteout_CascCreateOptions* self) {
    delete reinterpret_cast<whiteout::storages::casc::CreateOptions*>(self);
}

whiteout_CString whiteout_casc_CascCreateOptions_get_product(const whiteout_CascCreateOptions* self) {
    auto* __owned = new std::string(reinterpret_cast<const whiteout::storages::casc::CreateOptions*>(self)->product);
    return whiteout_CString{ __owned->c_str(), __owned->size(), __owned };
}

void whiteout_casc_CascCreateOptions_set_product(whiteout_CascCreateOptions* self, const char* value) {
    reinterpret_cast<whiteout::storages::casc::CreateOptions*>(self)->product = (value ? value : "");
}

whiteout_CString whiteout_casc_CascCreateOptions_get_version(const whiteout_CascCreateOptions* self) {
    auto* __owned = new std::string(reinterpret_cast<const whiteout::storages::casc::CreateOptions*>(self)->version);
    return whiteout_CString{ __owned->c_str(), __owned->size(), __owned };
}

void whiteout_casc_CascCreateOptions_set_version(whiteout_CascCreateOptions* self, const char* value) {
    reinterpret_cast<whiteout::storages::casc::CreateOptions*>(self)->version = (value ? value : "");
}

uint32_t whiteout_casc_CascCreateOptions_get_archiveMaxSize(const whiteout_CascCreateOptions* self) {
    return reinterpret_cast<const whiteout::storages::casc::CreateOptions*>(self)->archiveMaxSize;
}

void whiteout_casc_CascCreateOptions_set_archiveMaxSize(whiteout_CascCreateOptions* self, uint32_t value) {
    reinterpret_cast<whiteout::storages::casc::CreateOptions*>(self)->archiveMaxSize = value;
}

uint32_t whiteout_casc_CascCreateOptions_get_blteFrameSize(const whiteout_CascCreateOptions* self) {
    return reinterpret_cast<const whiteout::storages::casc::CreateOptions*>(self)->blteFrameSize;
}

void whiteout_casc_CascCreateOptions_set_blteFrameSize(whiteout_CascCreateOptions* self, uint32_t value) {
    reinterpret_cast<whiteout::storages::casc::CreateOptions*>(self)->blteFrameSize = value;
}

int32_t whiteout_casc_CascCreateOptions_get_rootFormat(const whiteout_CascCreateOptions* self) {
    return static_cast<int32_t>(reinterpret_cast<const whiteout::storages::casc::CreateOptions*>(self)->rootFormat);
}

void whiteout_casc_CascCreateOptions_set_rootFormat(whiteout_CascCreateOptions* self, int32_t value) {
    reinterpret_cast<whiteout::storages::casc::CreateOptions*>(self)->rootFormat = static_cast<whiteout::storages::casc::RootFormat>(value);
}

} // extern "C"

// ── CascWriteOptions ─────────────────────────────────────────────────

extern "C" {

whiteout_CascWriteOptions* whiteout_casc_CascWriteOptions_new(void) {
    return reinterpret_cast<whiteout_CascWriteOptions*>(new whiteout::storages::casc::WriteOptions());
}

void whiteout_casc_CascWriteOptions_delete(whiteout_CascWriteOptions* self) {
    delete reinterpret_cast<whiteout::storages::casc::WriteOptions*>(self);
}

uint32_t whiteout_casc_CascWriteOptions_get_localeFlags(const whiteout_CascWriteOptions* self) {
    return reinterpret_cast<const whiteout::storages::casc::WriteOptions*>(self)->localeFlags;
}

void whiteout_casc_CascWriteOptions_set_localeFlags(whiteout_CascWriteOptions* self, uint32_t value) {
    reinterpret_cast<whiteout::storages::casc::WriteOptions*>(self)->localeFlags = value;
}

uint32_t whiteout_casc_CascWriteOptions_get_contentFlags(const whiteout_CascWriteOptions* self) {
    return reinterpret_cast<const whiteout::storages::casc::WriteOptions*>(self)->contentFlags;
}

void whiteout_casc_CascWriteOptions_set_contentFlags(whiteout_CascWriteOptions* self, uint32_t value) {
    reinterpret_cast<whiteout::storages::casc::WriteOptions*>(self)->contentFlags = value;
}

int32_t whiteout_casc_CascWriteOptions_get_compress(const whiteout_CascWriteOptions* self) {
    return reinterpret_cast<const whiteout::storages::casc::WriteOptions*>(self)->compress;
}

void whiteout_casc_CascWriteOptions_set_compress(whiteout_CascWriteOptions* self, int32_t value) {
    reinterpret_cast<whiteout::storages::casc::WriteOptions*>(self)->compress = value;
}

} // extern "C"

// ── CascStorage ─────────────────────────────────────────────────

extern "C" {

void whiteout_casc_CascStorage_delete(whiteout_CascStorage* self) {
    delete reinterpret_cast<whiteout::storages::casc::Storage*>(self);
}

struct whiteout_CascStorage* whiteout_casc_CascStorage_open(const char* path, void* pool) {
    auto __r = whiteout::storages::casc::Storage::open(std::string(path ? path : ""), reinterpret_cast<whiteout::interfaces::WorkerPool*>(pool));
    if (!__r) return nullptr;
    return reinterpret_cast<struct whiteout_CascStorage*>(
        new whiteout::storages::casc::Storage(std::move(*__r)));
}

struct whiteout_CascStorage* whiteout_casc_CascStorage_open_path_localeMask_pool(const char* path, uint32_t localeMask, void* pool) {
    auto __r = whiteout::storages::casc::Storage::open(std::string(path ? path : ""), localeMask, reinterpret_cast<whiteout::interfaces::WorkerPool*>(pool));
    if (!__r) return nullptr;
    return reinterpret_cast<struct whiteout_CascStorage*>(
        new whiteout::storages::casc::Storage(std::move(*__r)));
}

struct whiteout_CascStorage* whiteout_casc_CascStorage_open_path_product_pool(const char* path, const char* product, void* pool) {
    auto __r = whiteout::storages::casc::Storage::open(std::string(path ? path : ""), std::string(product ? product : ""), reinterpret_cast<whiteout::interfaces::WorkerPool*>(pool));
    if (!__r) return nullptr;
    return reinterpret_cast<struct whiteout_CascStorage*>(
        new whiteout::storages::casc::Storage(std::move(*__r)));
}

void whiteout_casc_CascStorage_close(whiteout_CascStorage* self) {
    reinterpret_cast<whiteout::storages::casc::Storage*>(self)->close();
}

int32_t whiteout_casc_CascStorage_isLocal(const whiteout_CascStorage* self) {
    return reinterpret_cast<const whiteout::storages::casc::Storage*>(self)->isLocal();
}

int32_t whiteout_casc_CascStorage_isOnline(const whiteout_CascStorage* self) {
    return reinterpret_cast<const whiteout::storages::casc::Storage*>(self)->isOnline();
}

int32_t whiteout_casc_CascStorage_isWritable(const whiteout_CascStorage* self) {
    return reinterpret_cast<const whiteout::storages::casc::Storage*>(self)->isWritable();
}

int32_t whiteout_casc_CascStorage_rootFormat(const whiteout_CascStorage* self) {
    return static_cast<int32_t>(reinterpret_cast<const whiteout::storages::casc::Storage*>(self)->rootFormat());
}

uint64_t whiteout_casc_CascStorage_entryCount(const whiteout_CascStorage* self) {
    return reinterpret_cast<const whiteout::storages::casc::Storage*>(self)->entryCount();
}

whiteout_Bytes whiteout_casc_CascStorage_readFile(const whiteout_CascStorage* self, const char* cascPath) {
    auto __r = reinterpret_cast<const whiteout::storages::casc::Storage*>(self)->readFile(std::string(cascPath ? cascPath : ""));
    if (!__r) return emptyBytes();
    return wrapBytes(std::move(*__r));
}

whiteout_Bytes whiteout_casc_CascStorage_readFile_cascPath_localeFlags_openFlags(const whiteout_CascStorage* self, const char* cascPath, uint32_t localeFlags, uint32_t openFlags) {
    auto __r = reinterpret_cast<const whiteout::storages::casc::Storage*>(self)->readFile(std::string(cascPath ? cascPath : ""), localeFlags, openFlags);
    if (!__r) return emptyBytes();
    return wrapBytes(std::move(*__r));
}

whiteout_Bytes whiteout_casc_CascStorage_readFile_fileId_hint(const whiteout_CascStorage* self, int32_t fileId, int32_t hint) {
    auto __r = reinterpret_cast<const whiteout::storages::casc::Storage*>(self)->readFile(fileId, static_cast<whiteout::storages::casc::FileIdHint>(hint));
    if (!__r) return emptyBytes();
    return wrapBytes(std::move(*__r));
}

whiteout_Bytes whiteout_casc_CascStorage_readFile_fileId_localeFlags_openFlags_hint(const whiteout_CascStorage* self, int32_t fileId, uint32_t localeFlags, uint32_t openFlags, int32_t hint) {
    auto __r = reinterpret_cast<const whiteout::storages::casc::Storage*>(self)->readFile(fileId, localeFlags, openFlags, static_cast<whiteout::storages::casc::FileIdHint>(hint));
    if (!__r) return emptyBytes();
    return wrapBytes(std::move(*__r));
}

int32_t whiteout_casc_CascStorage_fileExists(const whiteout_CascStorage* self, const char* cascPath) {
    return reinterpret_cast<const whiteout::storages::casc::Storage*>(self)->fileExists(std::string(cascPath ? cascPath : ""));
}

int32_t whiteout_casc_CascStorage_fileExists_fileId_hint(const whiteout_CascStorage* self, int32_t fileId, int32_t hint) {
    return reinterpret_cast<const whiteout::storages::casc::Storage*>(self)->fileExists(fileId, static_cast<whiteout::storages::casc::FileIdHint>(hint));
}

int32_t whiteout_casc_CascStorage_fileSize(const whiteout_CascStorage* self, const char* cascPath, uint64_t* out_value) {
    auto __r = reinterpret_cast<const whiteout::storages::casc::Storage*>(self)->fileSize(std::string(cascPath ? cascPath : ""));
    if (!__r) return 0;
    if (out_value) *out_value = static_cast<uint64_t>(*__r);
    return 1;
}

int32_t whiteout_casc_CascStorage_fileSize_fileId_hint(const whiteout_CascStorage* self, int32_t fileId, int32_t hint, uint64_t* out_value) {
    auto __r = reinterpret_cast<const whiteout::storages::casc::Storage*>(self)->fileSize(fileId, static_cast<whiteout::storages::casc::FileIdHint>(hint));
    if (!__r) return 0;
    if (out_value) *out_value = static_cast<uint64_t>(*__r);
    return 1;
}

size_t whiteout_casc_CascStorage_listFiles_count(const whiteout_CascStorage* self) {
    return reinterpret_cast<const whiteout::storages::casc::Storage*>(self)->listFiles().size();
}

whiteout_CString whiteout_casc_CascStorage_listFiles_at(const whiteout_CascStorage* self, size_t index) {
    const auto& __v = reinterpret_cast<const whiteout::storages::casc::Storage*>(self)->listFiles();
    if (index >= __v.size()) return emptyCString();
    return wrapCString(std::string(__v[index]));
}


struct whiteout_StringList* whiteout_casc_CascStorage_listFiles(const whiteout_CascStorage* self) {
    return reinterpret_cast<struct whiteout_StringList*>(
        new std::vector<std::string>(
            reinterpret_cast<const whiteout::storages::casc::Storage*>(self)->listFiles()));
}
void* whiteout_casc_CascStorage_listEntries_snapshot(const whiteout_CascStorage* self) {
    return new std::vector<whiteout::storages::casc::FindEntry>(reinterpret_cast<const whiteout::storages::casc::Storage*>(self)->listEntries());
}

size_t whiteout_casc_CascStorage_listEntries_count(void* snapshot) {
    return snapshot ? reinterpret_cast<std::vector<whiteout::storages::casc::FindEntry>*>(snapshot)->size() : 0;
}

whiteout_Bytes whiteout_casc_CascStorage_listEntries_cKey_at(void* snapshot, size_t index) {
    auto* __v = reinterpret_cast<std::vector<whiteout::storages::casc::FindEntry>*>(snapshot);
    if (!__v || index >= __v->size()) return emptyBytes();
    const auto& __a = (*__v)[index].cKey;
    return wrapBytes(std::vector<whiteout::u8>(__a.begin(), __a.end()));
}

uint64_t whiteout_casc_CascStorage_listEntries_fileSize_at(void* snapshot, size_t index) {
    auto* __v = reinterpret_cast<std::vector<whiteout::storages::casc::FindEntry>*>(snapshot);
    if (!__v || index >= __v->size()) return 0;
    return (*__v)[index].fileSize;
}

uint32_t whiteout_casc_CascStorage_listEntries_localeFlags_at(void* snapshot, size_t index) {
    auto* __v = reinterpret_cast<std::vector<whiteout::storages::casc::FindEntry>*>(snapshot);
    if (!__v || index >= __v->size()) return 0;
    return (*__v)[index].localeFlags;
}

uint32_t whiteout_casc_CascStorage_listEntries_contentFlags_at(void* snapshot, size_t index) {
    auto* __v = reinterpret_cast<std::vector<whiteout::storages::casc::FindEntry>*>(snapshot);
    if (!__v || index >= __v->size()) return 0;
    return (*__v)[index].contentFlags;
}

int32_t whiteout_casc_CascStorage_listEntries_fileDataId_at(void* snapshot, size_t index) {
    auto* __v = reinterpret_cast<std::vector<whiteout::storages::casc::FindEntry>*>(snapshot);
    if (!__v || index >= __v->size()) return 0;
    return (*__v)[index].fileDataId;
}

whiteout_CString whiteout_casc_CascStorage_listEntries_path_at(void* snapshot, size_t index) {
    auto* __v = reinterpret_cast<std::vector<whiteout::storages::casc::FindEntry>*>(snapshot);
    if (!__v || index >= __v->size()) return emptyCString();
    return wrapCString(std::string((*__v)[index].path));
}

void whiteout_casc_CascStorage_listEntries_free(void* snapshot) {
    delete reinterpret_cast<std::vector<whiteout::storages::casc::FindEntry>*>(snapshot);
}

int32_t whiteout_casc_CascStorage_totalFileCount(const whiteout_CascStorage* self, uint32_t* out_value) {
    auto __r = reinterpret_cast<const whiteout::storages::casc::Storage*>(self)->totalFileCount();
    if (!__r) return 0;
    if (out_value) *out_value = static_cast<uint32_t>(*__r);
    return 1;
}

int32_t whiteout_casc_CascStorage_importKeysFromString(whiteout_CascStorage* self, const char* keyList) {
    return reinterpret_cast<whiteout::storages::casc::Storage*>(self)->importKeysFromString(std::string(keyList ? keyList : ""));
}

int32_t whiteout_casc_CascStorage_importKeysFromFile(whiteout_CascStorage* self, const char* keyFilePath) {
    return reinterpret_cast<whiteout::storages::casc::Storage*>(self)->importKeysFromFile(std::string(keyFilePath ? keyFilePath : ""));
}

void whiteout_casc_CascStorage_setZeroFillEncrypted(whiteout_CascStorage* self, int32_t on) {
    reinterpret_cast<whiteout::storages::casc::Storage*>(self)->setZeroFillEncrypted(on);
}

int32_t whiteout_casc_CascStorage_findEncryptionKey(const whiteout_CascStorage* self, uint64_t keyName, uint8_t* out_value) {
    auto __r = reinterpret_cast<const whiteout::storages::casc::Storage*>(self)->findEncryptionKey(keyName);
    if (!__r) return 0;
    if (out_value) {
        for (size_t __i = 0; __i < 16; ++__i)
            out_value[__i] = static_cast<uint8_t>((*__r)[__i]);
    }
    return 1;
}

void whiteout_casc_CascStorage_flushCache(whiteout_CascStorage* self) {
    reinterpret_cast<whiteout::storages::casc::Storage*>(self)->flushCache();
}

int32_t whiteout_casc_CascStorage_prefetch(whiteout_CascStorage* self) {
    return reinterpret_cast<whiteout::storages::casc::Storage*>(self)->prefetch();
}

uint32_t whiteout_casc_CascStorage_lastError(void) {
    return whiteout::storages::casc::Storage::lastError();
}

} // extern "C"

// ── CascStorageWritable ─────────────────────────────────────────────────

extern "C" {

void whiteout_casc_CascStorageWritable_delete(whiteout_CascStorageWritable* self) {
    delete reinterpret_cast<whiteout::storages::casc::StorageWritable*>(self);
}

struct whiteout_CascStorageWritable* whiteout_casc_CascStorageWritable_create(struct whiteout_CascCreateOptions* opts, void* pool) {
    return reinterpret_cast<struct whiteout_CascStorageWritable*>(
        new whiteout::storages::casc::StorageWritable(whiteout::storages::casc::StorageWritable::create(*reinterpret_cast<const whiteout::storages::casc::CreateOptions*>(opts), reinterpret_cast<whiteout::interfaces::WorkerPool*>(pool))));
}

int32_t whiteout_casc_CascStorageWritable_reserveFileId(whiteout_CascStorageWritable* self, const char* name, uint32_t* out_value) {
    auto __r = reinterpret_cast<whiteout::storages::casc::StorageWritable*>(self)->reserveFileId(std::string(name ? name : ""));
    if (!__r) return 0;
    if (out_value) *out_value = static_cast<uint32_t>(*__r);
    return 1;
}

int32_t whiteout_casc_CascStorageWritable_writeFile(whiteout_CascStorageWritable* self, const char* path, const uint8_t* data, size_t data_size, struct whiteout_CascWriteOptions* opts) {
    return reinterpret_cast<whiteout::storages::casc::StorageWritable*>(self)->writeFile(std::string(path ? path : ""), std::vector<whiteout::u8>(data, data + data_size), *reinterpret_cast<const whiteout::storages::casc::WriteOptions*>(opts));
}

int32_t whiteout_casc_CascStorageWritable_writeFile_fileId_data_opts_hint(whiteout_CascStorageWritable* self, int32_t fileId, const uint8_t* data, size_t data_size, struct whiteout_CascWriteOptions* opts, int32_t hint) {
    return reinterpret_cast<whiteout::storages::casc::StorageWritable*>(self)->writeFile(fileId, std::vector<whiteout::u8>(data, data + data_size), *reinterpret_cast<const whiteout::storages::casc::WriteOptions*>(opts), static_cast<whiteout::storages::casc::FileIdHint>(hint));
}

int32_t whiteout_casc_CascStorageWritable_deleteFile(whiteout_CascStorageWritable* self, const char* path) {
    return reinterpret_cast<whiteout::storages::casc::StorageWritable*>(self)->deleteFile(std::string(path ? path : ""));
}

int32_t whiteout_casc_CascStorageWritable_deleteFile_fileId_hint(whiteout_CascStorageWritable* self, int32_t fileId, int32_t hint) {
    return reinterpret_cast<whiteout::storages::casc::StorageWritable*>(self)->deleteFile(fileId, static_cast<whiteout::storages::casc::FileIdHint>(hint));
}

int32_t whiteout_casc_CascStorageWritable_save(whiteout_CascStorageWritable* self) {
    return reinterpret_cast<whiteout::storages::casc::StorageWritable*>(self)->save();
}

int32_t whiteout_casc_CascStorageWritable_save_path(whiteout_CascStorageWritable* self, const char* path) {
    return reinterpret_cast<whiteout::storages::casc::StorageWritable*>(self)->save(std::string(path ? path : ""));
}

} // extern "C"