mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-16 09:21:36 +00:00
128 lines
2.8 KiB
C++
128 lines
2.8 KiB
C++
|
#include <stdint.h>
|
||
|
#include <ctype.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
/* ======================================================================== */
|
||
|
|
||
|
/* By Paul Hsieh (C) 2004, 2005. Covered under the Paul Hsieh derivative
|
||
|
license. See:
|
||
|
http://www.azillionmonkeys.com/qed/weblicense.html for license details.
|
||
|
|
||
|
http://www.azillionmonkeys.com/qed/hash.html */
|
||
|
|
||
|
#undef get16bits
|
||
|
#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
|
||
|
|| defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
|
||
|
#define get16bits(d) (*((const uint16_t *) (d)))
|
||
|
#endif
|
||
|
|
||
|
#if !defined (get16bits)
|
||
|
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
|
||
|
+(uint32_t)(((const uint8_t *)(d))[0]) )
|
||
|
#endif
|
||
|
|
||
|
uint32_t SuperFastHash (const char *data, size_t len)
|
||
|
{
|
||
|
uint32_t hash = 0, tmp;
|
||
|
size_t rem;
|
||
|
|
||
|
if (len == 0 || data == NULL) return 0;
|
||
|
|
||
|
rem = len & 3;
|
||
|
len >>= 2;
|
||
|
|
||
|
/* Main loop */
|
||
|
for (;len > 0; len--)
|
||
|
{
|
||
|
hash += get16bits (data);
|
||
|
tmp = (get16bits (data+2) << 11) ^ hash;
|
||
|
hash = (hash << 16) ^ tmp;
|
||
|
data += 2*sizeof (uint16_t);
|
||
|
hash += hash >> 11;
|
||
|
}
|
||
|
|
||
|
/* Handle end cases */
|
||
|
switch (rem)
|
||
|
{
|
||
|
case 3: hash += get16bits (data);
|
||
|
hash ^= hash << 16;
|
||
|
hash ^= data[sizeof (uint16_t)] << 18;
|
||
|
hash += hash >> 11;
|
||
|
break;
|
||
|
case 2: hash += get16bits (data);
|
||
|
hash ^= hash << 11;
|
||
|
hash += hash >> 17;
|
||
|
break;
|
||
|
case 1: hash += *data;
|
||
|
hash ^= hash << 10;
|
||
|
hash += hash >> 1;
|
||
|
}
|
||
|
|
||
|
/* Force "avalanching" of final 127 bits */
|
||
|
hash ^= hash << 3;
|
||
|
hash += hash >> 5;
|
||
|
hash ^= hash << 4;
|
||
|
hash += hash >> 17;
|
||
|
hash ^= hash << 25;
|
||
|
hash += hash >> 6;
|
||
|
|
||
|
return hash;
|
||
|
}
|
||
|
|
||
|
/* A modified version to do a case-insensitive hash */
|
||
|
|
||
|
#undef get16bits
|
||
|
#define get16bits(d) ((((uint32_t)tolower(((const uint8_t *)(d))[1])) << 8)\
|
||
|
+(uint32_t)tolower(((const uint8_t *)(d))[0]) )
|
||
|
|
||
|
uint32_t SuperFastHashI (const char *data, size_t len)
|
||
|
{
|
||
|
uint32_t hash = 0, tmp;
|
||
|
size_t rem;
|
||
|
|
||
|
if (len <= 0 || data == NULL) return 0;
|
||
|
|
||
|
rem = len & 3;
|
||
|
len >>= 2;
|
||
|
|
||
|
/* Main loop */
|
||
|
for (;len > 0; len--)
|
||
|
{
|
||
|
hash += get16bits (data);
|
||
|
tmp = (get16bits (data+2) << 11) ^ hash;
|
||
|
hash = (hash << 16) ^ tmp;
|
||
|
data += 2*sizeof (uint16_t);
|
||
|
hash += hash >> 11;
|
||
|
}
|
||
|
|
||
|
/* Handle end cases */
|
||
|
switch (rem)
|
||
|
{
|
||
|
case 3: hash += get16bits (data);
|
||
|
hash ^= hash << 16;
|
||
|
hash ^= tolower(data[sizeof (uint16_t)]) << 18;
|
||
|
hash += hash >> 11;
|
||
|
break;
|
||
|
case 2: hash += get16bits (data);
|
||
|
hash ^= hash << 11;
|
||
|
hash += hash >> 17;
|
||
|
break;
|
||
|
case 1: hash += tolower(*data);
|
||
|
hash ^= hash << 10;
|
||
|
hash += hash >> 1;
|
||
|
}
|
||
|
|
||
|
/* Force "avalanching" of final 127 bits */
|
||
|
hash ^= hash << 3;
|
||
|
hash += hash >> 5;
|
||
|
hash ^= hash << 4;
|
||
|
hash += hash >> 17;
|
||
|
hash ^= hash << 25;
|
||
|
hash += hash >> 6;
|
||
|
|
||
|
return hash;
|
||
|
}
|
||
|
|
||
|
/* ======================================================================== */
|
||
|
|