git

Форк
0
/
diff-delta.c 
496 строк · 15.5 Кб
1
/*
2
 * diff-delta.c: generate a delta between two buffers
3
 *
4
 * This code was greatly inspired by parts of LibXDiff from Davide Libenzi
5
 * http://www.xmailserver.org/xdiff-lib.html
6
 *
7
 * Rewritten for GIT by Nicolas Pitre <nico@fluxnic.net>, (C) 2005-2007
8
 *
9
 * This code is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License version 2 as
11
 * published by the Free Software Foundation.
12
 */
13

14
#include "git-compat-util.h"
15
#include "delta.h"
16

17
/* maximum hash entry list for the same hash bucket */
18
#define HASH_LIMIT 64
19

20
#define RABIN_SHIFT 23
21
#define RABIN_WINDOW 16
22

23
static const unsigned int T[256] = {
24
	0x00000000, 0xab59b4d1, 0x56b369a2, 0xfdeadd73, 0x063f6795, 0xad66d344,
25
	0x508c0e37, 0xfbd5bae6, 0x0c7ecf2a, 0xa7277bfb, 0x5acda688, 0xf1941259,
26
	0x0a41a8bf, 0xa1181c6e, 0x5cf2c11d, 0xf7ab75cc, 0x18fd9e54, 0xb3a42a85,
27
	0x4e4ef7f6, 0xe5174327, 0x1ec2f9c1, 0xb59b4d10, 0x48719063, 0xe32824b2,
28
	0x1483517e, 0xbfdae5af, 0x423038dc, 0xe9698c0d, 0x12bc36eb, 0xb9e5823a,
29
	0x440f5f49, 0xef56eb98, 0x31fb3ca8, 0x9aa28879, 0x6748550a, 0xcc11e1db,
30
	0x37c45b3d, 0x9c9defec, 0x6177329f, 0xca2e864e, 0x3d85f382, 0x96dc4753,
31
	0x6b369a20, 0xc06f2ef1, 0x3bba9417, 0x90e320c6, 0x6d09fdb5, 0xc6504964,
32
	0x2906a2fc, 0x825f162d, 0x7fb5cb5e, 0xd4ec7f8f, 0x2f39c569, 0x846071b8,
33
	0x798aaccb, 0xd2d3181a, 0x25786dd6, 0x8e21d907, 0x73cb0474, 0xd892b0a5,
34
	0x23470a43, 0x881ebe92, 0x75f463e1, 0xdeadd730, 0x63f67950, 0xc8afcd81,
35
	0x354510f2, 0x9e1ca423, 0x65c91ec5, 0xce90aa14, 0x337a7767, 0x9823c3b6,
36
	0x6f88b67a, 0xc4d102ab, 0x393bdfd8, 0x92626b09, 0x69b7d1ef, 0xc2ee653e,
37
	0x3f04b84d, 0x945d0c9c, 0x7b0be704, 0xd05253d5, 0x2db88ea6, 0x86e13a77,
38
	0x7d348091, 0xd66d3440, 0x2b87e933, 0x80de5de2, 0x7775282e, 0xdc2c9cff,
39
	0x21c6418c, 0x8a9ff55d, 0x714a4fbb, 0xda13fb6a, 0x27f92619, 0x8ca092c8,
40
	0x520d45f8, 0xf954f129, 0x04be2c5a, 0xafe7988b, 0x5432226d, 0xff6b96bc,
41
	0x02814bcf, 0xa9d8ff1e, 0x5e738ad2, 0xf52a3e03, 0x08c0e370, 0xa39957a1,
42
	0x584ced47, 0xf3155996, 0x0eff84e5, 0xa5a63034, 0x4af0dbac, 0xe1a96f7d,
43
	0x1c43b20e, 0xb71a06df, 0x4ccfbc39, 0xe79608e8, 0x1a7cd59b, 0xb125614a,
44
	0x468e1486, 0xedd7a057, 0x103d7d24, 0xbb64c9f5, 0x40b17313, 0xebe8c7c2,
45
	0x16021ab1, 0xbd5bae60, 0x6cb54671, 0xc7ecf2a0, 0x3a062fd3, 0x915f9b02,
46
	0x6a8a21e4, 0xc1d39535, 0x3c394846, 0x9760fc97, 0x60cb895b, 0xcb923d8a,
47
	0x3678e0f9, 0x9d215428, 0x66f4eece, 0xcdad5a1f, 0x3047876c, 0x9b1e33bd,
48
	0x7448d825, 0xdf116cf4, 0x22fbb187, 0x89a20556, 0x7277bfb0, 0xd92e0b61,
49
	0x24c4d612, 0x8f9d62c3, 0x7836170f, 0xd36fa3de, 0x2e857ead, 0x85dcca7c,
50
	0x7e09709a, 0xd550c44b, 0x28ba1938, 0x83e3ade9, 0x5d4e7ad9, 0xf617ce08,
51
	0x0bfd137b, 0xa0a4a7aa, 0x5b711d4c, 0xf028a99d, 0x0dc274ee, 0xa69bc03f,
52
	0x5130b5f3, 0xfa690122, 0x0783dc51, 0xacda6880, 0x570fd266, 0xfc5666b7,
53
	0x01bcbbc4, 0xaae50f15, 0x45b3e48d, 0xeeea505c, 0x13008d2f, 0xb85939fe,
54
	0x438c8318, 0xe8d537c9, 0x153feaba, 0xbe665e6b, 0x49cd2ba7, 0xe2949f76,
55
	0x1f7e4205, 0xb427f6d4, 0x4ff24c32, 0xe4abf8e3, 0x19412590, 0xb2189141,
56
	0x0f433f21, 0xa41a8bf0, 0x59f05683, 0xf2a9e252, 0x097c58b4, 0xa225ec65,
57
	0x5fcf3116, 0xf49685c7, 0x033df00b, 0xa86444da, 0x558e99a9, 0xfed72d78,
58
	0x0502979e, 0xae5b234f, 0x53b1fe3c, 0xf8e84aed, 0x17bea175, 0xbce715a4,
59
	0x410dc8d7, 0xea547c06, 0x1181c6e0, 0xbad87231, 0x4732af42, 0xec6b1b93,
60
	0x1bc06e5f, 0xb099da8e, 0x4d7307fd, 0xe62ab32c, 0x1dff09ca, 0xb6a6bd1b,
61
	0x4b4c6068, 0xe015d4b9, 0x3eb80389, 0x95e1b758, 0x680b6a2b, 0xc352defa,
62
	0x3887641c, 0x93ded0cd, 0x6e340dbe, 0xc56db96f, 0x32c6cca3, 0x999f7872,
63
	0x6475a501, 0xcf2c11d0, 0x34f9ab36, 0x9fa01fe7, 0x624ac294, 0xc9137645,
64
	0x26459ddd, 0x8d1c290c, 0x70f6f47f, 0xdbaf40ae, 0x207afa48, 0x8b234e99,
65
	0x76c993ea, 0xdd90273b, 0x2a3b52f7, 0x8162e626, 0x7c883b55, 0xd7d18f84,
66
	0x2c043562, 0x875d81b3, 0x7ab75cc0, 0xd1eee811
67
};
68

