@ -1710,52 +1710,21 @@ static int retry_bad_packed_offset(struct packed_git *p, off_t obj_offset)
@@ -1710,52 +1710,21 @@ static int retry_bad_packed_offset(struct packed_git *p, off_t obj_offset)
return type;
}
#define POI_STACK_PREALLOC 64
static int packed_object_info(struct packed_git *p, off_t obj_offset,
unsigned long *sizep, int *rtype,
unsigned long *disk_sizep)
static enum object_type packed_to_object_type(struct packed_git *p,
off_t obj_offset,
enum object_type type,
struct pack_window **w_curs,
off_t curpos)
{
struct pack_window *w_curs = NULL;
unsigned long size;
off_t curpos = obj_offset;
enum object_type type;
off_t small_poi_stack[POI_STACK_PREALLOC];
off_t *poi_stack = small_poi_stack;
int poi_stack_nr = 0, poi_stack_alloc = POI_STACK_PREALLOC;
type = unpack_object_header(p, &w_curs, &curpos, &size);
if (rtype)
*rtype = type; /* representation type */
if (sizep) {
if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
off_t tmp_pos = curpos;
off_t base_offset = get_delta_base(p, &w_curs, &tmp_pos,
type, obj_offset);
if (!base_offset) {
type = OBJ_BAD;
goto out;
}
*sizep = get_size_from_delta(p, &w_curs, tmp_pos);
if (*sizep == 0) {
type = OBJ_BAD;
goto out;
}
} else {
*sizep = size;
}
}
if (disk_sizep) {
struct revindex_entry *revidx = find_pack_revindex(p, obj_offset);
*disk_sizep = revidx[1].offset - obj_offset;
}
while (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
off_t base_offset;
unsigned long size;
/* Push the object we're going to leave behind */
if (poi_stack_nr >= poi_stack_alloc && poi_stack == small_poi_stack) {
poi_stack_alloc = alloc_nr(poi_stack_nr);
@ -1766,11 +1735,11 @@ static int packed_object_info(struct packed_git *p, off_t obj_offset,
@@ -1766,11 +1735,11 @@ static int packed_object_info(struct packed_git *p, off_t obj_offset,
}
poi_stack[poi_stack_nr++] = obj_offset;
/* If parsing the base offset fails, just unwind */
base_offset = get_delta_base(p, &w_curs, &curpos, type, obj_offset);
base_offset = get_delta_base(p, w_curs, &curpos, type, obj_offset);
if (!base_offset)
goto unwind;
curpos = obj_offset = base_offset;
type = unpack_object_header(p, &w_curs, &curpos, &size);
type = unpack_object_header(p, w_curs, &curpos, &size);
if (type <= OBJ_NONE) {
/* If getting the base itself fails, we first
* retry the base, otherwise unwind */
@ -1797,7 +1766,6 @@ static int packed_object_info(struct packed_git *p, off_t obj_offset,
@@ -1797,7 +1766,6 @@ static int packed_object_info(struct packed_git *p, off_t obj_offset,
out:
if (poi_stack != small_poi_stack)
free(poi_stack);
unuse_pack(&w_curs);
return type;
unwind:
@ -1811,6 +1779,51 @@ unwind:
@@ -1811,6 +1779,51 @@ unwind:
goto out;
}
static int packed_object_info(struct packed_git *p, off_t obj_offset,
unsigned long *sizep, int *rtype,
unsigned long *disk_sizep)
{
struct pack_window *w_curs = NULL;
unsigned long size;
off_t curpos = obj_offset;
enum object_type type;
type = unpack_object_header(p, &w_curs, &curpos, &size);
if (rtype)
*rtype = type; /* representation type */
if (sizep) {
if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
off_t tmp_pos = curpos;
off_t base_offset = get_delta_base(p, &w_curs, &tmp_pos,
type, obj_offset);
if (!base_offset) {
type = OBJ_BAD;
goto out;
}
*sizep = get_size_from_delta(p, &w_curs, tmp_pos);
if (*sizep == 0) {
type = OBJ_BAD;
goto out;
}
} else {
*sizep = size;
}
}
if (disk_sizep) {
struct revindex_entry *revidx = find_pack_revindex(p, obj_offset);
*disk_sizep = revidx[1].offset - obj_offset;
}
type = packed_to_object_type(p, obj_offset, type, &w_curs, curpos);
out:
unuse_pack(&w_curs);
return type;
}
static void *unpack_compressed_entry(struct packed_git *p,
struct pack_window **w_curs,
off_t curpos,