Skip to content

Commit

Permalink
OdbBackend: implement subclassed read_header
Browse files Browse the repository at this point in the history
  • Loading branch information
ddevault committed Oct 16, 2019
1 parent f4f4cd7 commit 52d7669
Showing 1 changed file with 67 additions and 3 deletions.
70 changes: 67 additions & 3 deletions src/odb_backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ struct py_odb_backend
git_odb_backend backend;
PyObject *self;
PyObject *read_callable,
*read_prefix_callable;
*read_prefix_callable,
*read_header_callable;
};

static int
Expand All @@ -65,7 +66,7 @@ py_odb_backend_read(void **ptr, size_t *sz,
return GIT_EUSER;

const char *bytes;
if (!PyArg_ParseTuple(result, "iy#", type, &bytes, sz) || !bytes)
if (!PyArg_ParseTuple(result, "ny#", type, &bytes, sz) || !bytes)
return GIT_EUSER;

/* XXX: This assumes the default libgit2 allocator is in use and will
Expand Down Expand Up @@ -100,7 +101,7 @@ py_odb_backend_read_prefix(git_oid *oid_out, void **ptr, size_t *sz,
return GIT_EUSER;

const char *bytes;
if (!PyArg_ParseTuple(result, "Oiy#",
if (!PyArg_ParseTuple(result, "Ony#",
&py_oid_out, type, &bytes, sz) || !bytes)
return GIT_EUSER;

Expand All @@ -115,6 +116,32 @@ py_odb_backend_read_prefix(git_oid *oid_out, void **ptr, size_t *sz,
return 0;
}

static int
py_odb_backend_read_header(size_t *len, git_object_t *type,
git_odb_backend *_be, const git_oid *oid)
{
int err;
PyObject *args, *py_oid, *result;
struct py_odb_backend *be = (struct py_odb_backend *)_be;

py_oid = git_oid_to_python(oid);
args = Py_BuildValue("(O)", py_oid);
result = PyObject_CallObject(be->read_header_callable, args);
Py_DECREF(py_oid);

if ((err = git_error_for_exc()) != 0) {
return err;
}

if (result == NULL)
return GIT_EUSER;

if (!PyArg_ParseTuple(result, "nn", type, len))
return GIT_EUSER;

return 0;
}

int
OdbBackend_init(OdbBackend *self, PyObject *args, PyObject *kwds)
{
Expand Down Expand Up @@ -143,6 +170,11 @@ OdbBackend_init(OdbBackend *self, PyObject *args, PyObject *kwds)
if (be->read_prefix_callable)
be->backend.read_prefix = py_odb_backend_read_prefix;

be->read_header_callable = PyObject_GetAttrString(
(PyObject *)self, "read_header");
if (be->read_header_callable)
be->backend.read_header = py_odb_backend_read_header;

self->odb_backend = &be->backend;
return 0;
}
Expand Down Expand Up @@ -267,9 +299,41 @@ OdbBackend_read_prefix(OdbBackend *self, PyObject *py_hex)
return tuple;
}

PyDoc_STRVAR(OdbBackend_read_header__doc__,
"read_header(oid) -> (type, len)\n"
"\n"
"Read raw object header from this odb backend.\n");

PyObject *
OdbBackend_read_header(OdbBackend *self, PyObject *py_hex)
{
int err;
size_t len;
git_object_t type;
git_oid oid;

if (self->odb_backend->read_header == NULL) {
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}

len = py_oid_to_git_oid(py_hex, &oid);
if (len == 0)
return NULL;

err = self->odb_backend->read_header(&len, &type, self->odb_backend, &oid);
if (err != 0) {
Error_set_oid(err, &oid, len);
return NULL;
}

return Py_BuildValue("(ni)", type, len);
}

PyMethodDef OdbBackend_methods[] = {
METHOD(OdbBackend, read, METH_O),
METHOD(OdbBackend, read_prefix, METH_O),
METHOD(OdbBackend, read_header, METH_O),
{NULL}
};

Expand Down

0 comments on commit 52d7669

Please sign in to comment.