1*f4ee7fbaSAndroid Build Coastguard Worker /* Copyright 2010 Google Inc. All Rights Reserved. 2*f4ee7fbaSAndroid Build Coastguard Worker 3*f4ee7fbaSAndroid Build Coastguard Worker Distributed under MIT license. 4*f4ee7fbaSAndroid Build Coastguard Worker See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5*f4ee7fbaSAndroid Build Coastguard Worker */ 6*f4ee7fbaSAndroid Build Coastguard Worker 7*f4ee7fbaSAndroid Build Coastguard Worker /* Function to find maximal matching prefixes of strings. */ 8*f4ee7fbaSAndroid Build Coastguard Worker 9*f4ee7fbaSAndroid Build Coastguard Worker #ifndef BROTLI_ENC_FIND_MATCH_LENGTH_H_ 10*f4ee7fbaSAndroid Build Coastguard Worker #define BROTLI_ENC_FIND_MATCH_LENGTH_H_ 11*f4ee7fbaSAndroid Build Coastguard Worker 12*f4ee7fbaSAndroid Build Coastguard Worker #include "../common/platform.h" 13*f4ee7fbaSAndroid Build Coastguard Worker #include <brotli/types.h> 14*f4ee7fbaSAndroid Build Coastguard Worker 15*f4ee7fbaSAndroid Build Coastguard Worker #if defined(__cplusplus) || defined(c_plusplus) 16*f4ee7fbaSAndroid Build Coastguard Worker extern "C" { 17*f4ee7fbaSAndroid Build Coastguard Worker #endif 18*f4ee7fbaSAndroid Build Coastguard Worker 19*f4ee7fbaSAndroid Build Coastguard Worker /* Separate implementation for little-endian 64-bit targets, for speed. */ 20*f4ee7fbaSAndroid Build Coastguard Worker #if defined(BROTLI_TZCNT64) && BROTLI_64_BITS && BROTLI_LITTLE_ENDIAN FindMatchLengthWithLimit(const uint8_t * s1,const uint8_t * s2,size_t limit)21*f4ee7fbaSAndroid Build Coastguard Workerstatic BROTLI_INLINE size_t FindMatchLengthWithLimit(const uint8_t* s1, 22*f4ee7fbaSAndroid Build Coastguard Worker const uint8_t* s2, 23*f4ee7fbaSAndroid Build Coastguard Worker size_t limit) { 24*f4ee7fbaSAndroid Build Coastguard Worker size_t matched = 0; 25*f4ee7fbaSAndroid Build Coastguard Worker size_t limit2 = (limit >> 3) + 1; /* + 1 is for pre-decrement in while */ 26*f4ee7fbaSAndroid Build Coastguard Worker while (BROTLI_PREDICT_TRUE(--limit2)) { 27*f4ee7fbaSAndroid Build Coastguard Worker if (BROTLI_PREDICT_FALSE(BROTLI_UNALIGNED_LOAD64LE(s2) == 28*f4ee7fbaSAndroid Build Coastguard Worker BROTLI_UNALIGNED_LOAD64LE(s1 + matched))) { 29*f4ee7fbaSAndroid Build Coastguard Worker s2 += 8; 30*f4ee7fbaSAndroid Build Coastguard Worker matched += 8; 31*f4ee7fbaSAndroid Build Coastguard Worker } else { 32*f4ee7fbaSAndroid Build Coastguard Worker uint64_t x = BROTLI_UNALIGNED_LOAD64LE(s2) ^ 33*f4ee7fbaSAndroid Build Coastguard Worker BROTLI_UNALIGNED_LOAD64LE(s1 + matched); 34*f4ee7fbaSAndroid Build Coastguard Worker size_t matching_bits = (size_t)BROTLI_TZCNT64(x); 35*f4ee7fbaSAndroid Build Coastguard Worker matched += matching_bits >> 3; 36*f4ee7fbaSAndroid Build Coastguard Worker return matched; 37*f4ee7fbaSAndroid Build Coastguard Worker } 38*f4ee7fbaSAndroid Build Coastguard Worker } 39*f4ee7fbaSAndroid Build Coastguard Worker limit = (limit & 7) + 1; /* + 1 is for pre-decrement in while */ 40*f4ee7fbaSAndroid Build Coastguard Worker while (--limit) { 41*f4ee7fbaSAndroid Build Coastguard Worker if (BROTLI_PREDICT_TRUE(s1[matched] == *s2)) { 42*f4ee7fbaSAndroid Build Coastguard Worker ++s2; 43*f4ee7fbaSAndroid Build Coastguard Worker ++matched; 44*f4ee7fbaSAndroid Build Coastguard Worker } else { 45*f4ee7fbaSAndroid Build Coastguard Worker return matched; 46*f4ee7fbaSAndroid Build Coastguard Worker } 47*f4ee7fbaSAndroid Build Coastguard Worker } 48*f4ee7fbaSAndroid Build Coastguard Worker return matched; 49*f4ee7fbaSAndroid Build Coastguard Worker } 50*f4ee7fbaSAndroid Build Coastguard Worker #else 51*f4ee7fbaSAndroid Build Coastguard Worker static BROTLI_INLINE size_t FindMatchLengthWithLimit(const uint8_t* s1, 52*f4ee7fbaSAndroid Build Coastguard Worker const uint8_t* s2, 53*f4ee7fbaSAndroid Build Coastguard Worker size_t limit) { 54*f4ee7fbaSAndroid Build Coastguard Worker size_t matched = 0; 55*f4ee7fbaSAndroid Build Coastguard Worker const uint8_t* s2_limit = s2 + limit; 56*f4ee7fbaSAndroid Build Coastguard Worker const uint8_t* s2_ptr = s2; 57*f4ee7fbaSAndroid Build Coastguard Worker /* Find out how long the match is. We loop over the data 32 bits at a 58*f4ee7fbaSAndroid Build Coastguard Worker time until we find a 32-bit block that doesn't match; then we find 59*f4ee7fbaSAndroid Build Coastguard Worker the first non-matching bit and use that to calculate the total 60*f4ee7fbaSAndroid Build Coastguard Worker length of the match. */ 61*f4ee7fbaSAndroid Build Coastguard Worker while (s2_ptr <= s2_limit - 4 && 62*f4ee7fbaSAndroid Build Coastguard Worker BrotliUnalignedRead32(s2_ptr) == 63*f4ee7fbaSAndroid Build Coastguard Worker BrotliUnalignedRead32(s1 + matched)) { 64*f4ee7fbaSAndroid Build Coastguard Worker s2_ptr += 4; 65*f4ee7fbaSAndroid Build Coastguard Worker matched += 4; 66*f4ee7fbaSAndroid Build Coastguard Worker } 67*f4ee7fbaSAndroid Build Coastguard Worker while ((s2_ptr < s2_limit) && (s1[matched] == *s2_ptr)) { 68*f4ee7fbaSAndroid Build Coastguard Worker ++s2_ptr; 69*f4ee7fbaSAndroid Build Coastguard Worker ++matched; 70*f4ee7fbaSAndroid Build Coastguard Worker } 71*f4ee7fbaSAndroid Build Coastguard Worker return matched; 72*f4ee7fbaSAndroid Build Coastguard Worker } 73*f4ee7fbaSAndroid Build Coastguard Worker #endif 74*f4ee7fbaSAndroid Build Coastguard Worker 75*f4ee7fbaSAndroid Build Coastguard Worker #if defined(__cplusplus) || defined(c_plusplus) 76*f4ee7fbaSAndroid Build Coastguard Worker } /* extern "C" */ 77*f4ee7fbaSAndroid Build Coastguard Worker #endif 78*f4ee7fbaSAndroid Build Coastguard Worker 79*f4ee7fbaSAndroid Build Coastguard Worker #endif /* BROTLI_ENC_FIND_MATCH_LENGTH_H_ */ 80