X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=diff-delta.c;h=890986eeb022816da078794555a9a0135783bd40;hb=cb754fdf5a742a5479458da84d8f92bce2434ed5;hp=480f03cd16841945352c176b50300613fbf71175;hpb=5569bf9bbedd63a00780fc5c110e0cfab3aa97b9;p=git.git diff --git a/diff-delta.c b/diff-delta.c index 480f03cd..890986ee 100644 --- a/diff-delta.c +++ b/diff-delta.c @@ -84,20 +84,15 @@ typedef struct s_chanode { } chanode_t; typedef struct s_chastore { - chanode_t *head, *tail; int isize, nsize; chanode_t *ancur; - chanode_t *sncur; - int scurr; } chastore_t; static void cha_init(chastore_t *cha, int isize, int icount) { - cha->head = cha->tail = NULL; cha->isize = isize; cha->nsize = icount * isize; - cha->ancur = cha->sncur = NULL; - cha->scurr = 0; + cha->ancur = NULL; } static void *cha_alloc(chastore_t *cha) @@ -111,12 +106,7 @@ static void *cha_alloc(chastore_t *cha) if (!ancur) return NULL; ancur->icurr = 0; - ancur->next = NULL; - if (cha->tail) - cha->tail->next = ancur; - if (!cha->head) - cha->head = ancur; - cha->tail = ancur; + ancur->next = cha->ancur; cha->ancur = ancur; } @@ -127,7 +117,7 @@ static void *cha_alloc(chastore_t *cha) static void cha_free(chastore_t *cha) { - chanode_t *cur = cha->head; + chanode_t *cur = cha->ancur; while (cur) { chanode_t *tmp = cur; cur = cur->next; @@ -142,7 +132,6 @@ typedef struct s_bdrecord { } bdrecord_t; typedef struct s_bdfile { - const unsigned char *data, *top; chastore_t cha; unsigned int fphbits; bdrecord_t **fphash; @@ -152,7 +141,7 @@ static int delta_prepare(const unsigned char *buf, int bufsize, bdfile_t *bdf) { unsigned int fphbits; int i, hsize; - const unsigned char *base, *data, *top; + const unsigned char *data, *top; bdrecord_t *brec; bdrecord_t **fphash; @@ -165,13 +154,12 @@ static int delta_prepare(const unsigned char *buf, int bufsize, bdfile_t *bdf) fphash[i] = NULL; cha_init(&bdf->cha, sizeof(bdrecord_t), hsize / 4 + 1); - bdf->data = data = base = buf; - bdf->top = top = buf + bufsize; - data += (bufsize / BLK_SIZE) * BLK_SIZE; + top = buf + bufsize; + data = buf + (bufsize / BLK_SIZE) * BLK_SIZE; if (data == top) data -= BLK_SIZE; - for ( ; data >= base; data -= BLK_SIZE) { + for ( ; data >= buf; data -= BLK_SIZE) { brec = cha_alloc(&bdf->cha); if (!brec) { cha_free(&bdf->cha); @@ -203,11 +191,12 @@ static void delta_cleanup(bdfile_t *bdf) void *diff_delta(void *from_buf, unsigned long from_size, void *to_buf, unsigned long to_size, - unsigned long *delta_size) + unsigned long *delta_size, + unsigned long max_size) { int i, outpos, outsize, inscnt, csize, msize, moff; unsigned int fp; - const unsigned char *data, *top, *ptr1, *ptr2; + const unsigned char *ref_data, *ref_top, *data, *top, *ptr1, *ptr2; unsigned char *out, *orig; bdrecord_t *brec; bdfile_t bdf; @@ -223,32 +212,28 @@ void *diff_delta(void *from_buf, unsigned long from_size, return NULL; } + ref_data = from_buf; + ref_top = from_buf + from_size; data = to_buf; top = to_buf + to_size; /* store reference buffer size */ - orig = out + outpos++; - *orig = i = 0; - do { - if (from_size & 0xff) { - *orig |= (1 << i); - out[outpos++] = from_size; - } - i++; - from_size >>= 8; - } while (from_size); + out[outpos++] = from_size; + from_size >>= 7; + while (from_size) { + out[outpos - 1] |= 0x80; + out[outpos++] = from_size; + from_size >>= 7; + } /* store target buffer size */ - orig = out + outpos++; - *orig = i = 0; - do { - if (to_size & 0xff) { - *orig |= (1 << i); - out[outpos++] = to_size; - } - i++; - to_size >>= 8; - } while (to_size); + out[outpos++] = to_size; + to_size >>= 7; + while (to_size) { + out[outpos - 1] |= 0x80; + out[outpos++] = to_size; + to_size >>= 7; + } inscnt = 0; moff = 0; @@ -258,7 +243,7 @@ void *diff_delta(void *from_buf, unsigned long from_size, i = HASH(fp, bdf.fphbits); for (brec = bdf.fphash[i]; brec; brec = brec->next) { if (brec->fp == fp) { - csize = bdf.top - brec->ptr; + csize = ref_top - brec->ptr; if (csize > top - data) csize = top - data; for (ptr1 = brec->ptr, ptr2 = data; @@ -267,7 +252,7 @@ void *diff_delta(void *from_buf, unsigned long from_size, csize = ptr1 - brec->ptr; if (csize > msize) { - moff = brec->ptr - bdf.data; + moff = brec->ptr - ref_data; msize = csize; if (msize >= 0x10000) { msize = 0x10000; @@ -311,6 +296,12 @@ void *diff_delta(void *from_buf, unsigned long from_size, *orig = i; } + if (max_size && outpos > max_size) { + free(out); + delta_cleanup(&bdf); + return NULL; + } + /* next time around the largest possible output is 1 + 4 + 3 */ if (outpos > outsize - 8) { void *tmp = out;