summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRamsay Jones <ramsay@ramsay1.demon.co.uk>2008-12-27 18:59:43 +0000
committerShawn O. Pearce <spearce@spearce.org>2008-12-30 07:52:55 -0800
commitc960d6a3f97ebd360dc3c9ea00fdb3cd5dc56224 (patch)
treed337abf625b6912fb8501993b7fb2b472d5ebcd3 /src
parent007e075337848055a92e218bdfe137451a4c9635 (diff)
downloadlibgit2-c960d6a3f97ebd360dc3c9ea00fdb3cd5dc56224.tar.gz
Add a routine to determine a git_oid given an git_obj
Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Diffstat (limited to 'src')
-rw-r--r--src/git/odb.h14
-rw-r--r--src/odb.c42
2 files changed, 56 insertions, 0 deletions
diff --git a/src/git/odb.h b/src/git/odb.h
index e8b17444a..0a7ee40d3 100644
--- a/src/git/odb.h
+++ b/src/git/odb.h
@@ -138,6 +138,20 @@ GIT_EXTERN(git_otype) git_obj_string_to_type(const char *str);
*/
GIT_EXTERN(int) git_obj__loose_object_type(git_otype type);
+/**
+ * Determine the object-ID (sha1 hash) of the given git_obj.
+ *
+ * The input obj must be a valid loose object type and the data
+ * pointer must not be NULL, unless the len field is also zero.
+ *
+ * @param id the resulting object-ID.
+ * @param obj the object whose hash is to be determined.
+ * @return
+ * - GIT_SUCCESS if the object-ID was correctly determined.
+ * - GIT_ERROR if the given object is malformed.
+ */
+GIT_EXTERN(int) git_obj_hash(git_oid *id, git_obj *obj);
+
/** @} */
GIT_END_DECL
#endif
diff --git a/src/odb.c b/src/odb.c
index a732c71d3..32a550a02 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -27,6 +27,8 @@
#include "git/zlib.h"
#include "common.h"
#include "fileops.h"
+#include "hash.h"
+#include <stdio.h>
struct git_odb {
/** Path to the "objects" directory. */
@@ -83,6 +85,46 @@ int git_obj__loose_object_type(git_otype type)
return obj_type_table[type].loose;
}
+static int format_object_header(char *hdr, size_t n, git_obj *obj)
+{
+ const char *type_str = git_obj_type_to_string(obj->type);
+ int len = snprintf(hdr, n, "%s %u", type_str, obj->len);
+
+ assert(len > 0); /* otherwise snprintf() is broken */
+ assert(len < n); /* otherwise the caller is broken! */
+
+ if (len < 0 || len >= n)
+ return GIT_ERROR;
+ return len+1;
+}
+
+int git_obj_hash(git_oid *id, git_obj *obj)
+{
+ git_buf_vec vec[2];
+ char hdr[64];
+ int hdrlen;
+
+ assert(id && obj);
+
+ if (!git_obj__loose_object_type(obj->type))
+ return GIT_ERROR;
+
+ if (!obj->data && obj->len != 0)
+ return GIT_ERROR;
+
+ if ((hdrlen = format_object_header(hdr, sizeof(hdr), obj)) < 0)
+ return GIT_ERROR;
+
+ vec[0].data = hdr;
+ vec[0].len = hdrlen;
+ vec[1].data = obj->data;
+ vec[1].len = obj->len;
+
+ git_hash_vec(id, vec, 2);
+
+ return GIT_SUCCESS;
+}
+
static int object_file_name(char *name, size_t n, char *dir, const git_oid *id)
{
size_t len = strlen(dir);