Files
geef/c_src/index.c
Carlos Martín Nieto 6c272e2c30 index: write out all fields to disc
There is still now way to access what the flags mean, and the times
need to be in pure timestamp form, rather than erlang's.

Non-essential fields are allowed to be 'undefined' and then the
entry's field will remain zeroed.
2013-10-16 15:01:16 +02:00

277 lines
6.8 KiB
C

#include "geef.h"
#include "oid.h"
#include "index.h"
#include "object.h"
#include <string.h>
#include <git2.h>
void geef_index_free(ErlNifEnv *env, void *cd)
{
geef_index *index = (geef_index *) cd;
git_index_free(index->index);
}
ERL_NIF_TERM
geef_index_new(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
geef_index *index;
ERL_NIF_TERM term;
index = enif_alloc_resource(geef_index_type, sizeof(geef_index));
if (!index)
return geef_oom(env);
if (git_index_new(&index->index) < 0)
return geef_error(env);
term = enif_make_resource(env, index);
enif_release_resource(index);
return enif_make_tuple2(env, atoms.ok, term);
}
ERL_NIF_TERM
geef_index_write(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
geef_index *index;
if (!enif_get_resource(env, argv[0], geef_index_type, (void **) &index))
return enif_make_badarg(env);
if (git_index_write(index->index) < 0)
return geef_error(env);
return atoms.ok;
}
ERL_NIF_TERM
geef_index_write_tree(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
geef_index *index;
geef_repository *repo;
ErlNifBinary bin;
git_oid id;
int error;
if (!enif_get_resource(env, argv[0], geef_index_type, (void **) &index))
return enif_make_badarg(env);
if (argc == 2) {
if (!enif_get_resource(env, argv[1], geef_repository_type, (void **) &repo))
return enif_make_badarg(env);
error = git_index_write_tree_to(&id, index->index, repo->repo);
} else {
error = git_index_write_tree(&id, index->index);
}
if (error < 0)
return geef_error(env);
if (geef_oid_bin(&bin, &id) < 0)
return geef_oom(env);
return enif_make_tuple2(env, atoms.ok, enif_make_binary(env, &bin));
}
ERL_NIF_TERM
geef_index_read_tree(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
geef_index *index;
geef_object *tree;
if (!enif_get_resource(env, argv[0], geef_index_type, (void **) &index))
return enif_make_badarg(env);
if (!enif_get_resource(env, argv[0], geef_object_type, (void **) &tree))
return enif_make_badarg(env);
if (git_index_read_tree(index->index, (git_tree *)tree->obj) < 0)
return geef_error(env);
return atoms.ok;
}
ERL_NIF_TERM
geef_index_add(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
geef_index *index;
const ERL_NIF_TERM *eentry;
int arity;
unsigned int tmp;
ErlNifBinary path, id;
git_index_entry entry;
if (!enif_get_resource(env, argv[0], geef_index_type, (void **) &index))
return enif_make_badarg(env);
if (!enif_get_tuple(env, argv[1], &arity, &eentry))
return enif_make_badarg(env);
memset(&entry, 0, sizeof(entry));
if (enif_compare(eentry[1], atoms.undefined) &&
!enif_get_int64(env, eentry[1], &entry.ctime.seconds))
return enif_make_badarg(env);
if (enif_compare(eentry[2], atoms.undefined) &&
!enif_get_int64(env, eentry[2], &entry.mtime.seconds))
return enif_make_badarg(env);
if (enif_compare(eentry[3], atoms.undefined) &&
!enif_get_uint(env, eentry[3], &entry.dev))
return enif_make_badarg(env);
if (enif_compare(eentry[4], atoms.undefined) &&
!enif_get_uint(env, eentry[4], &entry.ino))
return enif_make_badarg(env);
if (!enif_get_uint(env, eentry[5], &entry.mode))
return enif_make_badarg(env);
if (enif_compare(eentry[6], atoms.undefined) &&
!enif_get_uint(env, eentry[6], &entry.uid))
return enif_make_badarg(env);
if (enif_compare(eentry[7], atoms.undefined) &&
!enif_get_uint(env, eentry[7], &entry.gid))
return enif_make_badarg(env);
if (!enif_get_int64(env, eentry[8], &entry.file_size))
return enif_make_badarg(env);
/* [9] comes later */
if (enif_compare(eentry[10], atoms.undefined) &&
!enif_get_uint(env, eentry[10], &tmp))
return enif_make_badarg(env);
entry.flags = tmp;
if (enif_compare(eentry[11], atoms.undefined) &&
!enif_get_uint(env, eentry[11], &tmp))
return enif_make_badarg(env);
entry.flags_extended = tmp;
if (!enif_inspect_iolist_as_binary(env, eentry[12], &path))
return enif_make_badarg(env);
if (!geef_terminate_binary(&path))
return geef_oom(env);
entry.path = (char *) path.data;
if (!enif_inspect_binary(env, eentry[9], &id))
return enif_make_badarg(env);
git_oid_fromraw(&entry.oid, id.data);
if (git_index_add(index->index, &entry) < 0)
return geef_error(env);
return atoms.ok;
}
ERL_NIF_TERM
geef_index_count(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
geef_index *index;
if (!enif_get_resource(env, argv[0], geef_index_type, (void **) &index))
return enif_make_badarg(env);
return enif_make_uint(env, git_index_entrycount(index->index));
}
ERL_NIF_TERM entry_to_term(ErlNifEnv *env, const git_index_entry *entry)
{
ErlNifBinary id, path;
size_t len;
if (geef_oid_bin(&id, &entry->oid) < 0)
return geef_oom(env);
len = strlen(entry->path);
if (!enif_alloc_binary(len, &path)) {
enif_release_binary(&id);
return geef_oom(env);
}
memcpy(path.data, entry->path, len);
return enif_make_tuple(env, 13, atoms.ok,
enif_make_int64(env, entry->ctime.seconds),
enif_make_int64(env, entry->mtime.seconds),
enif_make_uint(env, entry->dev),
enif_make_uint(env, entry->ino),
enif_make_uint(env, entry->mode),
enif_make_uint(env, entry->uid),
enif_make_uint(env, entry->gid),
enif_make_int64(env, entry->file_size),
enif_make_binary(env, &id),
enif_make_uint(env, entry->flags),
enif_make_uint(env, entry->flags_extended),
enif_make_binary(env, &path));
}
ERL_NIF_TERM
geef_index_nth(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
size_t nth;
geef_index *index;
const git_index_entry *entry;
if (!enif_get_resource(env, argv[0], geef_index_type, (void **) &index))
return enif_make_badarg(env);
if (!enif_get_ulong(env, argv[1], &nth))
return enif_make_badarg(env);
entry = git_index_get_byindex(index->index, nth);
if (entry == NULL)
return geef_error(env);
return entry_to_term(env, entry);
}
ERL_NIF_TERM
geef_index_get(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
unsigned int stage;
ErlNifBinary path;
geef_index *index;
const git_index_entry *entry;
if (!enif_get_resource(env, argv[0], geef_index_type, (void **) &index))
return enif_make_badarg(env);
if (!enif_get_uint(env, argv[2], &stage))
return enif_make_badarg(env);
if (!enif_inspect_iolist_as_binary(env, argv[1], &path))
return enif_make_badarg(env);
if (geef_terminate_binary(&path) < 0) {
enif_release_binary(&path);
return geef_oom(env);
}
entry = git_index_get_bypath(index->index, (char *) path.data, stage);
enif_release_binary(&path);
if (entry == NULL)
return geef_error(env);
return entry_to_term(env, entry);
}
ERL_NIF_TERM
geef_index_clear(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
geef_index *index;
if (!enif_get_resource(env, argv[0], geef_index_type, (void **) &index))
return enif_make_badarg(env);
git_index_clear(index->index);
return atoms.ok;
}