mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-03-03 03:23:03 +00:00
Merge pull request #691 from Laupetin/chore/refactor-hashing-funcs
chore: streamline game hashing functions
This commit is contained in:
3
.github/workflows/ci.yaml
vendored
3
.github/workflows/ci.yaml
vendored
@@ -82,6 +82,7 @@ jobs:
|
|||||||
- name: Test
|
- name: Test
|
||||||
working-directory: ${{ github.workspace }}/build/lib/Release_${{ matrix.build_arch }}/tests
|
working-directory: ${{ github.workspace }}/build/lib/Release_${{ matrix.build_arch }}/tests
|
||||||
run: |
|
run: |
|
||||||
|
./CommonTests
|
||||||
./ObjCommonTests
|
./ObjCommonTests
|
||||||
./ObjCompilingTests
|
./ObjCompilingTests
|
||||||
./ObjLoadingTests
|
./ObjLoadingTests
|
||||||
@@ -138,6 +139,8 @@ jobs:
|
|||||||
working-directory: ${{ github.workspace }}/build/lib/Release_${{ matrix.build_arch }}/tests
|
working-directory: ${{ github.workspace }}/build/lib/Release_${{ matrix.build_arch }}/tests
|
||||||
run: |
|
run: |
|
||||||
$combinedExitCode = 0
|
$combinedExitCode = 0
|
||||||
|
./CommonTests
|
||||||
|
$combinedExitCode = [System.Math]::max($combinedExitCode, $LASTEXITCODE)
|
||||||
./ObjCommonTests
|
./ObjCommonTests
|
||||||
$combinedExitCode = [System.Math]::max($combinedExitCode, $LASTEXITCODE)
|
$combinedExitCode = [System.Math]::max($combinedExitCode, $LASTEXITCODE)
|
||||||
./ObjCompilingTests
|
./ObjCompilingTests
|
||||||
|
|||||||
@@ -195,6 +195,7 @@ group ""
|
|||||||
-- Tests
|
-- Tests
|
||||||
-- ========================
|
-- ========================
|
||||||
include "test/Catch2Common.lua"
|
include "test/Catch2Common.lua"
|
||||||
|
include "test/CommonTests.lua"
|
||||||
include "test/ObjCommonTestUtils.lua"
|
include "test/ObjCommonTestUtils.lua"
|
||||||
include "test/ObjCommonTests.lua"
|
include "test/ObjCommonTests.lua"
|
||||||
include "test/ObjCompilingTests.lua"
|
include "test/ObjCompilingTests.lua"
|
||||||
@@ -209,6 +210,7 @@ include "test/ZoneCommonTests.lua"
|
|||||||
-- Tests group: Unit test and other tests projects
|
-- Tests group: Unit test and other tests projects
|
||||||
group "Tests"
|
group "Tests"
|
||||||
Catch2Common:project()
|
Catch2Common:project()
|
||||||
|
CommonTests:project()
|
||||||
ObjCommonTestUtils:project()
|
ObjCommonTestUtils:project()
|
||||||
ObjCommonTests:project()
|
ObjCommonTests:project()
|
||||||
ObjCompilingTests:project()
|
ObjCompilingTests:project()
|
||||||
|
|||||||
@@ -1,28 +1,24 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "IW3.h"
|
#include "IW3.h"
|
||||||
|
#include "Utils/Djb2.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace IW3
|
namespace IW3
|
||||||
{
|
{
|
||||||
class Common
|
class Common
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static constexpr uint32_t R_HashString(const char* string, const uint32_t hash)
|
static constexpr uint32_t R_HashString(const char* str, const uint32_t hash)
|
||||||
{
|
{
|
||||||
const char* v2 = string; // edx@1
|
return djb2_xor_nocase(str, hash);
|
||||||
char v3 = *string; // cl@1
|
|
||||||
uint32_t result = hash;
|
|
||||||
|
|
||||||
for (; *v2; v3 = *v2)
|
|
||||||
{
|
|
||||||
++v2;
|
|
||||||
result = 33 * result ^ (v3 | 0x20);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr uint32_t R_HashString(const char* string)
|
static constexpr uint32_t R_HashString(const char* string)
|
||||||
{
|
{
|
||||||
|
// Using djb2 with a 0 starting value makes a worse hash func apparently
|
||||||
|
// but who am I to judge
|
||||||
return R_HashString(string, 0u);
|
return R_HashString(string, 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,26 +2,8 @@
|
|||||||
|
|
||||||
#include "Utils/Pack.h"
|
#include "Utils/Pack.h"
|
||||||
|
|
||||||
#include <cctype>
|
|
||||||
|
|
||||||
using namespace IW4;
|
using namespace IW4;
|
||||||
|
|
||||||
int Common::StringTable_HashString(const char* str)
|
|
||||||
{
|
|
||||||
if (!str)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
auto result = 0;
|
|
||||||
auto offset = 0;
|
|
||||||
while (str[offset])
|
|
||||||
{
|
|
||||||
const auto c = tolower(str[offset++]);
|
|
||||||
result = c + 31 * result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
PackedTexCoords Common::Vec2PackTexCoords(const float (&in)[2])
|
PackedTexCoords Common::Vec2PackTexCoords(const float (&in)[2])
|
||||||
{
|
{
|
||||||
return PackedTexCoords{pack32::Vec2PackTexCoordsVU(in)};
|
return PackedTexCoords{pack32::Vec2PackTexCoordsVU(in)};
|
||||||
|
|||||||
@@ -1,33 +1,41 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "IW4.h"
|
#include "IW4.h"
|
||||||
|
#include "Utils/Djb2.h"
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
namespace IW4
|
namespace IW4
|
||||||
{
|
{
|
||||||
class Common
|
class Common
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static constexpr uint32_t R_HashString(const char* string, const uint32_t hash)
|
static constexpr int StringTable_HashString(const char* str)
|
||||||
{
|
{
|
||||||
const char* v2 = string; // edx@1
|
if (!str)
|
||||||
char v3 = *string; // cl@1
|
return 0;
|
||||||
uint32_t result = hash;
|
|
||||||
|
|
||||||
for (; *v2; v3 = *v2)
|
// Lets do djb2 with 31 instead of 33 because why not
|
||||||
{
|
// and leave out the starting value while we are at it
|
||||||
++v2;
|
uint32_t hash = 0;
|
||||||
result = 33 * result ^ (v3 | 0x20);
|
for (char c = *str; c; c = *++str)
|
||||||
}
|
hash = hash * 31 + std::tolower(c);
|
||||||
return result;
|
|
||||||
|
return static_cast<int>(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr uint32_t R_HashString(const char* str, const uint32_t hash)
|
||||||
|
{
|
||||||
|
return djb2_xor_nocase(str, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr uint32_t R_HashString(const char* string)
|
static constexpr uint32_t R_HashString(const char* string)
|
||||||
{
|
{
|
||||||
|
// Using djb2 with a 0 starting value makes a worse hash func apparently
|
||||||
|
// but who am I to judge
|
||||||
return R_HashString(string, 0u);
|
return R_HashString(string, 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int StringTable_HashString(const char* str);
|
|
||||||
|
|
||||||
static PackedTexCoords Vec2PackTexCoords(const float (&in)[2]);
|
static PackedTexCoords Vec2PackTexCoords(const float (&in)[2]);
|
||||||
static PackedUnitVec Vec3PackUnitVec(const float (&in)[3]);
|
static PackedUnitVec Vec3PackUnitVec(const float (&in)[3]);
|
||||||
static GfxColor Vec4PackGfxColor(const float (&in)[4]);
|
static GfxColor Vec4PackGfxColor(const float (&in)[4]);
|
||||||
|
|||||||
@@ -2,26 +2,8 @@
|
|||||||
|
|
||||||
#include "Utils/Pack.h"
|
#include "Utils/Pack.h"
|
||||||
|
|
||||||
#include <cctype>
|
|
||||||
|
|
||||||
using namespace IW5;
|
using namespace IW5;
|
||||||
|
|
||||||
int Common::StringTable_HashString(const char* str)
|
|
||||||
{
|
|
||||||
if (!str)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
auto result = 0;
|
|
||||||
auto offset = 0;
|
|
||||||
while (str[offset])
|
|
||||||
{
|
|
||||||
const auto c = tolower(str[offset++]);
|
|
||||||
result = c + 31 * result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
PackedTexCoords Common::Vec2PackTexCoords(const float (&in)[2])
|
PackedTexCoords Common::Vec2PackTexCoords(const float (&in)[2])
|
||||||
{
|
{
|
||||||
return PackedTexCoords{pack32::Vec2PackTexCoordsVU(in)};
|
return PackedTexCoords{pack32::Vec2PackTexCoordsVU(in)};
|
||||||
|
|||||||
@@ -1,26 +1,38 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "IW5.h"
|
#include "IW5.h"
|
||||||
|
#include "Utils/Djb2.h"
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
namespace IW5
|
namespace IW5
|
||||||
{
|
{
|
||||||
class Common
|
class Common
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static int StringTable_HashString(const char* str);
|
static constexpr int StringTable_HashString(const char* str)
|
||||||
|
|
||||||
static constexpr uint32_t R_HashString(const char* str, uint32_t hash)
|
|
||||||
{
|
{
|
||||||
for (const auto* pos = str; *pos; pos++)
|
if (!str)
|
||||||
{
|
return 0;
|
||||||
hash = 33 * hash ^ (*pos | 0x20);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash;
|
// Lets do djb2 with 31 instead of 33 because why not
|
||||||
|
// and leave out the starting value while we are at it
|
||||||
|
uint32_t hash = 0;
|
||||||
|
for (char c = *str; c; c = *++str)
|
||||||
|
hash = hash * 31 + std::tolower(c);
|
||||||
|
|
||||||
|
return static_cast<int>(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr uint32_t R_HashString(const char* str, const uint32_t hash)
|
||||||
|
{
|
||||||
|
return djb2_xor_nocase(str, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr uint32_t R_HashString(const char* string)
|
static constexpr uint32_t R_HashString(const char* string)
|
||||||
{
|
{
|
||||||
|
// Using djb2 with a 0 starting value makes a worse hash func apparently
|
||||||
|
// but who am I to judge
|
||||||
return R_HashString(string, 0u);
|
return R_HashString(string, 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,62 +2,8 @@
|
|||||||
|
|
||||||
#include "Utils/Pack.h"
|
#include "Utils/Pack.h"
|
||||||
|
|
||||||
#include <cctype>
|
|
||||||
|
|
||||||
using namespace T5;
|
using namespace T5;
|
||||||
|
|
||||||
int Common::Com_HashKey(const char* str, const int maxLen)
|
|
||||||
{
|
|
||||||
if (str == nullptr)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
int hash = 0;
|
|
||||||
for (int i = 0; i < maxLen; i++)
|
|
||||||
{
|
|
||||||
if (str[i] == '\0')
|
|
||||||
break;
|
|
||||||
|
|
||||||
hash += str[i] * (0x77 + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash ^ ((hash ^ (hash >> 10)) >> 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Common::Com_HashString(const char* str)
|
|
||||||
{
|
|
||||||
if (!str)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
auto result = 0x1505;
|
|
||||||
auto offset = 0;
|
|
||||||
while (str[offset])
|
|
||||||
{
|
|
||||||
const auto c = tolower(str[offset++]);
|
|
||||||
result = c + 33 * result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Common::Com_HashString(const char* str, const int len)
|
|
||||||
{
|
|
||||||
if (!str)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
int result = 0x1505;
|
|
||||||
int offset = 0;
|
|
||||||
while (str[offset])
|
|
||||||
{
|
|
||||||
if (len > 0 && offset >= len)
|
|
||||||
break;
|
|
||||||
|
|
||||||
const int c = tolower(str[offset++]);
|
|
||||||
result = c + 33 * result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
PackedTexCoords Common::Vec2PackTexCoords(const float (&in)[2])
|
PackedTexCoords Common::Vec2PackTexCoords(const float (&in)[2])
|
||||||
{
|
{
|
||||||
return PackedTexCoords{pack32::Vec2PackTexCoordsVU(in)};
|
return PackedTexCoords{pack32::Vec2PackTexCoordsVU(in)};
|
||||||
|
|||||||
@@ -1,28 +1,48 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "T5.h"
|
#include "T5.h"
|
||||||
|
#include "Utils/Djb2.h"
|
||||||
|
|
||||||
namespace T5
|
namespace T5
|
||||||
{
|
{
|
||||||
class Common
|
class Common
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static int Com_HashKey(const char* str, int maxLen);
|
static constexpr int Com_HashKey(const char* str, const int maxLen)
|
||||||
static int Com_HashString(const char* str);
|
|
||||||
static int Com_HashString(const char* str, int len);
|
|
||||||
|
|
||||||
static constexpr uint32_t R_HashString(const char* str, uint32_t hash)
|
|
||||||
{
|
{
|
||||||
for (const auto* pos = str; *pos; pos++)
|
if (str == nullptr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int hash = 0;
|
||||||
|
for (int i = 0; i < maxLen; i++)
|
||||||
{
|
{
|
||||||
hash = 33 * hash ^ (*pos | 0x20);
|
if (str[i] == '\0')
|
||||||
|
break;
|
||||||
|
|
||||||
|
hash += str[i] * (0x77 + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
return hash;
|
return hash ^ ((hash ^ (hash >> 10)) >> 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr int Com_HashString(const char* str)
|
||||||
|
{
|
||||||
|
// Hashing aesthetics seem to be a thing
|
||||||
|
if (!str)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return static_cast<int>(djb2_lower(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr uint32_t R_HashString(const char* str, const uint32_t hash)
|
||||||
|
{
|
||||||
|
return djb2_xor_nocase(str, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr uint32_t R_HashString(const char* string)
|
static constexpr uint32_t R_HashString(const char* string)
|
||||||
{
|
{
|
||||||
|
// Using djb2 with a 0 starting value makes a worse hash func apparently
|
||||||
|
// but who am I to judge
|
||||||
return R_HashString(string, 0u);
|
return R_HashString(string, 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "T6.h"
|
#include "T6.h"
|
||||||
|
#include "Utils/Djb2.h"
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
|
||||||
@@ -28,51 +29,22 @@ namespace T6
|
|||||||
|
|
||||||
static constexpr int Com_HashString(const char* str)
|
static constexpr int Com_HashString(const char* str)
|
||||||
{
|
{
|
||||||
|
// Hashing aesthetics seem to be a thing
|
||||||
if (!str)
|
if (!str)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auto result = 0x1505;
|
return static_cast<int>(djb2_lower(str));
|
||||||
auto offset = 0;
|
|
||||||
while (str[offset])
|
|
||||||
{
|
|
||||||
const auto c = tolower(str[offset++]);
|
|
||||||
result = c + 33 * result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr int Com_HashString(const char* str, const int len)
|
static constexpr uint32_t R_HashString(const char* str, const uint32_t hash)
|
||||||
{
|
{
|
||||||
if (!str)
|
return djb2_xor_nocase(str, hash);
|
||||||
return 0;
|
|
||||||
|
|
||||||
int result = 0x1505;
|
|
||||||
int offset = 0;
|
|
||||||
while (str[offset])
|
|
||||||
{
|
|
||||||
if (len > 0 && offset >= len)
|
|
||||||
break;
|
|
||||||
|
|
||||||
const int c = tolower(str[offset++]);
|
|
||||||
result = c + 33 * result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr uint32_t R_HashString(const char* str, uint32_t hash)
|
|
||||||
{
|
|
||||||
for (const auto* pos = str; *pos; pos++)
|
|
||||||
{
|
|
||||||
hash = 33 * hash ^ (*pos | 0x20);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr uint32_t R_HashString(const char* string)
|
static constexpr uint32_t R_HashString(const char* string)
|
||||||
{
|
{
|
||||||
|
// Using djb2 with a 0 starting value makes a worse hash func apparently
|
||||||
|
// but who am I to judge
|
||||||
return R_HashString(string, 0u);
|
return R_HashString(string, 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,6 +53,9 @@ namespace T6
|
|||||||
if (!str || !*str)
|
if (!str || !*str)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
// Seems to be somewhat based on sdbm
|
||||||
|
// http://www.cse.yorku.ca/~oz/hash.html
|
||||||
|
|
||||||
auto result = 0x1505;
|
auto result = 0x1505;
|
||||||
auto offset = 0u;
|
auto offset = 0u;
|
||||||
|
|
||||||
|
|||||||
100
src/Common/Utils/Djb2.h
Normal file
100
src/Common/Utils/Djb2.h
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
// This header contains multiple varying implementations of the DJB2 algorithm:
|
||||||
|
// http://www.cse.yorku.ca/~oz/hash.html
|
||||||
|
|
||||||
|
constexpr uint32_t DJB2_STARTING_VALUE = 5381;
|
||||||
|
|
||||||
|
static constexpr uint32_t djb2(const char* str, uint32_t hash)
|
||||||
|
{
|
||||||
|
for (char c = *str; c; c = *++str)
|
||||||
|
{
|
||||||
|
// hash * 33 + c
|
||||||
|
hash = ((hash << 5) + hash) + c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr uint32_t djb2(const char* str)
|
||||||
|
{
|
||||||
|
return djb2(str, DJB2_STARTING_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr uint32_t djb2_nocase(const char* str, uint32_t hash)
|
||||||
|
{
|
||||||
|
for (char c = *str; c; c = *++str)
|
||||||
|
{
|
||||||
|
// Or with 0x20 makes the string case-insensitive
|
||||||
|
// but also messes up non-letters
|
||||||
|
hash = ((hash << 5) + hash) + (c | 0x20);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr uint32_t djb2_nocase(const char* str)
|
||||||
|
{
|
||||||
|
return djb2_nocase(str, DJB2_STARTING_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr uint32_t djb2_lower(const char* str, uint32_t hash)
|
||||||
|
{
|
||||||
|
for (char c = *str; c; c = *++str)
|
||||||
|
hash = ((hash << 5) + hash) + std::tolower(c);
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr uint32_t djb2_lower(const char* str)
|
||||||
|
{
|
||||||
|
return djb2_lower(str, DJB2_STARTING_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr uint32_t djb2_xor(const char* str, uint32_t hash)
|
||||||
|
{
|
||||||
|
for (char c = *str; c; c = *++str)
|
||||||
|
{
|
||||||
|
hash = ((hash << 5) + hash) ^ c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr uint32_t djb2_xor(const char* str)
|
||||||
|
{
|
||||||
|
return djb2_xor(str, DJB2_STARTING_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr uint32_t djb2_xor_nocase(const char* str, uint32_t hash)
|
||||||
|
{
|
||||||
|
for (char c = *str; c; c = *++str)
|
||||||
|
{
|
||||||
|
// Or with 0x20 makes the string case-insensitive
|
||||||
|
// but also messes up non-letters
|
||||||
|
hash = ((hash << 5) + hash) ^ (c | 0x20);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr uint32_t djb2_xor_nocase(const char* str)
|
||||||
|
{
|
||||||
|
return djb2_xor_nocase(str, DJB2_STARTING_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr uint32_t djb2_xor_lower(const char* str, uint32_t hash)
|
||||||
|
{
|
||||||
|
for (char c = *str; c; c = *++str)
|
||||||
|
hash = ((hash << 5) + hash) ^ std::tolower(c);
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr uint32_t djb2_xor_lower(const char* str)
|
||||||
|
{
|
||||||
|
return djb2_xor_lower(str, DJB2_STARTING_VALUE);
|
||||||
|
}
|
||||||
54
test/CommonTests.lua
Normal file
54
test/CommonTests.lua
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
CommonTests = {}
|
||||||
|
|
||||||
|
function CommonTests:include(includes)
|
||||||
|
if includes:handle(self:name()) then
|
||||||
|
includedirs {
|
||||||
|
path.join(TestFolder(), "CommonTests")
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function CommonTests:link(links)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function CommonTests:use()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function CommonTests:name()
|
||||||
|
return "CommonTests"
|
||||||
|
end
|
||||||
|
|
||||||
|
function CommonTests:project()
|
||||||
|
local folder = TestFolder()
|
||||||
|
local includes = Includes:create()
|
||||||
|
local links = Links:create()
|
||||||
|
|
||||||
|
project(self:name())
|
||||||
|
targetdir(TargetDirectoryTest)
|
||||||
|
location "%{wks.location}/test/%{prj.name}"
|
||||||
|
kind "ConsoleApp"
|
||||||
|
language "C++"
|
||||||
|
|
||||||
|
files {
|
||||||
|
path.join(folder, "CommonTests/**.h"),
|
||||||
|
path.join(folder, "CommonTests/**.cpp")
|
||||||
|
}
|
||||||
|
|
||||||
|
vpaths {
|
||||||
|
["*"] = {
|
||||||
|
path.join(folder, "CommonTests")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self:include(includes)
|
||||||
|
Catch2Common:include(includes)
|
||||||
|
Common:include(includes)
|
||||||
|
catch2:include(includes)
|
||||||
|
|
||||||
|
links:linkto(Common)
|
||||||
|
links:linkto(catch2)
|
||||||
|
links:linkto(Catch2Common)
|
||||||
|
links:linkall()
|
||||||
|
end
|
||||||
28
test/CommonTests/Game/IW3/CommonIW3Tests.cpp
Normal file
28
test/CommonTests/Game/IW3/CommonIW3Tests.cpp
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#include "Game/IW3/CommonIW3.h"
|
||||||
|
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
#include <catch2/generators/catch_generators.hpp>
|
||||||
|
|
||||||
|
TEST_CASE("IW3: Check checksums", "[iw3]")
|
||||||
|
{
|
||||||
|
SECTION("for R_HashString")
|
||||||
|
{
|
||||||
|
const auto [str, expectedHash] = GENERATE(Catch::Generators::table<const char*, uint32_t>({
|
||||||
|
{"hello world", 0xe7d74060},
|
||||||
|
{"universe2", 0x113fdcd7},
|
||||||
|
{"lit_r0c0n0x0_b1c1n1s1v1_b2c2n2x2", 0xdd0153c5},
|
||||||
|
{"AngularVelocityScale", 0x18f2cb6d},
|
||||||
|
{"BakedLightingIntensity", 0xd627f218},
|
||||||
|
{"Layer1OffsetBobbleDelay", 0xcd91b6ae},
|
||||||
|
{"MaxDepth", 0x61ed5959},
|
||||||
|
{"MomentumColor", 0xc80f3595},
|
||||||
|
{"SparkleScale", 0x5488816a},
|
||||||
|
{"TickMarkColorAndHarshness", 0xd6c718bd},
|
||||||
|
{"worldViewProjectionMatrix", 0x7f661409},
|
||||||
|
}));
|
||||||
|
|
||||||
|
CAPTURE(str);
|
||||||
|
const auto hash = IW3::Common::R_HashString(str);
|
||||||
|
REQUIRE(hash == expectedHash);
|
||||||
|
}
|
||||||
|
}
|
||||||
49
test/CommonTests/Game/IW4/CommonIW4Tests.cpp
Normal file
49
test/CommonTests/Game/IW4/CommonIW4Tests.cpp
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#include "Game/IW4/CommonIW4.h"
|
||||||
|
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
#include <catch2/generators/catch_generators.hpp>
|
||||||
|
|
||||||
|
TEST_CASE("IW4: Check checksums", "[iw4]")
|
||||||
|
{
|
||||||
|
SECTION("for StringTable_HashString")
|
||||||
|
{
|
||||||
|
const auto [str, expectedHash] = GENERATE(Catch::Generators::table<const char*, int>({
|
||||||
|
{"hello world", 0x6aefe2c4},
|
||||||
|
{"universe2", 0xe796fe8d},
|
||||||
|
{"lit_r0c0n0x0_b1c1n1s1v1_b2c2n2x2", 0x16c4d3f1},
|
||||||
|
{"AngularVelocityScale", 0x573e9feb},
|
||||||
|
{"BakedLightingIntensity", 0x15af785c},
|
||||||
|
{"Layer1OffsetBobbleDelay", 0xfb83324a},
|
||||||
|
{"MaxDepth", 0x1892e3df},
|
||||||
|
{"MomentumColor", 0x5e7abdcb},
|
||||||
|
{"SparkleScale", 0x9e4409f4},
|
||||||
|
{"TickMarkColorAndHarshness", 0x5dfe4c47},
|
||||||
|
{"worldViewProjectionMatrix", 0xa2501a07},
|
||||||
|
}));
|
||||||
|
|
||||||
|
CAPTURE(str);
|
||||||
|
const auto hash = IW4::Common::StringTable_HashString(str);
|
||||||
|
REQUIRE(hash == expectedHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("for R_HashString")
|
||||||
|
{
|
||||||
|
const auto [str, expectedHash] = GENERATE(Catch::Generators::table<const char*, uint32_t>({
|
||||||
|
{"hello world", 0xe7d74060},
|
||||||
|
{"universe2", 0x113fdcd7},
|
||||||
|
{"lit_r0c0n0x0_b1c1n1s1v1_b2c2n2x2", 0xdd0153c5},
|
||||||
|
{"AngularVelocityScale", 0x18f2cb6d},
|
||||||
|
{"BakedLightingIntensity", 0xd627f218},
|
||||||
|
{"Layer1OffsetBobbleDelay", 0xcd91b6ae},
|
||||||
|
{"MaxDepth", 0x61ed5959},
|
||||||
|
{"MomentumColor", 0xc80f3595},
|
||||||
|
{"SparkleScale", 0x5488816a},
|
||||||
|
{"TickMarkColorAndHarshness", 0xd6c718bd},
|
||||||
|
{"worldViewProjectionMatrix", 0x7f661409},
|
||||||
|
}));
|
||||||
|
|
||||||
|
CAPTURE(str);
|
||||||
|
const auto hash = IW4::Common::R_HashString(str);
|
||||||
|
REQUIRE(hash == expectedHash);
|
||||||
|
}
|
||||||
|
}
|
||||||
49
test/CommonTests/Game/IW5/CommonIW5Tests.cpp
Normal file
49
test/CommonTests/Game/IW5/CommonIW5Tests.cpp
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#include "Game/IW5/CommonIW5.h"
|
||||||
|
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
#include <catch2/generators/catch_generators.hpp>
|
||||||
|
|
||||||
|
TEST_CASE("IW5: Check checksums", "[iw5]")
|
||||||
|
{
|
||||||
|
SECTION("for StringTable_HashString")
|
||||||
|
{
|
||||||
|
const auto [str, expectedHash] = GENERATE(Catch::Generators::table<const char*, int>({
|
||||||
|
{"hello world", 0x6aefe2c4},
|
||||||
|
{"universe2", 0xe796fe8d},
|
||||||
|
{"lit_r0c0n0x0_b1c1n1s1v1_b2c2n2x2", 0x16c4d3f1},
|
||||||
|
{"AngularVelocityScale", 0x573e9feb},
|
||||||
|
{"BakedLightingIntensity", 0x15af785c},
|
||||||
|
{"Layer1OffsetBobbleDelay", 0xfb83324a},
|
||||||
|
{"MaxDepth", 0x1892e3df},
|
||||||
|
{"MomentumColor", 0x5e7abdcb},
|
||||||
|
{"SparkleScale", 0x9e4409f4},
|
||||||
|
{"TickMarkColorAndHarshness", 0x5dfe4c47},
|
||||||
|
{"worldViewProjectionMatrix", 0xa2501a07},
|
||||||
|
}));
|
||||||
|
|
||||||
|
CAPTURE(str);
|
||||||
|
const auto hash = IW5::Common::StringTable_HashString(str);
|
||||||
|
REQUIRE(hash == expectedHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("for R_HashString")
|
||||||
|
{
|
||||||
|
const auto [str, expectedHash] = GENERATE(Catch::Generators::table<const char*, uint32_t>({
|
||||||
|
{"hello world", 0xe7d74060},
|
||||||
|
{"universe2", 0x113fdcd7},
|
||||||
|
{"lit_r0c0n0x0_b1c1n1s1v1_b2c2n2x2", 0xdd0153c5},
|
||||||
|
{"AngularVelocityScale", 0x18f2cb6d},
|
||||||
|
{"BakedLightingIntensity", 0xd627f218},
|
||||||
|
{"Layer1OffsetBobbleDelay", 0xcd91b6ae},
|
||||||
|
{"MaxDepth", 0x61ed5959},
|
||||||
|
{"MomentumColor", 0xc80f3595},
|
||||||
|
{"SparkleScale", 0x5488816a},
|
||||||
|
{"TickMarkColorAndHarshness", 0xd6c718bd},
|
||||||
|
{"worldViewProjectionMatrix", 0x7f661409},
|
||||||
|
}));
|
||||||
|
|
||||||
|
CAPTURE(str);
|
||||||
|
const auto hash = IW5::Common::R_HashString(str);
|
||||||
|
REQUIRE(hash == expectedHash);
|
||||||
|
}
|
||||||
|
}
|
||||||
70
test/CommonTests/Game/T5/CommonT5Tests.cpp
Normal file
70
test/CommonTests/Game/T5/CommonT5Tests.cpp
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
#include "Game/T5/CommonT5.h"
|
||||||
|
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
#include <catch2/generators/catch_generators.hpp>
|
||||||
|
|
||||||
|
TEST_CASE("T5: Check checksums", "[t5]")
|
||||||
|
{
|
||||||
|
SECTION("for Com_HashKey")
|
||||||
|
{
|
||||||
|
const auto [str, expectedHash] = GENERATE(Catch::Generators::table<const char*, int>({
|
||||||
|
{"hello world", 0x21c3f},
|
||||||
|
{"universe2", 0x1be55},
|
||||||
|
{"lit_r0c0n0x0_b1c1n1s1v1_b2c2n2x2", 0x56e0f},
|
||||||
|
{"AngularVelocityScale", 0x4043a},
|
||||||
|
{"BakedLightingIntensity", 0x47a5c},
|
||||||
|
{"Layer1OffsetBobbleDelay", 0x47950},
|
||||||
|
{"MaxDepth", 0x17ca1},
|
||||||
|
{"MomentumColor", 0x2998e},
|
||||||
|
{"SparkleScale", 0x24cea},
|
||||||
|
{"TickMarkColorAndHarshness", 0x50d40},
|
||||||
|
{"worldViewProjectionMatrix", 0x548c4},
|
||||||
|
}));
|
||||||
|
|
||||||
|
CAPTURE(str);
|
||||||
|
const auto hash = T5::Common::Com_HashKey(str, 64);
|
||||||
|
REQUIRE(hash == expectedHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("for Com_HashString")
|
||||||
|
{
|
||||||
|
const auto [str, expectedHash] = GENERATE(Catch::Generators::table<const char*, int>({
|
||||||
|
{"hello world", 0x3551c8c1},
|
||||||
|
{"universe2", 0x608d72a8},
|
||||||
|
{"lit_r0c0n0x0_b1c1n1s1v1_b2c2n2x2", 0xf93c46aa},
|
||||||
|
{"AngularVelocityScale", 0x2eb08fc6},
|
||||||
|
{"BakedLightingIntensity", 0xd8fd95b9},
|
||||||
|
{"Layer1OffsetBobbleDelay", 0x4166172f},
|
||||||
|
{"MaxDepth", 0x5dc1dee0},
|
||||||
|
{"MomentumColor", 0x21c79416},
|
||||||
|
{"SparkleScale", 0x42f7ecdf},
|
||||||
|
{"TickMarkColorAndHarshness", 0xbb5761dc},
|
||||||
|
{"worldViewProjectionMatrix", 0x25962bfa},
|
||||||
|
}));
|
||||||
|
|
||||||
|
CAPTURE(str);
|
||||||
|
const auto hash = T5::Common::Com_HashString(str);
|
||||||
|
REQUIRE(hash == expectedHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("for R_HashString")
|
||||||
|
{
|
||||||
|
const auto [str, expectedHash] = GENERATE(Catch::Generators::table<const char*, uint32_t>({
|
||||||
|
{"hello world", 0xe7d74060},
|
||||||
|
{"universe2", 0x113fdcd7},
|
||||||
|
{"lit_r0c0n0x0_b1c1n1s1v1_b2c2n2x2", 0xdd0153c5},
|
||||||
|
{"AngularVelocityScale", 0x18f2cb6d},
|
||||||
|
{"BakedLightingIntensity", 0xd627f218},
|
||||||
|
{"Layer1OffsetBobbleDelay", 0xcd91b6ae},
|
||||||
|
{"MaxDepth", 0x61ed5959},
|
||||||
|
{"MomentumColor", 0xc80f3595},
|
||||||
|
{"SparkleScale", 0x5488816a},
|
||||||
|
{"TickMarkColorAndHarshness", 0xd6c718bd},
|
||||||
|
{"worldViewProjectionMatrix", 0x7f661409},
|
||||||
|
}));
|
||||||
|
|
||||||
|
CAPTURE(str);
|
||||||
|
const auto hash = T5::Common::R_HashString(str);
|
||||||
|
REQUIRE(hash == expectedHash);
|
||||||
|
}
|
||||||
|
}
|
||||||
91
test/CommonTests/Game/T6/CommonT6Tests.cpp
Normal file
91
test/CommonTests/Game/T6/CommonT6Tests.cpp
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
#include "Game/T6/CommonT6.h"
|
||||||
|
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
#include <catch2/generators/catch_generators.hpp>
|
||||||
|
|
||||||
|
TEST_CASE("T6: Check checksums", "[t6]")
|
||||||
|
{
|
||||||
|
SECTION("for Com_HashKey")
|
||||||
|
{
|
||||||
|
const auto [str, expectedHash] = GENERATE(Catch::Generators::table<const char*, int>({
|
||||||
|
{"hello world", 0x21c3f},
|
||||||
|
{"universe2", 0x1be55},
|
||||||
|
{"lit_r0c0n0x0_b1c1n1s1v1_b2c2n2x2", 0x56e0f},
|
||||||
|
{"AngularVelocityScale", 0x4043a},
|
||||||
|
{"BakedLightingIntensity", 0x47a5c},
|
||||||
|
{"Layer1OffsetBobbleDelay", 0x47950},
|
||||||
|
{"MaxDepth", 0x17ca1},
|
||||||
|
{"MomentumColor", 0x2998e},
|
||||||
|
{"SparkleScale", 0x24cea},
|
||||||
|
{"TickMarkColorAndHarshness", 0x50d40},
|
||||||
|
{"worldViewProjectionMatrix", 0x548c4},
|
||||||
|
}));
|
||||||
|
|
||||||
|
CAPTURE(str);
|
||||||
|
const auto hash = T6::Common::Com_HashKey(str, 64);
|
||||||
|
REQUIRE(hash == expectedHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("for Com_HashString")
|
||||||
|
{
|
||||||
|
const auto [str, expectedHash] = GENERATE(Catch::Generators::table<const char*, int>({
|
||||||
|
{"hello world", 0x3551c8c1},
|
||||||
|
{"universe2", 0x608d72a8},
|
||||||
|
{"lit_r0c0n0x0_b1c1n1s1v1_b2c2n2x2", 0xf93c46aa},
|
||||||
|
{"AngularVelocityScale", 0x2eb08fc6},
|
||||||
|
{"BakedLightingIntensity", 0xd8fd95b9},
|
||||||
|
{"Layer1OffsetBobbleDelay", 0x4166172f},
|
||||||
|
{"MaxDepth", 0x5dc1dee0},
|
||||||
|
{"MomentumColor", 0x21c79416},
|
||||||
|
{"SparkleScale", 0x42f7ecdf},
|
||||||
|
{"TickMarkColorAndHarshness", 0xbb5761dc},
|
||||||
|
{"worldViewProjectionMatrix", 0x25962bfa},
|
||||||
|
}));
|
||||||
|
|
||||||
|
CAPTURE(str);
|
||||||
|
const auto hash = T6::Common::Com_HashString(str);
|
||||||
|
REQUIRE(hash == expectedHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("for R_HashString")
|
||||||
|
{
|
||||||
|
const auto [str, expectedHash] = GENERATE(Catch::Generators::table<const char*, uint32_t>({
|
||||||
|
{"hello world", 0xe7d74060},
|
||||||
|
{"universe2", 0x113fdcd7},
|
||||||
|
{"lit_r0c0n0x0_b1c1n1s1v1_b2c2n2x2", 0xdd0153c5},
|
||||||
|
{"AngularVelocityScale", 0x18f2cb6d},
|
||||||
|
{"BakedLightingIntensity", 0xd627f218},
|
||||||
|
{"Layer1OffsetBobbleDelay", 0xcd91b6ae},
|
||||||
|
{"MaxDepth", 0x61ed5959},
|
||||||
|
{"MomentumColor", 0xc80f3595},
|
||||||
|
{"SparkleScale", 0x5488816a},
|
||||||
|
{"TickMarkColorAndHarshness", 0xd6c718bd},
|
||||||
|
{"worldViewProjectionMatrix", 0x7f661409},
|
||||||
|
}));
|
||||||
|
|
||||||
|
CAPTURE(str);
|
||||||
|
const auto hash = T6::Common::R_HashString(str);
|
||||||
|
REQUIRE(hash == expectedHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("for SND_HashName")
|
||||||
|
{
|
||||||
|
const auto [str, expectedHash] = GENERATE(Catch::Generators::table<const char*, uint32_t>({
|
||||||
|
{"hello world", 0x9e420d7f},
|
||||||
|
{"universe2", 0xee605328},
|
||||||
|
{"lit_r0c0n0x0_b1c1n1s1v1_b2c2n2x2", 0xc38575b6},
|
||||||
|
{"AngularVelocityScale", 0x0c032bd0},
|
||||||
|
{"BakedLightingIntensity", 0x57f1a221},
|
||||||
|
{"Layer1OffsetBobbleDelay", 0x4f640b85},
|
||||||
|
{"MaxDepth", 0x50d1cae4},
|
||||||
|
{"MomentumColor", 0xbcab7666},
|
||||||
|
{"SparkleScale", 0x162259d9},
|
||||||
|
{"TickMarkColorAndHarshness", 0xbf3d7a42},
|
||||||
|
{"worldViewProjectionMatrix", 0x28db35e2},
|
||||||
|
}));
|
||||||
|
|
||||||
|
CAPTURE(str);
|
||||||
|
const auto hash = T6::Common::SND_HashName(str);
|
||||||
|
REQUIRE(hash == expectedHash);
|
||||||
|
}
|
||||||
|
}
|
||||||
133
test/CommonTests/Utils/Djb2Tests.cpp
Normal file
133
test/CommonTests/Utils/Djb2Tests.cpp
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
#include "Utils/Djb2.h"
|
||||||
|
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
#include <catch2/generators/catch_generators.hpp>
|
||||||
|
|
||||||
|
TEST_CASE("Djb2: Check checksums", "[djb2]")
|
||||||
|
{
|
||||||
|
SECTION("for djb2")
|
||||||
|
{
|
||||||
|
const auto [str, expectedHash] = GENERATE(Catch::Generators::table<const char*, uint32_t>({
|
||||||
|
{"hello world", 0x3551c8c1},
|
||||||
|
{"universe2", 0x608d72a8},
|
||||||
|
{"lit_r0c0n0x0_b1c1n1s1v1_b2c2n2x2", 0xf93c46aa},
|
||||||
|
{"AngularVelocityScale", 0xbba68366},
|
||||||
|
{"BakedLightingIntensity", 0x98a9e159},
|
||||||
|
{"Layer1OffsetBobbleDelay", 0x319c46af},
|
||||||
|
{"MaxDepth", 0xd34432a0},
|
||||||
|
{"MomentumColor", 0x33a353d6},
|
||||||
|
{"SparkleScale", 0x2249309f},
|
||||||
|
{"TickMarkColorAndHarshness", 0x0d77a53c},
|
||||||
|
{"worldViewProjectionMatrix", 0xcf668f9a},
|
||||||
|
}));
|
||||||
|
|
||||||
|
CAPTURE(str);
|
||||||
|
const auto hash = djb2(str);
|
||||||
|
REQUIRE(hash == expectedHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("for djb2_nocase")
|
||||||
|
{
|
||||||
|
const auto [str, expectedHash] = GENERATE(Catch::Generators::table<const char*, uint32_t>({
|
||||||
|
{"hello world", 0x3551c8c1},
|
||||||
|
{"universe2", 0x608d72a8},
|
||||||
|
{"lit_r0c0n0x0_b1c1n1s1v1_b2c2n2x2", 0xd12da30a},
|
||||||
|
{"AngularVelocityScale", 0x2eb08fc6},
|
||||||
|
{"BakedLightingIntensity", 0xd8fd95b9},
|
||||||
|
{"Layer1OffsetBobbleDelay", 0x4166172f},
|
||||||
|
{"MaxDepth", 0x5dc1dee0},
|
||||||
|
{"MomentumColor", 0x21c79416},
|
||||||
|
{"SparkleScale", 0x42f7ecdf},
|
||||||
|
{"TickMarkColorAndHarshness", 0xbb5761dc},
|
||||||
|
{"worldViewProjectionMatrix", 0x25962bfa},
|
||||||
|
}));
|
||||||
|
|
||||||
|
CAPTURE(str);
|
||||||
|
const auto hash = djb2_nocase(str);
|
||||||
|
REQUIRE(hash == expectedHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("for djb2_lower")
|
||||||
|
{
|
||||||
|
const auto [str, expectedHash] = GENERATE(Catch::Generators::table<const char*, uint32_t>({
|
||||||
|
{"hello world", 0x3551c8c1},
|
||||||
|
{"universe2", 0x608d72a8},
|
||||||
|
{"lit_r0c0n0x0_b1c1n1s1v1_b2c2n2x2", 0xf93c46aa},
|
||||||
|
{"AngularVelocityScale", 0x2eb08fc6},
|
||||||
|
{"BakedLightingIntensity", 0xd8fd95b9},
|
||||||
|
{"Layer1OffsetBobbleDelay", 0x4166172f},
|
||||||
|
{"MaxDepth", 0x5dc1dee0},
|
||||||
|
{"MomentumColor", 0x21c79416},
|
||||||
|
{"SparkleScale", 0x42f7ecdf},
|
||||||
|
{"TickMarkColorAndHarshness", 0xbb5761dc},
|
||||||
|
{"worldViewProjectionMatrix", 0x25962bfa},
|
||||||
|
}));
|
||||||
|
|
||||||
|
CAPTURE(str);
|
||||||
|
const auto hash = djb2_lower(str);
|
||||||
|
REQUIRE(hash == expectedHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("for djb2_xor")
|
||||||
|
{
|
||||||
|
const auto [str, expectedHash] = GENERATE(Catch::Generators::table<const char*, uint32_t>({
|
||||||
|
{"hello world", 0xf8c65345},
|
||||||
|
{"universe2", 0xdce33172},
|
||||||
|
{"lit_r0c0n0x0_b1c1n1s1v1_b2c2n2x2", 0x7e4ed3e0},
|
||||||
|
{"AngularVelocityScale", 0xf65bbb88},
|
||||||
|
{"BakedLightingIntensity", 0xd79467bd},
|
||||||
|
{"Layer1OffsetBobbleDelay", 0xf033afcb},
|
||||||
|
{"MaxDepth", 0x190e08dc},
|
||||||
|
{"MomentumColor", 0xf4ded370},
|
||||||
|
{"SparkleScale", 0x9358a5ef},
|
||||||
|
{"TickMarkColorAndHarshness", 0x12d2e5f8},
|
||||||
|
{"worldViewProjectionMatrix", 0x88669e4c},
|
||||||
|
}));
|
||||||
|
|
||||||
|
CAPTURE(str);
|
||||||
|
const auto hash = djb2_xor(str);
|
||||||
|
REQUIRE(hash == expectedHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("for djb2_xor_nocase")
|
||||||
|
{
|
||||||
|
const auto [str, expectedHash] = GENERATE(Catch::Generators::table<const char*, uint32_t>({
|
||||||
|
{"hello world", 0xf8c65345},
|
||||||
|
{"universe2", 0xdce33172},
|
||||||
|
{"lit_r0c0n0x0_b1c1n1s1v1_b2c2n2x2", 0x3cc06840},
|
||||||
|
{"AngularVelocityScale", 0x7efc36a8},
|
||||||
|
{"BakedLightingIntensity", 0x3d52c39d},
|
||||||
|
{"Layer1OffsetBobbleDelay", 0x48574d8b},
|
||||||
|
{"MaxDepth", 0x3c5b84dc},
|
||||||
|
{"MomentumColor", 0x4d32f230},
|
||||||
|
{"SparkleScale", 0x7656c02f},
|
||||||
|
{"TickMarkColorAndHarshness", 0x917d8218},
|
||||||
|
{"worldViewProjectionMatrix", 0x721c412c},
|
||||||
|
}));
|
||||||
|
|
||||||
|
CAPTURE(str);
|
||||||
|
const auto hash = djb2_xor_nocase(str);
|
||||||
|
REQUIRE(hash == expectedHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("for djb2_xor_lower")
|
||||||
|
{
|
||||||
|
const auto [str, expectedHash] = GENERATE(Catch::Generators::table<const char*, uint32_t>({
|
||||||
|
{"hello world", 0xf8c65345},
|
||||||
|
{"universe2", 0xdce33172},
|
||||||
|
{"lit_r0c0n0x0_b1c1n1s1v1_b2c2n2x2", 0x7e4ed3e0},
|
||||||
|
{"AngularVelocityScale", 0x7efc36a8},
|
||||||
|
{"BakedLightingIntensity", 0x3d52c39d},
|
||||||
|
{"Layer1OffsetBobbleDelay", 0x48574d8b},
|
||||||
|
{"MaxDepth", 0x3c5b84dc},
|
||||||
|
{"MomentumColor", 0x4d32f230},
|
||||||
|
{"SparkleScale", 0x7656c02f},
|
||||||
|
{"TickMarkColorAndHarshness", 0x917d8218},
|
||||||
|
{"worldViewProjectionMatrix", 0x721c412c},
|
||||||
|
}));
|
||||||
|
|
||||||
|
CAPTURE(str);
|
||||||
|
const auto hash = djb2_xor_lower(str);
|
||||||
|
REQUIRE(hash == expectedHash);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user