2020-11-01 17:45:45 -06:00
|
|
|
#include "storm/String.hpp"
|
|
|
|
|
#include "storm/Error.hpp"
|
2020-11-14 17:18:49 -06:00
|
|
|
#include "storm/string/bjhash.hpp"
|
2020-11-14 17:58:34 -06:00
|
|
|
#include <cstring>
|
2020-11-15 12:47:41 -06:00
|
|
|
#include <strings.h>
|
2020-11-14 17:18:49 -06:00
|
|
|
|
|
|
|
|
uint8_t bytesFromUTF8[256] = {
|
|
|
|
|
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
|
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
|
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
|
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
|
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
|
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
|
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
|
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
|
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
|
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
|
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
|
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
|
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
|
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
|
|
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
|
|
|
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
uint32_t offsetsFromUTF8[8] = {
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0x3080,
|
|
|
|
|
0x0E2080,
|
|
|
|
|
0x3C82080,
|
|
|
|
|
0x0FA082080,
|
|
|
|
|
0x82082080,
|
|
|
|
|
0
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void GetNextTextUpper(uint32_t* orig, const char** string, uint32_t* upper) {
|
|
|
|
|
uint8_t byte = **string;
|
|
|
|
|
int32_t v3 = bytesFromUTF8[byte];
|
|
|
|
|
|
|
|
|
|
*orig = 0;
|
|
|
|
|
*upper = 0;
|
|
|
|
|
|
|
|
|
|
switch (v3) {
|
|
|
|
|
case 6:
|
|
|
|
|
case 5:
|
|
|
|
|
case 4:
|
|
|
|
|
case 3:
|
|
|
|
|
case 2:
|
|
|
|
|
*orig += **string;
|
|
|
|
|
(*string)++;
|
|
|
|
|
|
|
|
|
|
if (!**string) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*orig <<= 6;
|
|
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
|
*orig += **string;
|
|
|
|
|
(*string)++;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
*orig -= offsetsFromUTF8[v3];
|
|
|
|
|
|
|
|
|
|
if (*orig > 0xFFFF) {
|
|
|
|
|
*orig = 0xFFFF;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t v4 = *orig;
|
|
|
|
|
|
|
|
|
|
bool v5, v6;
|
|
|
|
|
|
|
|
|
|
if (v3 == 1) {
|
|
|
|
|
if (v4 < 0x61) {
|
|
|
|
|
*upper = v4;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
v5 = v4 < 0x7A;
|
|
|
|
|
v6 = v4 == 122;
|
|
|
|
|
|
|
|
|
|
if (!v5 && !v6) {
|
|
|
|
|
*upper = v4;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
v4 -= 32;
|
|
|
|
|
*upper = v4;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (v3 != 2) {
|
|
|
|
|
*upper = v4;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (v4 >= 0xE0 && v4 <= 0xFE) {
|
|
|
|
|
v4 -= 32;
|
|
|
|
|
*upper = v4;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (v4 == 339) {
|
|
|
|
|
*upper = 338;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (v4 == 1105) {
|
|
|
|
|
*upper = 1025;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (v4 >= 0x430) {
|
|
|
|
|
v5 = v4 < 0x44F;
|
|
|
|
|
v6 = v4 == 1103;
|
|
|
|
|
|
|
|
|
|
if (!v5 && !v6) {
|
|
|
|
|
*upper = v4;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
v4 -= 32;
|
|
|
|
|
*upper = v4;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*upper = v4;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-08 21:37:30 -05:00
|
|
|
|
2020-11-14 17:58:34 -06:00
|
|
|
int32_t SStrCmp(const char* string1, const char* string2, size_t maxchars) {
|
|
|
|
|
return strncmp(string1, string2, maxchars);
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-15 12:47:41 -06:00
|
|
|
int32_t SStrCmpI(const char* string1, const char* string2, size_t maxchars) {
|
|
|
|
|
return strncasecmp(string1, string2, maxchars);
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-08 21:37:30 -05:00
|
|
|
size_t SStrCopy(char* dest, const char* source, size_t destsize) {
|
|
|
|
|
STORM_ASSERT(dest);
|
|
|
|
|
STORM_ASSERT(source);
|
|
|
|
|
|
|
|
|
|
char* destbuf = dest;
|
|
|
|
|
|
2020-11-14 17:47:10 -06:00
|
|
|
if (destsize == STORM_MAX_STR) {
|
2020-09-08 21:37:30 -05:00
|
|
|
while (*source) {
|
|
|
|
|
*destbuf = *source;
|
|
|
|
|
|
|
|
|
|
++destbuf;
|
|
|
|
|
++source;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (*source) {
|
|
|
|
|
while (destbuf < &dest[destsize - 1]) {
|
|
|
|
|
*destbuf = *source;
|
|
|
|
|
|
|
|
|
|
++destbuf;
|
|
|
|
|
++source;
|
|
|
|
|
|
|
|
|
|
if (!*source) {
|
|
|
|
|
*destbuf = '\0';
|
|
|
|
|
return static_cast<size_t>(destbuf - dest);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*destbuf = '\0';
|
|
|
|
|
return static_cast<size_t>(destbuf - dest);
|
|
|
|
|
}
|
2020-11-14 17:18:49 -06:00
|
|
|
|
|
|
|
|
uint32_t SStrHashHT(const char* string) {
|
|
|
|
|
char normalized[0x400];
|
|
|
|
|
char* buf = normalized;
|
|
|
|
|
|
|
|
|
|
uint32_t length = 0;
|
|
|
|
|
|
|
|
|
|
if (*string) {
|
|
|
|
|
uint32_t value, orig, upper;
|
|
|
|
|
|
|
|
|
|
while (*string && length <= 0x3FB) {
|
|
|
|
|
// Convert each character to uppercase
|
|
|
|
|
GetNextTextUpper(&orig, &string, &upper);
|
|
|
|
|
|
|
|
|
|
// Replace forward slash with back slash
|
|
|
|
|
value = upper == '/' ? '\\' : upper;
|
|
|
|
|
|
|
|
|
|
while (value) {
|
|
|
|
|
*buf = value;
|
|
|
|
|
value >>= 8;
|
|
|
|
|
length++;
|
|
|
|
|
buf++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ensure string is terminated
|
|
|
|
|
*buf = 0;
|
|
|
|
|
|
|
|
|
|
return bjhash((uint8_t*)&normalized, length, 0);
|
|
|
|
|
}
|