From d8603ed901d4af4d0d2b493d1164c74eae34f147 Mon Sep 17 00:00:00 2001 From: Vicent Marti Date: Sat, 10 Jul 2010 16:51:15 -0700 Subject: [PATCH] Add parsing of tree file contents. The basic information (pointed trees and blobs) of each tree object in a revision pool can now be parsed and queried. Signed-off-by: Vicent Marti --- src/commit.c | 1 + src/git/tree.h | 12 ++++++++ src/tree.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/tree.h | 16 +++++++++++ 4 files changed, 103 insertions(+) diff --git a/src/commit.c b/src/commit.c index 6b0b66190..e4e56117d 100644 --- a/src/commit.c +++ b/src/commit.c @@ -83,6 +83,7 @@ git_commit *git_commit_parse(git_revpool *pool, const git_oid *id) return commit; error_cleanup: + /* FIXME: do not free; the commit is owned by the revpool */ free(commit); return NULL; } diff --git a/src/git/tree.h b/src/git/tree.h index d5f668c54..9a4973ba6 100644 --- a/src/git/tree.h +++ b/src/git/tree.h @@ -27,6 +27,18 @@ typedef struct git_tree git_tree; */ GIT_EXTERN(git_tree *) git_tree_lookup(git_revpool *pool, const git_oid *id); +/** + * Locate a reference to a tree object and parse its + * contents. + * The generated tree object is owned by the revision + * pool and shall not be freed by the user. + * + * @param pool the pool to use when locating the tree. + * @param id identity of the tree to locate. + * @return the tree; NULL if the tree could not be created + */ +GIT_EXTERN(git_tree *) git_tree_parse(git_revpool *pool, const git_oid *id); + /** * Get the id of a tree. * @param tree a previously loaded tree. diff --git a/src/tree.c b/src/tree.c index 2ba363e58..47b027322 100644 --- a/src/tree.c +++ b/src/tree.c @@ -65,3 +65,77 @@ git_tree *git_tree_lookup(git_revpool *pool, const git_oid *id) return tree; } + + +git_tree *git_tree_parse(git_revpool *pool, const git_oid *id) +{ + git_tree *tree = NULL; + + if ((tree = git_tree_lookup(pool, id)) == NULL) + return NULL; + + if (git_tree__parse(tree) < 0) + goto error_cleanup; + + return tree; + +error_cleanup: + /* FIXME: do not free; the tree is owned by the revpool */ + free(tree); + return NULL; +} + +int git_tree__parse(git_tree *tree) +{ + static const char tree_header[] = {'t', 'r', 'e', 'e', ' '}; + + int error = 0; + git_obj odb_object; + char *buffer, *buffer_end; + + error = git_odb_read(&odb_object, tree->object.pool->db, &tree->object.id); + if (error < 0) + return error; + + buffer = odb_object.data; + buffer_end = odb_object.data + odb_object.len; + + if (memcmp(buffer, tree_header, 5) != 0) + return GIT_EOBJCORRUPTED; + + buffer += 5; + + tree->byte_size = strtol(buffer, &buffer, 10); + + if (*buffer++ != 0) + return GIT_EOBJCORRUPTED; + + while (buffer < buffer_end) { + git_tree_entry *entry; + + entry = git__malloc(sizeof(git_tree_entry)); + entry->next = tree->entries; + + entry->attr = strtol(buffer, &buffer, 10); + + if (*buffer++ != ' ') { + error = GIT_EOBJCORRUPTED; + break; + } + + entry->filename = git__strdup(buffer); + + if (entry->filename == NULL) { + error = GIT_EOBJCORRUPTED; + break; + } + buffer += strlen(entry->filename); + + git_oid_mkraw(&entry->oid, (const unsigned char *)buffer); + buffer += GIT_OID_RAWSZ; + + tree->entries = entry; + } + + return error; +} diff --git a/src/tree.h b/src/tree.h index 532a2f46e..373345663 100644 --- a/src/tree.h +++ b/src/tree.h @@ -4,10 +4,26 @@ #include #include "revobject.h" +struct git_tree_entry { + + unsigned int attr; + char *filename; + git_oid oid; + + struct git_tree_entry *next; +}; + +typedef struct git_tree_entry git_tree_entry; + struct git_tree { git_revpool_object object; + + size_t byte_size; + git_tree_entry *entries; + unsigned int entry_count; }; void git_tree__free(git_tree *tree); +int git_tree__parse(git_tree *tree); #endif