-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbin_patch.c
More file actions
65 lines (52 loc) · 1.75 KB
/
bin_patch.c
File metadata and controls
65 lines (52 loc) · 1.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include "bin_patch.h"
static void blockcpy(u8_t *dest, u8_t *src, len_t len) {
// Here to remove needing standard lib
for (; len--; *dest++ = *src++);
}
len_t index_to_len(index_t n) {
len_t ret = 0;
for (u8_t i = 0; i < sizeof(index_t); i++)
ret |= n.b[i] << 8 * i;
return ret;
}
index_t len_to_index(len_t n) {
index_t ret;
for (u8_t i = 0; i < sizeof(index_t); i++)
ret.b[i] = n >> 8 * i;
return ret;
}
void apply_patch(u8_t *dest, struct binary_patch *patch) {
len_t curr_heap = 0;
len_t len = index_to_len(patch->diff_len);
len_t delta;
for (len_t i = 0; i < len; i++) {
delta = index_to_len(patch->diff_delta[i]);
blockcpy(&dest[index_to_len(patch->diff_start[i])],
&patch->heap[curr_heap],
delta);
curr_heap += delta;
}
}
enum bp_ret_code gen_patch(u8_t *old, u8_t *new, len_t bin_len, struct binary_patch *patch) {
len_t len_diff = index_to_len(patch->diff_len);
len_t len_heap = index_to_len(patch->heap_len);
len_t curr_diff = 0;
len_t curr_heap = 0;
len_t i, j;
for (j = 0; curr_diff < len_diff; curr_diff++) {
for (i = j; i < bin_len && old[i] == new[i]; i++);
if (i >= bin_len) {
patch->diff_len = len_to_index(curr_diff);
patch->heap_len = len_to_index(curr_heap);
return SUCCESS;
}
for (j = i; j < bin_len && old[j] != new[j]; j++);
if (j - i > len_heap - curr_heap)
return OUT_OF_HEAP;
patch->diff_start[curr_diff] = len_to_index(i);
patch->diff_delta[curr_diff] = len_to_index(j - i);
blockcpy(&patch->heap[curr_heap], &new[i], j - i);
curr_heap += j - i;
}
return OUT_OF_DIFF;
}