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
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2026 Fernando Sahmkow
/// @file constants.h
/// @brief Shared CASC module constants and small utilities.
///
/// Internal header — not part of the public include path.
/// Only constants used by more than one translation unit belong here.
/// Single-file constants live in their respective .cpp files.
#pragma once
#include <whiteout/common_types.h>
#include "../../common/hex.h"
#include <array>
#include <string>
namespace whiteout::storages::casc {
// ============================================================================
// Archive constants
// ============================================================================
/// Size of the per-entry header prepended to each BLTE blob in a data archive.
/// Layout: EKey(16 reversed) + encodedSize(4 LE) + flags(2) + checksum(8) = 30 bytes.
static constexpr u32 kArchiveEntryHeaderSize = 30;
/// Archive slots reserved per chunk in a static-build-config install, whose
/// archives are named `data.<chunk>.<uid>` rather than `data.<n>`.
static constexpr u32 kStaticArchiveUidSpan = 256;
/// Flatten a static-layout `data.<chunk>.<uid>` name into an archive slot.
inline constexpr u32 staticArchiveSlot(u32 chunk, u32 uid) noexcept {
return chunk * kStaticArchiveUidSpan + uid;
}
/// Container cache budget for Diablo IV, whose root entries are slices of
/// shared combined-meta containers. 3.0.x ships 30 of them, 382 MB decoded in
/// total and 33 MB for the largest; a budget that cannot hold the working set
/// thrashes, and each miss costs a full container re-decode. The cache fills
/// lazily, so this is a ceiling and not an allocation.
static constexpr size_t kD4ContainerCacheSize = 512ull * 1024 * 1024;
// ============================================================================
// Key sizes
// ============================================================================
/// Standard content key size (MD5, 16 bytes).
static constexpr u8 kCKeySize = 16;
/// Standard encoding key size (MD5, 16 bytes).
static constexpr u8 kEKeySize = 16;
// ============================================================================
// TVFS constants (shared between parser and writer)
// ============================================================================
/// TVFS format version.
static constexpr u8 kTvfsFormatVersion = 1;
/// TVFS path table control bytes.
static constexpr u8 kTvfsPathSeparator = 0x00;
static constexpr u8 kTvfsNodeValueMarker = 0xFF;
/// TVFS folder node indicator bit (bit 31 of nodeValue).
static constexpr u32 kTvfsFolderNodeBit = 0x80000000;
// ============================================================================
// Utility
// ============================================================================
/// Build a config file path from a base directory and a 16-byte hash key.
/// Result: <baseDir>/config/XX/YY/<hex32>
inline std::string configFilePath(const std::string& baseDir, const std::array<u8, 16>& key) {
auto hash = storages::common::hexEncode16(key);
return baseDir + "/config/" + hash.substr(0, 2) + "/" + hash.substr(2, 2) + "/" + hash;
}
} // namespace whiteout::storages::casc