69
static const unsigned int U[256] = {
70
	0x00000000, 0x7eb5200d, 0x5633f4cb, 0x2886d4c6, 0x073e5d47, 0x798b7d4a,
71
	0x510da98c, 0x2fb88981, 0x0e7cba8e, 0x70c99a83, 0x584f4e45, 0x26fa6e48,
72
	0x0942e7c9, 0x77f7c7c4, 0x5f711302, 0x21c4330f, 0x1cf9751c, 0x624c5511,
73
	0x4aca81d7, 0x347fa1da, 0x1bc7285b, 0x65720856, 0x4df4dc90, 0x3341fc9d,
74
	0x1285cf92, 0x6c30ef9f, 0x44b63b59, 0x3a031b54, 0x15bb92d5, 0x6b0eb2d8,
75
	0x4388661e, 0x3d3d4613, 0x39f2ea38, 0x4747ca35, 0x6fc11ef3, 0x11743efe,
76
	0x3eccb77f, 0x40799772, 0x68ff43b4, 0x164a63b9, 0x378e50b6, 0x493b70bb,
77
	0x61bda47d, 0x1f088470, 0x30b00df1, 0x4e052dfc, 0x6683f93a, 0x1836d937,
78
	0x250b9f24, 0x5bbebf29, 0x73386bef, 0x0d8d4be2, 0x2235c263, 0x5c80e26e,
79
	0x740636a8, 0x0ab316a5, 0x2b7725aa, 0x55c205a7, 0x7d44d161, 0x03f1f16c,
80
	0x2c4978ed, 0x52fc58e0, 0x7a7a8c26, 0x04cfac2b, 0x73e5d470, 0x0d50f47d,
81
	0x25d620bb, 0x5b6300b6, 0x74db8937, 0x0a6ea93a, 0x22e87dfc, 0x5c5d5df1,
82
	0x7d996efe, 0x032c4ef3, 0x2baa9a35, 0x551fba38, 0x7aa733b9, 0x041213b4,
83
	0x2c94c772, 0x5221e77f, 0x6f1ca16c, 0x11a98161, 0x392f55a7, 0x479a75aa,
84
	0x6822fc2b, 0x1697dc26, 0x3e1108e0, 0x40a428ed, 0x61601be2, 0x1fd53bef,
85
	0x3753ef29, 0x49e6cf24, 0x665e46a5, 0x18eb66a8, 0x306db26e, 0x4ed89263,
86
	0x4a173e48, 0x34a21e45, 0x1c24ca83, 0x6291ea8e, 0x4d29630f, 0x339c4302,
87
	0x1b1a97c4, 0x65afb7c9, 0x446b84c6, 0x3adea4cb, 0x1258700d, 0x6ced5000,
88
	0x4355d981, 0x3de0f98c, 0x15662d4a, 0x6bd30d47, 0x56ee4b54, 0x285b6b59,
89
	0x00ddbf9f, 0x7e689f92, 0x51d01613, 0x2f65361e, 0x07e3e2d8, 0x7956c2d5,
90
	0x5892f1da, 0x2627d1d7, 0x0ea10511, 0x7014251c, 0x5facac9d, 0x21198c90,
91
	0x099f5856, 0x772a785b, 0x4c921c31, 0x32273c3c, 0x1aa1e8fa, 0x6414c8f7,
92
	0x4bac4176, 0x3519617b, 0x1d9fb5bd, 0x632a95b0, 0x42eea6bf, 0x3c5b86b2,
93
	0x14dd5274, 0x6a687279, 0x45d0fbf8, 0x3b65dbf5, 0x13e30f33, 0x6d562f3e,
94
	0x506b692d, 0x2ede4920, 0x06589de6, 0x78edbdeb, 0x5755346a, 0x29e01467,
95
	0x0166c0a1, 0x7fd3e0ac, 0x5e17d3a3, 0x20a2f3ae, 0x08242768, 0x76910765,
96
	0x59298ee4, 0x279caee9, 0x0f1a7a2f, 0x71af5a22, 0x7560f609, 0x0bd5d604,
97
	0x235302c2, 0x5de622cf, 0x725eab4e, 0x0ceb8b43, 0x246d5f85, 0x5ad87f88,
98
	0x7b1c4c87, 0x05a96c8a, 0x2d2fb84c, 0x539a9841, 0x7c2211c0, 0x029731cd,
99
	0x2a11e50b, 0x54a4c506, 0x69998315, 0x172ca318, 0x3faa77de, 0x411f57d3,
100
	0x6ea7de52, 0x1012fe5f, 0x38942a99, 0x46210a94, 0x67e5399b, 0x19501996,
101
	0x31d6cd50, 0x4f63ed5d, 0x60db64dc, 0x1e6e44d1, 0x36e89017, 0x485db01a,
102
	0x3f77c841, 0x41c2e84c, 0x69443c8a, 0x17f11c87, 0x38499506, 0x46fcb50b,
103
	0x6e7a61cd, 0x10cf41c0, 0x310b72cf, 0x4fbe52c2, 0x67388604, 0x198da609,
104
	0x36352f88, 0x48800f85, 0x6006db43, 0x1eb3fb4e, 0x238ebd5d, 0x5d3b9d50,
105
	0x75bd4996, 0x0b08699b, 0x24b0e01a, 0x5a05c017, 0x728314d1, 0x0c3634dc,
106
	0x2df207d3, 0x534727de, 0x7bc1f318, 0x0574d315, 0x2acc5a94, 0x54797a99,
107
	0x7cffae5f, 0x024a8e52, 0x06852279, 0x78300274, 0x50b6d6b2, 0x2e03f6bf,
108
	0x01bb7f3e, 0x7f0e5f33, 0x57888bf5, 0x293dabf8, 0x08f998f7, 0x764cb8fa,
109
	0x5eca6c3c, 0x207f4c31, 0x0fc7c5b0, 0x7172e5bd, 0x59f4317b, 0x27411176,
110
	0x1a7c5765, 0x64c97768, 0x4c4fa3ae, 0x32fa83a3, 0x1d420a22, 0x63f72a2f,
111
	0x4b71fee9, 0x35c4dee4, 0x1400edeb, 0x6ab5cde6, 0x42331920, 0x3c86392d,
112
	0x133eb0ac, 0x6d8b90a1, 0x450d4467, 0x3bb8646a
113
};
114

