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);
}
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 */
out:
if (poi_stack != small_poi_stack)
free(poi_stack);
- unuse_pack(&w_curs);
return type;
unwind:
goto out;
}
+static int packed_object_info(struct packed_git *p, off_t obj_offset,
+ enum object_type *typep, unsigned long *sizep,
+ unsigned long *disk_sizep)
+{
+ struct pack_window *w_curs = NULL;
+ unsigned long size;
+ off_t curpos = obj_offset;
+ enum object_type type;
+
+ /*
+ * We always get the representation type, but only convert it to
+ * a "real" type later if the caller is interested.
+ */
+ type = unpack_object_header(p, &w_curs, &curpos, &size);
+
+ 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;
+ }
+
+ if (typep) {
+ *typep = packed_to_object_type(p, obj_offset, type, &w_curs, curpos);
+ if (*typep < 0) {
+ type = OBJ_BAD;
+ goto out;
+ }
+ }
+
+out:
+ unuse_pack(&w_curs);
+ return type;
+}
+
static void *unpack_compressed_entry(struct packed_git *p,
struct pack_window **w_curs,
off_t curpos,
return -1;
}
- type = packed_object_info(e.p, e.offset, oi->sizep, &rtype,
- oi->disk_sizep);
- if (type < 0) {
+ rtype = packed_object_info(e.p, e.offset, &type, oi->sizep,
+ oi->disk_sizep);
+ if (rtype < 0) {
mark_bad_packed_object(e.p, sha1);
- type = sha1_object_info_extended(sha1, oi);
+ return sha1_object_info_extended(sha1, oi);
} else if (in_delta_base_cache(e.p, e.offset)) {
oi->whence = OI_DBCACHED;
} else {