| Junio C Hamano | 8597697 | 2005-05-24 19:09:32 | [diff] [blame] | 1 | /* |
| 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>. |
| 5 | */ |
| 6 | #include <stdlib.h> |
| 7 | #include <string.h> |
| 8 | #include <limits.h> |
| Nicolas Pitre | dcde55b | 2005-06-29 06:49:56 | [diff] [blame] | 9 | #include "delta.h" |
| Junio C Hamano | 8597697 | 2005-05-24 19:09:32 | [diff] [blame] | 10 | #include "count-delta.h" |
| 11 | |
| Junio C Hamano | 8597697 | 2005-05-24 19:09:32 | [diff] [blame] | 12 | /* |
| 13 | * NOTE. We do not _interpret_ delta fully. As an approximation, we |
| 14 | * just count the number of bytes that are copied from the source, and |
| Junio C Hamano | 355e76a | 2005-06-03 08:36:03 | [diff] [blame] | 15 | * the number of literal data bytes that are inserted. |
| 16 | * |
| 17 | * Number of bytes that are _not_ copied from the source is deletion, |
| 18 | * and number of inserted literal bytes are addition, so sum of them |
| Nicolas Pitre | e7ad4a9 | 2006-02-10 15:20:40 | [diff] [blame] | 19 | * is the extent of damage. |
| Junio C Hamano | 8597697 | 2005-05-24 19:09:32 | [diff] [blame] | 20 | */ |
| Junio C Hamano | 355e76a | 2005-06-03 08:36:03 | [diff] [blame] | 21 | int count_delta(void *delta_buf, unsigned long delta_size, |
| 22 | unsigned long *src_copied, unsigned long *literal_added) |
| Junio C Hamano | 8597697 | 2005-05-24 19:09:32 | [diff] [blame] | 23 | { |
| 24 | unsigned long copied_from_source, added_literal; |
| 25 | const unsigned char *data, *top; |
| 26 | unsigned char cmd; |
| 27 | unsigned long src_size, dst_size, out; |
| 28 | |
| Nicolas Pitre | dcde55b | 2005-06-29 06:49:56 | [diff] [blame] | 29 | if (delta_size < DELTA_SIZE_MIN) |
| Junio C Hamano | 355e76a | 2005-06-03 08:36:03 | [diff] [blame] | 30 | return -1; |
| Junio C Hamano | 8597697 | 2005-05-24 19:09:32 | [diff] [blame] | 31 | |
| 32 | data = delta_buf; |
| 33 | top = delta_buf + delta_size; |
| 34 | |
| Nicolas Pitre | dcde55b | 2005-06-29 06:49:56 | [diff] [blame] | 35 | src_size = get_delta_hdr_size(&data); |
| 36 | dst_size = get_delta_hdr_size(&data); |
| Junio C Hamano | 8597697 | 2005-05-24 19:09:32 | [diff] [blame] | 37 | |
| 38 | added_literal = copied_from_source = out = 0; |
| 39 | while (data < top) { |
| 40 | cmd = *data++; |
| 41 | if (cmd & 0x80) { |
| 42 | unsigned long cp_off = 0, cp_size = 0; |
| 43 | if (cmd & 0x01) cp_off = *data++; |
| 44 | if (cmd & 0x02) cp_off |= (*data++ << 8); |
| 45 | if (cmd & 0x04) cp_off |= (*data++ << 16); |
| 46 | if (cmd & 0x08) cp_off |= (*data++ << 24); |
| 47 | if (cmd & 0x10) cp_size = *data++; |
| 48 | if (cmd & 0x20) cp_size |= (*data++ << 8); |
| Junio C Hamano | 91c7674 | 2006-02-10 01:15:59 | [diff] [blame] | 49 | if (cmd & 0x40) cp_size |= (*data++ << 16); |
| Junio C Hamano | 8597697 | 2005-05-24 19:09:32 | [diff] [blame] | 50 | if (cp_size == 0) cp_size = 0x10000; |
| 51 | |
| Junio C Hamano | 91c7674 | 2006-02-10 01:15:59 | [diff] [blame] | 52 | copied_from_source += cp_size; |
| Junio C Hamano | 8597697 | 2005-05-24 19:09:32 | [diff] [blame] | 53 | out += cp_size; |
| 54 | } else { |
| 55 | /* write literal into dst */ |
| 56 | added_literal += cmd; |
| 57 | out += cmd; |
| 58 | data += cmd; |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | /* sanity check */ |
| 63 | if (data != top || out != dst_size) |
| Junio C Hamano | 355e76a | 2005-06-03 08:36:03 | [diff] [blame] | 64 | return -1; |
| Junio C Hamano | 8597697 | 2005-05-24 19:09:32 | [diff] [blame] | 65 | |
| 66 | /* delete size is what was _not_ copied from source. |
| 67 | * edit size is that and literal additions. |
| 68 | */ |
| Junio C Hamano | 355e76a | 2005-06-03 08:36:03 | [diff] [blame] | 69 | *src_copied = copied_from_source; |
| 70 | *literal_added = added_literal; |
| 71 | return 0; |
| Junio C Hamano | 8597697 | 2005-05-24 19:09:32 | [diff] [blame] | 72 | } |