11cb0ef41Sopenharmony_ci/* Copyright 2010 Google Inc. All Rights Reserved.
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci   Distributed under MIT license.
41cb0ef41Sopenharmony_ci   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
51cb0ef41Sopenharmony_ci*/
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci/* Function to find maximal matching prefixes of strings. */
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci#ifndef BROTLI_ENC_FIND_MATCH_LENGTH_H_
101cb0ef41Sopenharmony_ci#define BROTLI_ENC_FIND_MATCH_LENGTH_H_
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci#include "../common/platform.h"
131cb0ef41Sopenharmony_ci#include <brotli/types.h>
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci#if defined(__cplusplus) || defined(c_plusplus)
161cb0ef41Sopenharmony_ciextern "C" {
171cb0ef41Sopenharmony_ci#endif
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ci/* Separate implementation for little-endian 64-bit targets, for speed. */
201cb0ef41Sopenharmony_ci#if defined(BROTLI_TZCNT64) && BROTLI_64_BITS && BROTLI_LITTLE_ENDIAN
211cb0ef41Sopenharmony_cistatic BROTLI_INLINE size_t FindMatchLengthWithLimit(const uint8_t* s1,
221cb0ef41Sopenharmony_ci                                                     const uint8_t* s2,
231cb0ef41Sopenharmony_ci                                                     size_t limit) {
241cb0ef41Sopenharmony_ci  size_t matched = 0;
251cb0ef41Sopenharmony_ci  size_t limit2 = (limit >> 3) + 1;  /* + 1 is for pre-decrement in while */
261cb0ef41Sopenharmony_ci  while (BROTLI_PREDICT_TRUE(--limit2)) {
271cb0ef41Sopenharmony_ci    if (BROTLI_PREDICT_FALSE(BROTLI_UNALIGNED_LOAD64LE(s2) ==
281cb0ef41Sopenharmony_ci                      BROTLI_UNALIGNED_LOAD64LE(s1 + matched))) {
291cb0ef41Sopenharmony_ci      s2 += 8;
301cb0ef41Sopenharmony_ci      matched += 8;
311cb0ef41Sopenharmony_ci    } else {
321cb0ef41Sopenharmony_ci      uint64_t x = BROTLI_UNALIGNED_LOAD64LE(s2) ^
331cb0ef41Sopenharmony_ci          BROTLI_UNALIGNED_LOAD64LE(s1 + matched);
341cb0ef41Sopenharmony_ci      size_t matching_bits = (size_t)BROTLI_TZCNT64(x);
351cb0ef41Sopenharmony_ci      matched += matching_bits >> 3;
361cb0ef41Sopenharmony_ci      return matched;
371cb0ef41Sopenharmony_ci    }
381cb0ef41Sopenharmony_ci  }
391cb0ef41Sopenharmony_ci  limit = (limit & 7) + 1;  /* + 1 is for pre-decrement in while */
401cb0ef41Sopenharmony_ci  while (--limit) {
411cb0ef41Sopenharmony_ci    if (BROTLI_PREDICT_TRUE(s1[matched] == *s2)) {
421cb0ef41Sopenharmony_ci      ++s2;
431cb0ef41Sopenharmony_ci      ++matched;
441cb0ef41Sopenharmony_ci    } else {
451cb0ef41Sopenharmony_ci      return matched;
461cb0ef41Sopenharmony_ci    }
471cb0ef41Sopenharmony_ci  }
481cb0ef41Sopenharmony_ci  return matched;
491cb0ef41Sopenharmony_ci}
501cb0ef41Sopenharmony_ci#else
511cb0ef41Sopenharmony_cistatic BROTLI_INLINE size_t FindMatchLengthWithLimit(const uint8_t* s1,
521cb0ef41Sopenharmony_ci                                                     const uint8_t* s2,
531cb0ef41Sopenharmony_ci                                                     size_t limit) {
541cb0ef41Sopenharmony_ci  size_t matched = 0;
551cb0ef41Sopenharmony_ci  const uint8_t* s2_limit = s2 + limit;
561cb0ef41Sopenharmony_ci  const uint8_t* s2_ptr = s2;
571cb0ef41Sopenharmony_ci  /* Find out how long the match is. We loop over the data 32 bits at a
581cb0ef41Sopenharmony_ci     time until we find a 32-bit block that doesn't match; then we find
591cb0ef41Sopenharmony_ci     the first non-matching bit and use that to calculate the total
601cb0ef41Sopenharmony_ci     length of the match. */
611cb0ef41Sopenharmony_ci  while (s2_ptr <= s2_limit - 4 &&
621cb0ef41Sopenharmony_ci         BrotliUnalignedRead32(s2_ptr) ==
631cb0ef41Sopenharmony_ci         BrotliUnalignedRead32(s1 + matched)) {
641cb0ef41Sopenharmony_ci    s2_ptr += 4;
651cb0ef41Sopenharmony_ci    matched += 4;
661cb0ef41Sopenharmony_ci  }
671cb0ef41Sopenharmony_ci  while ((s2_ptr < s2_limit) && (s1[matched] == *s2_ptr)) {
681cb0ef41Sopenharmony_ci    ++s2_ptr;
691cb0ef41Sopenharmony_ci    ++matched;
701cb0ef41Sopenharmony_ci  }
711cb0ef41Sopenharmony_ci  return matched;
721cb0ef41Sopenharmony_ci}
731cb0ef41Sopenharmony_ci#endif
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci#if defined(__cplusplus) || defined(c_plusplus)
761cb0ef41Sopenharmony_ci}  /* extern "C" */
771cb0ef41Sopenharmony_ci#endif
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci#endif  /* BROTLI_ENC_FIND_MATCH_LENGTH_H_ */
80