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_signature_check(sig); /* If block_sigs is full, allocate more space. */ if (sig->count == sig->size) { sig->size = sig->size ? sig->size * 2 : 16; sig->block_sigs = rs_realloc(sig->block_sigs, sig->size * rs_block_sig_size(sig), "signature->block_sigs"); } rs_block_sig_t *b = rs_block_sig_ptr(sig, sig->count++); rs_block_sig_init(b, weak_sum, strong_sum, sig->strong_sum_len); return b; }
rs_result rs_signature_init(rs_signature_t *sig, int magic, int block_len, int strong_len, rs_long_t sig_fsize) { int max_strong_len; /* Check and set default arguments. */ magic = magic ? magic : RS_BLAKE2_SIG_MAGIC; switch (magic) { case RS_BLAKE2_SIG_MAGIC: max_strong_len = RS_BLAKE2_SUM_LENGTH; break; case RS_MD4_SIG_MAGIC: max_strong_len = RS_MD4_SUM_LENGTH; break; default: rs_error("invalid magic %#x", magic); return RS_BAD_MAGIC; } strong_len = strong_len ? strong_len : max_strong_len; if (strong_len < 1 || max_strong_len < strong_len) { rs_error("invalid strong_sum_len %d for magic %#x", strong_len, magic); return RS_PARAM_ERROR; } /* Set attributes from args. */ sig->magic = magic; sig->block_len = block_len; sig->strong_sum_len = strong_len; sig->count = 0; /* Calculate the number of blocks if we have the signature file size. */ /* Magic+header is 12 bytes, each block thereafter is 4 bytes weak_sum+strong_sum_len bytes */ sig->size = (int)(sig_fsize ? (sig_fsize - 12) / (4 + strong_len) : 0); if (sig->size) sig->block_sigs = rs_alloc(sig->size * rs_block_sig_size(sig), "signature->block_sigs"); else sig->block_sigs = NULL; sig->hashtable = NULL; #ifndef HASHTABLE_NSTATS sig->calc_strong_count = 0; #endif rs_signature_check(sig); return RS_DONE; }
/* Get the index of a block from a block_sig_t pointer. */ static inline int rs_block_sig_idx(const rs_signature_t *sig, rs_block_sig_t *block_sig) { return ((char *)block_sig - (char *)sig->block_sigs) / rs_block_sig_size(sig); }
/* Get the pointer to the block_sig_t from a block index. */ static inline rs_block_sig_t *rs_block_sig_ptr(const rs_signature_t *sig, int block_idx) { return (rs_block_sig_t*)((char*)sig->block_sigs + block_idx * rs_block_sig_size(sig)); }