| // 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> | |
| namespace chunked_compression { | |
| namespace test_utils { | |
| uint32_t ComputeChecksum(const uint8_t* header, size_t header_length) { | |
| constexpr size_t kOffsetAfterChecksum = kChunkArchiveHeaderCrc32Offset + sizeof(uint32_t); | |
| ZX_ASSERT(kOffsetAfterChecksum < header_length); | |
| ZX_ASSERT(kChunkArchiveMinHeaderSize <= 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); | |
| } | |
| 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 test_utils | |
| } // namespace chunked_compression |