115
struct index_entry {
116
	const unsigned char *ptr;
117
	unsigned int val;
118
};
119

120
struct unpacked_index_entry {
121
	struct index_entry entry;
122
	struct unpacked_index_entry *next;
123
};
124

125
struct delta_index {
126
	unsigned long memsize;
127
	const void *src_buf;
128
	unsigned long src_size;
129
	unsigned int hash_mask;
130
	struct index_entry *hash[FLEX_ARRAY];
131
};
132

133
struct delta_index * create_delta_index(const void *buf, unsigned long bufsize)
134
{
135
	unsigned int i, hsize, hmask, entries, prev_val, *hash_count;
136
	const unsigned char *data, *buffer = buf;
137
	struct delta_index *index;
138
	struct unpacked_index_entry *entry, **hash;
139
	struct index_entry *packed_entry, **packed_hash;
140
	void *mem;
141
	unsigned long memsize;
142

143
	if (!buf || !bufsize)
144
		return NULL;
145

146
	/* Determine index hash size.  Note that indexing skips the
147
	   first byte to allow for optimizing the Rabin's polynomial
148
	   initialization in create_delta(). */
149
	entries = (bufsize - 1) / RABIN_WINDOW;
150
	if (bufsize >= 0xffffffffUL) {
151
		/*
152
		 * Current delta format can't encode offsets into
153
		 * reference buffer with more than 32 bits.
154
		 */
155
		entries = 0xfffffffeU / RABIN_WINDOW;
156
	}
157
	hsize = entries / 4;
158
	for (i = 4; (1u << i) < hsize; i++);
159
	hsize = 1 << i;
160
	hmask = hsize - 1;
161

162
	/* allocate lookup index */
163
	memsize = sizeof(*hash) * hsize +
164
		  sizeof(*entry) * entries;
165
	mem = malloc(memsize);
166
	if (!mem)
167
		return NULL;
168
	hash = mem;
169
	mem = hash + hsize;
170
	entry = mem;
171

172
	memset(hash, 0, hsize * sizeof(*hash));
173

174
	/* allocate an array to count hash entries */
175
	hash_count = calloc(hsize, sizeof(*hash_count));
176
	if (!hash_count) {
177
		free(hash);
178
		return NULL;
179
	}
180

181
	/* then populate the index */
182
	prev_val = ~0;
183
	for (data = buffer + entries * RABIN_WINDOW - RABIN_WINDOW;
184
	     data >= buffer;
185
	     data -= RABIN_WINDOW) {
186
		unsigned int val = 0;
187
		for (i = 1; i <= RABIN_WINDOW; i++)
188
			val = ((val << 8) | data[i]) ^ T[val >> RABIN_SHIFT];
189
		if (val == prev_val) {
190
			/* keep the lowest of consecutive identical blocks */
191
			entry[-1].entry.ptr = data + RABIN_WINDOW;
192
			--entries;
193
		} else {
194
			prev_val = val;
195
			i = val & hmask;
196
			entry->entry.ptr = data + RABIN_WINDOW;
197
			entry->entry.val = val;
198
			entry->next = hash[i];
199
			hash[i] = entry++;
200
			hash_count[i]++;
201
		}
202
	}
203

204
	/*
205
	 * Determine a limit on the number of entries in the same hash
206
	 * bucket.  This guards us against pathological data sets causing
207
	 * really bad hash distribution with most entries in the same hash
208
	 * bucket that would bring us to O(m*n) computing costs (m and n
209
	 * corresponding to reference and target buffer sizes).
210
	 *
211
	 * Make sure none of the hash buckets has more entries than
212
	 * we're willing to test.  Otherwise we cull the entry list
213
	 * uniformly to still preserve a good repartition across
214
	 * the reference buffer.
215
	 */
216
	for (i = 0; i < hsize; i++) {
217
		int acc;
218

219
		if (hash_count[i] <= HASH_LIMIT)
220
			continue;
221

222
		/* We leave exactly HASH_LIMIT entries in the bucket */
223
		entries -= hash_count[i] - HASH_LIMIT;
224

225
		entry = hash[i];
226
		acc = 0;
227

228
		/*
229
		 * Assume that this loop is gone through exactly
230
		 * HASH_LIMIT times and is entered and left with
231
		 * acc==0.  So the first statement in the loop
232
		 * contributes (hash_count[i]-HASH_LIMIT)*HASH_LIMIT
233
		 * to the accumulator, and the inner loop consequently
234
		 * is run (hash_count[i]-HASH_LIMIT) times, removing
235
		 * one element from the list each time.  Since acc
236
		 * balances out to 0 at the final run, the inner loop
237
		 * body can't be left with entry==NULL.  So we indeed
238
		 * encounter entry==NULL in the outer loop only.
239
		 */
240
		do {
241
			acc += hash_count[i] - HASH_LIMIT;
242
			if (acc > 0) {
243
				struct unpacked_index_entry *keep = entry;
244
				do {
245
					entry = entry->next;
246
					acc -= HASH_LIMIT;
247
				} while (acc > 0);
248
				keep->next = entry->next;
249
			}
250
			entry = entry->next;
251
		} while (entry);
252
	}
253
	free(hash_count);
254

255
	/*
256
	 * Now create the packed index in array form
257
	 * rather than linked lists.
258
	 */
259
	memsize = sizeof(*index)
260
		+ sizeof(*packed_hash) * (hsize+1)
261
		+ sizeof(*packed_entry) * entries;
262
	mem = malloc(memsize);
263
	if (!mem) {
264
		free(hash);
265
		return NULL;
266
	}
267

268
	index = mem;
269
	index->memsize = memsize;
270
	index->src_buf = buf;
271
	index->src_size = bufsize;
272
	index->hash_mask = hmask;
273

274
	mem = index->hash;
275
	packed_hash = mem;
276
	mem = packed_hash + (hsize+1);
277
	packed_entry = mem;
278

279
	for (i = 0; i < hsize; i++) {
280
		/*
281
		 * Coalesce all entries belonging to one linked list
282
		 * into consecutive array entries.
283
		 */
284
		packed_hash[i] = packed_entry;
285
		for (entry = hash[i]; entry; entry = entry->next)
286
			*packed_entry++ = entry->entry;
287
	}
288

289
	/* Sentinel value to indicate the length of the last hash bucket */
290
	packed_hash[hsize] = packed_entry;
291

292
	assert(packed_entry - (struct index_entry *)mem == entries);
293
	free(hash);
294

295
	return index;
296
}
297

