mirror of
https://git.proxmox.com/git/libgit2
synced 2025-12-29 11:23:51 +00:00
Merge pull request #1112 from barrbrain/odb-pack-read-header
odb-pack: resurrect pack_backend__read_header
This commit is contained in:
commit
3368c520dc
@ -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;
|
||||
|
||||
50
src/pack.c
50
src/pack.c
@ -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,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user