diff --git a/src/hash.c b/src/hash.c index b14544c..29cda96 100644 --- a/src/hash.c +++ b/src/hash.c @@ -67,6 +67,29 @@ hash_digestv ( return result; } +uint64_t +hash_digestcb ( + hash_digestcb_func *callback, + void *user_data +) { + XXH3_state_t *state = XXH3_createState(); + xassert(state != NULL); + + xassert(0 == XXH3_64bits_reset_withSeed(state, seed)); + while (1) { + void const *buf; + size_t data_len = callback(user_data, &buf); + if (data_len == 0) { + break; + } + xassert(0 == XXH3_64bits_update(state, buf, data_len)); + } + + uint64_t result = XXH3_64bits_digest(state); + XXH3_freeState(state); + return result; +} + void hash_seed ( uint64_t s diff --git a/src/hash.h b/src/hash.h index 3e282c1..5c1208e 100644 --- a/src/hash.h +++ b/src/hash.h @@ -29,6 +29,19 @@ #include +/** + * Callback function for hash_digestcb(). + * + * The function should store the pointer to a buffer to buf_ptr, + * which only need to be valid until the next call to the callback. + * + * Returns the length of data in buffer, or 0 to terminate. + */ +typedef size_t (hash_digestcb_func) ( + void *user_data, + void const **buf_ptr +); + /** * Calculate the 64-bit hash for the given input. */ @@ -49,6 +62,18 @@ hash_digestv ( int bufcnt ); +/** + * Like hash_digest(), but takes a callback function. + * + * The callback function is called continuously for each part of + * the input data, until it returns 0. + */ +uint64_t +hash_digestcb ( + hash_digestcb_func *callback, + void *user_data +); + /** * Seed the hash function with the given value. * If not called, the seed equals to value 0.