1 /* radare - LGPL - Copyright 2009-2010 pancake<nopcode.org> */
5 R_API RDiff *r_diff_new(ut64 off_a, ut64 off_b) {
6 RDiff *d = R_NEW (RDiff);
16 R_API RDiff *r_diff_free(RDiff *d) {
21 R_API int r_diff_set_callback(RDiff *d, RDiffCallback callback, void *user) {
22 d->callback = callback;
27 R_API int r_diff_set_delta(RDiff *d, int delta) {
32 R_API int r_diff_buffers_static(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb) {
40 "Buffer truncated to %d bytes (%d not compared)\n",
43 for(i = 0; i<len; i++) {
48 struct r_diff_op_t o = {
49 .a_off = d->off_a+i-hit, .a_buf = a+i-hit, .a_len = hit,
50 .b_off = d->off_b+i-hit, .b_buf = b+i-hit, .b_len = hit
52 d->callback (d, d->user, &o);
58 struct r_diff_op_t o = {
59 .a_off = d->off_a+i-hit, .a_buf = a+i-hit, .a_len = hit,
60 .b_off = d->off_b+i-hit, .b_buf = b+i-hit, .b_len = hit
62 d->callback (d, d->user, &o);
68 R_API int r_diff_buffers_radiff(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb) {
69 char *ptr, *str, buf[64];
72 int ret, atl, btl, hit;
80 r_file_dump (".a", a, la);
81 r_file_dump (".b", b, lb);
82 r_sys_cmd ("radiff -d .a .b | rsc uncolor > .d");
83 fd = fopen (".d", "r");
86 ut64 oa, ob; // offset
87 int ba, bb = 0; // byte
91 if (!fgets (buf, 63, fd))
97 ptr = strchr (buf, ' ');
100 sscanf (str, "0x%08"PFMT64x"", &oa);
102 str = r_str_ichr (ptr+1, ' ');
103 if (*str!='|'&&*str!='>'&&*str!='<') {
104 ptr = strchr (str, ' ');
107 sscanf (str, "%02x", &ba);
110 str = r_str_ichr (ptr+1, ' ');
111 ptr = strchr (str, ' ');
114 sscanf (str, "%c", &op);
116 str = r_str_ichr (ptr+1, ' ');
117 if (str[0]!='0' || str[1]!='x') {
118 ptr = strchr(str, ' ');
121 sscanf (str, "%02x", &bb);
125 ptr = strchr (str, '\n');
128 sscanf (str, "0x%08"PFMT64x"", &ob);
130 if (oop == op || oop==-1) {
152 struct r_diff_op_t o = {
153 .a_off = ooa, .a_buf = at, .a_len = atl,
154 .b_off = oob, .b_buf = bt, .b_len = btl
156 ret = d->callback(d, d->user, &o);
167 struct r_diff_op_t o = {
168 .a_off = ooa, .a_buf = at, .a_len = atl,
169 .b_off = oob, .b_buf = bt, .b_len = btl
171 if (!d->callback (d, d->user, &o))
183 R_API int r_diff_buffers(RDiff *d, const ut8 *a, ut32 la, const ut8 *b, ut32 lb) {
185 return r_diff_buffers_delta (d, a, la, b, lb);
186 return r_diff_buffers_static (d, a, la, b, lb);
189 /* TODO: Move into r_util maybe? */
190 R_API int r_diff_buffers_distance(RDiff *d, const ut8 *a, ut32 la, const ut8 *b, ut32 lb,
191 ut32 *distance, double *similarity) {
192 int i, j, cost, tmin, **m;
194 if (!a || !b || la < 1 || lb < 1)
197 if ((m = malloc ((la+1) * sizeof(int*))) == NULL)
199 for(i = 0; i <= la; i++)
200 if ((m[i] = malloc ((lb+1) * sizeof(int))) == NULL)
203 for (i = 0; i <= la; i++)
205 for (j = 0; j <= lb; j++)
208 for (i = 1; i <= la; i++) {
209 for (j = 1; j <= lb; j++) {
210 if (a[i-1] == b[j-1])
213 tmin = R_MIN (m[i-1][j] + 1, m[i][j-1] + 1);
214 m[i][j] = R_MIN (tmin, m[i-1][j-1] + cost);
218 if (distance != NULL)
219 *distance = m[la][lb];
220 if (similarity != NULL) {
221 if (la == 0 || lb == 0)
224 *similarity = (double)1 - (double)(m[la][lb])/(double)(R_MAX(la, lb));
227 for(i = 0; i <= la; i++)