Commit d8603ed9 by Vicent Marti

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 <tanoku@gmail.com>
parent 3e590fb2
......@@ -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;
}
......
......@@ -28,6 +28,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.
* @return object identity for the tree.
......
......@@ -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;
}
......@@ -4,10 +4,26 @@
#include <git/tree.h>
#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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment