Hash :
d6fb0924
Author :
Date :
2012-11-05T12:37:15
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
/*
* Copyright (C) 2009-2012 the libgit2 contributors
*
* 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 <stdio.h>
#include <string.h>
#include "common.h"
#include "hash.h"
extern void hash_ppc_core(uint32_t *hash, const unsigned char *p,
unsigned int nblocks);
git_hash_ctx *git_hash_ctx_new(void)
{
git_hash_ctx *ctx = git__malloc(sizeof(git_hash_ctx));
if (!ctx)
return NULL;
git_hash_init(ctx);
return ctx;
}
int git_hash_init(git_hash_ctx *c)
{
c->hash[0] = 0x67452301;
c->hash[1] = 0xEFCDAB89;
c->hash[2] = 0x98BADCFE;
c->hash[3] = 0x10325476;
c->hash[4] = 0xC3D2E1F0;
c->len = 0;
c->cnt = 0;
return 0;
}
int git_hash_update(git_hash_ctx *c, const void *ptr, size_t n)
{
unsigned long nb;
const unsigned char *p = ptr;
c->len += (uint64_t) n << 3;
while (n != 0) {
if (c->cnt || n < 64) {
nb = 64 - c->cnt;
if (nb > n)
nb = n;
memcpy(&c->buf.b[c->cnt], p, nb);
if ((c->cnt += nb) == 64) {
hash_ppc_core(c->hash, c->buf.b, 1);
c->cnt = 0;
}
} else {
nb = n >> 6;
hash_ppc_core(c->hash, p, nb);
nb <<= 6;
}
n -= nb;
p += nb;
}
return 0;
}
int git_hash_final(git_oid *oid, git_hash_ctx *c)
{
unsigned int cnt = c->cnt;
c->buf.b[cnt++] = 0x80;
if (cnt > 56) {
if (cnt < 64)
memset(&c->buf.b[cnt], 0, 64 - cnt);
hash_ppc_core(c->hash, c->buf.b, 1);
cnt = 0;
}
if (cnt < 56)
memset(&c->buf.b[cnt], 0, 56 - cnt);
c->buf.l[7] = c->len;
hash_ppc_core(c->hash, c->buf.b, 1);
memcpy(oid->id, c->hash, 20);
return 0;
}
void git_hash_ctx_free(git_hash_ctx *ctx)
{
if (ctx)
git__free(ctx);
}