]> git.proxmox.com Git - libgit2.git/blobdiff - src/hash.c
New upstream version 1.4.3+dfsg.1
[libgit2.git] / src / hash.c
index ff85ca957341ea675afc87dd1f97a2cfb737a37f..98ceb05d26038e40a3a40429c9ac3b5a7c09769e 100644 (file)
 /*
- * Copyright (C) 2009-2011 the libgit2 contributors
+ * Copyright (C) the libgit2 contributors. All rights reserved.
  *
  * This file is part of libgit2, distributed under the GNU GPL v2 with
  * a Linking Exception. For full terms see the included COPYING file.
  */
 
-#include "common.h"
 #include "hash.h"
 
-#if defined(PPC_SHA1)
-# include "ppc/sha1.h"
-#else
-# include "sha1.h"
-#endif
-
-struct git_hash_ctx {
-       SHA_CTX c;
-};
+int git_hash_global_init(void)
+{
+       return git_hash_sha1_global_init();
+}
 
-git_hash_ctx *git_hash_new_ctx(void)
+int git_hash_ctx_init(git_hash_ctx *ctx, git_hash_algorithm_t algorithm)
 {
-       git_hash_ctx *ctx = git__malloc(sizeof(*ctx));
+       int error;
 
-       if (!ctx)
-               return NULL;
+       switch (algorithm) {
+       case GIT_HASH_ALGORITHM_SHA1:
+               error = git_hash_sha1_ctx_init(&ctx->ctx.sha1);
+               break;
+       default:
+               git_error_set(GIT_ERROR_INTERNAL, "unknown hash algorithm");
+               error = -1;
+       }
 
-       SHA1_Init(&ctx->c);
+       ctx->algorithm = algorithm;
+       return error;
+}
 
-       return ctx;
+void git_hash_ctx_cleanup(git_hash_ctx *ctx)
+{
+       switch (ctx->algorithm) {
+       case GIT_HASH_ALGORITHM_SHA1:
+               git_hash_sha1_ctx_cleanup(&ctx->ctx.sha1);
+               return;
+       default:
+               /* unreachable */ ;
+       }
 }
 
-void git_hash_free_ctx(git_hash_ctx *ctx)
+int git_hash_init(git_hash_ctx *ctx)
 {
-       free(ctx);
+       switch (ctx->algorithm) {
+       case GIT_HASH_ALGORITHM_SHA1:
+               return git_hash_sha1_init(&ctx->ctx.sha1);
+       default:
+               /* unreachable */ ;
+       }
+
+       git_error_set(GIT_ERROR_INTERNAL, "unknown hash algorithm");
+       return -1;
 }
 
-void git_hash_init(git_hash_ctx *ctx)
+int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len)
 {
-       assert(ctx);
-       SHA1_Init(&ctx->c);
+       switch (ctx->algorithm) {
+       case GIT_HASH_ALGORITHM_SHA1:
+               return git_hash_sha1_update(&ctx->ctx.sha1, data, len);
+       default:
+               /* unreachable */ ;
+       }
+
+       git_error_set(GIT_ERROR_INTERNAL, "unknown hash algorithm");
+       return -1;
 }
 
-void git_hash_update(git_hash_ctx *ctx, const void *data, size_t len)
+int git_hash_final(unsigned char *out, git_hash_ctx *ctx)
 {
-       assert(ctx);
-       SHA1_Update(&ctx->c, data, len);
+       switch (ctx->algorithm) {
+       case GIT_HASH_ALGORITHM_SHA1:
+               return git_hash_sha1_final(out, &ctx->ctx.sha1);
+       default:
+               /* unreachable */ ;
+       }
+
+       git_error_set(GIT_ERROR_INTERNAL, "unknown hash algorithm");
+       return -1;
 }
 
-void git_hash_final(git_oid *out, git_hash_ctx *ctx)
+int git_hash_buf(
+       unsigned char *out,
+       const void *data,
+       size_t len,
+       git_hash_algorithm_t algorithm)
 {
-       assert(ctx);
-       SHA1_Final(out->id, &ctx->c);
+       git_hash_ctx ctx;
+       int error = 0;
+
+       if (git_hash_ctx_init(&ctx, algorithm) < 0)
+               return -1;
+
+       if ((error = git_hash_update(&ctx, data, len)) >= 0)
+               error = git_hash_final(out, &ctx);
+
+       git_hash_ctx_cleanup(&ctx);
+
+       return error;
 }
 
-void git_hash_buf(git_oid *out, const void *data, size_t len)
+int git_hash_vec(
+       unsigned char *out,
+       git_str_vec *vec,
+       size_t n,
+       git_hash_algorithm_t algorithm)
 {
-       SHA_CTX c;
+       git_hash_ctx ctx;
+       size_t i;
+       int error = 0;
+
+       if (git_hash_ctx_init(&ctx, algorithm) < 0)
+               return -1;
+
+       for (i = 0; i < n; i++) {
+               if ((error = git_hash_update(&ctx, vec[i].data, vec[i].len)) < 0)
+                       goto done;
+       }
 
-       SHA1_Init(&c);
-       SHA1_Update(&c, data, len);
-       SHA1_Final(out->id, &c);
+       error = git_hash_final(out, &ctx);
+
+done:
+       git_hash_ctx_cleanup(&ctx);
+
+       return error;
 }
 
-void git_hash_vec(git_oid *out, git_buf_vec *vec, size_t n)
+int git_hash_fmt(char *out, unsigned char *hash, size_t hash_len)
 {
-       SHA_CTX c;
+       static char hex[] = "0123456789abcdef";
+       char *str = out;
        size_t i;
 
-       SHA1_Init(&c);
-       for (i = 0; i < n; i++)
-               SHA1_Update(&c, vec[i].data, vec[i].len);
-       SHA1_Final(out->id, &c);
+       for (i = 0; i < hash_len; i++) {
+               *str++ = hex[hash[i] >> 4];
+               *str++ = hex[hash[i] & 0x0f];
+       }
+
+       *str++ = '\0';
+
+       return 0;
 }