1299425Smm/* 2299425SmmxxHash - Fast Hash algorithm 3299425SmmCopyright (C) 2012-2014, Yann Collet. 4299425SmmBSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 5299425Smm 6299425SmmRedistribution and use in source and binary forms, with or without 7299425Smmmodification, are permitted provided that the following conditions are 8299425Smmmet: 9299425Smm 10299425Smm* Redistributions of source code must retain the above copyright 11299425Smmnotice, this list of conditions and the following disclaimer. 12299425Smm* Redistributions in binary form must reproduce the above 13299425Smmcopyright notice, this list of conditions and the following disclaimer 14299425Smmin the documentation and/or other materials provided with the 15299425Smmdistribution. 16299425Smm 17299425SmmTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18299425Smm"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19299425SmmLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20299425SmmA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21299425SmmOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22299425SmmSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23299425SmmLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24299425SmmDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25299425SmmTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26299425Smm(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27299425SmmOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28299425Smm 29299425SmmYou can contact the author at : 30299425Smm- xxHash source repository : http://code.google.com/p/xxhash/ 31299425Smm*/ 32313570Smm#include "archive_platform.h" 33313570Smm 34299425Smm#include <stdlib.h> 35299425Smm#include <string.h> 36299425Smm 37299425Smm#include "archive_xxhash.h" 38299425Smm 39299425Smm#ifdef HAVE_LIBLZ4 40299425Smm 41299425Smm/*************************************** 42299425Smm** Tuning parameters 43299425Smm****************************************/ 44299425Smm/* Unaligned memory access is automatically enabled for "common" CPU, such as x86. 45299425Smm** For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected. 46299425Smm** If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance. 47299425Smm** You can also enable this parameter if you know your input data will always be aligned (boundaries of 4, for U32). 48299425Smm*/ 49299425Smm#if defined(__ARM_FEATURE_UNALIGNED) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) 50299425Smm# define XXH_USE_UNALIGNED_ACCESS 1 51299425Smm#endif 52299425Smm 53299425Smm/* XXH_ACCEPT_NULL_INPUT_POINTER : 54299425Smm** If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer. 55299425Smm** When this option is enabled, xxHash output for null input pointers will be the same as a null-length input. 56299425Smm** This option has a very small performance cost (only measurable on small inputs). 57299425Smm** By default, this option is disabled. To enable it, uncomment below define : 58299425Smm** #define XXH_ACCEPT_NULL_INPUT_POINTER 1 59299425Smm 60299425Smm** XXH_FORCE_NATIVE_FORMAT : 61299425Smm** By default, xxHash library provides endian-independent Hash values, based on little-endian convention. 62299425Smm** Results are therefore identical for little-endian and big-endian CPU. 63299425Smm** This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format. 64313570Smm** Should endian-independence be of no importance for your application, you may set the #define below to 1. 65299425Smm** It will improve speed for Big-endian CPU. 66299425Smm** This option has no impact on Little_Endian CPU. 67299425Smm*/ 68299425Smm#define XXH_FORCE_NATIVE_FORMAT 0 69299425Smm 70299425Smm/*************************************** 71299425Smm** Compiler Specific Options 72299425Smm****************************************/ 73299425Smm/* Disable some Visual warning messages */ 74299425Smm#ifdef _MSC_VER /* Visual Studio */ 75299425Smm# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ 76299425Smm#endif 77299425Smm 78299425Smm#ifdef _MSC_VER /* Visual Studio */ 79299425Smm# define FORCE_INLINE __forceinline 80299425Smm#else 81299425Smm# ifdef __GNUC__ 82299425Smm# define FORCE_INLINE inline __attribute__((always_inline)) 83299425Smm# else 84299425Smm# define FORCE_INLINE inline 85299425Smm# endif 86299425Smm#endif 87299425Smm 88299425Smm/*************************************** 89299425Smm** Includes & Memory related functions 90299425Smm****************************************/ 91299425Smm#define XXH_malloc malloc 92299425Smm#define XXH_free free 93299425Smm#define XXH_memcpy memcpy 94299425Smm 95299425Smm 96299425Smmstatic unsigned int XXH32 (const void*, unsigned int, unsigned int); 97299425Smmstatic void* XXH32_init (unsigned int); 98299425Smmstatic XXH_errorcode XXH32_update (void*, const void*, unsigned int); 99299425Smmstatic unsigned int XXH32_digest (void*); 100299425Smm/*static int XXH32_sizeofState(void);*/ 101299425Smmstatic XXH_errorcode XXH32_resetState(void*, unsigned int); 102299425Smm#define XXH32_SIZEOFSTATE 48 103299425Smmtypedef struct { long long ll[(XXH32_SIZEOFSTATE+(sizeof(long long)-1))/sizeof(long long)]; } XXH32_stateSpace_t; 104299425Smmstatic unsigned int XXH32_intermediateDigest (void*); 105299425Smm 106299425Smm/*************************************** 107299425Smm** Basic Types 108299425Smm****************************************/ 109299425Smm#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ 110299425Smm# include <stdint.h> 111299425Smm typedef uint8_t BYTE; 112299425Smm typedef uint16_t U16; 113299425Smm typedef uint32_t U32; 114299425Smm typedef int32_t S32; 115299425Smm typedef uint64_t U64; 116299425Smm#else 117299425Smm typedef unsigned char BYTE; 118299425Smm typedef unsigned short U16; 119299425Smm typedef unsigned int U32; 120299425Smm typedef signed int S32; 121299425Smm typedef unsigned long long U64; 122299425Smm#endif 123299425Smm 124299425Smm#if defined(__GNUC__) && !defined(XXH_USE_UNALIGNED_ACCESS) 125299425Smm# define _PACKED __attribute__ ((packed)) 126299425Smm#else 127299425Smm# define _PACKED 128299425Smm#endif 129299425Smm 130299425Smm#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__) 131299425Smm# ifdef __IBMC__ 132299425Smm# pragma pack(1) 133299425Smm# else 134299425Smm# pragma pack(push, 1) 135299425Smm# endif 136299425Smm#endif 137299425Smm 138299425Smmtypedef struct _U32_S { U32 v; } _PACKED U32_S; 139299425Smm 140299425Smm#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__) 141299425Smm# pragma pack(pop) 142299425Smm#endif 143299425Smm 144299425Smm 145299425Smm/**************************************** 146299425Smm** Compiler-specific Functions and Macros 147299425Smm*****************************************/ 148318482Smm#define GCC_VERSION ((__GNUC__-0) * 100 + (__GNUC_MINOR__ - 0)) 149299425Smm 150318482Smm#if GCC_VERSION >= 409 151318482Smm__attribute__((__no_sanitize_undefined__)) 152318482Smm#endif 153370535Sgit2svn#if defined(_MSC_VER) 154370535Sgit2svnstatic __inline U32 A32(const void * x) 155370535Sgit2svn#else 156370535Sgit2svnstatic inline U32 A32(const void* x) 157370535Sgit2svn#endif 158318482Smm{ 159318482Smm return (((const U32_S *)(x))->v); 160318482Smm} 161318482Smm 162299425Smm/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */ 163299425Smm#if defined(_MSC_VER) 164299425Smm# define XXH_rotl32(x,r) _rotl(x,r) 165299425Smm#else 166299425Smm# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r))) 167299425Smm#endif 168299425Smm 169299425Smm#if defined(_MSC_VER) /* Visual Studio */ 170299425Smm# define XXH_swap32 _byteswap_ulong 171299425Smm#elif GCC_VERSION >= 403 172299425Smm# define XXH_swap32 __builtin_bswap32 173299425Smm#else 174299425Smmstatic inline U32 XXH_swap32 (U32 x) { 175299425Smm return ((x << 24) & 0xff000000 ) | 176299425Smm ((x << 8) & 0x00ff0000 ) | 177299425Smm ((x >> 8) & 0x0000ff00 ) | 178299425Smm ((x >> 24) & 0x000000ff );} 179299425Smm#endif 180299425Smm 181299425Smm 182299425Smm/*************************************** 183299425Smm** Constants 184299425Smm****************************************/ 185299425Smm#define PRIME32_1 2654435761U 186299425Smm#define PRIME32_2 2246822519U 187299425Smm#define PRIME32_3 3266489917U 188299425Smm#define PRIME32_4 668265263U 189299425Smm#define PRIME32_5 374761393U 190299425Smm 191299425Smm 192299425Smm/*************************************** 193299425Smm** Architecture Macros 194299425Smm****************************************/ 195299425Smmtypedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess; 196299425Smm#ifndef XXH_CPU_LITTLE_ENDIAN /* It is possible to define XXH_CPU_LITTLE_ENDIAN externally, for example using a compiler switch */ 197299425Smm static const int one = 1; 198299425Smm# define XXH_CPU_LITTLE_ENDIAN (*(const char*)(&one)) 199299425Smm#endif 200299425Smm 201299425Smm 202299425Smm/*************************************** 203299425Smm** Macros 204299425Smm****************************************/ 205299425Smm#define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(!!(c)) }; } /* use only *after* variable declarations */ 206299425Smm 207299425Smm 208299425Smm/***************************** 209299425Smm** Memory reads 210299425Smm******************************/ 211299425Smmtypedef enum { XXH_aligned, XXH_unaligned } XXH_alignment; 212299425Smm 213299425Smmstatic 214299425SmmFORCE_INLINE U32 XXH_readLE32_align(const U32* ptr, XXH_endianess endian, XXH_alignment align) 215299425Smm{ 216299425Smm if (align==XXH_unaligned) 217299425Smm return endian==XXH_littleEndian ? A32(ptr) : XXH_swap32(A32(ptr)); 218299425Smm else 219299425Smm return endian==XXH_littleEndian ? *ptr : XXH_swap32(*ptr); 220299425Smm} 221299425Smm 222299425Smmstatic 223299425SmmFORCE_INLINE U32 XXH_readLE32(const U32* ptr, XXH_endianess endian) { return XXH_readLE32_align(ptr, endian, XXH_unaligned); } 224299425Smm 225299425Smm 226299425Smm/***************************** 227299425Smm** Simple Hash Functions 228299425Smm******************************/ 229299425Smmstatic 230299425SmmFORCE_INLINE U32 XXH32_endian_align(const void* input, unsigned int len, U32 seed, XXH_endianess endian, XXH_alignment align) 231299425Smm{ 232299425Smm const BYTE* p = (const BYTE*)input; 233299425Smm const BYTE* bEnd = p + len; 234299425Smm U32 h32; 235299425Smm#define XXH_get32bits(p) XXH_readLE32_align((const U32*)p, endian, align) 236299425Smm 237299425Smm#ifdef XXH_ACCEPT_NULL_INPUT_POINTER 238299425Smm if (p==NULL) { len=0; bEnd=p=(const BYTE*)(size_t)16; } 239299425Smm#endif 240299425Smm 241299425Smm if (len>=16) 242299425Smm { 243299425Smm const BYTE* const limit = bEnd - 16; 244299425Smm U32 v1 = seed + PRIME32_1 + PRIME32_2; 245299425Smm U32 v2 = seed + PRIME32_2; 246299425Smm U32 v3 = seed + 0; 247299425Smm U32 v4 = seed - PRIME32_1; 248299425Smm 249299425Smm do 250299425Smm { 251299425Smm v1 += XXH_get32bits(p) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4; 252299425Smm v2 += XXH_get32bits(p) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4; 253299425Smm v3 += XXH_get32bits(p) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4; 254299425Smm v4 += XXH_get32bits(p) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4; 255299425Smm } while (p<=limit); 256299425Smm 257299425Smm h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); 258299425Smm } 259299425Smm else 260299425Smm { 261299425Smm h32 = seed + PRIME32_5; 262299425Smm } 263299425Smm 264299425Smm h32 += (U32) len; 265299425Smm 266299425Smm while (p<=bEnd-4) 267299425Smm { 268299425Smm h32 += XXH_get32bits(p) * PRIME32_3; 269299425Smm h32 = XXH_rotl32(h32, 17) * PRIME32_4 ; 270299425Smm p+=4; 271299425Smm } 272299425Smm 273299425Smm while (p<bEnd) 274299425Smm { 275299425Smm h32 += (*p) * PRIME32_5; 276299425Smm h32 = XXH_rotl32(h32, 11) * PRIME32_1 ; 277299425Smm p++; 278299425Smm } 279299425Smm 280299425Smm h32 ^= h32 >> 15; 281299425Smm h32 *= PRIME32_2; 282299425Smm h32 ^= h32 >> 13; 283299425Smm h32 *= PRIME32_3; 284299425Smm h32 ^= h32 >> 16; 285299425Smm 286299425Smm return h32; 287299425Smm} 288299425Smm 289299425Smm 290299425SmmU32 XXH32(const void* input, unsigned int len, U32 seed) 291299425Smm{ 292299425Smm#if 0 293299425Smm // Simple version, good for code maintenance, but unfortunately slow for small inputs 294299425Smm void* state = XXH32_init(seed); 295299425Smm XXH32_update(state, input, len); 296299425Smm return XXH32_digest(state); 297299425Smm#else 298299425Smm XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; 299299425Smm 300299425Smm# if !defined(XXH_USE_UNALIGNED_ACCESS) 301299425Smm if ((((size_t)input) & 3) == 0) /* Input is aligned, let's leverage the speed advantage */ 302299425Smm { 303299425Smm if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) 304299425Smm return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); 305299425Smm else 306299425Smm return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); 307299425Smm } 308299425Smm# endif 309299425Smm 310299425Smm if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) 311299425Smm return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); 312299425Smm else 313299425Smm return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); 314299425Smm#endif 315299425Smm} 316299425Smm 317299425Smm/***************************** 318299425Smm** Advanced Hash Functions 319299425Smm******************************/ 320299425Smm 321299425Smmstruct XXH_state32_t 322299425Smm{ 323299425Smm U64 total_len; 324299425Smm U32 seed; 325299425Smm U32 v1; 326299425Smm U32 v2; 327299425Smm U32 v3; 328299425Smm U32 v4; 329299425Smm int memsize; 330299425Smm char memory[16]; 331299425Smm}; 332299425Smm 333299425Smm#if 0 334299425Smmstatic 335299425Smmint XXH32_sizeofState(void) 336299425Smm{ 337299425Smm XXH_STATIC_ASSERT(XXH32_SIZEOFSTATE >= sizeof(struct XXH_state32_t)); /* A compilation error here means XXH32_SIZEOFSTATE is not large enough */ 338299425Smm return sizeof(struct XXH_state32_t); 339299425Smm} 340299425Smm#endif 341299425Smm 342299425Smmstatic 343299425SmmXXH_errorcode XXH32_resetState(void* state_in, U32 seed) 344299425Smm{ 345299425Smm struct XXH_state32_t * state = (struct XXH_state32_t *) state_in; 346299425Smm state->seed = seed; 347299425Smm state->v1 = seed + PRIME32_1 + PRIME32_2; 348299425Smm state->v2 = seed + PRIME32_2; 349299425Smm state->v3 = seed + 0; 350299425Smm state->v4 = seed - PRIME32_1; 351299425Smm state->total_len = 0; 352299425Smm state->memsize = 0; 353299425Smm return XXH_OK; 354299425Smm} 355299425Smm 356299425Smmstatic 357299425Smmvoid* XXH32_init (U32 seed) 358299425Smm{ 359299425Smm void* state = XXH_malloc (sizeof(struct XXH_state32_t)); 360299425Smm XXH32_resetState(state, seed); 361299425Smm return state; 362299425Smm} 363299425Smm 364299425Smmstatic 365299425SmmFORCE_INLINE XXH_errorcode XXH32_update_endian (void* state_in, const void* input, int len, XXH_endianess endian) 366299425Smm{ 367299425Smm struct XXH_state32_t * state = (struct XXH_state32_t *) state_in; 368299425Smm const BYTE* p = (const BYTE*)input; 369299425Smm const BYTE* const bEnd = p + len; 370299425Smm 371299425Smm#ifdef XXH_ACCEPT_NULL_INPUT_POINTER 372299425Smm if (input==NULL) return XXH_ERROR; 373299425Smm#endif 374299425Smm 375299425Smm state->total_len += len; 376299425Smm 377299425Smm if (state->memsize + len < 16) /* fill in tmp buffer */ 378299425Smm { 379299425Smm XXH_memcpy(state->memory + state->memsize, input, len); 380299425Smm state->memsize += len; 381299425Smm return XXH_OK; 382299425Smm } 383299425Smm 384299425Smm if (state->memsize) /* some data left from previous update */ 385299425Smm { 386299425Smm XXH_memcpy(state->memory + state->memsize, input, 16-state->memsize); 387299425Smm { 388299425Smm const U32* p32 = (const U32*)state->memory; 389299425Smm state->v1 += XXH_readLE32(p32, endian) * PRIME32_2; state->v1 = XXH_rotl32(state->v1, 13); state->v1 *= PRIME32_1; p32++; 390299425Smm state->v2 += XXH_readLE32(p32, endian) * PRIME32_2; state->v2 = XXH_rotl32(state->v2, 13); state->v2 *= PRIME32_1; p32++; 391299425Smm state->v3 += XXH_readLE32(p32, endian) * PRIME32_2; state->v3 = XXH_rotl32(state->v3, 13); state->v3 *= PRIME32_1; p32++; 392299425Smm state->v4 += XXH_readLE32(p32, endian) * PRIME32_2; state->v4 = XXH_rotl32(state->v4, 13); state->v4 *= PRIME32_1; p32++; 393299425Smm } 394299425Smm p += 16-state->memsize; 395299425Smm state->memsize = 0; 396299425Smm } 397299425Smm 398299425Smm if (p <= bEnd-16) 399299425Smm { 400299425Smm const BYTE* const limit = bEnd - 16; 401299425Smm U32 v1 = state->v1; 402299425Smm U32 v2 = state->v2; 403299425Smm U32 v3 = state->v3; 404299425Smm U32 v4 = state->v4; 405299425Smm 406299425Smm do 407299425Smm { 408299425Smm v1 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4; 409299425Smm v2 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4; 410299425Smm v3 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4; 411299425Smm v4 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4; 412299425Smm } while (p<=limit); 413299425Smm 414299425Smm state->v1 = v1; 415299425Smm state->v2 = v2; 416299425Smm state->v3 = v3; 417299425Smm state->v4 = v4; 418299425Smm } 419299425Smm 420299425Smm if (p < bEnd) 421299425Smm { 422299425Smm XXH_memcpy(state->memory, p, bEnd-p); 423299425Smm state->memsize = (int)(bEnd-p); 424299425Smm } 425299425Smm 426299425Smm return XXH_OK; 427299425Smm} 428299425Smm 429299425Smmstatic 430299425SmmXXH_errorcode XXH32_update (void* state_in, const void* input, unsigned int len) 431299425Smm{ 432299425Smm XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; 433299425Smm 434299425Smm if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) 435299425Smm return XXH32_update_endian(state_in, input, len, XXH_littleEndian); 436299425Smm else 437299425Smm return XXH32_update_endian(state_in, input, len, XXH_bigEndian); 438299425Smm} 439299425Smm 440299425Smm 441299425Smm 442299425Smmstatic 443299425SmmFORCE_INLINE U32 XXH32_intermediateDigest_endian (void* state_in, XXH_endianess endian) 444299425Smm{ 445299425Smm struct XXH_state32_t * state = (struct XXH_state32_t *) state_in; 446299425Smm const BYTE * p = (const BYTE*)state->memory; 447299425Smm BYTE* bEnd = (BYTE*)state->memory + state->memsize; 448299425Smm U32 h32; 449299425Smm 450299425Smm if (state->total_len >= 16) 451299425Smm { 452299425Smm h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18); 453299425Smm } 454299425Smm else 455299425Smm { 456299425Smm h32 = state->seed + PRIME32_5; 457299425Smm } 458299425Smm 459299425Smm h32 += (U32) state->total_len; 460299425Smm 461299425Smm while (p<=bEnd-4) 462299425Smm { 463299425Smm h32 += XXH_readLE32((const U32*)p, endian) * PRIME32_3; 464299425Smm h32 = XXH_rotl32(h32, 17) * PRIME32_4; 465299425Smm p+=4; 466299425Smm } 467299425Smm 468299425Smm while (p<bEnd) 469299425Smm { 470299425Smm h32 += (*p) * PRIME32_5; 471299425Smm h32 = XXH_rotl32(h32, 11) * PRIME32_1; 472299425Smm p++; 473299425Smm } 474299425Smm 475299425Smm h32 ^= h32 >> 15; 476299425Smm h32 *= PRIME32_2; 477299425Smm h32 ^= h32 >> 13; 478299425Smm h32 *= PRIME32_3; 479299425Smm h32 ^= h32 >> 16; 480299425Smm 481299425Smm return h32; 482299425Smm} 483299425Smm 484299425Smmstatic 485299425SmmU32 XXH32_intermediateDigest (void* state_in) 486299425Smm{ 487299425Smm XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; 488299425Smm 489299425Smm if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) 490299425Smm return XXH32_intermediateDigest_endian(state_in, XXH_littleEndian); 491299425Smm else 492299425Smm return XXH32_intermediateDigest_endian(state_in, XXH_bigEndian); 493299425Smm} 494299425Smm 495299425Smmstatic 496299425SmmU32 XXH32_digest (void* state_in) 497299425Smm{ 498299425Smm U32 h32 = XXH32_intermediateDigest(state_in); 499299425Smm 500299425Smm XXH_free(state_in); 501299425Smm 502299425Smm return h32; 503299425Smm} 504299425Smm 505299425Smmconst 506299425Smmstruct archive_xxhash __archive_xxhash = { 507299425Smm XXH32, 508299425Smm XXH32_init, 509299425Smm XXH32_update, 510299425Smm XXH32_digest 511299425Smm}; 512299425Smm#else 513299425Smm 514299425Smm/* 515299425Smm * Define an empty version of the struct if we aren't using the LZ4 library. 516299425Smm */ 517299425Smmconst 518299425Smmstruct archive_xxhash __archive_xxhash = { 519299425Smm NULL, 520299425Smm NULL, 521299425Smm NULL, 522299425Smm NULL 523299425Smm}; 524299425Smm 525299425Smm#endif /* HAVE_LIBLZ4 */ 526