blob: d8b6487f3f26265e98ea7dbb3029ab757f0625ec [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <lib/cksum.h>
#include <zircon/assert.h>
#include <zircon/types.h>
#include <initializer_list>
#include <fbl/array.h>
#include <src/lib/chunked-compression/chunked-archive.h>
#include <zxtest/zxtest.h>
namespace chunked_compression {
namespace {
uint32_t ComputeChecksum(const uint8_t* header, size_t header_length) {
constexpr size_t kOffsetAfterChecksum = kChunkArchiveHeaderCrc32Offset + sizeof(uint32_t);
EXPECT_LT(kOffsetAfterChecksum, header_length);
// Independently compute a checksum for the bytes before and after the CRC32 slot, using the first
// as a seed for the second to combine them.
constexpr uint32_t seed = 0u;
uint32_t first_crc = crc32(seed, header, kChunkArchiveHeaderCrc32Offset);
return crc32(first_crc, header + kOffsetAfterChecksum, header_length - kOffsetAfterChecksum);
}
} // namespace
fbl::Array<uint8_t> CreateHeader(std::initializer_list<SeekTableEntry> entries) {
unsigned num_entries = static_cast<unsigned>(entries.size());
size_t sz = kChunkArchiveSeekTableOffset + (num_entries * sizeof(SeekTableEntry));
fbl::Array<uint8_t> buf(new uint8_t[sz], sz);
bzero(buf.get(), sz);
// In practice the magic is always at the start of the header, but for consistency with other
// accesses we offset |data| by |kChunkArchiveMagicOffset|.
memcpy(buf.get(), kChunkArchiveMagic, kArchiveMagicLength);
reinterpret_cast<ArchiveVersionType*>(buf.get() + kChunkArchiveVersionOffset)[0] = kVersion;
reinterpret_cast<ChunkCountType*>(buf.get() + kChunkArchiveNumChunksOffset)[0] = num_entries;
for (unsigned i = 0; i < num_entries; ++i) {
reinterpret_cast<SeekTableEntry*>(buf.get() + kChunkArchiveSeekTableOffset)[i] =
entries.begin()[i];
}
reinterpret_cast<uint32_t*>(buf.get() + kChunkArchiveHeaderCrc32Offset)[0] =
ComputeChecksum(buf.get(), sz);
return buf;
}
} // namespace chunked_compression