whiteoutlib 0.1.6

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
// 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 mpq --backend c-source

#include "whiteout_mpq.h"

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

#include <whiteout/storages/mpq/types.h>
#include <whiteout/storages/mpq/storage.h>
#include <whiteout/utils/mpq_file_system.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_mpq_StringList_size(const whiteout_StringList* self) {
    return reinterpret_cast<const std::vector<std::string>*>(self)->size();
}

whiteout_CString whiteout_mpq_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_mpq_StringList_delete(whiteout_StringList* self) {
    delete reinterpret_cast<std::vector<std::string>*>(self);
}
// ── MpqFileInfo ─────────────────────────────────────────────────

extern "C" {

whiteout_MpqFileInfo* whiteout_mpq_MpqFileInfo_new(void) {
    return reinterpret_cast<whiteout_MpqFileInfo*>(new whiteout::storages::mpq::FileInfo());
}

void whiteout_mpq_MpqFileInfo_delete(whiteout_MpqFileInfo* self) {
    delete reinterpret_cast<whiteout::storages::mpq::FileInfo*>(self);
}

whiteout_CString whiteout_mpq_MpqFileInfo_get_name(const whiteout_MpqFileInfo* self) {
    auto* __owned = new std::string(reinterpret_cast<const whiteout::storages::mpq::FileInfo*>(self)->name);
    return whiteout_CString{ __owned->c_str(), __owned->size(), __owned };
}

void whiteout_mpq_MpqFileInfo_set_name(whiteout_MpqFileInfo* self, const char* value) {
    reinterpret_cast<whiteout::storages::mpq::FileInfo*>(self)->name = (value ? value : "");
}

uint32_t whiteout_mpq_MpqFileInfo_get_compressedSize(const whiteout_MpqFileInfo* self) {
    return reinterpret_cast<const whiteout::storages::mpq::FileInfo*>(self)->compressedSize;
}

void whiteout_mpq_MpqFileInfo_set_compressedSize(whiteout_MpqFileInfo* self, uint32_t value) {
    reinterpret_cast<whiteout::storages::mpq::FileInfo*>(self)->compressedSize = value;
}

uint32_t whiteout_mpq_MpqFileInfo_get_uncompressedSize(const whiteout_MpqFileInfo* self) {
    return reinterpret_cast<const whiteout::storages::mpq::FileInfo*>(self)->uncompressedSize;
}

void whiteout_mpq_MpqFileInfo_set_uncompressedSize(whiteout_MpqFileInfo* self, uint32_t value) {
    reinterpret_cast<whiteout::storages::mpq::FileInfo*>(self)->uncompressedSize = value;
}

int32_t whiteout_mpq_MpqFileInfo_get_flags(const whiteout_MpqFileInfo* self) {
    return static_cast<int32_t>(reinterpret_cast<const whiteout::storages::mpq::FileInfo*>(self)->flags);
}

void whiteout_mpq_MpqFileInfo_set_flags(whiteout_MpqFileInfo* self, int32_t value) {
    reinterpret_cast<whiteout::storages::mpq::FileInfo*>(self)->flags = static_cast<whiteout::storages::mpq::FileFlags>(value);
}

uint16_t whiteout_mpq_MpqFileInfo_get_locale(const whiteout_MpqFileInfo* self) {
    return reinterpret_cast<const whiteout::storages::mpq::FileInfo*>(self)->locale;
}

void whiteout_mpq_MpqFileInfo_set_locale(whiteout_MpqFileInfo* self, uint16_t value) {
    reinterpret_cast<whiteout::storages::mpq::FileInfo*>(self)->locale = value;
}

} // extern "C"

// ── MpqArchiveInfo ─────────────────────────────────────────────────

