/* insert_string_tpl.h -- Private insert_string functions shared with more than * one insert string implementation * * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler * * Copyright (C) 2013 Intel Corporation. All rights reserved. * Authors: * Wajdi Feghali * Jim Guilford * Vinodh Gopal * Erdinc Ozturk * Jim Kukunas * * Portions are Copyright (C) 2016 12Sided Technology, LLC. * Author: * Phil Vachon * * For conditions of distribution and use, see copyright notice in zlib.h * */ #ifndef HASH_CALC_READ # define HASH_CALC_READ val = Z_U32_FROM_LE(zng_memread_4(strstart)); #endif /* =========================================================================== * Update a hash value with the given input byte * IN assertion: all calls to UPDATE_HASH are made with consecutive * input characters, so that a running hash key can be computed from the * previous key instead of complete recalculation each time. */ Z_FORCEINLINE static uint32_t UPDATE_HASH(uint32_t h, uint32_t val) { HASH_CALC(h, val); return h & HASH_CALC_MASK; } /* =========================================================================== * Quick insert string str in the dictionary using a pre-read value and set match_head * to the previous head of the hash chain (the most recent string with same hash key). * Return the previous length of the hash chain. */ Z_FORCEINLINE static uint32_t QUICK_INSERT_VALUE(deflate_state *const s, uint32_t str, uint32_t val) { uint32_t hm, head; HASH_CALC_VAR_INIT; HASH_CALC(HASH_CALC_VAR, val); HASH_CALC_VAR &= HASH_CALC_MASK; hm = HASH_CALC_VAR; head = s->head[hm]; if (LIKELY(head != str)) { s->prev[str & W_MASK(s)] = (Pos)head; s->head[hm] = (Pos)str; } return head; } /* =========================================================================== * Quick insert string str in the dictionary and set match_head to the previous head * of the hash chain (the most recent string with same hash key). Return * the previous length of the hash chain. */ Z_FORCEINLINE static uint32_t QUICK_INSERT_STRING(deflate_state *const s, uint32_t str) { uint8_t *strstart = s->window + str + HASH_CALC_OFFSET; uint32_t val, hm, head; HASH_CALC_VAR_INIT; HASH_CALC_READ; HASH_CALC(HASH_CALC_VAR, val); HASH_CALC_VAR &= HASH_CALC_MASK; hm = HASH_CALC_VAR; head = s->head[hm]; if (LIKELY(head != str)) { s->prev[str & W_MASK(s)] = (Pos)head; s->head[hm] = (Pos)str; } return head; } /* =========================================================================== * Insert string str in the dictionary and set match_head to the previous head * of the hash chain (the most recent string with same hash key). Return * the previous length of the hash chain. * IN assertion: all calls to INSERT_STRING are made with consecutive * input characters and the first STD_MIN_MATCH bytes of str are valid * (except for the last STD_MIN_MATCH-1 bytes of the input file). */ Z_FORCEINLINE static void INSERT_STRING(deflate_state *const s, uint32_t str, uint32_t count) { uint8_t *strstart = s->window + str + HASH_CALC_OFFSET; uint8_t *strend = strstart + count; /* Local pointers to avoid indirection */ Pos *headp = s->head; Pos *prevp = s->prev; const unsigned int w_mask = W_MASK(s); for (uint32_t idx = str; strstart < strend; idx++, strstart++) { uint32_t val, hm, head; HASH_CALC_VAR_INIT; HASH_CALC_READ; HASH_CALC(HASH_CALC_VAR, val); HASH_CALC_VAR &= HASH_CALC_MASK; hm = HASH_CALC_VAR; head = headp[hm]; if (LIKELY(head != idx)) { prevp[idx & w_mask] = (Pos)head; headp[hm] = (Pos)idx; } } } // Cleanup #undef HASH_SLIDE #undef HASH_CALC #undef HASH_CALC_READ #undef HASH_CALC_MASK #undef HASH_CALC_OFFSET #undef HASH_CALC_VAR #undef HASH_CALC_VAR_INIT #undef UPDATE_HASH #undef INSERT_STRING #undef QUICK_INSERT_STRING #undef QUICK_INSERT_VALUE