// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using EpicGames.Core;
namespace EpicGames.UHT.Utils
{
///
/// Support for generating hash values using the existing UHT algorithms
///
public struct UhtHash
{
private ulong _hash;
///
/// Start the hash computation
///
public void Begin()
{
_hash = 0;
}
///
/// Add a span of text to the current hash value
///
///
public void Add(ReadOnlySpan text)
{
while (text.Length != 0)
{
int crPos = text.IndexOf('\r');
if (crPos == -1)
{
HashText(text[..]);
break;
}
else
{
HashText(text[..crPos]);
text = text[(crPos + 1)..];
}
}
}
///
/// Return the final hash value
///
/// Final hash value
public readonly uint End()
{
return (uint)(_hash + (_hash >> 32));
}
///
/// Generate the hash value for a block of text
///
/// Text to hash
/// Hash value
public static uint GenenerateTextHash(ReadOnlySpan text)
{
UhtHash hash = new();
hash.Begin();
hash.Add(text);
return hash.End();
}
private void HashText(ReadOnlySpan text)
{
if (text.Length > 0)
{
unsafe
{
fixed (char* textPtr = text)
{
_hash = CityHash.CityHash64WithSeed((byte*)textPtr, (uint)(text.Length * sizeof(char)), _hash);
}
}
}
}
}
}