59 std::span<const ArchiveBuildItem> items,
65 "legacy DAT archives require at least one index item"));
71 "archive item count exceeds the 16-bit DataTag space"));
78 "zlib compression level must be between 0 and 9"));
85 std::uint32_t uncompressedSize{};
90 std::vector<EncodedItem>
encoded;
93 const std::uint64_t dataStart =
96 std::uint64_t nextOffset = dataStart;
98 for (
const auto& item : items)
100 if (item.emptySlot())
110 "present items require a non-Unknown type and payload"));
113 if (item.payload.size() >
static_cast<std::size_t
>(
114 std::numeric_limits<std::int32_t>::max()))
117 "uncompressed item exceeds the signed Win32 size field"));
121 static_cast<uLong>(item.payload.size()));
127 reinterpret_cast<const Bytef*
>(item.payload.data()),
128 static_cast<uLong>(item.payload.size()),
134 "zlib failed while compressing an archive item"));
139 if (
compressed.size() >
static_cast<std::size_t
>(
140 std::numeric_limits<std::int32_t>::max()) ||
141 nextOffset >
static_cast<std::uint64_t
>(
142 std::numeric_limits<std::int32_t>::max()) ||
143 nextOffset +
compressed.size() >
static_cast<std::uint64_t
>(
144 std::numeric_limits<std::int32_t>::max()))
147 "archive offsets exceed the signed Win32 DAT fields"));
153 static_cast<std::uint32_t
>(nextOffset),
154 static_cast<std::uint32_t
>(item.payload.size()),
159 nextOffset +=
encoded.back().compressed.size();
163 archive.reserve(
static_cast<std::size_t
>(nextOffset));
165 for (
const char value : {
'A',
'r',
't',
'e',
'c',
'h',
'\0',
'\0' })
167 archive.push_back(
static_cast<std::byte
>(
value));
176 appendU32Le(archive,
static_cast<std::uint32_t
>(items.size()));
179 for (
const auto& item :
encoded)
194 static_cast<std::uint32_t
>(item.type));
197 static_cast<std::uint32_t
>(item.compressed.size()));
200 for (
const auto& item :
encoded)
204 item.compressed.begin(),
205 item.compressed.end());
209 const auto checksumBytes = std::span<const std::byte>(archive).subspan(
216 const auto amount = std::min<std::size_t>(
218 static_cast<std::size_t
>(
219 std::numeric_limits<uInt>::max()));
222 reinterpret_cast<const Bytef*
>(
224 static_cast<uInt>(amount));
231 static_cast<std::uint32_t
>(
checksum));
std::vector< std::byte > bytes