]>
Commit | Line | Data |
---|---|---|
1 | #ifndef DELTA_H | |
2 | #define DELTA_H | |
3 | ||
4 | /* opaque object for delta index */ | |
5 | struct delta_index; | |
6 | ||
7 | /* | |
8 | * create_delta_index: compute index data from given buffer | |
9 | * | |
10 | * This returns a pointer to a struct delta_index that should be passed to | |
11 | * subsequent create_delta() calls, or to free_delta_index(). A NULL pointer | |
12 | * is returned on failure. The given buffer must not be freed nor altered | |
13 | * before free_delta_index() is called. The returned pointer must be freed | |
14 | * using free_delta_index(). | |
15 | */ | |
16 | extern struct delta_index * | |
17 | create_delta_index(const void *buf, unsigned long bufsize); | |
18 | ||
19 | /* | |
20 | * free_delta_index: free the index created by create_delta_index() | |
21 | * | |
22 | * Given pointer must be what create_delta_index() returned, or NULL. | |
23 | */ | |
24 | extern void free_delta_index(struct delta_index *index); | |
25 | ||
26 | /* | |
27 | * sizeof_delta_index: returns memory usage of delta index | |
28 | * | |
29 | * Given pointer must be what create_delta_index() returned, or NULL. | |
30 | */ | |
31 | extern unsigned long sizeof_delta_index(struct delta_index *index); | |
32 | ||
33 | /* | |
34 | * create_delta: create a delta from given index for the given buffer | |
35 | * | |
36 | * This function may be called multiple times with different buffers using | |
37 | * the same delta_index pointer. If max_delta_size is non-zero and the | |
38 | * resulting delta is to be larger than max_delta_size then NULL is returned. | |
39 | * On success, a non-NULL pointer to the buffer with the delta data is | |
40 | * returned and *delta_size is updated with its size. The returned buffer | |
41 | * must be freed by the caller. | |
42 | */ | |
43 | extern void * | |
44 | create_delta(const struct delta_index *index, | |
45 | const void *buf, unsigned long bufsize, | |
46 | unsigned long *delta_size, unsigned long max_delta_size); | |
47 | ||
48 | /* | |
49 | * diff_delta: create a delta from source buffer to target buffer | |
50 | * | |
51 | * If max_delta_size is non-zero and the resulting delta is to be larger | |
52 | * than max_delta_size then NULL is returned. On success, a non-NULL | |
53 | * pointer to the buffer with the delta data is returned and *delta_size is | |
54 | * updated with its size. The returned buffer must be freed by the caller. | |
55 | */ | |
56 | static inline void * | |
57 | diff_delta(const void *src_buf, unsigned long src_bufsize, | |
58 | const void *trg_buf, unsigned long trg_bufsize, | |
59 | unsigned long *delta_size, unsigned long max_delta_size) | |
60 | { | |
61 | struct delta_index *index = create_delta_index(src_buf, src_bufsize); | |
62 | if (index) { | |
63 | void *delta = create_delta(index, trg_buf, trg_bufsize, | |
64 | delta_size, max_delta_size); | |
65 | free_delta_index(index); | |
66 | return delta; | |
67 | } | |
68 | return NULL; | |
69 | } | |
70 | ||
71 | /* | |
72 | * patch_delta: recreate target buffer given source buffer and delta data | |
73 | * | |
74 | * On success, a non-NULL pointer to the target buffer is returned and | |
75 | * *trg_bufsize is updated with its size. On failure a NULL pointer is | |
76 | * returned. The returned buffer must be freed by the caller. | |
77 | */ | |
78 | extern void *patch_delta(const void *src_buf, unsigned long src_size, | |
79 | const void *delta_buf, unsigned long delta_size, | |
80 | unsigned long *dst_size); | |
81 | ||
82 | /* the smallest possible delta size is 4 bytes */ | |
83 | #define DELTA_SIZE_MIN 4 | |
84 | ||
85 | /* | |
86 | * This must be called twice on the delta data buffer, first to get the | |
87 | * expected source buffer size, and again to get the target buffer size. | |
88 | */ | |
89 | static inline unsigned long get_delta_hdr_size(const unsigned char **datap, | |
90 | const unsigned char *top) | |
91 | { | |
92 | const unsigned char *data = *datap; | |
93 | unsigned long cmd, size = 0; | |
94 | int i = 0; | |
95 | do { | |
96 | cmd = *data++; | |
97 | size |= (cmd & 0x7f) << i; | |
98 | i += 7; | |
99 | } while (cmd & 0x80 && data < top); | |
100 | *datap = data; | |
101 | return size; | |
102 | } | |
103 | ||
104 | #endif |