Convert unpack_entry_gently and friends to use offsets.

Change unpack_entry_gently and its helper functions to use offsets
rather than addresses and left counts to supply pack position
information.  In most cases this makes the code easier to follow,
and it reduces the number of local variables in a few functions.
It also better prepares this code for mapping partial segments of
packs and altering what regions of a pack are mapped while unpacking
an entry.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
Shawn Pearce 2006-08-26 04:12:27 -04:00 committed by Junio C Hamano
parent 465b26eeef
commit eb950c192a

View File

@ -1041,9 +1041,9 @@ static int packed_object_info(struct pack_entry *entry,
return 0; return 0;
} }
static void *unpack_compressed_entry(unsigned char *data, static void *unpack_compressed_entry(struct packed_git *p,
unsigned long size, unsigned long offset,
unsigned long left) unsigned long size)
{ {
int st; int st;
z_stream stream; z_stream stream;
@ -1052,8 +1052,8 @@ static void *unpack_compressed_entry(unsigned char *data,
buffer = xmalloc(size + 1); buffer = xmalloc(size + 1);
buffer[size] = 0; buffer[size] = 0;
memset(&stream, 0, sizeof(stream)); memset(&stream, 0, sizeof(stream));
stream.next_in = data; stream.next_in = (unsigned char*)p->pack_base + offset;
stream.avail_in = left; stream.avail_in = p->pack_size - offset;
stream.next_out = buffer; stream.next_out = buffer;
stream.avail_out = size; stream.avail_out = size;
@ -1068,21 +1068,22 @@ static void *unpack_compressed_entry(unsigned char *data,
return buffer; return buffer;
} }
static void *unpack_delta_entry(unsigned char *base_sha1, static void *unpack_delta_entry(struct packed_git *p,
unsigned long offset,
unsigned long delta_size, unsigned long delta_size,
unsigned long left,
char *type, char *type,
unsigned long *sizep, unsigned long *sizep)
struct packed_git *p)
{ {
struct pack_entry base_ent; struct pack_entry base_ent;
void *delta_data, *result, *base; void *delta_data, *result, *base;
unsigned long result_size, base_size; unsigned long result_size, base_size;
unsigned char* base_sha1;
if (left < 20) if ((offset + 20) >= p->pack_size)
die("truncated pack file"); die("truncated pack file");
/* The base entry _must_ be in the same pack */ /* The base entry _must_ be in the same pack */
base_sha1 = (unsigned char*)p->pack_base + offset;
if (!find_pack_entry_one(base_sha1, &base_ent, p)) if (!find_pack_entry_one(base_sha1, &base_ent, p))
die("failed to find delta-pack base object %s", die("failed to find delta-pack base object %s",
sha1_to_hex(base_sha1)); sha1_to_hex(base_sha1));
@ -1091,8 +1092,7 @@ static void *unpack_delta_entry(unsigned char *base_sha1,
die("failed to read delta-pack base object %s", die("failed to read delta-pack base object %s",
sha1_to_hex(base_sha1)); sha1_to_hex(base_sha1));
delta_data = unpack_compressed_entry(base_sha1 + 20, delta_data = unpack_compressed_entry(p, offset + 20, delta_size);
delta_size, left - 20);
result = patch_delta(base, base_size, result = patch_delta(base, base_size,
delta_data, delta_size, delta_data, delta_size,
&result_size); &result_size);
@ -1124,23 +1124,20 @@ void *unpack_entry_gently(struct pack_entry *entry,
char *type, unsigned long *sizep) char *type, unsigned long *sizep)
{ {
struct packed_git *p = entry->p; struct packed_git *p = entry->p;
unsigned long offset, size, left; unsigned long offset, size;
unsigned char *pack;
enum object_type kind; enum object_type kind;
offset = unpack_object_header(p, entry->offset, &kind, &size); offset = unpack_object_header(p, entry->offset, &kind, &size);
pack = (unsigned char *) p->pack_base + offset;
left = p->pack_size - offset;
switch (kind) { switch (kind) {
case OBJ_DELTA: case OBJ_DELTA:
return unpack_delta_entry(pack, size, left, type, sizep, p); return unpack_delta_entry(p, offset, size, type, sizep);
case OBJ_COMMIT: case OBJ_COMMIT:
case OBJ_TREE: case OBJ_TREE:
case OBJ_BLOB: case OBJ_BLOB:
case OBJ_TAG: case OBJ_TAG:
strcpy(type, type_names[kind]); strcpy(type, type_names[kind]);
*sizep = size; *sizep = size;
return unpack_compressed_entry(pack, size, left); return unpack_compressed_entry(p, offset, size);
default: default:
return NULL; return NULL;
} }