126fa459cSmrg/* Copyright 2010 Google Inc. All Rights Reserved. 226fa459cSmrg 326fa459cSmrg Distributed under MIT license. 426fa459cSmrg See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 526fa459cSmrg*/ 626fa459cSmrg 726fa459cSmrg/* Function to find maximal matching prefixes of strings. */ 826fa459cSmrg 926fa459cSmrg#ifndef BROTLI_ENC_FIND_MATCH_LENGTH_H_ 1026fa459cSmrg#define BROTLI_ENC_FIND_MATCH_LENGTH_H_ 1126fa459cSmrg 1226fa459cSmrg#include "../common/platform.h" 1326fa459cSmrg#include <brotli/types.h> 1426fa459cSmrg 1526fa459cSmrg#if defined(__cplusplus) || defined(c_plusplus) 1626fa459cSmrgextern "C" { 1726fa459cSmrg#endif 1826fa459cSmrg 1926fa459cSmrg/* Separate implementation for little-endian 64-bit targets, for speed. */ 2026fa459cSmrg#if defined(BROTLI_TZCNT64) && BROTLI_64_BITS && BROTLI_LITTLE_ENDIAN 2126fa459cSmrgstatic BROTLI_INLINE size_t FindMatchLengthWithLimit(const uint8_t* s1, 2226fa459cSmrg const uint8_t* s2, 2326fa459cSmrg size_t limit) { 2426fa459cSmrg size_t matched = 0; 2526fa459cSmrg size_t limit2 = (limit >> 3) + 1; /* + 1 is for pre-decrement in while */ 2626fa459cSmrg while (BROTLI_PREDICT_TRUE(--limit2)) { 2726fa459cSmrg if (BROTLI_PREDICT_FALSE(BROTLI_UNALIGNED_LOAD64LE(s2) == 2826fa459cSmrg BROTLI_UNALIGNED_LOAD64LE(s1 + matched))) { 2926fa459cSmrg s2 += 8; 3026fa459cSmrg matched += 8; 3126fa459cSmrg } else { 3226fa459cSmrg uint64_t x = BROTLI_UNALIGNED_LOAD64LE(s2) ^ 3326fa459cSmrg BROTLI_UNALIGNED_LOAD64LE(s1 + matched); 3426fa459cSmrg size_t matching_bits = (size_t)BROTLI_TZCNT64(x); 3526fa459cSmrg matched += matching_bits >> 3; 3626fa459cSmrg return matched; 3726fa459cSmrg } 3826fa459cSmrg } 3926fa459cSmrg limit = (limit & 7) + 1; /* + 1 is for pre-decrement in while */ 4026fa459cSmrg while (--limit) { 4126fa459cSmrg if (BROTLI_PREDICT_TRUE(s1[matched] == *s2)) { 4226fa459cSmrg ++s2; 4326fa459cSmrg ++matched; 4426fa459cSmrg } else { 4526fa459cSmrg return matched; 4626fa459cSmrg } 4726fa459cSmrg } 4826fa459cSmrg return matched; 4926fa459cSmrg} 5026fa459cSmrg#else 5126fa459cSmrgstatic BROTLI_INLINE size_t FindMatchLengthWithLimit(const uint8_t* s1, 5226fa459cSmrg const uint8_t* s2, 5326fa459cSmrg size_t limit) { 5426fa459cSmrg size_t matched = 0; 5526fa459cSmrg const uint8_t* s2_limit = s2 + limit; 5626fa459cSmrg const uint8_t* s2_ptr = s2; 5726fa459cSmrg /* Find out how long the match is. We loop over the data 32 bits at a 5826fa459cSmrg time until we find a 32-bit block that doesn't match; then we find 5926fa459cSmrg the first non-matching bit and use that to calculate the total 6026fa459cSmrg length of the match. */ 6126fa459cSmrg while (s2_ptr <= s2_limit - 4 && 6226fa459cSmrg BrotliUnalignedRead32(s2_ptr) == 6326fa459cSmrg BrotliUnalignedRead32(s1 + matched)) { 6426fa459cSmrg s2_ptr += 4; 6526fa459cSmrg matched += 4; 6626fa459cSmrg } 6726fa459cSmrg while ((s2_ptr < s2_limit) && (s1[matched] == *s2_ptr)) { 6826fa459cSmrg ++s2_ptr; 6926fa459cSmrg ++matched; 7026fa459cSmrg } 7126fa459cSmrg return matched; 7226fa459cSmrg} 7326fa459cSmrg#endif 7426fa459cSmrg 7526fa459cSmrg#if defined(__cplusplus) || defined(c_plusplus) 7626fa459cSmrg} /* extern "C" */ 7726fa459cSmrg#endif 7826fa459cSmrg 7926fa459cSmrg#endif /* BROTLI_ENC_FIND_MATCH_LENGTH_H_ */ 80