extern "C" {

whiteout_MpqArchiveInfo* whiteout_mpq_MpqArchiveInfo_new(void) {
    return reinterpret_cast<whiteout_MpqArchiveInfo*>(new whiteout::storages::mpq::ArchiveInfo());
}

void whiteout_mpq_MpqArchiveInfo_delete(whiteout_MpqArchiveInfo* self) {
    delete reinterpret_cast<whiteout::storages::mpq::ArchiveInfo*>(self);
}

uint16_t whiteout_mpq_MpqArchiveInfo_get_formatVersion(const whiteout_MpqArchiveInfo* self) {
    return reinterpret_cast<const whiteout::storages::mpq::ArchiveInfo*>(self)->formatVersion;
}

void whiteout_mpq_MpqArchiveInfo_set_formatVersion(whiteout_MpqArchiveInfo* self, uint16_t value) {
    reinterpret_cast<whiteout::storages::mpq::ArchiveInfo*>(self)->formatVersion = value;
}

uint32_t whiteout_mpq_MpqArchiveInfo_get_hashTableEntries(const whiteout_MpqArchiveInfo* self) {
    return reinterpret_cast<const whiteout::storages::mpq::ArchiveInfo*>(self)->hashTableEntries;
}

void whiteout_mpq_MpqArchiveInfo_set_hashTableEntries(whiteout_MpqArchiveInfo* self, uint32_t value) {
    reinterpret_cast<whiteout::storages::mpq::ArchiveInfo*>(self)->hashTableEntries = value;
}

uint32_t whiteout_mpq_MpqArchiveInfo_get_blockTableEntries(const whiteout_MpqArchiveInfo* self) {
    return reinterpret_cast<const whiteout::storages::mpq::ArchiveInfo*>(self)->blockTableEntries;
}

void whiteout_mpq_MpqArchiveInfo_set_blockTableEntries(whiteout_MpqArchiveInfo* self, uint32_t value) {
    reinterpret_cast<whiteout::storages::mpq::ArchiveInfo*>(self)->blockTableEntries = value;
}

uint32_t whiteout_mpq_MpqArchiveInfo_get_sectorSize(const whiteout_MpqArchiveInfo* self) {
    return reinterpret_cast<const whiteout::storages::mpq::ArchiveInfo*>(self)->sectorSize;
}

void whiteout_mpq_MpqArchiveInfo_set_sectorSize(whiteout_MpqArchiveInfo* self, uint32_t value) {
    reinterpret_cast<whiteout::storages::mpq::ArchiveInfo*>(self)->sectorSize = value;
}

uint64_t whiteout_mpq_MpqArchiveInfo_get_archiveSize(const whiteout_MpqArchiveInfo* self) {
    return reinterpret_cast<const whiteout::storages::mpq::ArchiveInfo*>(self)->archiveSize;
}

void whiteout_mpq_MpqArchiveInfo_set_archiveSize(whiteout_MpqArchiveInfo* self, uint64_t value) {
    reinterpret_cast<whiteout::storages::mpq::ArchiveInfo*>(self)->archiveSize = value;
}

} // extern "C"

// ── MpqWriteOptions ─────────────────────────────────────────────────

extern "C" {

whiteout_MpqWriteOptions* whiteout_mpq_MpqWriteOptions_new(void) {
    return reinterpret_cast<whiteout_MpqWriteOptions*>(new whiteout::storages::mpq::WriteOptions());
}

void whiteout_mpq_MpqWriteOptions_delete(whiteout_MpqWriteOptions* self) {
    delete reinterpret_cast<whiteout::storages::mpq::WriteOptions*>(self);
}

int32_t whiteout_mpq_MpqWriteOptions_get_compression(const whiteout_MpqWriteOptions* self) {
    return static_cast<int32_t>(reinterpret_cast<const whiteout::storages::mpq::WriteOptions*>(self)->compression);
}

void whiteout_mpq_MpqWriteOptions_set_compression(whiteout_MpqWriteOptions* self, int32_t value) {
    reinterpret_cast<whiteout::storages::mpq::WriteOptions*>(self)->compression = static_cast<whiteout::storages::mpq::Compression>(value);
}

uint16_t whiteout_mpq_MpqWriteOptions_get_locale(const whiteout_MpqWriteOptions* self) {
    return reinterpret_cast<const whiteout::storages::mpq::WriteOptions*>(self)->locale;
}

void whiteout_mpq_MpqWriteOptions_set_locale(whiteout_MpqWriteOptions* self, uint16_t value) {
    reinterpret_cast<whiteout::storages::mpq::WriteOptions*>(self)->locale = value;
}

int32_t whiteout_mpq_MpqWriteOptions_get_encrypt(const whiteout_MpqWriteOptions* self) {
    return reinterpret_cast<const whiteout::storages::mpq::WriteOptions*>(self)->encrypt;
}

void whiteout_mpq_MpqWriteOptions_set_encrypt(whiteout_MpqWriteOptions* self, int32_t value) {
    reinterpret_cast<whiteout::storages::mpq::WriteOptions*>(self)->encrypt = value;
}

int32_t whiteout_mpq_MpqWriteOptions_get_singleUnit(const whiteout_MpqWriteOptions* self) {
    return reinterpret_cast<const whiteout::storages::mpq::WriteOptions*>(self)->singleUnit;
}

void whiteout_mpq_MpqWriteOptions_set_singleUnit(whiteout_MpqWriteOptions* self, int32_t value) {
    reinterpret_cast<whiteout::storages::mpq::WriteOptions*>(self)->singleUnit = value;
}

} // extern "C"

