|
@@ -35,8 +35,8 @@ struct crc_context {
|
|
|
int have_match;
|
|
int have_match;
|
|
|
|
|
|
|
|
/* Final block is special (if a different size) */
|
|
/* Final block is special (if a different size) */
|
|
|
- size_t final_size;
|
|
|
|
|
- uint32_t final_crc;
|
|
|
|
|
|
|
+ size_t tail_size;
|
|
|
|
|
+ uint32_t tail_crc;
|
|
|
|
|
|
|
|
/* Uncrc tab. */
|
|
/* Uncrc tab. */
|
|
|
uint32_t uncrc_tab[256];
|
|
uint32_t uncrc_tab[256];
|
|
@@ -66,25 +66,20 @@ static void init_uncrc_tab(uint32_t uncrc_tab[], unsigned int wsize)
|
|
|
|
|
|
|
|
struct crc_context *crc_context_new(size_t block_size, unsigned crcbits,
|
|
struct crc_context *crc_context_new(size_t block_size, unsigned crcbits,
|
|
|
const uint32_t crc[], unsigned num_crcs,
|
|
const uint32_t crc[], unsigned num_crcs,
|
|
|
- size_t final_size)
|
|
|
|
|
|
|
+ size_t tail_size)
|
|
|
{
|
|
{
|
|
|
struct crc_context *ctx;
|
|
struct crc_context *ctx;
|
|
|
|
|
|
|
|
assert(num_crcs > 0);
|
|
assert(num_crcs > 0);
|
|
|
assert(block_size > 0);
|
|
assert(block_size > 0);
|
|
|
- assert(final_size > 0);
|
|
|
|
|
- assert(final_size <= block_size);
|
|
|
|
|
|
|
+ assert(tail_size < block_size);
|
|
|
|
|
|
|
|
ctx = malloc(sizeof(*ctx) + sizeof(crc[0])*num_crcs);
|
|
ctx = malloc(sizeof(*ctx) + sizeof(crc[0])*num_crcs);
|
|
|
if (ctx) {
|
|
if (ctx) {
|
|
|
ctx->block_size = block_size;
|
|
ctx->block_size = block_size;
|
|
|
- if (final_size != block_size) {
|
|
|
|
|
- ctx->final_size = final_size;
|
|
|
|
|
- ctx->final_crc = crc[--num_crcs];
|
|
|
|
|
- } else {
|
|
|
|
|
- /* If this is 0, we never compare against it. */
|
|
|
|
|
- ctx->final_size = 0;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ ctx->tail_size = tail_size;
|
|
|
|
|
+ if (tail_size)
|
|
|
|
|
+ ctx->tail_crc = crc[--num_crcs];
|
|
|
|
|
|
|
|
/* Technically, 1 << 32 is undefined. */
|
|
/* Technically, 1 << 32 is undefined. */
|
|
|
if (crcbits >= 32)
|
|
if (crcbits >= 32)
|
|
@@ -123,12 +118,12 @@ static int crc_matches(const struct crc_context *ctx)
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static bool final_matches(const struct crc_context *ctx)
|
|
|
|
|
|
|
+static bool tail_matches(const struct crc_context *ctx)
|
|
|
{
|
|
{
|
|
|
- if (ctx->literal_bytes != ctx->final_size)
|
|
|
|
|
|
|
+ if (ctx->literal_bytes != ctx->tail_size)
|
|
|
return false;
|
|
return false;
|
|
|
|
|
|
|
|
- return (ctx->running_crc & ctx->crcmask) == ctx->final_crc;
|
|
|
|
|
|
|
+ return (ctx->running_crc & ctx->crcmask) == ctx->tail_crc;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static uint32_t crc_add_byte(uint32_t crc, uint8_t newbyte)
|
|
static uint32_t crc_add_byte(uint32_t crc, uint8_t newbyte)
|
|
@@ -197,7 +192,7 @@ size_t crc_read_block(struct crc_context *ctx, long *result,
|
|
|
old = buf;
|
|
old = buf;
|
|
|
/* We don't roll this csum, we only look for it after
|
|
/* We don't roll this csum, we only look for it after
|
|
|
* a block match. It's simpler and faster. */
|
|
* a block match. It's simpler and faster. */
|
|
|
- if (final_matches(ctx)) {
|
|
|
|
|
|
|
+ if (tail_matches(ctx)) {
|
|
|
crcmatch = ctx->num_crcs;
|
|
crcmatch = ctx->num_crcs;
|
|
|
goto have_match;
|
|
goto have_match;
|
|
|
}
|
|
}
|
|
@@ -217,7 +212,7 @@ size_t crc_read_block(struct crc_context *ctx, long *result,
|
|
|
have_match:
|
|
have_match:
|
|
|
*result = -crcmatch-1;
|
|
*result = -crcmatch-1;
|
|
|
if (crcmatch == ctx->num_crcs)
|
|
if (crcmatch == ctx->num_crcs)
|
|
|
- assert(ctx->literal_bytes == ctx->final_size);
|
|
|
|
|
|
|
+ assert(ctx->literal_bytes == ctx->tail_size);
|
|
|
else
|
|
else
|
|
|
assert(ctx->literal_bytes == ctx->block_size);
|
|
assert(ctx->literal_bytes == ctx->block_size);
|
|
|
ctx->literal_bytes = 0;
|
|
ctx->literal_bytes = 0;
|