2 * Copyright (C) 2005 Junio C Hamano
3 * The delta-parsing part is almost straight copy of patch-delta.c
4 * which is (C) 2005 Nicolas Pitre <nico@cam.org>.
8 #include "count-delta.h"
19 static void touch_range(struct span **span,
20 unsigned long ofs, unsigned long end)
22 struct span *e = *span;
23 struct span *p = NULL;
25 while (e && e->ofs <= ofs) {
28 while (e->end < end) {
29 if (e->next && e->next->ofs <= end) {
30 e->end = e->next->ofs;
43 if (e && e->ofs <= end) {
48 e = xmalloc(sizeof(*e));
62 static unsigned long count_range(struct span *s)
68 sz += s->end - s->ofs;
76 * NOTE. We do not _interpret_ delta fully. As an approximation, we
77 * just count the number of bytes that are copied from the source, and
78 * the number of literal data bytes that are inserted.
80 * Number of bytes that are _not_ copied from the source is deletion,
81 * and number of inserted literal bytes are addition, so sum of them
82 * is the extent of damage.
84 int count_delta(void *delta_buf, unsigned long delta_size,
85 unsigned long *src_copied, unsigned long *literal_added)
87 unsigned long added_literal;
88 const unsigned char *data, *top;
90 unsigned long src_size, dst_size, out;
91 struct span *span = NULL;
93 if (delta_size < DELTA_SIZE_MIN)
97 top = delta_buf + delta_size;
99 src_size = get_delta_hdr_size(&data);
100 dst_size = get_delta_hdr_size(&data);
102 added_literal = out = 0;
106 unsigned long cp_off = 0, cp_size = 0;
107 if (cmd & 0x01) cp_off = *data++;
108 if (cmd & 0x02) cp_off |= (*data++ << 8);
109 if (cmd & 0x04) cp_off |= (*data++ << 16);
110 if (cmd & 0x08) cp_off |= (*data++ << 24);
111 if (cmd & 0x10) cp_size = *data++;
112 if (cmd & 0x20) cp_size |= (*data++ << 8);
113 if (cmd & 0x40) cp_size |= (*data++ << 16);
114 if (cp_size == 0) cp_size = 0x10000;
116 touch_range(&span, cp_off, cp_off+cp_size);
119 /* write literal into dst */
120 added_literal += cmd;
126 *src_copied = count_range(span);
129 if (data != top || out != dst_size)
132 /* delete size is what was _not_ copied from source.
133 * edit size is that and literal additions.
135 *literal_added = added_literal;