// ── MpqCreateOptions ─────────────────────────────────────────────────

extern "C" {

whiteout_MpqCreateOptions* whiteout_mpq_MpqCreateOptions_new(void) {
    return reinterpret_cast<whiteout_MpqCreateOptions*>(new whiteout::storages::mpq::CreateOptions());
}

void whiteout_mpq_MpqCreateOptions_delete(whiteout_MpqCreateOptions* self) {
    delete reinterpret_cast<whiteout::storages::mpq::CreateOptions*>(self);
}

int32_t whiteout_mpq_MpqCreateOptions_get_version(const whiteout_MpqCreateOptions* self) {
    return static_cast<int32_t>(reinterpret_cast<const whiteout::storages::mpq::CreateOptions*>(self)->version);
}

void whiteout_mpq_MpqCreateOptions_set_version(whiteout_MpqCreateOptions* self, int32_t value) {
    reinterpret_cast<whiteout::storages::mpq::CreateOptions*>(self)->version = static_cast<whiteout::storages::mpq::FormatVersion>(value);
}

uint32_t whiteout_mpq_MpqCreateOptions_get_hashTableSize(const whiteout_MpqCreateOptions* self) {
    return reinterpret_cast<const whiteout::storages::mpq::CreateOptions*>(self)->hashTableSize;
}

void whiteout_mpq_MpqCreateOptions_set_hashTableSize(whiteout_MpqCreateOptions* self, uint32_t value) {
    reinterpret_cast<whiteout::storages::mpq::CreateOptions*>(self)->hashTableSize = value;
}

uint16_t whiteout_mpq_MpqCreateOptions_get_sectorSizeShift(const whiteout_MpqCreateOptions* self) {
    return reinterpret_cast<const whiteout::storages::mpq::CreateOptions*>(self)->sectorSizeShift;
}

void whiteout_mpq_MpqCreateOptions_set_sectorSizeShift(whiteout_MpqCreateOptions* self, uint16_t value) {
    reinterpret_cast<whiteout::storages::mpq::CreateOptions*>(self)->sectorSizeShift = value;
}

} // extern "C"

// ── MpqStorage ─────────────────────────────────────────────────