298
void free_delta_index(struct delta_index *index)
299
{
300
	free(index);
301
}
302

303
unsigned long sizeof_delta_index(struct delta_index *index)
304
{
305
	if (index)
306
		return index->memsize;
307
	else
308
		return 0;
309
}
310

311
/*
312
 * The maximum size for any opcode sequence, including the initial header
313
 * plus Rabin window plus biggest copy.
314
 */
315
#define MAX_OP_SIZE	(5 + 5 + 1 + RABIN_WINDOW + 7)
316

317
void *
318
create_delta(const struct delta_index *index,
319
	     const void *trg_buf, unsigned long trg_size,
320
	     unsigned long *delta_size, unsigned long max_size)
321
{
322
	unsigned int i, val;
323
	off_t outpos, moff;
324
	size_t l, outsize, msize;
325
	int inscnt;
326
	const unsigned char *ref_data, *ref_top, *data, *top;
327
	unsigned char *out;
328

329
	*delta_size = 0;
330

331
	if (!trg_buf || !trg_size)
332
		return NULL;
333

334
	outpos = 0;
335
	outsize = 8192;
336
	if (max_size && outsize >= max_size)
337
		outsize = max_size + MAX_OP_SIZE + 1;
338
	out = malloc(outsize);
339
	if (!out)
340
		return NULL;
341

342
	/* store reference buffer size */
343
	l = index->src_size;
344
	while (l >= 0x80) {
345
		out[outpos++] = l | 0x80;
346
		l >>= 7;
347
	}
348
	out[outpos++] = l;
349

350
	/* store target buffer size */
351
	l = trg_size;
352
	while (l >= 0x80) {
353
		out[outpos++] = l | 0x80;
354
		l >>= 7;
355
	}
356
	out[outpos++] = l;
357

358
	ref_data = index->src_buf;
359
	ref_top = ref_data + index->src_size;
360
	data = trg_buf;
361
	top = (const unsigned char *) trg_buf + trg_size;
362

363
	outpos++;
364
	val = 0;
365
	for (i = 0; i < RABIN_WINDOW && data < top; i++, data++) {
366
		out[outpos++] = *data;
367
		val = ((val << 8) | *data) ^ T[val >> RABIN_SHIFT];
368
	}
369
	inscnt = i;
370

371
	moff = 0;
372
	msize = 0;
373
	while (data < top) {
374
		if (msize < 4096) {
375
			struct index_entry *entry;
376
			val ^= U[data[-RABIN_WINDOW]];
377
			val = ((val << 8) | *data) ^ T[val >> RABIN_SHIFT];
378
			i = val & index->hash_mask;
379
			for (entry = index->hash[i]; entry < index->hash[i+1]; entry++) {
380
				const unsigned char *ref = entry->ptr;
381
				const unsigned char *src = data;
382
				unsigned int ref_size = ref_top - ref;
383
				if (entry->val != val)
384
					continue;
385
				if (ref_size > top - src)
386
					ref_size = top - src;
387
				if (ref_size <= msize)
388
					break;
389
				while (ref_size-- && *src++ == *ref)
390
					ref++;
391
				if (msize < ref - entry->ptr) {
392
					/* this is our best match so far */
393
					msize = ref - entry->ptr;
394
					moff = entry->ptr - ref_data;
395
					if (msize >= 4096) /* good enough */
396
						break;
397
				}
398
			}
399
		}
400

401
		if (msize < 4) {
402
			if (!inscnt)
403
				outpos++;
404
			out[outpos++] = *data++;
405
			inscnt++;
406
			if (inscnt == 0x7f) {
407
				out[outpos - inscnt - 1] = inscnt;
408
				inscnt = 0;
409
			}
410
			msize = 0;
411
		} else {
412
			unsigned int left;
413
			unsigned char *op;
414

415
			if (inscnt) {
416
				while (moff && ref_data[moff-1] == data[-1]) {
417
					/* we can match one byte back */
418
					msize++;
419
					moff--;
420
					data--;
421
					outpos--;
422
					if (--inscnt)
423
						continue;
424
					outpos--;  /* remove count slot */
425
					inscnt--;  /* make it -1 */
426
					break;
427
				}
428
				out[outpos - inscnt - 1] = inscnt;
429
				inscnt = 0;
430
			}
431

432
			/* A copy op is currently limited to 64KB (pack v2) */
433
			left = (msize < 0x10000) ? 0 : (msize - 0x10000);
434
			msize -= left;
435

436
			op = out + outpos++;
437
			i = 0x80;
438

439
			if (moff & 0x000000ff)
440
				out[outpos++] = moff >> 0,  i |= 0x01;
441
			if (moff & 0x0000ff00)
442
				out[outpos++] = moff >> 8,  i |= 0x02;
443
			if (moff & 0x00ff0000)
444
				out[outpos++] = moff >> 16, i |= 0x04;
445
			if (moff & 0xff000000)
446
				out[outpos++] = moff >> 24, i |= 0x08;
447

448
			if (msize & 0x00ff)
449
				out[outpos++] = msize >> 0, i |= 0x10;
450
			if (msize & 0xff00)
451
				out[outpos++] = msize >> 8, i |= 0x20;
452

453
			*op = i;
454

455
			data += msize;
456
			moff += msize;
457
			msize = left;
458

459
			if (moff > 0xffffffff)
460
				msize = 0;
461

462
			if (msize < 4096) {
463
				int j;
464
				val = 0;
465
				for (j = -RABIN_WINDOW; j < 0; j++)
466
					val = ((val << 8) | data[j])
467
					      ^ T[val >> RABIN_SHIFT];
468
			}
469
		}
470

471
		if (outpos >= outsize - MAX_OP_SIZE) {
472
			void *tmp = out;
473
			outsize = outsize * 3 / 2;
474
			if (max_size && outsize >= max_size)
475
				outsize = max_size + MAX_OP_SIZE + 1;
476
			if (max_size && outpos > max_size)
477
				break;
478
			out = realloc(out, outsize);
479
			if (!out) {
480
				free(tmp);
481
				return NULL;
482
			}
483
		}
484
	}
485

486
	if (inscnt)
487
		out[outpos - inscnt - 1] = inscnt;
488

489
	if (max_size && outpos > max_size) {
490
		free(out);
491
		return NULL;
492
	}
493

494
	*delta_size = outpos;
495
	return out;
496
}
497

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.