From a5903f95bca586083c9a8ec41a02a4be8196376f Mon Sep 17 00:00:00 2001 From: Martin Benjamins Date: Tue, 9 Jul 2024 14:17:45 +0200 Subject: [PATCH 1/2] Add cache for extension reflecting --- Warcraft.NET/Extensions/ReflectionExtensions.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Warcraft.NET/Extensions/ReflectionExtensions.cs b/Warcraft.NET/Extensions/ReflectionExtensions.cs index ad94bf6..a5f9317 100644 --- a/Warcraft.NET/Extensions/ReflectionExtensions.cs +++ b/Warcraft.NET/Extensions/ReflectionExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -7,6 +8,8 @@ namespace Warcraft.NET.Extensions { public static class ReflectionExtensions { + private static ConcurrentDictionary extensionMethodCache = new(); + /// /// Get all extension methods by Assembly /// @@ -27,7 +30,19 @@ where m.GetParameters()[0].ParameterType == type public static MethodInfo GetExtensionMethod(this Type type, Assembly extensionsAssembly, string name) { - return type.GetExtensionMethods(extensionsAssembly).FirstOrDefault(m => m.Name == name); + // This is a bit dirty, but it allows us to cache the MethodInfo for future use as reflecting is very expensive. + var uniqueKey = type.ToString() + "-" + extensionsAssembly.ToString() + "-" + name; + + if (extensionMethodCache.TryGetValue(uniqueKey, out var cachedMethodInfo)) + { + return cachedMethodInfo; + } + else + { + var methodInfo = type.GetExtensionMethods(extensionsAssembly).FirstOrDefault(m => m.Name == name); + extensionMethodCache.TryAdd(uniqueKey, methodInfo); + return methodInfo; + } } /// From 7695ed9d2dfbf9ff6b8ee3b246abe5e1b39e6184 Mon Sep 17 00:00:00 2001 From: Martin Benjamins Date: Tue, 9 Jul 2024 14:23:00 +0200 Subject: [PATCH 2/2] Fix typo & EndOfStream exceptions --- Warcraft.NET/Extensions/ExtendedIO.cs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/Warcraft.NET/Extensions/ExtendedIO.cs b/Warcraft.NET/Extensions/ExtendedIO.cs index 575e8c5..a76ba06 100644 --- a/Warcraft.NET/Extensions/ExtendedIO.cs +++ b/Warcraft.NET/Extensions/ExtendedIO.cs @@ -645,15 +645,25 @@ public static bool SeekChunk(this BinaryReader reader, string chunkSignature, bo try { - var foundChuckSignature = reader.ReadBinarySignature(reverseSignature); - while (foundChuckSignature != chunkSignature) + var foundChunkSignature = reader.ReadBinarySignature(reverseSignature); + while (foundChunkSignature != chunkSignature) { var size = reader.ReadUInt32(); + + // Return if we are about to seek outside of range + if ((reader.BaseStream.Position + size) > reader.BaseStream.Length) + return false; + reader.BaseStream.Position += size; - foundChuckSignature = reader.ReadBinarySignature(reverseSignature); + + // Return if we're done reading + if (reader.BaseStream.Position == reader.BaseStream.Length) + return false; + + foundChunkSignature = reader.ReadBinarySignature(reverseSignature); } - if (foundChuckSignature == chunkSignature) + if (foundChunkSignature == chunkSignature) { if (!skipSignature) reader.BaseStream.Position -= sizeof(uint);