diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | pack-objects.c | 29 | ||||
-rw-r--r-- | pack.h | 19 | ||||
-rw-r--r-- | sha1_file.c | 5 | ||||
-rw-r--r-- | unpack-objects.c | 7 |
5 files changed, 31 insertions, 31 deletions
@@ -47,7 +47,7 @@ LIB_OBJS=read-cache.o sha1_file.o usage.o object.o commit.o tree.o blob.o \ tag.o date.o index.o diff-delta.o patch-delta.o entry.o \ epoch.o refs.o csum-file.o LIB_FILE=libgit.a -LIB_H=cache.h object.h blob.h tree.h commit.h tag.h delta.h epoch.h csum-file.h +LIB_H=cache.h object.h blob.h tree.h commit.h tag.h delta.h epoch.h csum-file.h pack.h LIB_H += strbuf.h LIB_OBJS += strbuf.o diff --git a/pack-objects.c b/pack-objects.c index feee5600b9..fc969e342a 100644 --- a/pack-objects.c +++ b/pack-objects.c @@ -51,32 +51,19 @@ static void *delta_against(void *buf, unsigned long size, struct object_entry *e */ static int encode_header(enum object_type type, unsigned long size, unsigned char *hdr) { - int n = 1, i; + int n = 1; unsigned char c; if (type < OBJ_COMMIT || type > OBJ_DELTA) die("bad type %d", type); - /* - * Shift the size up by 7 bits at a time, - * until you get bits in the "high four". - * That will be our beginning. We'll have - * four size bits in 28..31, then groups - * of seven in 21..27, 14..20, 7..13 and - * finally 0..6. - */ - if (size) { - n = 5; - while (!(size & 0xfe000000)) { - size <<= 7; - n--; - } - } - c = (type << 4) | (size >> 28); - for (i = 1; i < n; i++) { + c = (type << 4) | (size & 15); + size >>= 4; + while (size) { *hdr++ = c | 0x80; - c = (size >> 21) & 0x7f; - size <<= 7; + c = size & 0x7f; + size >>= 7; + n++; } *hdr = c; return n; @@ -148,7 +135,7 @@ static void write_pack_file(void) else f = sha1create("%s.%s", base_name, "pack"); hdr.hdr_signature = htonl(PACK_SIGNATURE); - hdr.hdr_version = htonl(1); + hdr.hdr_version = htonl(PACK_VERSION); hdr.hdr_entries = htonl(nr_objects); sha1write(f, &hdr, sizeof(hdr)); offset = sizeof(hdr); @@ -1,19 +1,26 @@ #ifndef PACK_H #define PACK_H +/* + * The packed object type is stored in 3 bits. + * The type value 0 is a reserved prefix if ever there is more than 7 + * object types, or any future format extensions. + */ enum object_type { - OBJ_NONE, - OBJ_COMMIT, - OBJ_TREE, - OBJ_BLOB, - OBJ_TAG, - OBJ_DELTA, + OBJ_EXT = 0, + OBJ_COMMIT = 1, + OBJ_TREE = 2, + OBJ_BLOB = 3, + OBJ_TAG = 4, + /* 5/6 for future expansion */ + OBJ_DELTA = 7, }; /* * Packed object header */ #define PACK_SIGNATURE 0x5041434b /* "PACK" */ +#define PACK_VERSION 2 struct pack_header { unsigned int hdr_signature; unsigned int hdr_version; diff --git a/sha1_file.c b/sha1_file.c index 25208d2da3..0bdaa16e7f 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -659,6 +659,7 @@ static int packed_delta_info(unsigned char *base_sha1, static unsigned long unpack_object_header(struct packed_git *p, unsigned long offset, enum object_type *type, unsigned long *sizep) { + unsigned shift; unsigned char *pack, c; unsigned long size; @@ -670,12 +671,14 @@ static unsigned long unpack_object_header(struct packed_git *p, unsigned long of offset++; *type = (c >> 4) & 7; size = c & 15; + shift = 4; while (c & 0x80) { if (offset >= p->pack_size) die("object offset outside of pack file"); c = *pack++; offset++; - size = (size << 7) | (c & 0x7f); + size += (c & 0x7f) << shift; + shift += 7; } *sizep = size; return offset; diff --git a/unpack-objects.c b/unpack-objects.c index 0892d2b920..b9ddcb70e0 100644 --- a/unpack-objects.c +++ b/unpack-objects.c @@ -183,6 +183,7 @@ static int unpack_delta_entry(unsigned long delta_size) static void unpack_one(void) { + unsigned shift; unsigned char *pack, c; unsigned long size; enum object_type type; @@ -192,11 +193,13 @@ static void unpack_one(void) use(1); type = (c >> 4) & 7; size = (c & 15); + shift = 4; while (c & 0x80) { pack = fill(1); c = *pack++; use(1); - size = (size << 7) + (c & 0x7f); + size += (c & 0x7f) << shift; + shift += 7; } switch (type) { case OBJ_COMMIT: @@ -227,7 +230,7 @@ static void unpack_all(void) if (ntohl(hdr->hdr_signature) != PACK_SIGNATURE) die("bad pack file"); - if (version != 1) + if (version != PACK_VERSION) die("unable to handle pack file version %d", version); fprintf(stderr, "Unpacking %d objects\n", nr_objects); |