MCPcopy Create free account
hub / github.com/diasurgical/devilution / FindRep

Function FindRep

3rdParty/PKWare/implode.cpp:247–501  ·  view source on GitHub ↗

This function searches for a repetition (a previous occurence of the current byte sequence) Returns length of the repetition, and stores the backward distance to pWork structure.

Source from the content-addressed store, hash-verified

245// Returns length of the repetition, and stores the backward distance
246// to pWork structure.
247static unsigned int PKWAREAPI FindRep(TCmpStruct * pWork, unsigned char * input_data)
248{
249 unsigned short * phash_to_index; // Pointer into pWork->phash_to_index table
250 unsigned short * phash_offs; // Pointer to the table containing offsets of each PAIR_HASH
251 unsigned char * repetition_limit; // An eventual repetition must be at position below this pointer
252 unsigned char * prev_repetition; // Pointer to the previous occurence of the current PAIR_HASH
253 unsigned char * prev_rep_end; // End of the previous repetition
254 unsigned char * input_data_ptr;
255 unsigned short phash_offs_index; // Index to the table with PAIR_HASH positions
256 unsigned short min_phash_offs; // The lowest allowed hash offset
257 unsigned short offs_in_rep; // Offset within found repetition
258 unsigned int equal_byte_count; // Number of bytes that are equal to the previous occurence
259 unsigned int rep_length = 1; // Length of the found repetition
260 unsigned int rep_length2; // Secondary repetition
261 unsigned char pre_last_byte; // Last but one byte from a repetion
262 unsigned short di_val;
263
264 // Calculate the previous position of the PAIR_HASH
265 phash_to_index = pWork->phash_to_index + BYTE_PAIR_HASH(input_data);
266 min_phash_offs = (unsigned short)((input_data - pWork->work_buff) - pWork->dsize_bytes + 1);
267 phash_offs_index = phash_to_index[0];
268
269 // If the PAIR_HASH offset is below the limit, find a next one
270 phash_offs = pWork->phash_offs + phash_offs_index;
271 if(*phash_offs < min_phash_offs)
272 {
273 while(*phash_offs < min_phash_offs)
274 {
275 phash_offs_index++;
276 phash_offs++;
277 }
278 *phash_to_index = phash_offs_index;
279 }
280
281 // Get the first location of the PAIR_HASH,
282 // and thus the first eventual location of byte repetition
283 phash_offs = pWork->phash_offs + phash_offs_index;
284 prev_repetition = pWork->work_buff + phash_offs[0];
285 repetition_limit = input_data - 1;
286
287 // If the current PAIR_HASH was not encountered before,
288 // we haven't found a repetition.
289 if(prev_repetition >= repetition_limit)
290 return 0;
291
292 // We have found a match of a PAIR_HASH. Now we have to make sure
293 // that it is also a byte match, because PAIR_HASH is not unique.
294 // We compare the bytes and count the length of the repetition
295 input_data_ptr = input_data;
296 for(;;)
297 {
298 // If the first byte of the repetition and the so-far-last byte
299 // of the repetition are equal, we will compare the blocks.
300 if(*input_data_ptr == *prev_repetition && input_data_ptr[rep_length-1] == prev_repetition[rep_length-1])
301 {
302 // Skip the current byte
303 prev_repetition++;
304 input_data_ptr++;

Callers 1

WriteCmpDataFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected