Commit 3f27127d15dfe69943d3c9ddf96d09a2300de3a9

Russell Belfer 2013-04-16T11:51:02

Simplify object table parse functions This unifies the object parse functions into one signature that takes an odb_object.

diff --git a/src/blob.c b/src/blob.c
index 501c13d..a68c4cc 100644
--- a/src/blob.c
+++ b/src/blob.c
@@ -41,7 +41,7 @@ void git_blob__free(void *blob)
 	git__free(blob);
 }
 
-int git_blob__from_odb_object(void *blob, git_odb_object *odb_obj)
+int git_blob__parse(void *blob, git_odb_object *odb_obj)
 {
 	assert(blob);
 	git_cached_obj_incref((git_cached_obj *)odb_obj);
diff --git a/src/blob.h b/src/blob.h
index 4873505..22e37cc 100644
--- a/src/blob.h
+++ b/src/blob.h
@@ -18,7 +18,7 @@ struct git_blob {
 };
 
 void git_blob__free(void *blob);
-int git_blob__from_odb_object(void *blob, git_odb_object *obj);
+int git_blob__parse(void *blob, git_odb_object *obj);
 int git_blob__getbuf(git_buf *buffer, git_blob *blob);
 
 #endif
diff --git a/src/commit.c b/src/commit.c
index 3eca5b3..46c02c2 100644
--- a/src/commit.c
+++ b/src/commit.c
@@ -168,9 +168,11 @@ int git_commit_create(
 	return retval;
 }
 
-int git_commit__parse(void *_commit, const char *buffer, const char *buffer_end)
+int git_commit__parse(void *_commit, git_odb_object *odb_obj)
 {
 	git_commit *commit = _commit;
+	const char *buffer = git_odb_object_data(odb_obj);
+	const char *buffer_end = buffer + git_odb_object_size(odb_obj);
 	git_oid parent_id;
 
 	if (git_vector_init(&commit->parent_ids, 4, NULL) < 0)
diff --git a/src/commit.h b/src/commit.h
index 0c2c3ab..d0981b1 100644
--- a/src/commit.h
+++ b/src/commit.h
@@ -28,6 +28,6 @@ struct git_commit {
 };
 
 void git_commit__free(void *commit);
-int git_commit__parse(void *commit, const char *buf, const char *bufend);
+int git_commit__parse(void *commit, git_odb_object *obj);
 
 #endif
diff --git a/src/object.c b/src/object.c
index 3698808..b87a074 100644
--- a/src/object.c
+++ b/src/object.c
@@ -22,33 +22,32 @@ typedef struct {
 	const char	*str;	/* type name string */
 	size_t		size;	/* size in bytes of the object structure */
 
-	int  (*from_odb)(void *self, git_odb_object *obj);
-	int  (*parse)(void *self, const char *buf, const char *buf_end);
+	int  (*parse)(void *self, git_odb_object *obj);
 	void (*free)(void *self);
 } git_object_def;
 
 static git_object_def git_objects_table[] = {
 	/* 0 = GIT_OBJ__EXT1 */
-	{ "", 0, NULL, NULL, NULL },
+	{ "", 0, NULL, NULL },
 
 	/* 1 = GIT_OBJ_COMMIT */
-	{ "commit", sizeof(git_commit), NULL, git_commit__parse, git_commit__free },
+	{ "commit", sizeof(git_commit), git_commit__parse, git_commit__free },
 
 	/* 2 = GIT_OBJ_TREE */
-	{ "tree", sizeof(git_tree), NULL, git_tree__parse, git_tree__free },
+	{ "tree", sizeof(git_tree), git_tree__parse, git_tree__free },
 
 	/* 3 = GIT_OBJ_BLOB */
-	{ "blob", sizeof(git_blob), git_blob__from_odb_object, NULL, git_blob__free },
+	{ "blob", sizeof(git_blob), git_blob__parse, git_blob__free },
 
 	/* 4 = GIT_OBJ_TAG */
-	{ "tag", sizeof(git_tag), NULL, git_tag__parse, git_tag__free },
+	{ "tag", sizeof(git_tag), git_tag__parse, git_tag__free },
 
 	/* 5 = GIT_OBJ__EXT2 */
-	{ "", 0, NULL, NULL, NULL },
+	{ "", 0, NULL, NULL },
 	/* 6 = GIT_OBJ_OFS_DELTA */
-	{ "OFS_DELTA", 0, NULL, NULL, NULL },
+	{ "OFS_DELTA", 0, NULL, NULL },
 	/* 7 = GIT_OBJ_REF_DELTA */
-	{ "REF_DELTA", 0, NULL, NULL, NULL },
+	{ "REF_DELTA", 0, NULL, NULL },
 };
 
 int git_object__from_odb_object(
@@ -88,22 +87,14 @@ int git_object__from_odb_object(
 
 	/* Parse raw object data */
 	def = &git_objects_table[odb_obj->cached.type];
-	assert(def->free && (def->from_odb || def->parse));
+	assert(def->free && def->parse);
 
-	if (def->from_odb) {
-		error = def->from_odb(object, odb_obj);
-	} else {
-		const char *data = (const char *)git_odb_object_data(odb_obj);
-		error = def->parse(object, data, data + git_odb_object_size(odb_obj));
-	}
-
-	if (error < 0) {
+	if ((error = def->parse(object, odb_obj)) < 0)
 		def->free(object);
-		return error;
-	}
+	else
+		*object_out = git_cache_store_parsed(&repo->objects, object);
 
-	*object_out = git_cache_store_parsed(&repo->objects, object);
-	return 0;
+	return error;
 }
 
 void git_object__free(void *obj)
diff --git a/src/tag.c b/src/tag.c
index 7dadc7e..b9a806c 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -70,13 +70,12 @@ static int tag_error(const char *str)
 	return -1;
 }
 
-int git_tag__parse(void *_tag, const char *buffer, const char *buffer_end)
+static int tag_parse(git_tag *tag, const char *buffer, const char *buffer_end)
 {
 	static const char *tag_types[] = {
 		NULL, "commit\n", "tree\n", "blob\n", "tag\n"
 	};
 
-	git_tag *tag = _tag;
 	unsigned int i;
 	size_t text_len;
 	char *search;
@@ -157,6 +156,15 @@ int git_tag__parse(void *_tag, const char *buffer, const char *buffer_end)
 	return 0;
 }
 
+int git_tag__parse(void *_tag, git_odb_object *odb_obj)
+{
+	git_tag *tag = _tag;
+	const char *buffer = git_odb_object_data(odb_obj);
+	const char *buffer_end = buffer + git_odb_object_size(odb_obj);
+
+	return tag_parse(tag, buffer, buffer_end);
+}
+
 static int retrieve_tag_reference(
 	git_reference **tag_reference_out,
 	git_buf *ref_name_out,
@@ -277,23 +285,23 @@ cleanup:
 }
 
 int git_tag_create(
-		git_oid *oid,
-		git_repository *repo,
-		const char *tag_name,
-		const git_object *target,
-		const git_signature *tagger,
-		const char *message,
-		int allow_ref_overwrite)
+	git_oid *oid,
+	git_repository *repo,
+	const char *tag_name,
+	const git_object *target,
+	const git_signature *tagger,
+	const char *message,
+	int allow_ref_overwrite)
 {
 	return git_tag_create__internal(oid, repo, tag_name, target, tagger, message, allow_ref_overwrite, 1);
 }
 
 int git_tag_create_lightweight(
-		git_oid *oid,
-		git_repository *repo,
-		const char *tag_name,
-		const git_object *target,
-		int allow_ref_overwrite)
+	git_oid *oid,
+	git_repository *repo,
+	const char *tag_name,
+	const git_object *target,
+	int allow_ref_overwrite)
 {
 	return git_tag_create__internal(oid, repo, tag_name, target, NULL, NULL, allow_ref_overwrite, 0);
 }
