consolidate two copies of new style object header parsing code.

Also while we are at it, remove redundant typename[] array from
unpack_sha1_header.  The only reason it is different from the
type_names[] array in object.c module is that this code cares
about the subset of object types that are valid in a loose
object, so prepare a separate array of boolean that tells us
which types are valid, and share the name translation with the
others.

Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
Junio C Hamano 2006-09-01 15:17:01 -07:00
parent 501524e938
commit ad1ed5ee89

View File

@ -711,17 +711,39 @@ int legacy_loose_object(unsigned char *map)
return 0; return 0;
} }
static unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep)
{
unsigned shift;
unsigned char c;
unsigned long size;
unsigned long used = 0;
c = buf[used++];
*type = (c >> 4) & 7;
size = c & 15;
shift = 4;
while (c & 0x80) {
if (len <= used)
return 0;
if (sizeof(long) * 8 <= shift)
return 0;
c = buf[used++];
size += (c & 0x7f) << shift;
shift += 7;
}
*sizep = size;
return used;
}
static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz) static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz)
{ {
unsigned char c; unsigned long size, used;
unsigned int bits; static const char valid_loose_object_type[8] = {
unsigned long size; 0, /* OBJ_EXT */
static const char *typename[8] = { 1, 1, 1, 1, /* "commit", "tree", "blob", "tag" */
NULL, /* OBJ_EXT */ 0, /* "delta" and others are invalid in a loose object */
"commit", "tree", "blob", "tag",
NULL, NULL, NULL
}; };
const char *type; enum object_type type;
/* Get the data stream */ /* Get the data stream */
memset(stream, 0, sizeof(*stream)); memset(stream, 0, sizeof(*stream));
@ -735,22 +757,11 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon
return inflate(stream, 0); return inflate(stream, 0);
} }
c = *map++; used = unpack_object_header_gently(map, mapsize, &type, &size);
mapsize--; if (!used || !valid_loose_object_type[type])
type = typename[(c >> 4) & 7];
if (!type)
return -1; return -1;
map += used;
bits = 4; mapsize -= used;
size = c & 0xf;
while ((c & 0x80)) {
if (bits >= 8*sizeof(long))
return -1;
c = *map++;
size += (c & 0x7f) << bits;
bits += 7;
mapsize--;
}
/* Set up the stream for the rest.. */ /* Set up the stream for the rest.. */
stream->next_in = map; stream->next_in = map;
@ -758,7 +769,8 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon
inflateInit(stream); inflateInit(stream);
/* And generate the fake traditional header */ /* And generate the fake traditional header */
stream->total_out = 1 + snprintf(buffer, bufsiz, "%s %lu", type, size); stream->total_out = 1 + snprintf(buffer, bufsiz, "%s %lu",
type_names[type], size);
return 0; return 0;
} }
@ -916,25 +928,18 @@ static int packed_delta_info(unsigned char *base_sha1,
static unsigned long unpack_object_header(struct packed_git *p, unsigned long offset, static unsigned long unpack_object_header(struct packed_git *p, unsigned long offset,
enum object_type *type, unsigned long *sizep) enum object_type *type, unsigned long *sizep)
{ {
unsigned shift; unsigned long used;
unsigned char c;
unsigned long size;
if (offset >= p->pack_size) if (p->pack_size <= offset)
die("object offset outside of pack file"); die("object offset outside of pack file");
c = *((unsigned char *)p->pack_base + offset++);
*type = (c >> 4) & 7; used = unpack_object_header_gently((unsigned char *)p->pack_base +
size = c & 15; offset,
shift = 4; p->pack_size - offset, type, sizep);
while (c & 0x80) { if (!used)
if (offset >= p->pack_size)
die("object offset outside of pack file"); die("object offset outside of pack file");
c = *((unsigned char *)p->pack_base + offset++);
size += (c & 0x7f) << shift; return offset + used;
shift += 7;
}
*sizep = size;
return offset;
} }
int check_reuse_pack_delta(struct packed_git *p, unsigned long offset, int check_reuse_pack_delta(struct packed_git *p, unsigned long offset,