|  | #include "test-tool.h" | 
|  | #include "cache.h" | 
|  |  | 
|  | int cmd_hash_impl(int ac, const char **av, int algo) | 
|  | { | 
|  | git_hash_ctx ctx; | 
|  | unsigned char hash[GIT_MAX_HEXSZ]; | 
|  | unsigned bufsz = 8192; | 
|  | int binary = 0; | 
|  | char *buffer; | 
|  | const struct git_hash_algo *algop = &hash_algos[algo]; | 
|  |  | 
|  | if (ac == 2) { | 
|  | if (!strcmp(av[1], "-b")) | 
|  | binary = 1; | 
|  | else | 
|  | bufsz = strtoul(av[1], NULL, 10) * 1024 * 1024; | 
|  | } | 
|  |  | 
|  | if (!bufsz) | 
|  | bufsz = 8192; | 
|  |  | 
|  | while ((buffer = malloc(bufsz)) == NULL) { | 
|  | fprintf(stderr, "bufsz %u is too big, halving...\n", bufsz); | 
|  | bufsz /= 2; | 
|  | if (bufsz < 1024) | 
|  | die("OOPS"); | 
|  | } | 
|  |  | 
|  | algop->init_fn(&ctx); | 
|  |  | 
|  | while (1) { | 
|  | ssize_t sz, this_sz; | 
|  | char *cp = buffer; | 
|  | unsigned room = bufsz; | 
|  | this_sz = 0; | 
|  | while (room) { | 
|  | sz = xread(0, cp, room); | 
|  | if (sz == 0) | 
|  | break; | 
|  | if (sz < 0) | 
|  | die_errno("test-hash"); | 
|  | this_sz += sz; | 
|  | cp += sz; | 
|  | room -= sz; | 
|  | } | 
|  | if (this_sz == 0) | 
|  | break; | 
|  | algop->update_fn(&ctx, buffer, this_sz); | 
|  | } | 
|  | algop->final_fn(hash, &ctx); | 
|  |  | 
|  | if (binary) | 
|  | fwrite(hash, 1, algop->rawsz, stdout); | 
|  | else | 
|  | puts(hash_to_hex_algop(hash, algop)); | 
|  | exit(0); | 
|  | } |