diff --git a/core/hash/hash.c b/core/hash/hash.c index a9f6353..f0ddc2f 100644 --- a/core/hash/hash.c +++ b/core/hash/hash.c @@ -1,6 +1,8 @@ #include "hash.h" #include +#include +#include #include #include #include @@ -116,6 +118,43 @@ enum b_status b_hash_ctx_update(struct b_hash_ctx *ctx, const void *p, size_t le return B_SUCCESS; } +static void update_rope(const b_rope *rope, void *arg) +{ + struct b_hash_ctx *ctx = arg; + unsigned int type = B_ROPE_TYPE(rope->r_flags); + char tmp[64]; + size_t len = 0; + + switch (type) { + case B_ROPE_F_CHAR: + b_hash_ctx_update(ctx, &rope->r_v.v_char, sizeof rope->r_v.v_char); + break; + case B_ROPE_F_CSTR: + case B_ROPE_F_CSTR_BORROWED: + case B_ROPE_F_CSTR_STATIC: + b_hash_ctx_update( + ctx, rope->r_v.v_cstr.s, strlen(rope->r_v.v_cstr.s)); + break; + case B_ROPE_F_INT: + len = snprintf(tmp, sizeof tmp, "%" PRIdPTR, rope->r_v.v_int); + b_hash_ctx_update(ctx, tmp, len); + break; + case B_ROPE_F_UINT: + len = snprintf(tmp, sizeof tmp, "%" PRIuPTR, rope->r_v.v_uint); + b_hash_ctx_update(ctx, tmp, len); + break; + default: + break; + } +} + +enum b_status b_hash_ctx_update_rope( + struct b_hash_ctx *ctx, const struct b_rope *rope) +{ + b_rope_iterate(rope, update_rope, ctx); + return B_SUCCESS; +} + enum b_status b_hash_ctx_finish( struct b_hash_ctx *ctx, void *out_digest, size_t out_max) { diff --git a/core/include/blue/core/hash.h b/core/include/blue/core/hash.h index f309369..1e6fe6a 100644 --- a/core/include/blue/core/hash.h +++ b/core/include/blue/core/hash.h @@ -29,6 +29,7 @@ #define B_DIGEST_LENGTH_SHAKE256 B_DIGEST_LENGTH_256 struct b_hash_function_ops; +struct b_rope; typedef enum b_hash_function { B_HASH_NONE = 0, @@ -103,6 +104,7 @@ BLUE_API uint64_t b_hash_cstr_ex(const char *s, size_t *len); BLUE_API b_status b_hash_ctx_init(b_hash_ctx *ctx, b_hash_function func); BLUE_API b_status b_hash_ctx_reset(b_hash_ctx *ctx); BLUE_API b_status b_hash_ctx_update(b_hash_ctx *ctx, const void *p, size_t len); +BLUE_API b_status b_hash_ctx_update_rope(b_hash_ctx *ctx, const struct b_rope *rope); BLUE_API b_status b_hash_ctx_finish( b_hash_ctx *ctx, void *out_digest, size_t out_max);