15#include <catch_amalgamated.hpp>
24std::vector<uint8_t> sampleData(
size_t n)
27 std::vector<uint8_t>
data(
n);
29 for (
size_t i = 0;
i <
n; ++
i) {
35auto const allAlgos = {Algo::ZSTD, Algo::ZLIB, Algo::LZMA, Algo::LZ4};
38TEST_CASE(
"xxh64 matches the reference implementation")
40 std::vector<uint8_t> big(768);
41 for (
size_t i = 0;
i < big.size(); ++
i) {
45 CHECK(
xxh64(std::vector<uint8_t>{
'a'}) == 0xd24ec4f1a98c6e5bULL);
46 CHECK(
xxh64(std::vector<uint8_t>{
'a',
'b',
'c'}) == 0x44bc2cf5ad770999ULL);
52 auto data = sampleData(100000);
53 for (
auto algo : allAlgos) {
55 std::vector<uint8_t> out(
data.size());
63 auto data = sampleData(50000);
64 for (
auto algo : allAlgos) {
66 std::vector<uint8_t> out(
data.size());
72TEST_CASE(
"bounded decompression stops exactly at maxOut")
74 auto data = sampleData(40000);
75 for (
auto algo : allAlgos) {
76 for (
size_t maxOut : {size_t(1), size_t(9999), size_t(10000), size_t(25001), size_t(39999)}) {
79 std::vector<uint8_t> out(maxOut + 1, 0xAB);
81 CHECK(std::equal(out.begin(), out.begin() + maxOut,
data.begin()));
82 CHECK(out[maxOut] == 0xAB);
87TEST_CASE(
"prefix reads of large chunks stop exactly at the bound")
91 auto data = sampleData(1 << 20);
92 constexpr size_t block = 128 * 1024;
93 for (
auto algo : allAlgos) {
95 for (
size_t maxOut : {size_t(1), block - 1, block, block + 1, 2 * block + 17, size_t(599999), size_t(600000), size_t(600001),
data.size() - 1}) {
96 INFO(
"algorithm " << (
int)algo <<
", bound " << maxOut);
97 std::vector<uint8_t> out(maxOut + 64, 0xAB);
100 CHECK(std::equal(out.begin(), out.begin() + maxOut,
data.begin()));
101 CHECK(std::all_of(out.begin() + maxOut, out.end(), [](uint8_t
b) { return b == 0xAB; }));
108 auto data = sampleData(1000);
110 std::vector<uint8_t> out(
data.size());
113 CHECK_THROWS_AS(d.read(out.data(), 10), std::logic_error);
116TEST_CASE(
"incremental reads of odd sizes produce the same bytes")
118 auto data = sampleData(70000);
119 for (
auto algo : allAlgos) {
122 std::vector<uint8_t> out(
data.size());
124 for (
size_t step = 1;
pos <
data.size(); step = step * 3 + 1) {
125 auto n = std::min(step,
data.size() -
pos);
126 d.read(out.data() +
pos,
n);
136 auto data = sampleData(30000);
137 for (
auto algo : allAlgos) {
139 std::vector<uint8_t> out(
data.size());
140 for (
size_t keep : {size_t(0), size_t(5), payload.size() / 2, payload.size() - 1}) {
141 std::vector<uint8_t> truncated(payload.begin(), payload.begin() + keep);
149 auto data = sampleData(30000);
150 for (
auto algo : allAlgos) {
152 std::vector<uint8_t> out(
data.size());
154 auto corrupt = payload;
155 for (
size_t i = corrupt.size() / 3;
i < corrupt.size() / 3 + 16; ++
i) {
165 auto wrongSize = payload;
166 wrongSize[6] ^= 0x01;
173 auto data = sampleData(5000);
176 std::vector<uint8_t> out(
data.size());
180TEST_CASE(
"legacy and unknown algorithms are unsupported")
182 auto data = sampleData(100);
184 std::vector<uint8_t> out(
data.size());
193TEST_CASE(
"chunks larger than the object length are rejected")
195 auto data = sampleData(1000);
197 std::vector<uint8_t> out(
data.size());
void readPrefix(uint8_t *dst, size_t n)
GLboolean GLboolean GLboolean b
std::vector< uint8_t > rootCompress(Algo algo, std::span< const uint8_t > in, size_t chunkSize=0xffffff)
size_t decompressBounded(std::span< const uint8_t > src, uint32_t objLen, uint8_t *dst, size_t maxOut, std::string const &file="<memory>", uint64_t fileOffset=0)
uint64_t xxh64(std::span< const uint8_t > data)
XXH64 with seed 0, as used for the LZ4 chunk checksum.
uint8_t itsSharedClusterMap uint8_t
TEST_CASE("xxh64 matches the reference implementation")