1 /*
2  * Copyright (C) the libgit2 contributors. All rights reserved.
3  *
4  * This file is part of libgit2, distributed under the GNU GPL v2 with
5  * a Linking Exception. For full terms see the included COPYING file.
6  */
7 
8 #include "hash.h"
9 
git_hash_global_init(void)10 int git_hash_global_init(void)
11 {
12 	return git_hash_sha1_global_init();
13 }
14 
git_hash_ctx_init(git_hash_ctx * ctx)15 int git_hash_ctx_init(git_hash_ctx *ctx)
16 {
17 	int error;
18 
19 	if ((error = git_hash_sha1_ctx_init(&ctx->sha1)) < 0)
20 		return error;
21 
22 	ctx->algo = GIT_HASH_ALGO_SHA1;
23 
24 	return 0;
25 }
26 
git_hash_ctx_cleanup(git_hash_ctx * ctx)27 void git_hash_ctx_cleanup(git_hash_ctx *ctx)
28 {
29 	switch (ctx->algo) {
30 		case GIT_HASH_ALGO_SHA1:
31 			git_hash_sha1_ctx_cleanup(&ctx->sha1);
32 			return;
33 		default:
34 			/* unreachable */ ;
35 	}
36 }
37 
git_hash_init(git_hash_ctx * ctx)38 int git_hash_init(git_hash_ctx *ctx)
39 {
40 	switch (ctx->algo) {
41 		case GIT_HASH_ALGO_SHA1:
42 			return git_hash_sha1_init(&ctx->sha1);
43 		default:
44 			/* unreachable */ ;
45 	}
46 	GIT_ASSERT(0);
47 	return -1;
48 }
49 
git_hash_update(git_hash_ctx * ctx,const void * data,size_t len)50 int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len)
51 {
52 	switch (ctx->algo) {
53 		case GIT_HASH_ALGO_SHA1:
54 			return git_hash_sha1_update(&ctx->sha1, data, len);
55 		default:
56 			/* unreachable */ ;
57 	}
58 	GIT_ASSERT(0);
59 	return -1;
60 }
61 
git_hash_final(git_oid * out,git_hash_ctx * ctx)62 int git_hash_final(git_oid *out, git_hash_ctx *ctx)
63 {
64 	switch (ctx->algo) {
65 		case GIT_HASH_ALGO_SHA1:
66 			return git_hash_sha1_final(out, &ctx->sha1);
67 		default:
68 			/* unreachable */ ;
69 	}
70 	GIT_ASSERT(0);
71 	return -1;
72 }
73 
git_hash_buf(git_oid * out,const void * data,size_t len)74 int git_hash_buf(git_oid *out, const void *data, size_t len)
75 {
76 	git_hash_ctx ctx;
77 	int error = 0;
78 
79 	if (git_hash_ctx_init(&ctx) < 0)
80 		return -1;
81 
82 	if ((error = git_hash_update(&ctx, data, len)) >= 0)
83 		error = git_hash_final(out, &ctx);
84 
85 	git_hash_ctx_cleanup(&ctx);
86 
87 	return error;
88 }
89 
git_hash_vec(git_oid * out,git_buf_vec * vec,size_t n)90 int git_hash_vec(git_oid *out, git_buf_vec *vec, size_t n)
91 {
92 	git_hash_ctx ctx;
93 	size_t i;
94 	int error = 0;
95 
96 	if (git_hash_ctx_init(&ctx) < 0)
97 		return -1;
98 
99 	for (i = 0; i < n; i++) {
100 		if ((error = git_hash_update(&ctx, vec[i].data, vec[i].len)) < 0)
101 			goto done;
102 	}
103 
104 	error = git_hash_final(out, &ctx);
105 
106 done:
107 	git_hash_ctx_cleanup(&ctx);
108 
109 	return error;
110 }
111