-#include "crcsync/crcsync.h"
-#include "../crcsync.c"
-#include "tap/tap.h"
+#include <ccan/crcsync/crcsync.h>
+#include <ccan/crcsync/crcsync.c>
+#include <ccan/tap/tap.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
const struct result results[], size_t num_results)
{
struct crc_context *ctx;
- size_t used, ret, i, curr_literal, finalsize;
+ size_t used, ret, i, curr_literal, tailsize;
long result;
- uint32_t crcs[num_blocks(len1, block_size)];
+ uint64_t crcs[num_blocks(len1, block_size)];
- crc_of_blocks(buffer1, len1, block_size, 32, crcs);
+ crc_of_blocks(buffer1, len1, block_size, 64, crcs);
- finalsize = len1 % block_size ?: block_size;
+ tailsize = len1 % block_size;
/* Normal method. */
- ctx = crc_context_new(block_size, 32, crcs, ARRAY_SIZE(crcs),
- finalsize);
+ ctx = crc_context_new(block_size, 64, crcs, ARRAY_SIZE(crcs),
+ tailsize);
curr_literal = 0;
for (used = 0, i = 0; used < len2; used += ret) {
crc_context_free(ctx);
/* Byte-at-a-time method. */
- ctx = crc_context_new(block_size, 32, crcs, ARRAY_SIZE(crcs),
- finalsize);
+ ctx = crc_context_new(block_size, 64, crcs, ARRAY_SIZE(crcs),
+ tailsize);
curr_literal = 0;
for (used = 0, i = 0; used < len2; used += ret) {
crc_context_free(ctx);
}
+#define BUFFER_SIZE 512
+#define BLOCK_SIZE 128
+#define NUM_BLOCKS (BUFFER_SIZE / BLOCK_SIZE)
+
int main(int argc, char *argv[])
{
char *buffer1, *buffer2;
unsigned int i;
- uint32_t crcs1[12], crcs2[12];
+ uint64_t crcs1[NUM_BLOCKS], crcs2[NUM_BLOCKS];
- plan_tests(1454);
+ plan_tests(664);
- buffer1 = calloc(1024, 1);
- buffer2 = calloc(1024, 1);
+ buffer1 = calloc(BUFFER_SIZE, 1);
+ buffer2 = calloc(BUFFER_SIZE, 1);
/* Truncated end block test. */
- crcs1[11] = 0xdeadbeef;
- crc_of_blocks(buffer1, 1024, 100, 32, crcs1);
- ok1(crcs1[11] == 0xdeadbeef);
- crc_of_blocks(buffer2, 1024, 100, 32, crcs2);
- ok1(memcmp(crcs1, crcs2, sizeof(crcs1[0])*11) == 0);
+ crcs1[ARRAY_SIZE(crcs1)-1] = 0xdeadbeef;
+ crc_of_blocks(buffer1, BUFFER_SIZE-BLOCK_SIZE-1, BLOCK_SIZE, 64, crcs1);
+ ok1(crcs1[ARRAY_SIZE(crcs1)-1] == 0xdeadbeef);
+ crc_of_blocks(buffer2, BUFFER_SIZE-BLOCK_SIZE-1, BLOCK_SIZE, 64, crcs2);
+ ok1(memcmp(crcs1, crcs2, sizeof(crcs1[0])*(ARRAY_SIZE(crcs1)-1)) == 0);
/* Fill with non-zero pattern, retest. */
- for (i = 0; i < 1024; i++)
- buffer1[i] = buffer2[i] = i + i/128;
+ for (i = 0; i < BUFFER_SIZE; i++)
+ buffer1[i] = buffer2[i] = i + i/BLOCK_SIZE;
- crcs1[11] = 0xdeadbeef;
- crc_of_blocks(buffer1, 1024, 100, 32, crcs1);
- ok1(crcs1[11] == 0xdeadbeef);
- crc_of_blocks(buffer2, 1024, 100, 32, crcs2);
- ok1(memcmp(crcs1, crcs2, sizeof(crcs1[0])*11) == 0);
+ crcs1[ARRAY_SIZE(crcs1)-1] = 0xdeadbeef;
+ crc_of_blocks(buffer1, BUFFER_SIZE-BLOCK_SIZE-1, BLOCK_SIZE, 64, crcs1);
+ ok1(crcs1[ARRAY_SIZE(crcs1)-1] == 0xdeadbeef);
+ crc_of_blocks(buffer2, BUFFER_SIZE-BLOCK_SIZE-1, BLOCK_SIZE, 64, crcs2);
+ ok1(memcmp(crcs1, crcs2, sizeof(crcs1[0])*(ARRAY_SIZE(crcs1)-1)) == 0);
/* Check that it correctly masks bits. */
- crc_of_blocks(buffer1, 1024, 128, 32, crcs1);
- crc_of_blocks(buffer2, 1024, 128, 8, crcs2);
- for (i = 0; i < 1024/128; i++)
- ok1(crcs2[i] == (crcs1[i] & 0xFF));
+ crc_of_blocks(buffer1, BUFFER_SIZE, BLOCK_SIZE, 64, crcs1);
+ crc_of_blocks(buffer2, BUFFER_SIZE, BLOCK_SIZE, 8, crcs2);
+ for (i = 0; i < NUM_BLOCKS; i++)
+ ok1(crcs2[i] == (crcs1[i] & 0xFF00000000000000ULL));
/* Now test the "exact match" "round blocks" case. */
{
- struct result res[] = {
- { BLOCK, 0 },
- { BLOCK, 1 },
- { BLOCK, 2 },
- { BLOCK, 3 },
- { BLOCK, 4 },
- { BLOCK, 5 },
- { BLOCK, 6 },
- { BLOCK, 7 } };
- test_sync(buffer1, 1024, buffer2, 1024, 128,
+ struct result res[NUM_BLOCKS];
+
+ for (i = 0; i < ARRAY_SIZE(res); i++) {
+ res[i].type = BLOCK;
+ res[i].val = i;
+ }
+ test_sync(buffer1, BUFFER_SIZE, buffer2,
+ BUFFER_SIZE, BLOCK_SIZE,
res, ARRAY_SIZE(res));
}
/* Now test the "exact match" with end block case. */
{
- struct result res[] = {
- { BLOCK, 0 },
- { BLOCK, 1 },
- { BLOCK, 2 },
- { BLOCK, 3 },
- { BLOCK, 4 },
- { BLOCK, 5 },
- { BLOCK, 6 },
- { BLOCK, 7 },
- { BLOCK, 8 },
- { BLOCK, 9 },
- { BLOCK, 10 } };
- test_sync(buffer1, 1024, buffer2, 1024, 100,
+ struct result res[NUM_BLOCKS+1];
+ for (i = 0; i < ARRAY_SIZE(res); i++) {
+ res[i].type = BLOCK;
+ res[i].val = i;
+ }
+ test_sync(buffer1, BUFFER_SIZE, buffer2,
+ BUFFER_SIZE, BLOCK_SIZE-1,
res, ARRAY_SIZE(res));
}
/* Now test the "one byte append" "round blocks" case. */
{
- struct result res[] = {
- { BLOCK, 0 },
- { BLOCK, 1 },
- { BLOCK, 2 },
- { BLOCK, 3 },
- { BLOCK, 4 },
- { BLOCK, 5 },
- { BLOCK, 6 },
- { LITERAL, 1 } };
- test_sync(buffer1, 1024-128, buffer2, 1024-127, 128,
+ struct result res[NUM_BLOCKS];
+ for (i = 0; i < ARRAY_SIZE(res)-1; i++) {
+ res[i].type = BLOCK;
+ res[i].val = i;
+ }
+ res[i].type = LITERAL;
+ res[i].val = 1;
+
+ test_sync(buffer1, BUFFER_SIZE-BLOCK_SIZE,
+ buffer2, BUFFER_SIZE-BLOCK_SIZE+1, BLOCK_SIZE,
res, ARRAY_SIZE(res));
}
/* Now test the "one byte append" with end block case. */
{
- struct result res[] = {
- { BLOCK, 0 },
- { BLOCK, 1 },
- { BLOCK, 2 },
- { BLOCK, 3 },
- { BLOCK, 4 },
- { BLOCK, 5 },
- { BLOCK, 6 },
- { BLOCK, 7 },
- { BLOCK, 8 },
- { BLOCK, 9 },
- { BLOCK, 10 },
- { LITERAL, 1 } };
- test_sync(buffer1, 1023, buffer2, 1024, 100,
- res, ARRAY_SIZE(res));
+ struct result res[NUM_BLOCKS+2];
+ for (i = 0; i < ARRAY_SIZE(res)-1; i++) {
+ res[i].type = BLOCK;
+ res[i].val = i;
+ }
+ res[i].type = LITERAL;
+ res[i].val = 1;
+
+ test_sync(buffer1, BUFFER_SIZE-1,
+ buffer2, BUFFER_SIZE,
+ BLOCK_SIZE - 1, res, ARRAY_SIZE(res));
}
/* Now try changing one block at a time, check we get right results. */
- for (i = 0; i < 1024/128; i++) {
+ for (i = 0; i < NUM_BLOCKS; i++) {
unsigned int j;
- struct result res[8];
+ struct result res[NUM_BLOCKS];
/* Mess with block. */
- memcpy(buffer2, buffer1, 1024);
- buffer2[i * 128]++;
+ memcpy(buffer2, buffer1, BUFFER_SIZE);
+ buffer2[i * BLOCK_SIZE]++;
for (j = 0; j < ARRAY_SIZE(res); j++) {
if (j == i) {
res[j].type = LITERAL;
- res[j].val = 128;
+ res[j].val = BLOCK_SIZE;
} else {
res[j].type = BLOCK;
res[j].val = j;
}
}
- test_sync(buffer1, 1024, buffer2, 1024, 128,
- res, ARRAY_SIZE(res));
+ test_sync(buffer1, BUFFER_SIZE,
+ buffer2, BUFFER_SIZE,
+ BLOCK_SIZE, res, ARRAY_SIZE(res));
}
/* Now try shrinking one block at a time, check we get right results. */
- for (i = 0; i < 1024/128; i++) {
+ for (i = 0; i < NUM_BLOCKS; i++) {
unsigned int j;
- struct result res[8];
+ struct result res[NUM_BLOCKS];
/* Shrink block. */
- memcpy(buffer2, buffer1, i * 128 + 64);
- memcpy(buffer2 + i * 128 + 64, buffer1 + i * 128 + 65,
- 1024 - (i * 128 + 65));
+ memcpy(buffer2, buffer1, i * BLOCK_SIZE + BLOCK_SIZE/2);
+ memcpy(buffer2 + i * BLOCK_SIZE + BLOCK_SIZE/2,
+ buffer1 + i * BLOCK_SIZE + BLOCK_SIZE/2 + 1,
+ BUFFER_SIZE - (i * BLOCK_SIZE + BLOCK_SIZE/2 + 1));
for (j = 0; j < ARRAY_SIZE(res); j++) {
if (j == i) {
res[j].type = LITERAL;
- res[j].val = 127;
+ res[j].val = BLOCK_SIZE-1;
} else {
res[j].type = BLOCK;
res[j].val = j;
}
}
- test_sync(buffer1, 1024, buffer2, 1023, 128,
- res, ARRAY_SIZE(res));
+ test_sync(buffer1, BUFFER_SIZE,
+ buffer2, BUFFER_SIZE-1,
+ BLOCK_SIZE, res, ARRAY_SIZE(res));
}
- /* Now try shrinking one block at a time, check we get right results. */
- for (i = 0; i < 1024/128; i++) {
- unsigned int j;
- struct result res[8];
-
- /* Shrink block. */
- memcpy(buffer2, buffer1, i * 128 + 64);
- memcpy(buffer2 + i * 128 + 64, buffer1 + i * 128 + 65,
- 1024 - (i * 128 + 65));
-
- for (j = 0; j < ARRAY_SIZE(res); j++) {
- if (j == i) {
- res[j].type = LITERAL;
- res[j].val = 127;
+ /* Finally, all possible combinations. */
+ for (i = 0; i < (1 << NUM_BLOCKS); i++) {
+ unsigned int j, num_res;
+ struct result res[NUM_BLOCKS];
+
+ memcpy(buffer2, buffer1, BUFFER_SIZE);
+ for (j = num_res = 0; j < ARRAY_SIZE(res); j++) {
+ if (i & (i << j)) {
+ res[num_res].type = BLOCK;
+ res[num_res].val = j;
+ num_res++;
} else {
- res[j].type = BLOCK;
- res[j].val = j;
+ /* Mess with block. */
+ buffer2[j * BLOCK_SIZE]++;
+ if (num_res && res[num_res-1].type == LITERAL)
+ res[num_res-1].val += BLOCK_SIZE;
+ else {
+ res[num_res].type = LITERAL;
+ res[num_res].val = BLOCK_SIZE;
+ num_res++;
+ }
}
}
- test_sync(buffer1, 1024, buffer2, 1023, 128,
- res, ARRAY_SIZE(res));
+ test_sync(buffer1, BUFFER_SIZE,
+ buffer2, BUFFER_SIZE,
+ BLOCK_SIZE, res, num_res);
}
+ free(buffer1);
+ free(buffer2);
return exit_status();
}