mirror of
https://github.com/godotengine/godot.git
synced 2024-11-25 13:43:15 +00:00
Fix platform-dependent hashing for char* and wchar_t*
Since char/wchar_t can be either signed or unsigned, its conversion to uint32_t leads to different values depending on platform. In particular, the same string represented as char* (Latin-1; StringName direct construction) or uint32_t (UTF-8; constructed via String) previously resulted in different hashes.
This commit is contained in:
parent
ed3015e979
commit
43be9fa0c8
@ -2763,12 +2763,13 @@ double String::to_float() const {
|
||||
}
|
||||
|
||||
uint32_t String::hash(const char *p_cstr) {
|
||||
// static_cast: avoid negative values on platforms where char is signed.
|
||||
uint32_t hashv = 5381;
|
||||
uint32_t c = *p_cstr++;
|
||||
uint32_t c = static_cast<uint8_t>(*p_cstr++);
|
||||
|
||||
while (c) {
|
||||
hashv = ((hashv << 5) + hashv) + c; /* hash * 33 + c */
|
||||
c = *p_cstr++;
|
||||
c = static_cast<uint8_t>(*p_cstr++);
|
||||
}
|
||||
|
||||
return hashv;
|
||||
@ -2777,28 +2778,35 @@ uint32_t String::hash(const char *p_cstr) {
|
||||
uint32_t String::hash(const char *p_cstr, int p_len) {
|
||||
uint32_t hashv = 5381;
|
||||
for (int i = 0; i < p_len; i++) {
|
||||
hashv = ((hashv << 5) + hashv) + p_cstr[i]; /* hash * 33 + c */
|
||||
// static_cast: avoid negative values on platforms where char is signed.
|
||||
hashv = ((hashv << 5) + hashv) + static_cast<uint8_t>(p_cstr[i]); /* hash * 33 + c */
|
||||
}
|
||||
|
||||
return hashv;
|
||||
}
|
||||
|
||||
uint32_t String::hash(const wchar_t *p_cstr, int p_len) {
|
||||
// Avoid negative values on platforms where wchar_t is signed. Account for different sizes.
|
||||
using wide_unsigned = std::conditional<sizeof(wchar_t) == 2, uint16_t, uint32_t>::type;
|
||||
|
||||
uint32_t hashv = 5381;
|
||||
for (int i = 0; i < p_len; i++) {
|
||||
hashv = ((hashv << 5) + hashv) + p_cstr[i]; /* hash * 33 + c */
|
||||
hashv = ((hashv << 5) + hashv) + static_cast<wide_unsigned>(p_cstr[i]); /* hash * 33 + c */
|
||||
}
|
||||
|
||||
return hashv;
|
||||
}
|
||||
|
||||
uint32_t String::hash(const wchar_t *p_cstr) {
|
||||
// Avoid negative values on platforms where wchar_t is signed. Account for different sizes.
|
||||
using wide_unsigned = std::conditional<sizeof(wchar_t) == 2, uint16_t, uint32_t>::type;
|
||||
|
||||
uint32_t hashv = 5381;
|
||||
uint32_t c = *p_cstr++;
|
||||
uint32_t c = static_cast<wide_unsigned>(*p_cstr++);
|
||||
|
||||
while (c) {
|
||||
hashv = ((hashv << 5) + hashv) + c; /* hash * 33 + c */
|
||||
c = *p_cstr++;
|
||||
c = static_cast<wide_unsigned>(*p_cstr++);
|
||||
}
|
||||
|
||||
return hashv;
|
||||
|
Loading…
Reference in New Issue
Block a user