| // 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 |