11cb0ef41Sopenharmony_ci/* insert_string.h 21cb0ef41Sopenharmony_ci * 31cb0ef41Sopenharmony_ci * Copyright 2019 The Chromium Authors 41cb0ef41Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 51cb0ef41Sopenharmony_ci * found in the Chromium source repository LICENSE file. 61cb0ef41Sopenharmony_ci */ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#ifndef INSERT_STRING_H 91cb0ef41Sopenharmony_ci#define INSERT_STRING_H 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ci#ifndef INLINE 121cb0ef41Sopenharmony_ci#if defined(_MSC_VER) && !defined(__clang__) 131cb0ef41Sopenharmony_ci#define INLINE __inline 141cb0ef41Sopenharmony_ci#else 151cb0ef41Sopenharmony_ci#define INLINE inline 161cb0ef41Sopenharmony_ci#endif 171cb0ef41Sopenharmony_ci#endif 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ci#include <stdint.h> 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci/** 221cb0ef41Sopenharmony_ci * Some applications need to match zlib DEFLATE output exactly [3]. Use the 231cb0ef41Sopenharmony_ci * canonical zlib Rabin-Karp rolling hash [1,2] in that case. 241cb0ef41Sopenharmony_ci * 251cb0ef41Sopenharmony_ci * [1] For a description of the Rabin and Karp algorithm, see "Algorithms" 261cb0ef41Sopenharmony_ci * book by R. Sedgewick, Addison-Wesley, p252. 271cb0ef41Sopenharmony_ci * [2] https://www.euccas.me/zlib/#zlib_rabin_karp and also "rolling hash" 281cb0ef41Sopenharmony_ci * https://en.wikipedia.org/wiki/Rolling_hash 291cb0ef41Sopenharmony_ci * [3] crbug.com/1316541 AOSP incremental client APK package OTA upgrades. 301cb0ef41Sopenharmony_ci */ 311cb0ef41Sopenharmony_ci#ifdef CHROMIUM_ZLIB_NO_CASTAGNOLI 321cb0ef41Sopenharmony_ci#define USE_ZLIB_RABIN_KARP_ROLLING_HASH 331cb0ef41Sopenharmony_ci#endif 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci/* =========================================================================== 361cb0ef41Sopenharmony_ci * Update a hash value with the given input byte (Rabin-Karp rolling hash). 371cb0ef41Sopenharmony_ci * IN assertion: all calls to UPDATE_HASH are made with consecutive input 381cb0ef41Sopenharmony_ci * characters, so that a running hash key can be computed from the previous 391cb0ef41Sopenharmony_ci * key instead of complete recalculation each time. 401cb0ef41Sopenharmony_ci */ 411cb0ef41Sopenharmony_ci#define UPDATE_HASH(s, h, c) (h = (((h) << s->hash_shift) ^ (c)) & s->hash_mask) 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci/* =========================================================================== 441cb0ef41Sopenharmony_ci * Insert string str in the dictionary and set match_head to the previous head 451cb0ef41Sopenharmony_ci * of the hash chain (the most recent string with same hash key). Return 461cb0ef41Sopenharmony_ci * the previous length of the hash chain. 471cb0ef41Sopenharmony_ci * If this file is compiled with -DFASTEST, the compression level is forced 481cb0ef41Sopenharmony_ci * to 1, and no hash chains are maintained. 491cb0ef41Sopenharmony_ci * IN assertion: all calls to INSERT_STRING are made with consecutive input 501cb0ef41Sopenharmony_ci * characters and the first MIN_MATCH bytes of str are valid (except for 511cb0ef41Sopenharmony_ci * the last MIN_MATCH-1 bytes of the input file). 521cb0ef41Sopenharmony_ci */ 531cb0ef41Sopenharmony_cilocal INLINE Pos insert_string(deflate_state* const s, const Pos str) { 541cb0ef41Sopenharmony_ci Pos ret; 551cb0ef41Sopenharmony_ci/* insert_string dictionary insertion: ANZAC++ hasher 561cb0ef41Sopenharmony_ci * significantly improves data compression speed. 571cb0ef41Sopenharmony_ci * 581cb0ef41Sopenharmony_ci * Note: the generated compressed output is a valid DEFLATE stream, but will 591cb0ef41Sopenharmony_ci * differ from canonical zlib output. 601cb0ef41Sopenharmony_ci */ 611cb0ef41Sopenharmony_ci#if defined(USE_ZLIB_RABIN_KARP_ROLLING_HASH) 621cb0ef41Sopenharmony_ci UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH - 1)]); 631cb0ef41Sopenharmony_ci#else 641cb0ef41Sopenharmony_ci uint32_t value; 651cb0ef41Sopenharmony_ci // Validated for little endian archs (i.e. x86, Arm). YMMV for big endian. 661cb0ef41Sopenharmony_ci zmemcpy(&value, &s->window[str], sizeof(value)); 671cb0ef41Sopenharmony_ci s->ins_h = ((value * 66521 + 66521) >> 16) & s->hash_mask; 681cb0ef41Sopenharmony_ci#endif 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci#ifdef FASTEST 711cb0ef41Sopenharmony_ci ret = s->head[s->ins_h]; 721cb0ef41Sopenharmony_ci#else 731cb0ef41Sopenharmony_ci ret = s->prev[str & s->w_mask] = s->head[s->ins_h]; 741cb0ef41Sopenharmony_ci#endif 751cb0ef41Sopenharmony_ci s->head[s->ins_h] = str; 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci return ret; 781cb0ef41Sopenharmony_ci} 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci#endif /* INSERT_STRING_H */ 81