#include <assert.h>
#include "hashtable.h"
#include "checksum.h"
typedef struct rs_block_sig {
rs_weak_sum_t weak_sum;
rs_strong_sum_t strong_sum;
} rs_block_sig_t;
struct rs_signature {
int magic;
int block_len;
int strong_sum_len;
int count;
int size;
void *block_sigs;
hashtable_t *hashtable;
#ifndef HASHTABLE_NSTATS
long calc_strong_count;
#endif
};
rs_result rs_signature_init(rs_signature_t *sig, int magic, int block_len,
int strong_len, rs_long_t sig_fsize);
void rs_signature_done(rs_signature_t *sig);
rs_block_sig_t *rs_signature_add_block(rs_signature_t *sig,
rs_weak_sum_t weak_sum,
rs_strong_sum_t *strong_sum);
rs_long_t rs_signature_find_match(rs_signature_t *sig, rs_weak_sum_t weak_sum,
void const *buf, size_t len);
#define rs_signature_check(sig) do {\
assert(((sig)->magic & 0xffffff00) == (RS_MD4_SIG_MAGIC & 0xffffff00));\
assert(((sig)->magic & 0xf0) == 0x30 || ((sig)->magic & 0xf0) == 0x40);\
assert((((sig)->magic & 0x0f) == 0x07 &&\
(sig)->strong_sum_len <= RS_BLAKE2_SUM_LENGTH) ||\
(((sig)->magic & 0x0f) == 0x06 &&\
(sig)->strong_sum_len <= RS_MD4_SUM_LENGTH));\
assert(0 < (sig)->block_len);\
assert(0 < (sig)->strong_sum_len &&\
(sig)->strong_sum_len <= RS_MAX_STRONG_SUM_LENGTH);\
assert(0 <= (sig)->count && (sig)->count <= (sig)->size);\
assert(!(sig)->hashtable || (sig)->hashtable->count <= (sig)->count);\
} while (0)
static inline weaksum_kind_t rs_signature_weaksum_kind(rs_signature_t const
*sig)
{
return (sig->magic & 0xf0) == 0x30 ? RS_ROLLSUM : RS_RABINKARP;
}
static inline strongsum_kind_t rs_signature_strongsum_kind(rs_signature_t const
*sig)
{
return (sig->magic & 0x0f) == 0x06 ? RS_MD4 : RS_BLAKE2;
}
static inline rs_weak_sum_t rs_signature_calc_weak_sum(rs_signature_t const
*sig, void const *buf,
size_t len)
{
return rs_calc_weak_sum(rs_signature_weaksum_kind(sig), buf, len);
}
static inline void rs_signature_calc_strong_sum(rs_signature_t const *sig,
void const *buf, size_t len,
rs_strong_sum_t *sum)
{
rs_calc_strong_sum(rs_signature_strongsum_kind(sig), buf, len, sum);
}