From 321e5051db447f3e0f8c84c33b3099916af5604c Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sun, 19 Nov 2023 13:40:01 -0600 Subject: [PATCH] Externals: update xxhash to 0.8.2 as submodule; put in logic to ensure LZ4 which is also using xxhash does not clash when linking symbols --- .gitmodules | 3 + Externals/lz4/CMakeLists.txt | 2 +- Externals/lz4/LZ4.vcxproj | 5 + Externals/xxhash/CMakeLists.txt | 4 +- Externals/xxhash/LICENSE | 24 - Externals/xxhash/exports.props | 2 +- Externals/xxhash/xxHash | 1 + Externals/xxhash/xxhash.c | 890 ---------------- Externals/xxhash/xxhash.h | 301 ------ Externals/xxhash/xxhash.vcxproj | 6 +- Externals/xxhash/xxhsum.c | 1238 ----------------------- Source/Core/DolphinQt/DolphinQt.vcxproj | 1 + 12 files changed, 17 insertions(+), 2460 deletions(-) delete mode 100644 Externals/xxhash/LICENSE create mode 160000 Externals/xxhash/xxHash delete mode 100644 Externals/xxhash/xxhash.c delete mode 100644 Externals/xxhash/xxhash.h delete mode 100644 Externals/xxhash/xxhsum.c diff --git a/.gitmodules b/.gitmodules index 8e701abf03..bfc0bdf7fb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -66,3 +66,6 @@ [submodule "Externals/lz4/lz4"] path = Externals/lz4/lz4 url = https://github.com/lz4/lz4 +[submodule "Externals/xxhash/xxHash"] + path = Externals/xxhash/xxHash + url = https://github.com/Cyan4973/xxHash.git diff --git a/Externals/lz4/CMakeLists.txt b/Externals/lz4/CMakeLists.txt index 065e52593a..7af19ebbe2 100644 --- a/Externals/lz4/CMakeLists.txt +++ b/Externals/lz4/CMakeLists.txt @@ -10,4 +10,4 @@ add_subdirectory(lz4/build/cmake) dolphin_disable_warnings_msvc(lz4_static) add_library(LZ4::LZ4 ALIAS lz4_static) - +target_compile_definitions(lz4_static PRIVATE XXH_NAMESPACE=LZ4_) diff --git a/Externals/lz4/LZ4.vcxproj b/Externals/lz4/LZ4.vcxproj index 4bb1b83268..36167718b1 100644 --- a/Externals/lz4/LZ4.vcxproj +++ b/Externals/lz4/LZ4.vcxproj @@ -15,6 +15,11 @@ + + + XXH_NAMESPACE=LZ4_;%(PreprocessorDefinitions) + + diff --git a/Externals/xxhash/CMakeLists.txt b/Externals/xxhash/CMakeLists.txt index 1a3d637387..6d52f56478 100644 --- a/Externals/xxhash/CMakeLists.txt +++ b/Externals/xxhash/CMakeLists.txt @@ -1,8 +1,8 @@ project(xxhash C) -add_library(xxhash STATIC xxhash.c) +add_library(xxhash STATIC xxHash/xxhash.c) dolphin_disable_warnings_msvc(xxhash) target_include_directories(xxhash PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/xxHash ) diff --git a/Externals/xxhash/LICENSE b/Externals/xxhash/LICENSE deleted file mode 100644 index 7de801ed1b..0000000000 --- a/Externals/xxhash/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -xxHash Library -Copyright (c) 2012-2014, Yann Collet -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Externals/xxhash/exports.props b/Externals/xxhash/exports.props index 3329ab6f61..6bcd16a46d 100644 --- a/Externals/xxhash/exports.props +++ b/Externals/xxhash/exports.props @@ -2,7 +2,7 @@ - $(ExternalsDir)xxhash;%(AdditionalIncludeDirectories) + $(ExternalsDir)xxhash\xxHash\;%(AdditionalIncludeDirectories) diff --git a/Externals/xxhash/xxHash b/Externals/xxhash/xxHash new file mode 160000 index 0000000000..bbb27a5efb --- /dev/null +++ b/Externals/xxhash/xxHash @@ -0,0 +1 @@ +Subproject commit bbb27a5efb85b92a0486cf361a8635715a53f6ba diff --git a/Externals/xxhash/xxhash.c b/Externals/xxhash/xxhash.c deleted file mode 100644 index 4546c54dbe..0000000000 --- a/Externals/xxhash/xxhash.c +++ /dev/null @@ -1,890 +0,0 @@ -/* -* xxHash - Fast Hash algorithm -* Copyright (C) 2012-2016, Yann Collet -* -* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are -* met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above -* copyright notice, this list of conditions and the following disclaimer -* in the documentation and/or other materials provided with the -* distribution. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* You can contact the author at : -* - xxHash homepage: http://www.xxhash.com -* - xxHash source repository : https://github.com/Cyan4973/xxHash -*/ - - -/* ************************************* -* Tuning parameters -***************************************/ -/*!XXH_FORCE_MEMORY_ACCESS : - * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. - * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. - * The below switch allow to select different access method for improved performance. - * Method 0 (default) : use `memcpy()`. Safe and portable. - * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). - * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. - * Method 2 : direct access. This method doesn't depend on compiler but violate C standard. - * It can generate buggy code on targets which do not support unaligned memory accesses. - * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) - * See http://stackoverflow.com/a/32095106/646947 for details. - * Prefer these methods in priority order (0 > 1 > 2) - */ -#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ -# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) -# define XXH_FORCE_MEMORY_ACCESS 2 -# elif defined(__INTEL_COMPILER) || \ - (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) -# define XXH_FORCE_MEMORY_ACCESS 1 -# endif -#endif - -/*!XXH_ACCEPT_NULL_INPUT_POINTER : - * If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer. - * When this option is enabled, xxHash output for null input pointers will be the same as a null-length input. - * By default, this option is disabled. To enable it, uncomment below define : - */ -/* #define XXH_ACCEPT_NULL_INPUT_POINTER 1 */ - -/*!XXH_FORCE_NATIVE_FORMAT : - * By default, xxHash library provides endian-independant Hash values, based on little-endian convention. - * Results are therefore identical for little-endian and big-endian CPU. - * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format. - * Should endian-independance be of no importance for your application, you may set the #define below to 1, - * to improve speed for Big-endian CPU. - * This option has no impact on Little_Endian CPU. - */ -#ifndef XXH_FORCE_NATIVE_FORMAT /* can be defined externally */ -# define XXH_FORCE_NATIVE_FORMAT 0 -#endif - -/*!XXH_FORCE_ALIGN_CHECK : - * This is a minor performance trick, only useful with lots of very small keys. - * It means : check for aligned/unaligned input. - * The check costs one initial branch per hash; set to 0 when the input data - * is guaranteed to be aligned. - */ -#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */ -# if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) -# define XXH_FORCE_ALIGN_CHECK 0 -# else -# define XXH_FORCE_ALIGN_CHECK 1 -# endif -#endif - - -/* ************************************* -* Includes & Memory related functions -***************************************/ -/* Modify the local functions below should you wish to use some other memory routines */ -/* for malloc(), free() */ -#include -static void* XXH_malloc(size_t s) { return malloc(s); } -static void XXH_free (void* p) { free(p); } -/* for memcpy() */ -#include -static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); } - -#define XXH_STATIC_LINKING_ONLY -#include "xxhash.h" - - -/* ************************************* -* Compiler Specific Options -***************************************/ -#ifdef _MSC_VER /* Visual Studio */ -# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ -# define FORCE_INLINE static __forceinline -#else -# if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ -# ifdef __GNUC__ -# define FORCE_INLINE static inline __attribute__((always_inline)) -# else -# define FORCE_INLINE static inline -# endif -# else -# define FORCE_INLINE static -# endif /* __STDC_VERSION__ */ -#endif - - -/* ************************************* -* Basic Types -***************************************/ -#ifndef MEM_MODULE -# if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include - typedef uint8_t BYTE; - typedef uint16_t U16; - typedef uint32_t U32; - typedef int32_t S32; -# else - typedef unsigned char BYTE; - typedef unsigned short U16; - typedef unsigned int U32; - typedef signed int S32; -# endif -#endif - -#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) - -/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ -static U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; } - -#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) - -/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ -/* currently only defined for gcc and icc */ -typedef union { U32 u32; } __attribute__((packed)) unalign; -static U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } - -#else - -/* portable and safe solution. Generally efficient. - * see : http://stackoverflow.com/a/32095106/646947 - */ -static U32 XXH_read32(const void* memPtr) -{ - U32 val; - memcpy(&val, memPtr, sizeof(val)); - return val; -} - -#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ - - -/* **************************************** -* Compiler-specific Functions and Macros -******************************************/ -#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) - -/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */ -#if defined(_MSC_VER) -# define XXH_rotl32(x,r) _rotl(x,r) -# define XXH_rotl64(x,r) _rotl64(x,r) -#else -# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r))) -# define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r))) -#endif - -#if defined(_MSC_VER) /* Visual Studio */ -# define XXH_swap32 _byteswap_ulong -#elif GCC_VERSION >= 403 -# define XXH_swap32 __builtin_bswap32 -#else -static U32 XXH_swap32 (U32 x) -{ - return ((x << 24) & 0xff000000 ) | - ((x << 8) & 0x00ff0000 ) | - ((x >> 8) & 0x0000ff00 ) | - ((x >> 24) & 0x000000ff ); -} -#endif - - -/* ************************************* -* Architecture Macros -***************************************/ -typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess; - -/* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */ -#ifndef XXH_CPU_LITTLE_ENDIAN - static const int g_one = 1; -# define XXH_CPU_LITTLE_ENDIAN (*(const char*)(&g_one)) -#endif - - -/* *************************** -* Memory reads -*****************************/ -typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment; - -FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align) -{ - if (align==XXH_unaligned) - return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr)); - else - return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr); -} - -FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianess endian) -{ - return XXH_readLE32_align(ptr, endian, XXH_unaligned); -} - -static U32 XXH_readBE32(const void* ptr) -{ - return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr); -} - - -/* ************************************* -* Macros -***************************************/ -#define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */ -XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; } - - -/* ******************************************************************* -* 32-bits hash functions -*********************************************************************/ -static const U32 PRIME32_1 = 2654435761U; -static const U32 PRIME32_2 = 2246822519U; -static const U32 PRIME32_3 = 3266489917U; -static const U32 PRIME32_4 = 668265263U; -static const U32 PRIME32_5 = 374761393U; - -static U32 XXH32_round(U32 seed, U32 input) -{ - seed += input * PRIME32_2; - seed = XXH_rotl32(seed, 13); - seed *= PRIME32_1; - return seed; -} - -FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align) -{ - const BYTE* p = (const BYTE*)input; - const BYTE* bEnd = p + len; - U32 h32; -#define XXH_get32bits(p) XXH_readLE32_align(p, endian, align) - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (p==NULL) { - len=0; - bEnd=p=(const BYTE*)(size_t)16; - } -#endif - - if (len>=16) { - const BYTE* const limit = bEnd - 16; - U32 v1 = seed + PRIME32_1 + PRIME32_2; - U32 v2 = seed + PRIME32_2; - U32 v3 = seed + 0; - U32 v4 = seed - PRIME32_1; - - do { - v1 = XXH32_round(v1, XXH_get32bits(p)); p+=4; - v2 = XXH32_round(v2, XXH_get32bits(p)); p+=4; - v3 = XXH32_round(v3, XXH_get32bits(p)); p+=4; - v4 = XXH32_round(v4, XXH_get32bits(p)); p+=4; - } while (p<=limit); - - h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); - } else { - h32 = seed + PRIME32_5; - } - - h32 += (U32) len; - - while (p+4<=bEnd) { - h32 += XXH_get32bits(p) * PRIME32_3; - h32 = XXH_rotl32(h32, 17) * PRIME32_4 ; - p+=4; - } - - while (p> 15; - h32 *= PRIME32_2; - h32 ^= h32 >> 13; - h32 *= PRIME32_3; - h32 ^= h32 >> 16; - - return h32; -} - - -XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int seed) -{ -#if 0 - /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ - XXH32_CREATESTATE_STATIC(state); - XXH32_reset(state, seed); - XXH32_update(state, input, len); - return XXH32_digest(state); -#else - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if (XXH_FORCE_ALIGN_CHECK) { - if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */ - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); - else - return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); - } } - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); - else - return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); -#endif -} - - - -/*====== Hash streaming ======*/ - -XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void) -{ - return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t)); -} -XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr) -{ - XXH_free(statePtr); - return XXH_OK; -} - -XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* restrict dstState, const XXH32_state_t* restrict srcState) -{ - memcpy(dstState, srcState, sizeof(*dstState)); -} - -XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int seed) -{ - XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ - memset(&state, 0, sizeof(state)-4); /* do not write into reserved, for future removal */ - state.v1 = seed + PRIME32_1 + PRIME32_2; - state.v2 = seed + PRIME32_2; - state.v3 = seed + 0; - state.v4 = seed - PRIME32_1; - memcpy(statePtr, &state, sizeof(state)); - return XXH_OK; -} - - -FORCE_INLINE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void* input, size_t len, XXH_endianess endian) -{ - const BYTE* p = (const BYTE*)input; - const BYTE* const bEnd = p + len; - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (input==NULL) return XXH_ERROR; -#endif - - state->total_len_32 += (unsigned)len; - state->large_len |= (len>=16) | (state->total_len_32>=16); - - if (state->memsize + len < 16) { /* fill in tmp buffer */ - XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len); - state->memsize += (unsigned)len; - return XXH_OK; - } - - if (state->memsize) { /* some data left from previous update */ - XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize); - { const U32* p32 = state->mem32; - state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++; - state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++; - state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++; - state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian)); p32++; - } - p += 16-state->memsize; - state->memsize = 0; - } - - if (p <= bEnd-16) { - const BYTE* const limit = bEnd - 16; - U32 v1 = state->v1; - U32 v2 = state->v2; - U32 v3 = state->v3; - U32 v4 = state->v4; - - do { - v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p+=4; - v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p+=4; - v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p+=4; - v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p+=4; - } while (p<=limit); - - state->v1 = v1; - state->v2 = v2; - state->v3 = v3; - state->v4 = v4; - } - - if (p < bEnd) { - XXH_memcpy(state->mem32, p, (size_t)(bEnd-p)); - state->memsize = (unsigned)(bEnd-p); - } - - return XXH_OK; -} - -XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len) -{ - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_update_endian(state_in, input, len, XXH_littleEndian); - else - return XXH32_update_endian(state_in, input, len, XXH_bigEndian); -} - - - -FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian) -{ - const BYTE * p = (const BYTE*)state->mem32; - const BYTE* const bEnd = (const BYTE*)(state->mem32) + state->memsize; - U32 h32; - - if (state->large_len) { - h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18); - } else { - h32 = state->v3 /* == seed */ + PRIME32_5; - } - - h32 += state->total_len_32; - - while (p+4<=bEnd) { - h32 += XXH_readLE32(p, endian) * PRIME32_3; - h32 = XXH_rotl32(h32, 17) * PRIME32_4; - p+=4; - } - - while (p> 15; - h32 *= PRIME32_2; - h32 ^= h32 >> 13; - h32 *= PRIME32_3; - h32 ^= h32 >> 16; - - return h32; -} - - -XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in) -{ - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_digest_endian(state_in, XXH_littleEndian); - else - return XXH32_digest_endian(state_in, XXH_bigEndian); -} - - -/*====== Canonical representation ======*/ - -/*! Default XXH result types are basic unsigned 32 and 64 bits. -* The canonical representation follows human-readable write convention, aka big-endian (large digits first). -* These functions allow transformation of hash result into and from its canonical format. -* This way, hash values can be written into a file or buffer, and remain comparable across different systems and programs. -*/ - -XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash) -{ - XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); - if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash); - memcpy(dst, &hash, sizeof(*dst)); -} - -XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src) -{ - return XXH_readBE32(src); -} - - -#ifndef XXH_NO_LONG_LONG - -/* ******************************************************************* -* 64-bits hash functions -*********************************************************************/ - -/*====== Memory access ======*/ - -#ifndef MEM_MODULE -# define MEM_MODULE -# if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include - typedef uint64_t U64; -# else - typedef unsigned long long U64; /* if your compiler doesn't support unsigned long long, replace by another 64-bit type here. Note that xxhash.h will also need to be updated. */ -# endif -#endif - - -#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) - -/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ -static U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; } - -#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) - -/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ -/* currently only defined for gcc and icc */ -typedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign64; - -static U64 XXH_read64(const void* ptr) { return ((const unalign64*)ptr)->u64; } - -#else - -/* portable and safe solution. Generally efficient. - * see : http://stackoverflow.com/a/32095106/646947 - */ - -static U64 XXH_read64(const void* memPtr) -{ - U64 val; - memcpy(&val, memPtr, sizeof(val)); - return val; -} - -#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ - -#if defined(_MSC_VER) /* Visual Studio */ -# define XXH_swap64 _byteswap_uint64 -#elif GCC_VERSION >= 403 -# define XXH_swap64 __builtin_bswap64 -#else -static U64 XXH_swap64 (U64 x) -{ - return ((x << 56) & 0xff00000000000000ULL) | - ((x << 40) & 0x00ff000000000000ULL) | - ((x << 24) & 0x0000ff0000000000ULL) | - ((x << 8) & 0x000000ff00000000ULL) | - ((x >> 8) & 0x00000000ff000000ULL) | - ((x >> 24) & 0x0000000000ff0000ULL) | - ((x >> 40) & 0x000000000000ff00ULL) | - ((x >> 56) & 0x00000000000000ffULL); -} -#endif - -FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align) -{ - if (align==XXH_unaligned) - return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr)); - else - return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr); -} - -FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianess endian) -{ - return XXH_readLE64_align(ptr, endian, XXH_unaligned); -} - -static U64 XXH_readBE64(const void* ptr) -{ - return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr); -} - - -/*====== xxh64 ======*/ - -static const U64 PRIME64_1 = 11400714785074694791ULL; -static const U64 PRIME64_2 = 14029467366897019727ULL; -static const U64 PRIME64_3 = 1609587929392839161ULL; -static const U64 PRIME64_4 = 9650029242287828579ULL; -static const U64 PRIME64_5 = 2870177450012600261ULL; - -static U64 XXH64_round(U64 acc, U64 input) -{ - acc += input * PRIME64_2; - acc = XXH_rotl64(acc, 31); - acc *= PRIME64_1; - return acc; -} - -static U64 XXH64_mergeRound(U64 acc, U64 val) -{ - val = XXH64_round(0, val); - acc ^= val; - acc = acc * PRIME64_1 + PRIME64_4; - return acc; -} - -FORCE_INLINE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align) -{ - const BYTE* p = (const BYTE*)input; - const BYTE* const bEnd = p + len; - U64 h64; -#define XXH_get64bits(p) XXH_readLE64_align(p, endian, align) - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (p==NULL) { - len=0; - bEnd=p=(const BYTE*)(size_t)32; - } -#endif - - if (len>=32) { - const BYTE* const limit = bEnd - 32; - U64 v1 = seed + PRIME64_1 + PRIME64_2; - U64 v2 = seed + PRIME64_2; - U64 v3 = seed + 0; - U64 v4 = seed - PRIME64_1; - - do { - v1 = XXH64_round(v1, XXH_get64bits(p)); p+=8; - v2 = XXH64_round(v2, XXH_get64bits(p)); p+=8; - v3 = XXH64_round(v3, XXH_get64bits(p)); p+=8; - v4 = XXH64_round(v4, XXH_get64bits(p)); p+=8; - } while (p<=limit); - - h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); - h64 = XXH64_mergeRound(h64, v1); - h64 = XXH64_mergeRound(h64, v2); - h64 = XXH64_mergeRound(h64, v3); - h64 = XXH64_mergeRound(h64, v4); - - } else { - h64 = seed + PRIME64_5; - } - - h64 += (U64) len; - - while (p+8<=bEnd) { - U64 const k1 = XXH64_round(0, XXH_get64bits(p)); - h64 ^= k1; - h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; - p+=8; - } - - if (p+4<=bEnd) { - h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1; - h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; - p+=4; - } - - while (p> 33; - h64 *= PRIME64_2; - h64 ^= h64 >> 29; - h64 *= PRIME64_3; - h64 ^= h64 >> 32; - - return h64; -} - - -XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed) -{ -#if 0 - /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ - XXH64_CREATESTATE_STATIC(state); - XXH64_reset(state, seed); - XXH64_update(state, input, len); - return XXH64_digest(state); -#else - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if (XXH_FORCE_ALIGN_CHECK) { - if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */ - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); - else - return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); - } } - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); - else - return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); -#endif -} - -/*====== Hash Streaming ======*/ - -XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void) -{ - return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t)); -} -XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr) -{ - XXH_free(statePtr); - return XXH_OK; -} - -XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* restrict dstState, const XXH64_state_t* restrict srcState) -{ - memcpy(dstState, srcState, sizeof(*dstState)); -} - -XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long long seed) -{ - XXH64_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ - memset(&state, 0, sizeof(state)-8); /* do not write into reserved, for future removal */ - state.v1 = seed + PRIME64_1 + PRIME64_2; - state.v2 = seed + PRIME64_2; - state.v3 = seed + 0; - state.v4 = seed - PRIME64_1; - memcpy(statePtr, &state, sizeof(state)); - return XXH_OK; -} - -FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian) -{ - const BYTE* p = (const BYTE*)input; - const BYTE* const bEnd = p + len; - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (input==NULL) return XXH_ERROR; -#endif - - state->total_len += len; - - if (state->memsize + len < 32) { /* fill in tmp buffer */ - XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len); - state->memsize += (U32)len; - return XXH_OK; - } - - if (state->memsize) { /* tmp buffer is full */ - XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize); - state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0, endian)); - state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1, endian)); - state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2, endian)); - state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3, endian)); - p += 32-state->memsize; - state->memsize = 0; - } - - if (p+32 <= bEnd) { - const BYTE* const limit = bEnd - 32; - U64 v1 = state->v1; - U64 v2 = state->v2; - U64 v3 = state->v3; - U64 v4 = state->v4; - - do { - v1 = XXH64_round(v1, XXH_readLE64(p, endian)); p+=8; - v2 = XXH64_round(v2, XXH_readLE64(p, endian)); p+=8; - v3 = XXH64_round(v3, XXH_readLE64(p, endian)); p+=8; - v4 = XXH64_round(v4, XXH_readLE64(p, endian)); p+=8; - } while (p<=limit); - - state->v1 = v1; - state->v2 = v2; - state->v3 = v3; - state->v4 = v4; - } - - if (p < bEnd) { - XXH_memcpy(state->mem64, p, (size_t)(bEnd-p)); - state->memsize = (unsigned)(bEnd-p); - } - - return XXH_OK; -} - -XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len) -{ - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_update_endian(state_in, input, len, XXH_littleEndian); - else - return XXH64_update_endian(state_in, input, len, XXH_bigEndian); -} - -FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian) -{ - const BYTE * p = (const BYTE*)state->mem64; - const BYTE* const bEnd = (const BYTE*)state->mem64 + state->memsize; - U64 h64; - - if (state->total_len >= 32) { - U64 const v1 = state->v1; - U64 const v2 = state->v2; - U64 const v3 = state->v3; - U64 const v4 = state->v4; - - h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); - h64 = XXH64_mergeRound(h64, v1); - h64 = XXH64_mergeRound(h64, v2); - h64 = XXH64_mergeRound(h64, v3); - h64 = XXH64_mergeRound(h64, v4); - } else { - h64 = state->v3 + PRIME64_5; - } - - h64 += (U64) state->total_len; - - while (p+8<=bEnd) { - U64 const k1 = XXH64_round(0, XXH_readLE64(p, endian)); - h64 ^= k1; - h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; - p+=8; - } - - if (p+4<=bEnd) { - h64 ^= (U64)(XXH_readLE32(p, endian)) * PRIME64_1; - h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; - p+=4; - } - - while (p> 33; - h64 *= PRIME64_2; - h64 ^= h64 >> 29; - h64 *= PRIME64_3; - h64 ^= h64 >> 32; - - return h64; -} - -XXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* state_in) -{ - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_digest_endian(state_in, XXH_littleEndian); - else - return XXH64_digest_endian(state_in, XXH_bigEndian); -} - - -/*====== Canonical representation ======*/ - -XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash) -{ - XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); - if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash); - memcpy(dst, &hash, sizeof(*dst)); -} - -XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src) -{ - return XXH_readBE64(src); -} - -#endif /* XXH_NO_LONG_LONG */ diff --git a/Externals/xxhash/xxhash.h b/Externals/xxhash/xxhash.h deleted file mode 100644 index 947567397b..0000000000 --- a/Externals/xxhash/xxhash.h +++ /dev/null @@ -1,301 +0,0 @@ -/* - xxHash - Extremely Fast Hash algorithm - Header File - Copyright (C) 2012-2016, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - You can contact the author at : - - xxHash source repository : https://github.com/Cyan4973/xxHash -*/ - -/* Notice extracted from xxHash homepage : - -xxHash is an extremely fast Hash algorithm, running at RAM speed limits. -It also successfully passes all tests from the SMHasher suite. - -Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz) - -Name Speed Q.Score Author -xxHash 5.4 GB/s 10 -CrapWow 3.2 GB/s 2 Andrew -MumurHash 3a 2.7 GB/s 10 Austin Appleby -SpookyHash 2.0 GB/s 10 Bob Jenkins -SBox 1.4 GB/s 9 Bret Mulvey -Lookup3 1.2 GB/s 9 Bob Jenkins -SuperFastHash 1.2 GB/s 1 Paul Hsieh -CityHash64 1.05 GB/s 10 Pike & Alakuijala -FNV 0.55 GB/s 5 Fowler, Noll, Vo -CRC32 0.43 GB/s 9 -MD5-32 0.33 GB/s 10 Ronald L. Rivest -SHA1-32 0.28 GB/s 10 - -Q.Score is a measure of quality of the hash function. -It depends on successfully passing SMHasher test set. -10 is a perfect score. - -A 64-bits version, named XXH64, is available since r35. -It offers much better speed, but for 64-bits applications only. -Name Speed on 64 bits Speed on 32 bits -XXH64 13.8 GB/s 1.9 GB/s -XXH32 6.8 GB/s 6.0 GB/s -*/ - -#ifndef XXHASH_H_5627135585666179 -#define XXHASH_H_5627135585666179 1 - -#if defined (__cplusplus) -extern "C" { -#endif - - -/* **************************** -* Compiler specifics -******************************/ -#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) /* ! C99 */ -# define restrict /* disable restrict */ -#endif - - -/* **************************** -* Definitions -******************************/ -#include /* size_t */ -typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; - - -/* **************************** -* API modifier -******************************/ -/** XXH_PRIVATE_API -* This is useful to include xxhash functions in `static` mode -* in order to inline them, and remove their symbol from the public list. -* Methodology : -* #define XXH_PRIVATE_API -* #include "xxhash.h" -* `xxhash.c` is automatically included. -* It's not useful to compile and link it as a separate module. -*/ -#ifdef XXH_PRIVATE_API -# ifndef XXH_STATIC_LINKING_ONLY -# define XXH_STATIC_LINKING_ONLY -# endif -# if defined(__GNUC__) -# define XXH_PUBLIC_API static __inline __attribute__((unused)) -# elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) -# define XXH_PUBLIC_API static inline -# elif defined(_MSC_VER) -# define XXH_PUBLIC_API static __inline -# else -# define XXH_PUBLIC_API static /* this version may generate warnings for unused static functions; disable the relevant warning */ -# endif -#else -# define XXH_PUBLIC_API /* do nothing */ -#endif /* XXH_PRIVATE_API */ - -/*!XXH_NAMESPACE, aka Namespace Emulation : - -If you want to include _and expose_ xxHash functions from within your own library, -but also want to avoid symbol collisions with other libraries which may also include xxHash, - -you can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library -with the value of XXH_NAMESPACE (therefore, avoid NULL and numeric values). - -Note that no change is required within the calling program as long as it includes `xxhash.h` : -regular symbol name will be automatically translated by this header. -*/ -#ifdef XXH_NAMESPACE -# define XXH_CAT(A,B) A##B -# define XXH_NAME2(A,B) XXH_CAT(A,B) -# define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber) -# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32) -# define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState) -# define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState) -# define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset) -# define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update) -# define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest) -# define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState) -# define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash) -# define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical) -# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64) -# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState) -# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState) -# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset) -# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update) -# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest) -# define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState) -# define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash) -# define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical) -#endif - - -/* ************************************* -* Version -***************************************/ -#define XXH_VERSION_MAJOR 0 -#define XXH_VERSION_MINOR 6 -#define XXH_VERSION_RELEASE 2 -#define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) -XXH_PUBLIC_API unsigned XXH_versionNumber (void); - - -/*-********************************************************************** -* 32-bits hash -************************************************************************/ -typedef unsigned int XXH32_hash_t; - -/*! XXH32() : - Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input". - The memory between input & input+length must be valid (allocated and read-accessible). - "seed" can be used to alter the result predictably. - Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s */ -XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, unsigned int seed); - -/*====== Streaming ======*/ -typedef struct XXH32_state_s XXH32_state_t; /* incomplete type */ -XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void); -XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); -XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* restrict dst_state, const XXH32_state_t* restrict src_state); - -XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned int seed); -XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); -XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr); - -/* -These functions generate the xxHash of an input provided in multiple segments. -Note that, for small input, they are slower than single-call functions, due to state management. -For small input, prefer `XXH32()` and `XXH64()` . - -XXH state must first be allocated, using XXH*_createState() . - -Start a new hash by initializing state with a seed, using XXH*_reset(). - -Then, feed the hash state by calling XXH*_update() as many times as necessary. -Obviously, input must be allocated and read accessible. -The function returns an error code, with 0 meaning OK, and any other value meaning there is an error. - -Finally, a hash value can be produced anytime, by using XXH*_digest(). -This function returns the nn-bits hash as an int or long long. - -It's still possible to continue inserting input into the hash state after a digest, -and generate some new hashes later on, by calling again XXH*_digest(). - -When done, free XXH state space if it was allocated dynamically. -*/ - -/*====== Canonical representation ======*/ - -typedef struct { unsigned char digest[4]; } XXH32_canonical_t; -XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash); -XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); - -/* Default result type for XXH functions are primitive unsigned 32 and 64 bits. -* The canonical representation uses human-readable write convention, aka big-endian (large digits first). -* These functions allow transformation of hash result into and from its canonical format. -* This way, hash values can be written into a file / memory, and remain comparable on different systems and programs. -*/ - - -#ifndef XXH_NO_LONG_LONG -/*-********************************************************************** -* 64-bits hash -************************************************************************/ -typedef unsigned long long XXH64_hash_t; - -/*! XXH64() : - Calculate the 64-bits hash of sequence of length "len" stored at memory address "input". - "seed" can be used to alter the result predictably. - This function runs faster on 64-bits systems, but slower on 32-bits systems (see benchmark). -*/ -XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, unsigned long long seed); - -/*====== Streaming ======*/ -typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ -XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void); -XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); -XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* restrict dst_state, const XXH64_state_t* restrict src_state); - -XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed); -XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length); -XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr); - -/*====== Canonical representation ======*/ -typedef struct { unsigned char digest[8]; } XXH64_canonical_t; -XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash); -XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src); -#endif /* XXH_NO_LONG_LONG */ - - -#ifdef XXH_STATIC_LINKING_ONLY - -/* ================================================================================================ - This section contains definitions which are not guaranteed to remain stable. - They may change in future versions, becoming incompatible with a different version of the library. - They shall only be used with static linking. - Never use these definitions in association with dynamic linking ! -=================================================================================================== */ - -/* These definitions are only meant to allow allocation of XXH state - statically, on stack, or in a struct for example. - Do not use members directly. */ - - struct XXH32_state_s { - unsigned total_len_32; - unsigned large_len; - unsigned v1; - unsigned v2; - unsigned v3; - unsigned v4; - unsigned mem32[4]; /* buffer defined as U32 for alignment */ - unsigned memsize; - unsigned reserved; /* never read nor write, will be removed in a future version */ - }; /* typedef'd to XXH32_state_t */ - -#ifndef XXH_NO_LONG_LONG - struct XXH64_state_s { - unsigned long long total_len; - unsigned long long v1; - unsigned long long v2; - unsigned long long v3; - unsigned long long v4; - unsigned long long mem64[4]; /* buffer defined as U64 for alignment */ - unsigned memsize; - unsigned reserved[2]; /* never read nor write, will be removed in a future version */ - }; /* typedef'd to XXH64_state_t */ -#endif - -# ifdef XXH_PRIVATE_API -# include "xxhash.c" /* include xxhash function bodies as `static`, for inlining */ -# endif - -#endif /* XXH_STATIC_LINKING_ONLY */ - - -#if defined (__cplusplus) -} -#endif - -#endif /* XXHASH_H_5627135585666179 */ diff --git a/Externals/xxhash/xxhash.vcxproj b/Externals/xxhash/xxhash.vcxproj index 80c7bb5654..3c51fd3ae6 100644 --- a/Externals/xxhash/xxhash.vcxproj +++ b/Externals/xxhash/xxhash.vcxproj @@ -16,14 +16,14 @@ - + - - + + diff --git a/Externals/xxhash/xxhsum.c b/Externals/xxhash/xxhsum.c deleted file mode 100644 index 049bc7217b..0000000000 --- a/Externals/xxhash/xxhsum.c +++ /dev/null @@ -1,1238 +0,0 @@ -/* -* xxhsum - Command line interface for xxhash algorithms -* Copyright (C) Yann Collet 2012-2016 -* -* GPL v2 License -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along -* with this program; if not, write to the Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -* -* You can contact the author at : -* - xxHash homepage : http://www.xxhash.com -* - xxHash source repository : https://github.com/Cyan4973/xxHash -*/ - -/* xxhsum : - * Provides hash value of a file content, or a list of files, or stdin - * Display convention is Big Endian, for both 32 and 64 bits algorithms - */ - -#ifndef XXHASH_C_2097394837 -#define XXHASH_C_2097394837 - -/* ************************************ -* Compiler Options -**************************************/ -/* MS Visual */ -#if defined(_MSC_VER) || defined(_WIN32) -# define _CRT_SECURE_NO_WARNINGS /* removes visual warnings */ -#endif - -/* Under Linux at least, pull in the *64 commands */ -#ifndef _LARGEFILE64_SOURCE -# define _LARGEFILE64_SOURCE -#endif - - -/* ************************************ -* Includes -**************************************/ -#include /* malloc */ -#include /* fprintf, fopen, ftello64, fread, stdin, stdout; when present : _fileno */ -#include /* strcmp */ -#include /* stat64 */ -#include /* stat64 */ -#include /* clock_t, clock, CLOCKS_PER_SEC */ - -#define XXH_STATIC_LINKING_ONLY /* *_state_t */ -#include "xxhash.h" - - -/*-************************************ -* OS-Specific Includes -**************************************/ -#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) -# include /* _O_BINARY */ -# include /* _setmode, _isatty */ -# ifdef __MINGW32__ - int _fileno(FILE *stream); /* MINGW somehow forgets to include this windows declaration into */ -# endif -# define SET_BINARY_MODE(file) _setmode(_fileno(file), _O_BINARY) -# define IS_CONSOLE(stdStream) _isatty(_fileno(stdStream)) -#else -# include /* isatty, STDIN_FILENO */ -# define SET_BINARY_MODE(file) -# define IS_CONSOLE(stdStream) isatty(STDIN_FILENO) -#endif - -#if !defined(S_ISREG) -# define S_ISREG(x) (((x) & S_IFMT) == S_IFREG) -#endif - - -/* ************************************ -* Basic Types -**************************************/ -#ifndef MEM_MODULE -# define MEM_MODULE -# if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ -# include - typedef uint8_t BYTE; - typedef uint16_t U16; - typedef uint32_t U32; - typedef int32_t S32; - typedef uint64_t U64; -# else - typedef unsigned char BYTE; - typedef unsigned short U16; - typedef unsigned int U32; - typedef signed int S32; - typedef unsigned long long U64; -# endif -#endif - -static unsigned BMK_isLittleEndian(void) -{ - const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ - return one.c[0]; -} - - -/* ************************************* -* Constants -***************************************/ -#define LIB_VERSION XXH_VERSION_MAJOR.XXH_VERSION_MINOR.XXH_VERSION_RELEASE -#define QUOTE(str) #str -#define EXPAND_AND_QUOTE(str) QUOTE(str) -#define PROGRAM_VERSION EXPAND_AND_QUOTE(LIB_VERSION) -static const int g_nbBits = (int)(sizeof(void*)*8); -static const char g_lename[] = "little endian"; -static const char g_bename[] = "big endian"; -#define ENDIAN_NAME (BMK_isLittleEndian() ? g_lename : g_bename) -static const char author[] = "Yann Collet"; -#define WELCOME_MESSAGE(exename) "%s %s (%i-bits %s), by %s \n", exename, PROGRAM_VERSION, g_nbBits, ENDIAN_NAME, author - -#define NBLOOPS 3 /* Default number of benchmark iterations */ -#define TIMELOOP_S 1 -#define TIMELOOP (TIMELOOP_S * CLOCKS_PER_SEC) /* Minimum timing per iteration */ -#define XXHSUM32_DEFAULT_SEED 0 /* Default seed for algo_xxh32 */ -#define XXHSUM64_DEFAULT_SEED 0 /* Default seed for algo_xxh64 */ - -#define KB *( 1<<10) -#define MB *( 1<<20) -#define GB *(1U<<30) - -#define MAX_MEM (2 GB - 64 MB) - -static const char stdinName[] = "-"; -typedef enum { algo_xxh32, algo_xxh64 } algoType; -static const algoType g_defaultAlgo = algo_xxh64; /* required within main() & usage() */ - -/* <16 hex char> <'\0'> - * '4096' is typical Linux PATH_MAX configuration. */ -#define DEFAULT_LINE_LENGTH (sizeof(XXH64_hash_t) * 2 + 2 + 4096 + 1) - -/* Maximum acceptable line length. */ -#define MAX_LINE_LENGTH (32 KB) - - -/* ************************************ -* Display macros -**************************************/ -#define DISPLAY(...) fprintf(stderr, __VA_ARGS__) -#define DISPLAYRESULT(...) fprintf(stdout, __VA_ARGS__) -#define DISPLAYLEVEL(l, ...) if (g_displayLevel>=l) DISPLAY(__VA_ARGS__); -static U32 g_displayLevel = 1; - - -/* ************************************ -* Local variables -**************************************/ -static size_t g_sampleSize = 100 KB; -static U32 g_nbIterations = NBLOOPS; - - -/* ************************************ -* Benchmark Functions -**************************************/ -static clock_t BMK_clockSpan( clock_t start ) -{ - return clock() - start; /* works even if overflow; Typical max span ~ 30 mn */ -} - - -static size_t BMK_findMaxMem(U64 requiredMem) -{ - size_t const step = 64 MB; - void* testmem = NULL; - - requiredMem = (((requiredMem >> 26) + 1) << 26); - requiredMem += 2*step; - if (requiredMem > MAX_MEM) requiredMem = MAX_MEM; - - while (!testmem) { - if (requiredMem > step) requiredMem -= step; - else requiredMem >>= 1; - testmem = malloc ((size_t)requiredMem); - } - free (testmem); - - /* keep some space available */ - if (requiredMem > step) requiredMem -= step; - else requiredMem >>= 1; - - return (size_t)requiredMem; -} - - -static U64 BMK_GetFileSize(const char* infilename) -{ - int r; -#if defined(_MSC_VER) - struct _stat64 statbuf; - r = _stat64(infilename, &statbuf); -#else - struct stat statbuf; - r = stat(infilename, &statbuf); -#endif - if (r || !S_ISREG(statbuf.st_mode)) return 0; /* No good... */ - return (U64)statbuf.st_size; -} - -typedef U32 (*hashFunction)(const void* buffer, size_t bufferSize, U32 seed); - -static U32 localXXH32(const void* buffer, size_t bufferSize, U32 seed) { return XXH32(buffer, bufferSize, seed); } - -static U32 localXXH64(const void* buffer, size_t bufferSize, U32 seed) { return (U32)XXH64(buffer, bufferSize, seed); } - -static void BMK_benchHash(hashFunction h, const char* hName, const void* buffer, size_t bufferSize) -{ - static const U32 nbh_perloop = 100; - U32 iterationNb; - double fastestH = 100000000.; - - DISPLAY("\r%79s\r", ""); /* Clean display line */ - if (g_nbIterations<1) g_nbIterations=1; - for (iterationNb = 1; iterationNb <= g_nbIterations; iterationNb++) { - U32 nbHashes = 0, r=0; - clock_t cStart; - - DISPLAY("%1i-%-17.17s : %10u ->\r", iterationNb, hName, (U32)bufferSize); - cStart = clock(); - while (clock() == cStart); /* starts clock() at its exact beginning */ - cStart = clock(); - - while (BMK_clockSpan(cStart) < TIMELOOP) { - U32 i; - for (i=0; i %7.1f MB/s\r", iterationNb, hName, (U32)bufferSize, ((double)bufferSize / (1<<20)) / fastestH ); - } - } - DISPLAY("%-19.19s : %10u -> %7.1f MB/s \n", hName, (U32)bufferSize, ((double)bufferSize / (1<<20)) / fastestH); -} - - -/* Note : buffer is supposed malloc'ed, hence aligned */ -static void BMK_benchMem(const void* buffer, size_t bufferSize) -{ - /* XXH32 bench */ - BMK_benchHash(localXXH32, "XXH32", buffer, bufferSize); - - /* Bench XXH32 on Unaligned input */ - if (bufferSize>1) - BMK_benchHash(localXXH32, "XXH32 unaligned", ((const char*)buffer)+1, bufferSize-1); - - /* Bench XXH64 */ - BMK_benchHash(localXXH64, "XXH64", buffer, bufferSize); - - /* Bench XXH64 on Unaligned input */ - if (bufferSize>1) - BMK_benchHash(localXXH64, "XXH64 unaligned", ((const char*)buffer)+1, bufferSize-1); -} - - -static size_t BMK_selectBenchedSize(const char* fileName) -{ U64 const inFileSize = BMK_GetFileSize(fileName); - size_t benchedSize = (size_t) BMK_findMaxMem(inFileSize); - if ((U64)benchedSize > inFileSize) benchedSize = (size_t)inFileSize; - if (benchedSize < inFileSize) { - DISPLAY("Not enough memory for '%s' full size; testing %i MB only...\n", fileName, (int)(benchedSize>>20)); - } - return benchedSize; -} - - -static int BMK_benchFiles(const char** fileNamesTable, int nbFiles) -{ - int fileIdx; - for (fileIdx=0; fileIdx> 10)); - BMK_benchMem(buffer, benchedSize); - - free(buffer); - return 0; -} - - -static void BMK_checkResult(U32 r1, U32 r2) -{ - static int nbTests = 1; - if (r1==r2) DISPLAY("\rTest%3i : %08X == %08X ok ", nbTests, r1, r2); - else { - DISPLAY("\rERROR : Test%3i : %08X <> %08X !!!!! \n", nbTests, r1, r2); - exit(1); - } - nbTests++; -} - - -static void BMK_checkResult64(U64 r1, U64 r2) -{ - static int nbTests = 1; - if (r1!=r2) { - DISPLAY("\rERROR : Test%3i : 64-bits values non equals !!!!! \n", nbTests); - DISPLAY("\r %08X%08X != %08X%08X \n", (U32)(r1>>32), (U32)r1, (U32)(r2>>32), (U32)r2); - exit(1); - } - nbTests++; -} - - -static void BMK_testSequence64(void* sentence, size_t len, U64 seed, U64 Nresult) -{ - XXH64_state_t state; - U64 Dresult; - size_t pos; - - Dresult = XXH64(sentence, len, seed); - BMK_checkResult64(Dresult, Nresult); - - XXH64_reset(&state, seed); - XXH64_update(&state, sentence, len); - Dresult = XXH64_digest(&state); - BMK_checkResult64(Dresult, Nresult); - - XXH64_reset(&state, seed); - for (pos=0; pos>24); - byteGen *= byteGen; - } - - BMK_testSequence(NULL, 0, 0, 0x02CC5D05); - BMK_testSequence(NULL, 0, prime, 0x36B78AE7); - BMK_testSequence(sanityBuffer, 1, 0, 0xB85CBEE5); - BMK_testSequence(sanityBuffer, 1, prime, 0xD5845D64); - BMK_testSequence(sanityBuffer, 14, 0, 0xE5AA0AB4); - BMK_testSequence(sanityBuffer, 14, prime, 0x4481951D); - BMK_testSequence(sanityBuffer, SANITY_BUFFER_SIZE, 0, 0x1F1AA412); - BMK_testSequence(sanityBuffer, SANITY_BUFFER_SIZE, prime, 0x498EC8E2); - - BMK_testSequence64(NULL , 0, 0, 0xEF46DB3751D8E999ULL); - BMK_testSequence64(NULL , 0, prime, 0xAC75FDA2929B17EFULL); - BMK_testSequence64(sanityBuffer, 1, 0, 0x4FCE394CC88952D8ULL); - BMK_testSequence64(sanityBuffer, 1, prime, 0x739840CB819FA723ULL); - BMK_testSequence64(sanityBuffer, 14, 0, 0xCFFA8DB881BC3A3DULL); - BMK_testSequence64(sanityBuffer, 14, prime, 0x5B9611585EFCC9CBULL); - BMK_testSequence64(sanityBuffer, SANITY_BUFFER_SIZE, 0, 0x0EAB543384F878ADULL); - BMK_testSequence64(sanityBuffer, SANITY_BUFFER_SIZE, prime, 0xCAA65939306F1E21ULL); - - DISPLAY("\r%79s\r", ""); /* Clean display line */ - DISPLAYLEVEL(2, "Sanity check -- all tests ok\n"); -} - - -/* ******************************************************** -* File Hashing -**********************************************************/ - -static void BMK_display_LittleEndian(const void* ptr, size_t length) -{ - const BYTE* p = (const BYTE*)ptr; - size_t idx; - for (idx=length-1; idx 30 ? 30 : fileNameSize; - size_t infoFilenameSize = 1; - while ( (infoFilenameSize < maxInfoFilenameSize) - &&(fileNameEnd[-1-infoFilenameSize] != '/') - &&(fileNameEnd[-1-infoFilenameSize] != '\\') ) - infoFilenameSize++; - DISPLAY("\rLoading %s... \r", fileNameEnd - infoFilenameSize); - } - - /* Load file & update hash */ - switch(hashType) - { - case algo_xxh32: - BMK_hashStream(&h32, algo_xxh32, inFile, buffer, blockSize); - break; - case algo_xxh64: - BMK_hashStream(&h64, algo_xxh64, inFile, buffer, blockSize); - break; - default: - break; - } - - fclose(inFile); - free(buffer); - - /* display Hash */ - switch(hashType) - { - case algo_xxh32: - { XXH32_canonical_t hcbe32; - XXH32_canonicalFromHash(&hcbe32, h32); - displayEndianess==big_endian ? - BMK_display_BigEndian(&hcbe32, sizeof(hcbe32)) : BMK_display_LittleEndian(&hcbe32, sizeof(hcbe32)); - DISPLAYRESULT(" %s\n", fileName); - break; - } - case algo_xxh64: - { XXH64_canonical_t hcbe64; - XXH64_canonicalFromHash(&hcbe64, h64); - displayEndianess==big_endian ? - BMK_display_BigEndian(&hcbe64, sizeof(hcbe64)) : BMK_display_LittleEndian(&hcbe64, sizeof(hcbe64)); - DISPLAYRESULT(" %s\n", fileName); - break; - } - default: - break; - } - - return 0; -} - - -static int BMK_hashFiles(const char** fnList, int fnTotal, - algoType hashType, endianess displayEndianess) -{ - int fnNb; - int result = 0; - - if (fnTotal==0) - return BMK_hash(stdinName, hashType, displayEndianess); - - for (fnNb=0; fnNb= *lineMax) { - char* newLineBuf = NULL; - int newBufSize = *lineMax; - - newBufSize += (newBufSize/2) + 1; /* x 1.5 */ - if (newBufSize > MAX_LINE_LENGTH) newBufSize = MAX_LINE_LENGTH; - if (len+1 >= newBufSize) return GetLine_exceedMaxLineLength; - - newLineBuf = (char*) realloc(*lineBuf, newBufSize); - if (newLineBuf == NULL) return GetLine_outOfMemory; - - *lineBuf = newLineBuf; - *lineMax = newBufSize; - } - - if (c == '\n') break; - (*lineBuf)[len++] = (char) c; - } - - (*lineBuf)[len] = '\0'; - return result; -} - - -/* Converts one hexadecimal character to integer. - * Returns -1, if given character is not hexadecimal. - */ -static int charToHex(char c) -{ - int result = -1; - if (c >= '0' && c <= '9') { - result = (int) (c - '0'); - } else if (c >= 'A' && c <= 'F') { - result = (int) (c - 'A') + 0x0a; - } else if (c >= 'a' && c <= 'f') { - result = (int) (c - 'a') + 0x0a; - } - return result; -} - - -/* Converts XXH32 canonical hexadecimal string hashStr to big endian unsigned char array dst. - * Returns CANONICAL_FROM_STRING_INVALID_FORMAT, if hashStr is not well formatted. - * Returns CANONICAL_FROM_STRING_OK, if hashStr is parsed successfully. - */ -static CanonicalFromStringResult canonicalFromString(unsigned char* dst, - size_t dstSize, - const char* hashStr) -{ - size_t i; - for (i = 0; i < dstSize; ++i) { - int h0, h1; - - h0 = charToHex(hashStr[i*2 + 0]); - if (h0 < 0) return CanonicalFromString_invalidFormat; - - h1 = charToHex(hashStr[i*2 + 1]); - if (h1 < 0) return CanonicalFromString_invalidFormat; - - dst[i] = (unsigned char) ((h0 << 4) | h1); - } - return CanonicalFromString_ok; -} - - -/* Parse single line of xxHash checksum file. - * Returns PARSE_LINE_ERROR_INVALID_FORMAT, if line is not well formatted. - * Returns PARSE_LINE_OK if line is parsed successfully. - * And members of parseLine will be filled by parsed values. - * - * - line must be ended with '\0'. - * - Since parsedLine.filename will point within given argument `line`, - * users must keep `line`s content during they are using parsedLine. - * - * Given xxHash checksum line should have the following format: - * - * <8 or 16 hexadecimal char> <'\0'> - */ -static ParseLineResult parseLine(ParsedLine* parsedLine, const char* line) -{ - const char* const firstSpace = strchr(line, ' '); - const char* const secondSpace = firstSpace + 1; - - parsedLine->filename = NULL; - parsedLine->xxhBits = 0; - - if (firstSpace == NULL || *secondSpace != ' ') return ParseLine_invalidFormat; - - switch (firstSpace - line) - { - case 8: - { XXH32_canonical_t* xxh32c = &parsedLine->canonical.xxh32; - if (canonicalFromString(xxh32c->digest, sizeof(xxh32c->digest), line) - != CanonicalFromString_ok) { - return ParseLine_invalidFormat; - } - parsedLine->xxhBits = 32; - break; - } - - case 16: - { XXH64_canonical_t* xxh64c = &parsedLine->canonical.xxh64; - if (canonicalFromString(xxh64c->digest, sizeof(xxh64c->digest), line) - != CanonicalFromString_ok) { - return ParseLine_invalidFormat; - } - parsedLine->xxhBits = 64; - break; - } - - default: - return ParseLine_invalidFormat; - break; - } - - parsedLine->filename = secondSpace + 1; - return ParseLine_ok; -} - - -/*! Parse xxHash checksum file. - */ -static void parseFile1(ParseFileArg* parseFileArg) -{ - const char* const inFileName = parseFileArg->inFileName; - ParseFileReport* const report = &parseFileArg->report; - - unsigned long lineNumber = 0; - memset(report, 0, sizeof(*report)); - - while (!report->quit) { - FILE* fp = NULL; - LineStatus lineStatus = LineStatus_hashFailed; - GetLineResult getLineResult; - ParsedLine parsedLine; - memset(&parsedLine, 0, sizeof(parsedLine)); - - lineNumber++; - if (lineNumber == 0) { - /* This is unlikely happen, but md5sum.c has this - * error check. */ - DISPLAY("%s : too many checksum lines\n", inFileName); - report->quit = 1; - break; - } - - getLineResult = getLine(&parseFileArg->lineBuf, &parseFileArg->lineMax, - parseFileArg->inFile); - if (getLineResult != GetLine_ok) { - if (getLineResult == GetLine_eof) break; - - switch (getLineResult) - { - case GetLine_ok: - case GetLine_eof: - /* These cases never happen. See above getLineResult related "if"s. - They exist just for make gcc's -Wswitch-enum happy. */ - break; - - default: - DISPLAY("%s : %lu: unknown error\n", inFileName, lineNumber); - break; - - case GetLine_exceedMaxLineLength: - DISPLAY("%s : %lu: too long line\n", inFileName, lineNumber); - break; - - case GetLine_outOfMemory: - DISPLAY("%s : %lu: out of memory\n", inFileName, lineNumber); - break; - } - report->quit = 1; - break; - } - - if (parseLine(&parsedLine, parseFileArg->lineBuf) != ParseLine_ok) { - report->nImproperlyFormattedLines++; - if (parseFileArg->warn) { - DISPLAY("%s : %lu: improperly formatted XXHASH checksum line\n" - , inFileName, lineNumber); - } - continue; - } - - if (report->xxhBits != 0 && report->xxhBits != parsedLine.xxhBits) { - /* Don't accept xxh32/xxh64 mixed file */ - report->nImproperlyFormattedLines++; - report->nMixedFormatLines++; - if (parseFileArg->warn) { - DISPLAY("%s : %lu: improperly formatted XXHASH checksum line (XXH32/64)\n" - , inFileName, lineNumber); - } - continue; - } - - report->nProperlyFormattedLines++; - if (report->xxhBits == 0) { - report->xxhBits = parsedLine.xxhBits; - } - - fp = fopen(parsedLine.filename, "rb"); - if (fp == NULL) { - lineStatus = LineStatus_failedToOpen; - } else { - lineStatus = LineStatus_hashFailed; - switch (parsedLine.xxhBits) - { - case 32: - { XXH32_hash_t xxh; - BMK_hashStream(&xxh, algo_xxh32, fp, parseFileArg->blockBuf, parseFileArg->blockSize); - if (xxh == XXH32_hashFromCanonical(&parsedLine.canonical.xxh32)) { - lineStatus = LineStatus_hashOk; - } } - break; - - case 64: - { XXH64_hash_t xxh; - BMK_hashStream(&xxh, algo_xxh64, fp, parseFileArg->blockBuf, parseFileArg->blockSize); - if (xxh == XXH64_hashFromCanonical(&parsedLine.canonical.xxh64)) { - lineStatus = LineStatus_hashOk; - } } - break; - - default: - break; - } - fclose(fp); - } - - switch (lineStatus) - { - default: - DISPLAY("%s : unknown error\n", inFileName); - report->quit = 1; - break; - - case LineStatus_failedToOpen: - report->nOpenOrReadFailures++; - if (!parseFileArg->statusOnly) { - DISPLAYRESULT("%s : %lu: FAILED open or read %s\n" - , inFileName, lineNumber, parsedLine.filename); - } - break; - - case LineStatus_hashOk: - case LineStatus_hashFailed: - { int b = 1; - if (lineStatus == LineStatus_hashOk) { - /* If --quiet is specified, don't display "OK" */ - if (parseFileArg->quiet) b = 0; - } else { - report->nMismatchedChecksums++; - } - - if (b && !parseFileArg->statusOnly) { - DISPLAYRESULT("%s: %s\n", parsedLine.filename - , lineStatus == LineStatus_hashOk ? "OK" : "FAILED"); - } } - break; - } - } /* while (!report->quit) */ -} - - -/* Parse xxHash checksum file. - * Returns 1, if all procedures were succeeded. - * Returns 0, if any procedures was failed. - * - * If strictMode != 0, return error code if any line is invalid. - * If statusOnly != 0, don't generate any output. - * If warn != 0, print a warning message to stderr. - * If quiet != 0, suppress "OK" line. - * - * "All procedures are succeeded" means: - * - Checksum file contains at least one line and less than SIZE_T_MAX lines. - * - All files are properly opened and read. - * - All hash values match with its content. - * - (strict mode) All lines in checksum file are consistent and well formatted. - * - */ -static int checkFile(const char* inFileName, - const endianess displayEndianess, - U32 strictMode, - U32 statusOnly, - U32 warn, - U32 quiet) -{ - int result = 0; - FILE* inFile = NULL; - ParseFileArg parseFileArgBody; - ParseFileArg* const parseFileArg = &parseFileArgBody; - ParseFileReport* const report = &parseFileArg->report; - - if (displayEndianess != big_endian) { - /* Don't accept little endian */ - DISPLAY( "Check file mode doesn't support little endian\n" ); - return 0; - } - - /* note : stdinName is special constant pointer. It is not a string. */ - if (inFileName == stdinName) { - /* note : Since we expect text input for xxhash -c mode, - * Don't set binary mode for stdin */ - inFile = stdin; - } else { - inFile = fopen( inFileName, "rt" ); - } - - if (inFile == NULL) { - DISPLAY( "Pb opening %s\n", inFileName); - return 0; - } - - parseFileArg->inFileName = inFileName; - parseFileArg->inFile = inFile; - parseFileArg->lineMax = DEFAULT_LINE_LENGTH; - parseFileArg->lineBuf = (char*) malloc((size_t) parseFileArg->lineMax); - parseFileArg->blockSize = 64 * 1024; - parseFileArg->blockBuf = (char*) malloc(parseFileArg->blockSize); - parseFileArg->strictMode = strictMode; - parseFileArg->statusOnly = statusOnly; - parseFileArg->warn = warn; - parseFileArg->quiet = quiet; - - parseFile1(parseFileArg); - - free(parseFileArg->blockBuf); - free(parseFileArg->lineBuf); - - if (inFile != stdin) fclose(inFile); - - /* Show error/warning messages. All messages are copied from md5sum.c - */ - if (report->nProperlyFormattedLines == 0) { - DISPLAY("%s: no properly formatted XXHASH checksum lines found\n", inFileName); - } else if (!statusOnly) { - if (report->nImproperlyFormattedLines) { - DISPLAYRESULT("%lu lines are improperly formatted\n" - , report->nImproperlyFormattedLines); - } - if (report->nOpenOrReadFailures) { - DISPLAYRESULT("%lu listed files could not be read\n" - , report->nOpenOrReadFailures); - } - if (report->nMismatchedChecksums) { - DISPLAYRESULT("%lu computed checksums did NOT match\n" - , report->nMismatchedChecksums); - } } - - /* Result (exit) code logic is copied from - * gnu coreutils/src/md5sum.c digest_check() */ - result = report->nProperlyFormattedLines != 0 - && report->nMismatchedChecksums == 0 - && report->nOpenOrReadFailures == 0 - && (!strictMode || report->nImproperlyFormattedLines == 0) - && report->quit == 0; - return result; -} - - -static int checkFiles(const char** fnList, int fnTotal, - const endianess displayEndianess, - U32 strictMode, - U32 statusOnly, - U32 warn, - U32 quiet) -{ - int ok = 1; - - /* Special case for stdinName "-", - * note: stdinName is not a string. It's special pointer. */ - if (fnTotal==0) { - ok &= checkFile(stdinName, displayEndianess, strictMode, statusOnly, warn, quiet); - } else { - int fnNb; - for (fnNb=0; fnNb='0' && argument[0]<='9') - g_sampleSize *= 10, g_sampleSize += argument[0]-'0', argument++; - break; - - default: - return badusage(exename); - } - } - } /* for(i=1; i +