{
hashflush(f);
checkpoint->offset = f->total;
- checkpoint->ctx = f->ctx;
+ the_hash_algo->clone_fn(&checkpoint->ctx, &f->ctx);
}
int hashfile_truncate(struct hashfile *f, struct hashfile_checkpoint *checkpoint)
#endif
#if defined(SHA256_GCRYPT)
+#define SHA256_NEEDS_CLONE_HELPER
#include "sha256/gcrypt.h"
#elif defined(SHA256_OPENSSL)
#include <openssl/sha.h>
#define git_SHA256_Update platform_SHA256_Update
#define git_SHA256_Final platform_SHA256_Final
+#ifdef platform_SHA256_Clone
+#define git_SHA256_Clone platform_SHA256_Clone
+#endif
+
#ifdef SHA1_MAX_BLOCK_SIZE
#include "compat/sha1-chunked.h"
#undef git_SHA1_Update
#define git_SHA1_Update git_SHA1_Update_Chunked
#endif
+static inline void git_SHA1_Clone(git_SHA_CTX *dst, const git_SHA_CTX *src)
+{
+ memcpy(dst, src, sizeof(*dst));
+}
+
+#ifndef SHA256_NEEDS_CLONE_HELPER
+static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *src)
+{
+ memcpy(dst, src, sizeof(*dst));
+}
+#endif
+
/*
* Note that these constants are suitable for indexing the hash_algos array and
* comparing against each other, but are otherwise arbitrary, so they should not
typedef union git_hash_ctx git_hash_ctx;
typedef void (*git_hash_init_fn)(git_hash_ctx *ctx);
+typedef void (*git_hash_clone_fn)(git_hash_ctx *dst, const git_hash_ctx *src);
typedef void (*git_hash_update_fn)(git_hash_ctx *ctx, const void *in, size_t len);
typedef void (*git_hash_final_fn)(unsigned char *hash, git_hash_ctx *ctx);
/* The hash initialization function. */
git_hash_init_fn init_fn;
+ /* The hash context cloning function. */
+ git_hash_clone_fn clone_fn;
+
/* The hash update function. */
git_hash_update_fn update_fn;
git_SHA1_Init(&ctx->sha1);
}
+static void git_hash_sha1_clone(git_hash_ctx *dst, const git_hash_ctx *src)
+{
+ git_SHA1_Clone(&dst->sha1, &src->sha1);
+}
+
static void git_hash_sha1_update(git_hash_ctx *ctx, const void *data, size_t len)
{
git_SHA1_Update(&ctx->sha1, data, len);
git_SHA256_Init(&ctx->sha256);
}
+static void git_hash_sha256_clone(git_hash_ctx *dst, const git_hash_ctx *src)
+{
+ git_SHA256_Clone(&dst->sha256, &src->sha256);
+}
+
static void git_hash_sha256_update(git_hash_ctx *ctx, const void *data, size_t len)
{
git_SHA256_Update(&ctx->sha256, data, len);
BUG("trying to init unknown hash");
}
+static void git_hash_unknown_clone(git_hash_ctx *dst, const git_hash_ctx *src)
+{
+ BUG("trying to clone unknown hash");
+}
+
static void git_hash_unknown_update(git_hash_ctx *ctx, const void *data, size_t len)
{
BUG("trying to update unknown hash");
0,
0,
git_hash_unknown_init,
+ git_hash_unknown_clone,
git_hash_unknown_update,
git_hash_unknown_final,
NULL,
GIT_SHA1_HEXSZ,
GIT_SHA1_BLKSZ,
git_hash_sha1_init,
+ git_hash_sha1_clone,
git_hash_sha1_update,
git_hash_sha1_final,
&empty_tree_oid,
GIT_SHA256_HEXSZ,
GIT_SHA256_BLKSZ,
git_hash_sha256_init,
+ git_hash_sha256_clone,
git_hash_sha256_update,
git_hash_sha256_final,
&empty_tree_oid_sha256,
memcpy(digest, gcry_md_read(*ctx, GCRY_MD_SHA256), SHA256_DIGEST_SIZE);
}
+inline void gcrypt_SHA256_Clone(gcrypt_SHA256_CTX *dst, const gcrypt_SHA256_CTX *src)
+{
+ gcry_md_copy(dst, *src);
+}
+
#define platform_SHA256_CTX gcrypt_SHA256_CTX
#define platform_SHA256_Init gcrypt_SHA256_Init
+#define platform_SHA256_Clone gcrypt_SHA256_Clone
#define platform_SHA256_Update gcrypt_SHA256_Update
#define platform_SHA256_Final gcrypt_SHA256_Final