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
;