extern "C" {

void whiteout_mpq_MpqStorage_delete(whiteout_MpqStorage* self) {
    delete reinterpret_cast<whiteout::storages::mpq::Storage*>(self);
}

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

struct whiteout_MpqStorage* whiteout_mpq_MpqStorage_create(struct whiteout_MpqCreateOptions* opts, void* pool) {
    return reinterpret_cast<struct whiteout_MpqStorage*>(
        new whiteout::storages::mpq::Storage(whiteout::storages::mpq::Storage::create(*reinterpret_cast<const whiteout::storages::mpq::CreateOptions*>(opts), reinterpret_cast<whiteout::interfaces::WorkerPool*>(pool))));
}

void whiteout_mpq_MpqStorage_close(whiteout_MpqStorage* self) {
    reinterpret_cast<whiteout::storages::mpq::Storage*>(self)->close();
}

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

whiteout_Bytes whiteout_mpq_MpqStorage_readFile_name_locale(const whiteout_MpqStorage* self, const char* name, uint16_t locale) {
    auto __r = reinterpret_cast<const whiteout::storages::mpq::Storage*>(self)->readFile(std::string(name ? name : ""), locale);
    if (!__r) return emptyBytes();
    return wrapBytes(std::move(*__r));
}

int32_t whiteout_mpq_MpqStorage_fileExists(const whiteout_MpqStorage* self, const char* name) {
    return reinterpret_cast<const whiteout::storages::mpq::Storage*>(self)->fileExists(std::string(name ? name : ""));
}

struct whiteout_MpqFileInfo* whiteout_mpq_MpqStorage_fileInfo(const whiteout_MpqStorage* self, const char* name) {
    auto __r = reinterpret_cast<const whiteout::storages::mpq::Storage*>(self)->fileInfo(std::string(name ? name : ""));
    if (!__r) return nullptr;
    return reinterpret_cast<struct whiteout_MpqFileInfo*>(
        new whiteout::storages::mpq::FileInfo(std::move(*__r)));
}

struct whiteout_MpqArchiveInfo* whiteout_mpq_MpqStorage_archiveInfo(const whiteout_MpqStorage* self) {
    return reinterpret_cast<struct whiteout_MpqArchiveInfo*>(
        new whiteout::storages::mpq::ArchiveInfo(reinterpret_cast<const whiteout::storages::mpq::Storage*>(self)->archiveInfo()));
}

size_t whiteout_mpq_MpqStorage_listFiles_count(const whiteout_MpqStorage* self) {
    return reinterpret_cast<const whiteout::storages::mpq::Storage*>(self)->listFiles().size();
}

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


struct whiteout_StringList* whiteout_mpq_MpqStorage_listFiles(const whiteout_MpqStorage* self) {
    return reinterpret_cast<struct whiteout_StringList*>(
        new std::vector<std::string>(
            reinterpret_cast<const whiteout::storages::mpq::Storage*>(self)->listFiles()));
}
int32_t whiteout_mpq_MpqStorage_writeFile(whiteout_MpqStorage* self, const char* name, const uint8_t* data, size_t data_size, struct whiteout_MpqWriteOptions* opts) {
    return reinterpret_cast<whiteout::storages::mpq::Storage*>(self)->writeFile(std::string(name ? name : ""), std::span<const whiteout::u8>(data, data_size), *reinterpret_cast<const whiteout::storages::mpq::WriteOptions*>(opts));
}

int32_t whiteout_mpq_MpqStorage_deleteFile(whiteout_MpqStorage* self, const char* name) {
    return reinterpret_cast<whiteout::storages::mpq::Storage*>(self)->deleteFile(std::string(name ? name : ""));
}

int32_t whiteout_mpq_MpqStorage_save(whiteout_MpqStorage* self) {
    return reinterpret_cast<whiteout::storages::mpq::Storage*>(self)->save();
}

int32_t whiteout_mpq_MpqStorage_save_path(whiteout_MpqStorage* self, const char* path) {
    return reinterpret_cast<whiteout::storages::mpq::Storage*>(self)->save(std::string(path ? path : ""));
}

} // extern "C"

// ── MpqFileSystem ─────────────────────────────────────────────────

extern "C" {

whiteout_MpqFileSystem* whiteout_mpq_MpqFileSystem_new_storage(struct whiteout_MpqStorage* storage) {
    return reinterpret_cast<whiteout_MpqFileSystem*>(new whiteout::utils::MpqFileSystem(*reinterpret_cast<whiteout::storages::mpq::Storage*>(storage)));
}

void whiteout_mpq_MpqFileSystem_delete(whiteout_MpqFileSystem* self) {
    delete reinterpret_cast<whiteout::utils::MpqFileSystem*>(self);
}

whiteout_Bytes whiteout_mpq_MpqFileSystem_readFile(const whiteout_MpqFileSystem* self, const char* path) {
    return wrapBytes(reinterpret_cast<const whiteout::utils::MpqFileSystem*>(self)->readFile(std::string(path ? path : "")));
}

int32_t whiteout_mpq_MpqFileSystem_writeFile(whiteout_MpqFileSystem* self, const char* path, const uint8_t* data, size_t data_size) {
    return reinterpret_cast<whiteout::utils::MpqFileSystem*>(self)->writeFile(std::string(path ? path : ""), std::vector<whiteout::u8>(data, data + data_size));
}

int32_t whiteout_mpq_MpqFileSystem_fileExists(const whiteout_MpqFileSystem* self, const char* path) {
    return reinterpret_cast<const whiteout::utils::MpqFileSystem*>(self)->fileExists(std::string(path ? path : ""));
}

} // extern "C"