Commit 3368c520 by Vicent Martí

Merge pull request #1112 from barrbrain/odb-pack-read-header

odb-pack: resurrect pack_backend__read_header
parents 7ea3a79f bfb8bcc1
......@@ -36,6 +36,19 @@ static int hdr_sz(
return 0;
}
int git__delta_read_header(
const unsigned char *delta,
size_t delta_len,
size_t *base_sz,
size_t *res_sz)
{
const unsigned char *delta_end = delta + delta_len;
if ((hdr_sz(base_sz, &delta, delta_end) < 0) ||
(hdr_sz(res_sz, &delta, delta_end) < 0))
return -1;
return 0;
}
int git__delta_apply(
git_rawobj *out,
const unsigned char *base,
......
......@@ -30,4 +30,21 @@ extern int git__delta_apply(
const unsigned char *delta,
size_t delta_len);
/**
* Read the header of a git binary delta.
*
* @param delta the delta to execute copy/insert instructions from.
* @param delta_len total number of bytes in the delta.
* @param base_sz pointer to store the base size field.
* @param res_sz pointer to store the result size field.
* @return
* - 0 on a successful decoding the header.
* - GIT_ERROR if the delta is corrupt.
*/
extern int git__delta_read_header(
const unsigned char *delta,
size_t delta_len,
size_t *base_sz,
size_t *res_sz);
#endif
......@@ -384,19 +384,18 @@ cleanup:
*
***********************************************************/
/*
int pack_backend__read_header(git_rawobj *obj, git_odb_backend *backend, const git_oid *oid)
static int pack_backend__read_header(size_t *len_p, git_otype *type_p, struct git_odb_backend *backend, const git_oid *oid)
{
pack_location location;
struct git_pack_entry e;
int error;
assert(obj && backend && oid);
assert(len_p && type_p && backend && oid);
if (locate_packfile(&location, (struct pack_backend *)backend, oid) < 0)
return GIT_ENOTFOUND;
if ((error = pack_entry_find(&e, (struct pack_backend *)backend, oid)) < 0)
return error;
return read_header_packed(obj, &location);
return git_packfile_resolve_header(len_p, type_p, e.p, e.offset);
}
*/
static int pack_backend__read(void **buffer_p, size_t *len_p, git_otype *type_p, git_odb_backend *backend, const git_oid *oid)
{
......@@ -579,7 +578,7 @@ int git_odb_backend_one_pack(git_odb_backend **backend_out, const char *idx)
backend->parent.read = &pack_backend__read;
backend->parent.read_prefix = &pack_backend__read_prefix;
backend->parent.read_header = NULL;
backend->parent.read_header = &pack_backend__read_header;
backend->parent.exists = &pack_backend__exists;
backend->parent.foreach = &pack_backend__foreach;
backend->parent.free = &pack_backend__free;
......@@ -616,7 +615,7 @@ int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir)
backend->parent.read = &pack_backend__read;
backend->parent.read_prefix = &pack_backend__read_prefix;
backend->parent.read_header = NULL;
backend->parent.read_header = &pack_backend__read_header;
backend->parent.exists = &pack_backend__exists;
backend->parent.foreach = &pack_backend__foreach;
backend->parent.writepack = &pack_backend__writepack;
......
......@@ -277,6 +277,56 @@ int git_packfile_unpack_header(
return 0;
}
int git_packfile_resolve_header(
size_t *size_p,
git_otype *type_p,
struct git_pack_file *p,
git_off_t offset)
{
git_mwindow *w_curs = NULL;
git_off_t curpos = offset;
size_t size;
git_otype type;
git_off_t base_offset;
int error;
error = git_packfile_unpack_header(&size, &type, &p->mwf, &w_curs, &curpos);
git_mwindow_close(&w_curs);
if (error < 0)
return error;
if (type == GIT_OBJ_OFS_DELTA || type == GIT_OBJ_REF_DELTA) {
size_t base_size;
git_rawobj delta;
base_offset = get_delta_base(p, &w_curs, &curpos, type, offset);
git_mwindow_close(&w_curs);
error = packfile_unpack_compressed(&delta, p, &w_curs, &curpos, size, type);
git_mwindow_close(&w_curs);
if (error < 0)
return error;
error = git__delta_read_header(delta.data, delta.len, &base_size, size_p);
git__free(delta.data);
if (error < 0)
return error;
} else
*size_p = size;
while (type == GIT_OBJ_OFS_DELTA || type == GIT_OBJ_REF_DELTA) {
curpos = base_offset;
error = git_packfile_unpack_header(&size, &type, &p->mwf, &w_curs, &curpos);
git_mwindow_close(&w_curs);
if (error < 0)
return error;
if (type != GIT_OBJ_OFS_DELTA && type != GIT_OBJ_REF_DELTA)
break;
base_offset = get_delta_base(p, &w_curs, &curpos, type, base_offset);
git_mwindow_close(&w_curs);
}
*type_p = type;
return error;
}
static int packfile_unpack_delta(
git_rawobj *obj,
struct git_pack_file *p,
......
......@@ -83,6 +83,12 @@ int git_packfile_unpack_header(
git_mwindow **w_curs,
git_off_t *curpos);
int git_packfile_resolve_header(
size_t *size_p,
git_otype *type_p,
struct git_pack_file *p,
git_off_t offset);
int git_packfile_unpack(git_rawobj *obj, struct git_pack_file *p, git_off_t *obj_offset);
int packfile_unpack_compressed(
git_rawobj *obj,
......
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