@@ -317,7 +325,7 @@ int git_tag_create_frombuffer(git_oid *oid, git_repository *repo, const char *bu
 		return -1;
 
 	/* validate the buffer */
-	if (git_tag__parse(&tag, buffer, buffer + strlen(buffer)) < 0)
+	if (tag_parse(&tag, buffer, buffer + strlen(buffer)) < 0)
 		return -1;
 
 	/* validate the target */
diff --git a/src/tag.h b/src/tag.h
index fb01a6f..d0cd393 100644
--- a/src/tag.h
+++ b/src/tag.h
@@ -23,6 +23,6 @@ struct git_tag {
 };
 
 void git_tag__free(void *tag);
-int git_tag__parse(void *tag, const char *buf, const char *buf_end);
+int git_tag__parse(void *tag, git_odb_object *obj);
 
 #endif
diff --git a/src/tree.c b/src/tree.c
index e66fa23..d6d4b77 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -372,8 +372,10 @@ static int tree_error(const char *str, const char *path)
 	return -1;
 }
 
-int git_tree__parse(void *tree, const char *buffer, const char *buffer_end)
+int git_tree__parse(void *tree, git_odb_object *odb_obj)
 {
+	const char *buffer = git_odb_object_data(odb_obj);
+	const char *buffer_end = buffer + git_odb_object_size(odb_obj);
 	git_vector *tree_entries = &((git_tree *)tree)->entries;
 
 	if (git_vector_init(tree_entries, DEFAULT_TREE_SIZE, entry_sort_cmp) < 0)
diff --git a/src/tree.h b/src/tree.h
index cf47fb4..7cb2dd3 100644
--- a/src/tree.h
+++ b/src/tree.h
@@ -38,7 +38,7 @@ GIT_INLINE(bool) git_tree_entry__is_tree(const struct git_tree_entry *e)
 extern int git_tree_entry_icmp(const git_tree_entry *e1, const git_tree_entry *e2);
 
 void git_tree__free(void *tree);
-int git_tree__parse(void *tree, const char *buf, const char *buf_end);
+int git_tree__parse(void *tree, git_odb_object *obj);
 
 /**
  * Lookup the first position in the tree with a given prefix.
diff --git a/tests-clar/commit/parse.c b/tests-clar/commit/parse.c
index 792b576..ad2c746 100644
--- a/tests-clar/commit/parse.c
+++ b/tests-clar/commit/parse.c
@@ -266,32 +266,35 @@ a simple commit which works\n",
 
 void test_commit_parse__entire_commit(void)
 {
-	const int broken_commit_count = sizeof(failing_commit_cases) / sizeof(*failing_commit_cases);
-	const int working_commit_count = sizeof(passing_commit_cases) / sizeof(*passing_commit_cases);
+	const int failing_commit_count = ARRAY_SIZE(failing_commit_cases);
+	const int passing_commit_count = ARRAY_SIZE(passing_commit_cases);
 	int i;
-	const char *buf;
+	git_commit *commit;
+	git_odb_object fake_odb_object;
+	memset(&fake_odb_object, 0, sizeof(fake_odb_object));
 
-	for (i = 0; i < broken_commit_count; ++i) {
-		git_commit *commit;
+	for (i = 0; i < failing_commit_count; ++i) {
 		commit = (git_commit*)git__malloc(sizeof(git_commit));
 		memset(commit, 0x0, sizeof(git_commit));
 		commit->object.repo = g_repo;
 
-		buf = failing_commit_cases[i];
-		cl_git_fail(git_commit__parse(commit, buf, buf + strlen(buf)));
+		fake_odb_object.buffer = failing_commit_cases[i];
+		fake_odb_object.cached.size = strlen(fake_odb_object.buffer);
+
+		cl_git_fail(git_commit__parse(commit, &fake_odb_object));
 
 		git_commit__free(commit);
 	}
 
-	for (i = 0; i < working_commit_count; ++i) {
-		git_commit *commit;
-
+	for (i = 0; i < passing_commit_count; ++i) {
 		commit = (git_commit*)git__malloc(sizeof(git_commit));
 		memset(commit, 0x0, sizeof(git_commit));
 		commit->object.repo = g_repo;
 
-		buf = passing_commit_cases[i];
-		cl_git_pass(git_commit__parse(commit, buf, buf + strlen(buf)));
+		fake_odb_object.buffer = passing_commit_cases[i];
+		fake_odb_object.cached.size = strlen(fake_odb_object.buffer);
+
+		cl_git_pass(git_commit__parse(commit, &fake_odb_object));
 
 		if (!i)
 			cl_assert_equal_s("", git_commit_message(commit));