/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.23.2 by Nicolas Pitre
Add the diff-delta.c and patch-delta.c files.
1
/*
2
 * patch-delta.c:
3
 * recreate a buffer from a source and the delta produced by diff-delta.c
4
 *
5
 * (C) 2005 Nicolas Pitre <nico@cam.org>
6
 *
7
 * This code is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License version 2 as
9
 * published by the Free Software Foundation.
10
 */
11
12
#include "git-compat-util.h"
13
#include "delta.h"
14
15
void *patch_delta(const void *src_buf, unsigned long src_size,
16
		  const void *delta_buf, unsigned long delta_size,
17
		  unsigned long *dst_size)
18
{
19
	const unsigned char *data, *top;
20
	unsigned char *dst_buf, *out, cmd;
21
	unsigned long size;
22
23
	if (delta_size < DELTA_SIZE_MIN)
24
		return NULL;
25
26
	data = delta_buf;
27
	top = (const unsigned char *) delta_buf + delta_size;
28
29
	/* make sure the orig file size matches what we expect */
30
	size = get_delta_hdr_size(&data, top);
31
	if (size != src_size)
32
		return NULL;
33
34
	/* now the result size */
35
	size = get_delta_hdr_size(&data, top);
36
	dst_buf = xmalloc(size + 1);
37
	dst_buf[size] = 0;
38
39
	out = dst_buf;
40
	while (data < top) {
41
		cmd = *data++;
42
		if (cmd & 0x80) {
43
			unsigned long cp_off = 0, cp_size = 0;
44
			if (cmd & 0x01) cp_off = *data++;
45
			if (cmd & 0x02) cp_off |= (*data++ << 8);
46
			if (cmd & 0x04) cp_off |= (*data++ << 16);
47
			if (cmd & 0x08) cp_off |= (*data++ << 24);
48
			if (cmd & 0x10) cp_size = *data++;
49
			if (cmd & 0x20) cp_size |= (*data++ << 8);
50
			if (cmd & 0x40) cp_size |= (*data++ << 16);
51
			if (cp_size == 0) cp_size = 0x10000;
52
			if (cp_off + cp_size < cp_size ||
53
			    cp_off + cp_size > src_size ||
54
			    cp_size > size)
55
				break;
56
			memcpy(out, (char *) src_buf + cp_off, cp_size);
57
			out += cp_size;
58
			size -= cp_size;
59
		} else if (cmd) {
60
			if (cmd > size)
61
				break;
62
			memcpy(out, data, cmd);
63
			out += cmd;
64
			data += cmd;
65
			size -= cmd;
66
		} else {
67
			/*
68
			 * cmd == 0 is reserved for future encoding
69
			 * extensions. In the mean time we must fail when
70
			 * encountering them (might be data corruption).
71
			 */
72
			error("unexpected delta opcode 0");
73
			goto bad;
74
		}
75
	}
76
77
	/* sanity check */
78
	if (data != top || size != 0) {
79
		error("delta replay has gone wild");
80
		bad:
81
		free(dst_buf);
82
		return NULL;
83
	}
84
85
	*dst_size = out - dst_buf;
86
	return dst_buf;
87
}