refactor: move FastByteArrayCompare from ChatGui to Util

This commit is contained in:
goaaats 2022-01-27 01:22:57 +01:00
parent c232befd83
commit a4ce3d0688
No known key found for this signature in database
GPG key ID: F18F057873895461
2 changed files with 57 additions and 50 deletions

View file

@ -11,6 +11,7 @@ using Dalamud.Game.Text.SeStringHandling.Payloads;
using Dalamud.Hooking;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Utility;
using Serilog;
namespace Dalamud.Game.Gui
@ -283,52 +284,6 @@ namespace Dalamud.Game.Gui
}
}
private static unsafe bool FastByteArrayCompare(byte[] a1, byte[] a2)
{
// Copyright (c) 2008-2013 Hafthor Stefansson
// Distributed under the MIT/X11 software license
// Ref: http://www.opensource.org/licenses/mit-license.php.
// https://stackoverflow.com/a/8808245
if (a1 == a2) return true;
if (a1 == null || a2 == null || a1.Length != a2.Length)
return false;
fixed (byte* p1 = a1, p2 = a2)
{
byte* x1 = p1, x2 = p2;
var l = a1.Length;
for (var i = 0; i < l / 8; i++, x1 += 8, x2 += 8)
{
if (*((long*)x1) != *((long*)x2))
return false;
}
if ((l & 4) != 0)
{
if (*((int*)x1) != *((int*)x2))
return false;
x1 += 4;
x2 += 4;
}
if ((l & 2) != 0)
{
if (*((short*)x1) != *((short*)x2))
return false;
x1 += 2;
x2 += 2;
}
if ((l & 1) != 0)
{
if (*((byte*)x1) != *((byte*)x2))
return false;
}
return true;
}
}
private void HandlePopulateItemLinkDetour(IntPtr linkObjectPtr, IntPtr itemInfoPtr)
{
try
@ -381,14 +336,14 @@ namespace Dalamud.Game.Gui
}
var newEdited = parsedMessage.Encode();
if (!FastByteArrayCompare(oldEdited, newEdited))
if (!Util.FastByteArrayCompare(oldEdited, newEdited))
{
Log.Verbose("SeString was edited, taking precedence over StdString edit.");
message.RawData = newEdited;
// Log.Debug($"\nOLD: {BitConverter.ToString(originalMessageData)}\nNEW: {BitConverter.ToString(newEdited)}");
}
if (!FastByteArrayCompare(originalMessageData, message.RawData))
if (!Util.FastByteArrayCompare(originalMessageData, message.RawData))
{
allocatedString = Service<LibcFunction>.Get().NewString(message.RawData);
Log.Debug($"HandlePrintMessageDetour String modified: {originalMessageData}({messagePtr}) -> {message}({allocatedString.Address})");
@ -396,14 +351,14 @@ namespace Dalamud.Game.Gui
}
var newEditedSender = parsedSender.Encode();
if (!FastByteArrayCompare(oldEditedSender, newEditedSender))
if (!Util.FastByteArrayCompare(oldEditedSender, newEditedSender))
{
Log.Verbose("SeString was edited, taking precedence over StdString edit.");
sender.RawData = newEditedSender;
// Log.Debug($"\nOLD: {BitConverter.ToString(originalMessageData)}\nNEW: {BitConverter.ToString(newEdited)}");
}
if (!FastByteArrayCompare(originalSenderData, sender.RawData))
if (!Util.FastByteArrayCompare(originalSenderData, sender.RawData))
{
allocatedStringSender = Service<LibcFunction>.Get().NewString(sender.RawData);
Log.Debug(

View file

@ -44,6 +44,58 @@ namespace Dalamud.Utility
/// </summary>
public static string AssemblyVersion { get; } = Assembly.GetAssembly(typeof(ChatHandlers)).GetName().Version.ToString();
/// <summary>
/// Check two byte arrays for equality.
/// </summary>
/// <param name="a1">The first byte array.</param>
/// <param name="a2">The second byte array.</param>
/// <returns>Whether or not the byte arrays are equal.</returns>
public static unsafe bool FastByteArrayCompare(byte[]? a1, byte[]? a2)
{
// Copyright (c) 2008-2013 Hafthor Stefansson
// Distributed under the MIT/X11 software license
// Ref: http://www.opensource.org/licenses/mit-license.php.
// https://stackoverflow.com/a/8808245
if (a1 == a2) return true;
if (a1 == null || a2 == null || a1.Length != a2.Length)
return false;
fixed (byte* p1 = a1, p2 = a2)
{
byte* x1 = p1, x2 = p2;
var l = a1.Length;
for (var i = 0; i < l / 8; i++, x1 += 8, x2 += 8)
{
if (*((long*)x1) != *((long*)x2))
return false;
}
if ((l & 4) != 0)
{
if (*((int*)x1) != *((int*)x2))
return false;
x1 += 4;
x2 += 4;
}
if ((l & 2) != 0)
{
if (*((short*)x1) != *((short*)x2))
return false;
x1 += 2;
x2 += 2;
}
if ((l & 1) != 0)
{
if (*((byte*)x1) != *((byte*)x2))
return false;
}
return true;
}
}
/// <summary>
/// Gets the git hash value from the assembly
/// or null if it cannot be found.