mirror of
https://github.com/SabreTools/SabreTools.Matching.git
synced 2026-02-06 13:47:33 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e96790d875 | ||
|
|
bf23967f74 | ||
|
|
8debf24a44 | ||
|
|
333b5be76c | ||
|
|
b0fdff2d6e | ||
|
|
3b0e74b9f4 |
Binary file not shown.
44
SabreTools.Matching.Test/MatchUtilTests.cs
Normal file
44
SabreTools.Matching.Test/MatchUtilTests.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using SabreTools.Matching.Content;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Matching.Test
|
||||
{
|
||||
public class MatchUtilTests
|
||||
{
|
||||
[Fact]
|
||||
public void ExactSizeArrayMatch()
|
||||
{
|
||||
byte[] source = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07];
|
||||
byte?[] check = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07];
|
||||
string expected = "match";
|
||||
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
new(check, expected),
|
||||
};
|
||||
|
||||
string? actual = MatchUtil.GetFirstMatch("testfile", source, matchers);
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExactSizeStreamMatch()
|
||||
{
|
||||
byte[] source = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07];
|
||||
var stream = new MemoryStream(source);
|
||||
|
||||
byte?[] check = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07];
|
||||
string expected = "match";
|
||||
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
new(check, expected),
|
||||
};
|
||||
|
||||
string? actual = MatchUtil.GetFirstMatch("testfile", stream, matchers);
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,16 +20,16 @@ namespace SabreTools.Matching.Compare
|
||||
{
|
||||
public class NaturalComparer : Comparer<string>, IDisposable
|
||||
{
|
||||
private readonly Dictionary<string, string[]> table;
|
||||
private readonly Dictionary<string, string[]> _table;
|
||||
|
||||
public NaturalComparer()
|
||||
{
|
||||
table = [];
|
||||
_table = [];
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
table.Clear();
|
||||
_table.Clear();
|
||||
}
|
||||
|
||||
public override int Compare(string? x, string? y)
|
||||
@@ -47,7 +47,7 @@ namespace SabreTools.Matching.Compare
|
||||
if (x.ToLowerInvariant() == y.ToLowerInvariant())
|
||||
return x.CompareTo(y);
|
||||
|
||||
if (!table.TryGetValue(x, out string[]? x1))
|
||||
if (!_table.TryGetValue(x, out string[]? x1))
|
||||
{
|
||||
//x1 = Regex.Split(x.Replace(" ", string.Empty), "([0-9]+)");
|
||||
#if NET20 || NET35
|
||||
@@ -65,15 +65,15 @@ namespace SabreTools.Matching.Compare
|
||||
.Where(s => !string.IsNullOrEmpty(s))
|
||||
.ToArray();
|
||||
#endif
|
||||
table.Add(x, x1);
|
||||
_table.Add(x, x1);
|
||||
}
|
||||
|
||||
if (!table.TryGetValue(y, out string[]? y1))
|
||||
if (!_table.TryGetValue(y, out string[]? y1))
|
||||
{
|
||||
//y1 = Regex.Split(y.Replace(" ", string.Empty), "([0-9]+)");
|
||||
#if NET20 || NET35
|
||||
var nonempty = new List<string>();
|
||||
y1 = Regex.Split(x.ToLowerInvariant(), "([0-9]+)");
|
||||
y1 = Regex.Split(y.ToLowerInvariant(), "([0-9]+)");
|
||||
foreach (var s in y1)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(s))
|
||||
@@ -82,11 +82,11 @@ namespace SabreTools.Matching.Compare
|
||||
|
||||
y1 = nonempty.ToArray();
|
||||
#else
|
||||
y1 = Regex.Split(x.ToLowerInvariant(), "([0-9]+)")
|
||||
y1 = Regex.Split(y.ToLowerInvariant(), "([0-9]+)")
|
||||
.Where(s => !string.IsNullOrEmpty(s))
|
||||
.ToArray();
|
||||
#endif
|
||||
table.Add(y, y1);
|
||||
_table.Add(y, y1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < x1.Length && i < y1.Length; i++)
|
||||
|
||||
@@ -20,16 +20,16 @@ namespace SabreTools.Matching.Compare
|
||||
{
|
||||
public class NaturalReversedComparer : Comparer<string>, IDisposable
|
||||
{
|
||||
private readonly Dictionary<string, string[]> table;
|
||||
private readonly Dictionary<string, string[]> _table;
|
||||
|
||||
public NaturalReversedComparer()
|
||||
{
|
||||
table = [];
|
||||
_table = [];
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
table.Clear();
|
||||
_table.Clear();
|
||||
}
|
||||
|
||||
public override int Compare(string? x, string? y)
|
||||
@@ -47,7 +47,7 @@ namespace SabreTools.Matching.Compare
|
||||
if (y.ToLowerInvariant() == x.ToLowerInvariant())
|
||||
return y.CompareTo(x);
|
||||
|
||||
if (!table.TryGetValue(x, out string[]? x1))
|
||||
if (!_table.TryGetValue(x, out string[]? x1))
|
||||
{
|
||||
//x1 = Regex.Split(x.Replace(" ", string.Empty), "([0-9]+)");
|
||||
#if NET20 || NET35
|
||||
@@ -65,15 +65,15 @@ namespace SabreTools.Matching.Compare
|
||||
.Where(s => !string.IsNullOrEmpty(s))
|
||||
.ToArray();
|
||||
#endif
|
||||
table.Add(x, x1);
|
||||
_table.Add(x, x1);
|
||||
}
|
||||
|
||||
if (!table.TryGetValue(y, out string[]? y1))
|
||||
if (!_table.TryGetValue(y, out string[]? y1))
|
||||
{
|
||||
//y1 = Regex.Split(y.Replace(" ", string.Empty), "([0-9]+)");
|
||||
#if NET20 || NET35
|
||||
var nonempty = new List<string>();
|
||||
y1 = Regex.Split(x.ToLowerInvariant(), "([0-9]+)");
|
||||
y1 = Regex.Split(y.ToLowerInvariant(), "([0-9]+)");
|
||||
foreach (var s in y1)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(s))
|
||||
@@ -82,11 +82,11 @@ namespace SabreTools.Matching.Compare
|
||||
|
||||
y1 = nonempty.ToArray();
|
||||
#else
|
||||
y1 = Regex.Split(x.ToLowerInvariant(), "([0-9]+)")
|
||||
y1 = Regex.Split(y.ToLowerInvariant(), "([0-9]+)")
|
||||
.Where(s => !string.IsNullOrEmpty(s))
|
||||
.ToArray();
|
||||
#endif
|
||||
table.Add(y, y1);
|
||||
_table.Add(y, y1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < x1.Length && i < y1.Length; i++)
|
||||
|
||||
@@ -10,11 +10,7 @@ namespace SabreTools.Matching.Content
|
||||
/// <summary>
|
||||
/// Content to match
|
||||
/// </summary>
|
||||
#if NETFRAMEWORK || NETCOREAPP
|
||||
public byte?[]? Needle { get; private set; }
|
||||
#else
|
||||
public byte?[]? Needle { get; init; }
|
||||
#endif
|
||||
public byte?[]? Needle { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Starting index for matching
|
||||
@@ -34,9 +30,9 @@ namespace SabreTools.Matching.Content
|
||||
/// <param name="end">Optional ending index</param>
|
||||
public ContentMatch(byte?[]? needle, int start = -1, int end = -1)
|
||||
{
|
||||
this.Needle = needle;
|
||||
this.Start = start;
|
||||
this.End = end;
|
||||
Needle = needle;
|
||||
Start = start;
|
||||
End = end;
|
||||
}
|
||||
|
||||
#region Array Matching
|
||||
@@ -50,22 +46,26 @@ namespace SabreTools.Matching.Content
|
||||
public int Match(byte[]? stack, bool reverse = false)
|
||||
{
|
||||
// If either array is null or empty, we can't do anything
|
||||
if (stack == null || stack.Length == 0 || this.Needle == null || this.Needle.Length == 0)
|
||||
if (stack == null || stack.Length == 0 || Needle == null || Needle.Length == 0)
|
||||
return -1;
|
||||
|
||||
// If the needle array is larger than the stack array, it can't be contained within
|
||||
if (this.Needle.Length > stack.Length)
|
||||
if (Needle.Length > stack.Length)
|
||||
return -1;
|
||||
|
||||
// If the needle and stack are identically sized, short-circuit
|
||||
if (Needle.Length == stack.Length)
|
||||
return EqualAt(stack, 0) ? 0 : -1;
|
||||
|
||||
// Set the default start and end values
|
||||
int start = this.Start;
|
||||
int end = this.End;
|
||||
int start = Start;
|
||||
int end = End;
|
||||
|
||||
// If start or end are not set properly, set them to defaults
|
||||
if (start < 0)
|
||||
start = 0;
|
||||
if (end < 0)
|
||||
end = stack.Length - this.Needle.Length;
|
||||
end = stack.Length - Needle.Length;
|
||||
|
||||
for (int i = reverse ? end : start; reverse ? i > start : i < end; i += reverse ? -1 : 1)
|
||||
{
|
||||
@@ -90,7 +90,7 @@ namespace SabreTools.Matching.Content
|
||||
private bool EqualAt(byte[] stack, int index)
|
||||
{
|
||||
// If the needle is invalid, we can't do anything
|
||||
if (this.Needle == null)
|
||||
if (Needle == null)
|
||||
return false;
|
||||
|
||||
// If the index is invalid, we can't do anything
|
||||
@@ -98,16 +98,16 @@ namespace SabreTools.Matching.Content
|
||||
return false;
|
||||
|
||||
// If we're too close to the end of the stack, return false
|
||||
if (this.Needle.Length > stack.Length - index)
|
||||
if (Needle.Length > stack.Length - index)
|
||||
return false;
|
||||
|
||||
// Loop through and check the value
|
||||
for (int i = 0; i < this.Needle.Length; i++)
|
||||
for (int i = 0; i < Needle.Length; i++)
|
||||
{
|
||||
// A null value is a wildcard
|
||||
if (this.Needle[i] == null)
|
||||
if (Needle[i] == null)
|
||||
continue;
|
||||
else if (stack[i + index] != this.Needle[i])
|
||||
else if (stack[i + index] != Needle[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -127,22 +127,26 @@ namespace SabreTools.Matching.Content
|
||||
public int Match(Stream? stack, bool reverse = false)
|
||||
{
|
||||
// If either array is null or empty, we can't do anything
|
||||
if (stack == null || stack.Length == 0 || this.Needle == null || this.Needle.Length == 0)
|
||||
if (stack == null || stack.Length == 0 || Needle == null || Needle.Length == 0)
|
||||
return -1;
|
||||
|
||||
// If the needle array is larger than the stack array, it can't be contained within
|
||||
if (this.Needle.Length > stack.Length)
|
||||
if (Needle.Length > stack.Length)
|
||||
return -1;
|
||||
|
||||
// If the needle and stack are identically sized, short-circuit
|
||||
if (Needle.Length == stack.Length)
|
||||
return EqualAt(stack, 0) ? 0 : -1;
|
||||
|
||||
// Set the default start and end values
|
||||
int start = this.Start;
|
||||
int end = this.End;
|
||||
int start = Start;
|
||||
int end = End;
|
||||
|
||||
// If start or end are not set properly, set them to defaults
|
||||
if (start < 0)
|
||||
start = 0;
|
||||
if (end < 0)
|
||||
end = (int)(stack.Length - this.Needle.Length);
|
||||
end = (int)(stack.Length - Needle.Length);
|
||||
|
||||
for (int i = reverse ? end : start; reverse ? i > start : i < end; i += reverse ? -1 : 1)
|
||||
{
|
||||
@@ -167,7 +171,7 @@ namespace SabreTools.Matching.Content
|
||||
private bool EqualAt(Stream stack, int index)
|
||||
{
|
||||
// If the needle is invalid, we can't do anything
|
||||
if (this.Needle == null)
|
||||
if (Needle == null)
|
||||
return false;
|
||||
|
||||
// If the index is invalid, we can't do anything
|
||||
@@ -175,7 +179,7 @@ namespace SabreTools.Matching.Content
|
||||
return false;
|
||||
|
||||
// If we're too close to the end of the stack, return false
|
||||
if (this.Needle.Length > stack.Length - index)
|
||||
if (Needle.Length > stack.Length - index)
|
||||
return false;
|
||||
|
||||
// Save the current position and move to the index
|
||||
@@ -186,16 +190,16 @@ namespace SabreTools.Matching.Content
|
||||
bool matched = true;
|
||||
|
||||
// Loop through and check the value
|
||||
for (int i = 0; i < this.Needle.Length; i++)
|
||||
for (int i = 0; i < Needle.Length; i++)
|
||||
{
|
||||
byte stackValue = (byte)stack.ReadByte();
|
||||
|
||||
// A null value is a wildcard
|
||||
if (this.Needle[i] == null)
|
||||
if (Needle[i] == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (stackValue != this.Needle[i])
|
||||
else if (stackValue != Needle[i])
|
||||
{
|
||||
matched = false;
|
||||
break;
|
||||
|
||||
@@ -19,10 +19,10 @@ namespace SabreTools.Matching.Content
|
||||
/// A content version method takes the file path, the file contents,
|
||||
/// and a list of found positions and returns a single string. That
|
||||
/// string is either a version string, in which case it will be appended
|
||||
/// to the protection name, or `null`, in which case it will cause
|
||||
/// the protection to be omitted.
|
||||
/// to the match name, or `null`, in which case it will cause
|
||||
/// the match name to be omitted.
|
||||
/// </remarks>
|
||||
public Func<string, byte[]?, List<int>, string?>? GetArrayVersion { get; private set; }
|
||||
public Func<string, byte[]?, List<int>, string?>? GetArrayVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Function to get a content version
|
||||
@@ -31,34 +31,34 @@ namespace SabreTools.Matching.Content
|
||||
/// A content version method takes the file path, the file contents,
|
||||
/// and a list of found positions and returns a single string. That
|
||||
/// string is either a version string, in which case it will be appended
|
||||
/// to the protection name, or `null`, in which case it will cause
|
||||
/// the protection to be omitted.
|
||||
/// to the match name, or `null`, in which case it will cause
|
||||
/// the match name to be omitted.
|
||||
/// </remarks>
|
||||
public Func<string, Stream?, List<int>, string?>? GetStreamVersion { get; private set; }
|
||||
public Func<string, Stream?, List<int>, string?>? GetStreamVersion { get; }
|
||||
|
||||
#region Generic Constructors
|
||||
|
||||
public ContentMatchSet(byte?[] needle, string protectionName)
|
||||
: this(new List<byte?[]> { needle }, getArrayVersion: null, protectionName) { }
|
||||
public ContentMatchSet(byte?[] needle, string matchName)
|
||||
: this([needle], getArrayVersion: null, matchName) { }
|
||||
|
||||
public ContentMatchSet(List<byte?[]> needles, string protectionName)
|
||||
: this(needles, getArrayVersion: null, protectionName) { }
|
||||
public ContentMatchSet(List<byte?[]> needles, string matchName)
|
||||
: this(needles, getArrayVersion: null, matchName) { }
|
||||
|
||||
public ContentMatchSet(ContentMatch needle, string protectionName)
|
||||
: this(new List<ContentMatch>() { needle }, getArrayVersion: null, protectionName) { }
|
||||
public ContentMatchSet(ContentMatch needle, string matchName)
|
||||
: this([needle], getArrayVersion: null, matchName) { }
|
||||
|
||||
public ContentMatchSet(List<ContentMatch> needles, string protectionName)
|
||||
: this(needles, getArrayVersion: null, protectionName) { }
|
||||
public ContentMatchSet(List<ContentMatch> needles, string matchName)
|
||||
: this(needles, getArrayVersion: null, matchName) { }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Array Constructors
|
||||
|
||||
public ContentMatchSet(byte?[] needle, Func<string, byte[]?, List<int>, string?>? getArrayVersion, string protectionName)
|
||||
: this(new List<byte?[]> { needle }, getArrayVersion, protectionName) { }
|
||||
public ContentMatchSet(byte?[] needle, Func<string, byte[]?, List<int>, string?>? getArrayVersion, string matchName)
|
||||
: this([needle], getArrayVersion, matchName) { }
|
||||
|
||||
#if NET20 || NET35
|
||||
public ContentMatchSet(List<byte?[]> needles, Func<string, byte[]?, List<int>, string?>? getArrayVersion, string protectionName)
|
||||
public ContentMatchSet(List<byte?[]> needles, Func<string, byte[]?, List<int>, string?>? getArrayVersion, string matchName)
|
||||
{
|
||||
var matchers = new List<ContentMatch>();
|
||||
foreach (var n in needles)
|
||||
@@ -68,32 +68,32 @@ namespace SabreTools.Matching.Content
|
||||
|
||||
Matchers = matchers;
|
||||
GetArrayVersion = getArrayVersion;
|
||||
ProtectionName = protectionName;
|
||||
MatchName = matchName;
|
||||
}
|
||||
#else
|
||||
public ContentMatchSet(List<byte?[]> needles, Func<string, byte[]?, List<int>, string?>? getArrayVersion, string protectionName)
|
||||
: this(needles.Select(n => new ContentMatch(n)).ToList(), getArrayVersion, protectionName) { }
|
||||
public ContentMatchSet(List<byte?[]> needles, Func<string, byte[]?, List<int>, string?>? getArrayVersion, string matchName)
|
||||
: this(needles.Select(n => new ContentMatch(n)).ToList(), getArrayVersion, matchName) { }
|
||||
#endif
|
||||
|
||||
public ContentMatchSet(ContentMatch needle, Func<string, byte[]?, List<int>, string?>? getArrayVersion, string protectionName)
|
||||
: this(new List<ContentMatch>() { needle }, getArrayVersion, protectionName) { }
|
||||
public ContentMatchSet(ContentMatch needle, Func<string, byte[]?, List<int>, string?>? getArrayVersion, string matchName)
|
||||
: this([needle], getArrayVersion, matchName) { }
|
||||
|
||||
public ContentMatchSet(List<ContentMatch> needles, Func<string, byte[]?, List<int>, string?>? getArrayVersion, string protectionName)
|
||||
public ContentMatchSet(List<ContentMatch> needles, Func<string, byte[]?, List<int>, string?>? getArrayVersion, string matchName)
|
||||
{
|
||||
Matchers = needles;
|
||||
GetArrayVersion = getArrayVersion;
|
||||
ProtectionName = protectionName;
|
||||
MatchName = matchName;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Stream Constructors
|
||||
|
||||
public ContentMatchSet(byte?[] needle, Func<string, Stream?, List<int>, string?>? getStreamVersion, string protectionName)
|
||||
: this(new List<byte?[]> { needle }, getStreamVersion, protectionName) { }
|
||||
public ContentMatchSet(byte?[] needle, Func<string, Stream?, List<int>, string?>? getStreamVersion, string matchName)
|
||||
: this([needle], getStreamVersion, matchName) { }
|
||||
|
||||
#if NET20 || NET35
|
||||
public ContentMatchSet(List<byte?[]> needles, Func<string, Stream?, List<int>, string?>? getStreamVersion, string protectionName)
|
||||
public ContentMatchSet(List<byte?[]> needles, Func<string, Stream?, List<int>, string?>? getStreamVersion, string matchName)
|
||||
{
|
||||
var matchers = new List<ContentMatch>();
|
||||
foreach (var n in needles)
|
||||
@@ -103,21 +103,21 @@ namespace SabreTools.Matching.Content
|
||||
|
||||
Matchers = matchers;
|
||||
GetStreamVersion = getStreamVersion;
|
||||
ProtectionName = protectionName;
|
||||
MatchName = matchName;
|
||||
}
|
||||
#else
|
||||
public ContentMatchSet(List<byte?[]> needles, Func<string, Stream?, List<int>, string?>? getStreamVersion, string protectionName)
|
||||
: this(needles.Select(n => new ContentMatch(n)).ToList(), getStreamVersion, protectionName) { }
|
||||
public ContentMatchSet(List<byte?[]> needles, Func<string, Stream?, List<int>, string?>? getStreamVersion, string matchName)
|
||||
: this(needles.Select(n => new ContentMatch(n)).ToList(), getStreamVersion, matchName) { }
|
||||
#endif
|
||||
|
||||
public ContentMatchSet(ContentMatch needle, Func<string, Stream?, List<int>, string?>? getStreamVersion, string protectionName)
|
||||
: this(new List<ContentMatch>() { needle }, getStreamVersion, protectionName) { }
|
||||
public ContentMatchSet(ContentMatch needle, Func<string, Stream?, List<int>, string?>? getStreamVersion, string matchName)
|
||||
: this([needle], getStreamVersion, matchName) { }
|
||||
|
||||
public ContentMatchSet(List<ContentMatch> needles, Func<string, Stream?, List<int>, string?>? getStreamVersion, string protectionName)
|
||||
public ContentMatchSet(List<ContentMatch> needles, Func<string, Stream?, List<int>, string?>? getStreamVersion, string matchName)
|
||||
{
|
||||
Matchers = needles;
|
||||
GetStreamVersion = getStreamVersion;
|
||||
ProtectionName = protectionName;
|
||||
MatchName = matchName;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -13,8 +13,8 @@ namespace SabreTools.Matching
|
||||
public IEnumerable<T>? Matchers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name of the protection to show
|
||||
/// Unique name for the match set
|
||||
/// </summary>
|
||||
public string? ProtectionName { get; set; }
|
||||
public string? MatchName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ namespace SabreTools.Matching
|
||||
/// <param name="stack">Array to search</param>
|
||||
/// <param name="matchers">Enumerable of ContentMatchSets to be run on the file</param>
|
||||
/// <param name="includeDebug">True to include positional data, false otherwise</param>
|
||||
/// <returns>List of strings representing the matched protections, null or empty otherwise</returns>
|
||||
/// <returns>List of strings representing the matches, null or empty otherwise</returns>
|
||||
#if NET20 || NET35
|
||||
public static Queue<string>? GetAllMatches(string file, byte[]? stack, IEnumerable<ContentMatchSet>? matchers, bool includeDebug = false)
|
||||
#else
|
||||
@@ -42,7 +42,7 @@ namespace SabreTools.Matching
|
||||
/// <param name="stack">Array to search</param>
|
||||
/// <param name="matchers">Enumerable of ContentMatchSets to be run on the file</param>
|
||||
/// <param name="includeDebug">True to include positional data, false otherwise</param>
|
||||
/// <returns>String representing the matched protection, null otherwise</returns>
|
||||
/// <returns>String representing the match, null otherwise</returns>
|
||||
public static string? GetFirstMatch(string file, byte[]? stack, IEnumerable<ContentMatchSet>? matchers, bool includeDebug = false)
|
||||
{
|
||||
var contentMatches = FindAllMatches(file, stack, matchers, includeDebug, true);
|
||||
@@ -64,7 +64,7 @@ namespace SabreTools.Matching
|
||||
/// <param name="matchers">Enumerable of ContentMatchSets to be run on the file</param>
|
||||
/// <param name="includeDebug">True to include positional data, false otherwise</param>
|
||||
/// <param name="stopAfterFirst">True to stop after the first match, false otherwise</param>
|
||||
/// <returns>List of strings representing the matched protections, null or empty otherwise</returns>
|
||||
/// <returns>List of strings representing the matches, null or empty otherwise</returns>
|
||||
#if NET20 || NET35
|
||||
private static Queue<string>? FindAllMatches(string file, byte[]? stack, IEnumerable<ContentMatchSet>? matchers, bool includeDebug, bool stopAfterFirst)
|
||||
#else
|
||||
@@ -79,11 +79,11 @@ namespace SabreTools.Matching
|
||||
#endif
|
||||
return null;
|
||||
|
||||
// Initialize the queue of matched protections
|
||||
// Initialize the queue of matches
|
||||
#if NET20 || NET35
|
||||
var matchedProtections = new Queue<string>();
|
||||
var matchesQueue = new Queue<string>();
|
||||
#else
|
||||
var matchedProtections = new ConcurrentQueue<string>();
|
||||
var matchesQueue = new ConcurrentQueue<string>();
|
||||
#endif
|
||||
|
||||
// Loop through and try everything otherwise
|
||||
@@ -106,10 +106,10 @@ namespace SabreTools.Matching
|
||||
string positionsString = string.Join(", ", positions);
|
||||
#endif
|
||||
|
||||
// If we there is no version method, just return the protection name
|
||||
// If we there is no version method, just return the match name
|
||||
if (matcher.GetArrayVersion == null)
|
||||
{
|
||||
matchedProtections.Enqueue((matcher.ProtectionName ?? "Unknown Protection") + (includeDebug ? $" (Index {positionsString})" : string.Empty));
|
||||
matchesQueue.Enqueue((matcher.MatchName ?? "Unknown") + (includeDebug ? $" (Index {positionsString})" : string.Empty));
|
||||
}
|
||||
|
||||
// Otherwise, invoke the version method
|
||||
@@ -120,15 +120,15 @@ namespace SabreTools.Matching
|
||||
if (version == null)
|
||||
continue;
|
||||
|
||||
matchedProtections.Enqueue($"{matcher.ProtectionName ?? "Unknown Protection"} {version}".Trim() + (includeDebug ? $" (Index {positionsString})" : string.Empty));
|
||||
matchesQueue.Enqueue($"{matcher.MatchName ?? "Unknown"} {version}".Trim() + (includeDebug ? $" (Index {positionsString})" : string.Empty));
|
||||
}
|
||||
|
||||
// If we're stopping after the first protection, bail out here
|
||||
// If we're stopping after the first match, bail out here
|
||||
if (stopAfterFirst)
|
||||
return matchedProtections;
|
||||
return matchesQueue;
|
||||
}
|
||||
|
||||
return matchedProtections;
|
||||
return matchesQueue;
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -142,7 +142,7 @@ namespace SabreTools.Matching
|
||||
/// <param name="stack">Stream to search</param>
|
||||
/// <param name="matchers">Enumerable of ContentMatchSets to be run on the file</param>
|
||||
/// <param name="includeDebug">True to include positional data, false otherwise</param>
|
||||
/// <returns>List of strings representing the matched protections, null or empty otherwise</returns>
|
||||
/// <returns>List of strings representing the matches, null or empty otherwise</returns>
|
||||
#if NET20 || NET35
|
||||
public static Queue<string>? GetAllMatches(string file, Stream? stack, IEnumerable<ContentMatchSet>? matchers, bool includeDebug = false)
|
||||
#else
|
||||
@@ -159,7 +159,7 @@ namespace SabreTools.Matching
|
||||
/// <param name="stack">Stream to search</param>
|
||||
/// <param name="matchers">Enumerable of ContentMatchSets to be run on the file</param>
|
||||
/// <param name="includeDebug">True to include positional data, false otherwise</param>
|
||||
/// <returns>String representing the matched protection, null otherwise</returns>
|
||||
/// <returns>String representing the match, null otherwise</returns>
|
||||
public static string? GetFirstMatch(string file, Stream? stack, IEnumerable<ContentMatchSet>? matchers, bool includeDebug = false)
|
||||
{
|
||||
var contentMatches = FindAllMatches(file, stack, matchers, includeDebug, true);
|
||||
@@ -181,7 +181,7 @@ namespace SabreTools.Matching
|
||||
/// <param name="matchers">Enumerable of ContentMatchSets to be run on the file</param>
|
||||
/// <param name="includeDebug">True to include positional data, false otherwise</param>
|
||||
/// <param name="stopAfterFirst">True to stop after the first match, false otherwise</param>
|
||||
/// <returns>List of strings representing the matched protections, null or empty otherwise</returns>
|
||||
/// <returns>List of strings representing the matches, null or empty otherwise</returns>
|
||||
#if NET20 || NET35
|
||||
private static Queue<string>? FindAllMatches(string file, Stream? stack, IEnumerable<ContentMatchSet>? matchers, bool includeDebug, bool stopAfterFirst)
|
||||
#else
|
||||
@@ -196,11 +196,11 @@ namespace SabreTools.Matching
|
||||
#endif
|
||||
return null;
|
||||
|
||||
// Initialize the queue of matched protections
|
||||
// Initialize the queue of matches
|
||||
#if NET20 || NET35
|
||||
var matchedProtections = new Queue<string>();
|
||||
var matchesQueue = new Queue<string>();
|
||||
#else
|
||||
var matchedProtections = new ConcurrentQueue<string>();
|
||||
var matchesQueue = new ConcurrentQueue<string>();
|
||||
#endif
|
||||
|
||||
// Loop through and try everything otherwise
|
||||
@@ -223,10 +223,10 @@ namespace SabreTools.Matching
|
||||
string positionsString = string.Join(", ", positions);
|
||||
#endif
|
||||
|
||||
// If we there is no version method, just return the protection name
|
||||
// If we there is no version method, just return the match name
|
||||
if (matcher.GetStreamVersion == null)
|
||||
{
|
||||
matchedProtections.Enqueue((matcher.ProtectionName ?? "Unknown Protection") + (includeDebug ? $" (Index {positionsString})" : string.Empty));
|
||||
matchesQueue.Enqueue((matcher.MatchName ?? "Unknown") + (includeDebug ? $" (Index {positionsString})" : string.Empty));
|
||||
}
|
||||
|
||||
// Otherwise, invoke the version method
|
||||
@@ -237,15 +237,15 @@ namespace SabreTools.Matching
|
||||
if (version == null)
|
||||
continue;
|
||||
|
||||
matchedProtections.Enqueue($"{matcher.ProtectionName ?? "Unknown Protection"} {version}".Trim() + (includeDebug ? $" (Index {positionsString})" : string.Empty));
|
||||
matchesQueue.Enqueue($"{matcher.MatchName ?? "Unknown"} {version}".Trim() + (includeDebug ? $" (Index {positionsString})" : string.Empty));
|
||||
}
|
||||
|
||||
// If we're stopping after the first protection, bail out here
|
||||
// If we're stopping after the first match, bail out here
|
||||
if (stopAfterFirst)
|
||||
return matchedProtections;
|
||||
return matchesQueue;
|
||||
}
|
||||
|
||||
return matchedProtections;
|
||||
return matchesQueue;
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -258,14 +258,14 @@ namespace SabreTools.Matching
|
||||
/// <param name="file">File path to check for matches</param>
|
||||
/// <param name="matchers">Enumerable of PathMatchSets to be run on the file</param>
|
||||
/// <param name="any">True if any path match is a success, false if all have to match</param>
|
||||
/// <returns>List of strings representing the matched protections, null or empty otherwise</returns>
|
||||
/// <returns>List of strings representing the matches, null or empty otherwise</returns>
|
||||
#if NET20 || NET35
|
||||
public static Queue<string> GetAllMatches(string file, IEnumerable<PathMatchSet>? matchers, bool any = false)
|
||||
#else
|
||||
public static ConcurrentQueue<string> GetAllMatches(string file, IEnumerable<PathMatchSet>? matchers, bool any = false)
|
||||
#endif
|
||||
{
|
||||
return FindAllMatches(new List<string> { file }, matchers, any, false);
|
||||
return FindAllMatches([file], matchers, any, false);
|
||||
}
|
||||
|
||||
// <summary>
|
||||
@@ -274,7 +274,7 @@ namespace SabreTools.Matching
|
||||
/// <param name="files">File paths to check for matches</param>
|
||||
/// <param name="matchers">Enumerable of PathMatchSets to be run on the file</param>
|
||||
/// <param name="any">True if any path match is a success, false if all have to match</param>
|
||||
/// <returns>List of strings representing the matched protections, null or empty otherwise</returns>
|
||||
/// <returns>List of strings representing the matches, null or empty otherwise</returns>
|
||||
#if NET20 || NET35
|
||||
public static Queue<string> GetAllMatches(IEnumerable<string>? files, IEnumerable<PathMatchSet>? matchers, bool any = false)
|
||||
#else
|
||||
@@ -290,7 +290,7 @@ namespace SabreTools.Matching
|
||||
/// <param name="file">File path to check for matches</param>
|
||||
/// <param name="matchers">Enumerable of PathMatchSets to be run on the file</param>
|
||||
/// <param name="any">True if any path match is a success, false if all have to match</param>
|
||||
/// <returns>String representing the matched protection, null otherwise</returns>
|
||||
/// <returns>String representing the match, null otherwise</returns>
|
||||
public static string? GetFirstMatch(string file, IEnumerable<PathMatchSet> matchers, bool any = false)
|
||||
{
|
||||
var contentMatches = FindAllMatches(new List<string> { file }, matchers, any, true);
|
||||
@@ -310,7 +310,7 @@ namespace SabreTools.Matching
|
||||
/// <param name="files">File paths to check for matches</param>
|
||||
/// <param name="matchers">Enumerable of PathMatchSets to be run on the file</param>
|
||||
/// <param name="any">True if any path match is a success, false if all have to match</param>
|
||||
/// <returns>String representing the matched protection, null otherwise</returns>
|
||||
/// <returns>String representing the match, null otherwise</returns>
|
||||
public static string? GetFirstMatch(IEnumerable<string> files, IEnumerable<PathMatchSet> matchers, bool any = false)
|
||||
{
|
||||
var contentMatches = FindAllMatches(files, matchers, any, true);
|
||||
@@ -331,7 +331,7 @@ namespace SabreTools.Matching
|
||||
/// <param name="matchers">Enumerable of PathMatchSets to be run on the file</param>
|
||||
/// <param name="any">True if any path match is a success, false if all have to match</param>
|
||||
/// <param name="stopAfterFirst">True to stop after the first match, false otherwise</param>
|
||||
/// <returns>List of strings representing the matched protections, null or empty otherwise</returns>
|
||||
/// <returns>List of strings representing the matches, null or empty otherwise</returns>
|
||||
#if NET20 || NET35
|
||||
private static Queue<string> FindAllMatches(IEnumerable<string>? files, IEnumerable<PathMatchSet>? matchers, bool any, bool stopAfterFirst)
|
||||
#else
|
||||
@@ -346,11 +346,11 @@ namespace SabreTools.Matching
|
||||
#endif
|
||||
return new();
|
||||
|
||||
// Initialize the list of matched protections
|
||||
// Initialize the list of matches
|
||||
#if NET20 || NET35
|
||||
var matchedProtections = new Queue<string>();
|
||||
var matchesQueue = new Queue<string>();
|
||||
#else
|
||||
var matchedProtections = new ConcurrentQueue<string>();
|
||||
var matchesQueue = new ConcurrentQueue<string>();
|
||||
#endif
|
||||
|
||||
// Loop through and try everything otherwise
|
||||
@@ -376,10 +376,10 @@ namespace SabreTools.Matching
|
||||
if (!passes || firstMatchedString == null)
|
||||
continue;
|
||||
|
||||
// If we there is no version method, just return the protection name
|
||||
// If we there is no version method, just return the match name
|
||||
if (matcher.GetVersion == null)
|
||||
{
|
||||
matchedProtections.Enqueue(matcher.ProtectionName ?? "Unknown Protection");
|
||||
matchesQueue.Enqueue(matcher.MatchName ?? "Unknown");
|
||||
}
|
||||
|
||||
// Otherwise, invoke the version method
|
||||
@@ -390,15 +390,15 @@ namespace SabreTools.Matching
|
||||
if (version == null)
|
||||
continue;
|
||||
|
||||
matchedProtections.Enqueue($"{matcher.ProtectionName ?? "Unknown Protection"} {version}".Trim());
|
||||
matchesQueue.Enqueue($"{matcher.MatchName ?? "Unknown"} {version}".Trim());
|
||||
}
|
||||
|
||||
// If we're stopping after the first protection, bail out here
|
||||
// If we're stopping after the first match, bail out here
|
||||
if (stopAfterFirst)
|
||||
return matchedProtections;
|
||||
return matchesQueue;
|
||||
}
|
||||
|
||||
return matchedProtections;
|
||||
return matchesQueue;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -13,11 +13,7 @@ namespace SabreTools.Matching.Paths
|
||||
/// <summary>
|
||||
/// String to match
|
||||
/// </summary>
|
||||
#if NETFRAMEWORK || NETCOREAPP
|
||||
public string? Needle { get; private set; }
|
||||
#else
|
||||
public string? Needle { get; init; }
|
||||
#endif
|
||||
public string? Needle { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Match exact casing instead of invariant
|
||||
|
||||
@@ -17,24 +17,24 @@ namespace SabreTools.Matching.Paths
|
||||
/// <remarks>
|
||||
/// A path version method takes the matched path and an enumerable of files
|
||||
/// and returns a single string. That string is either a version string,
|
||||
/// in which case it will be appended to the protection name, or `null`,
|
||||
/// in which case it will cause the protection to be omitted.
|
||||
/// in which case it will be appended to the match name, or `null`,
|
||||
/// in which case it will cause the match name to be omitted.
|
||||
/// </remarks>
|
||||
public Func<string, IEnumerable<string>?, string?>? GetVersion { get; private set; }
|
||||
public Func<string, IEnumerable<string>?, string?>? GetVersion { get; }
|
||||
|
||||
#region Constructors
|
||||
|
||||
public PathMatchSet(string needle, string protectionName)
|
||||
: this(new List<string> { needle }, null, protectionName) { }
|
||||
public PathMatchSet(string needle, string matchName)
|
||||
: this([needle], null, matchName) { }
|
||||
|
||||
public PathMatchSet(List<string> needles, string protectionName)
|
||||
: this(needles, null, protectionName) { }
|
||||
public PathMatchSet(List<string> needles, string matchName)
|
||||
: this(needles, null, matchName) { }
|
||||
|
||||
public PathMatchSet(string needle, Func<string, IEnumerable<string>?, string?>? getVersion, string protectionName)
|
||||
: this(new List<string> { needle }, getVersion, protectionName) { }
|
||||
public PathMatchSet(string needle, Func<string, IEnumerable<string>?, string?>? getVersion, string matchName)
|
||||
: this([needle], getVersion, matchName) { }
|
||||
|
||||
#if NET20 || NET35
|
||||
public PathMatchSet(List<string> needles, Func<string, IEnumerable<string>?, string?>? getVersion, string protectionName)
|
||||
public PathMatchSet(List<string> needles, Func<string, IEnumerable<string>?, string?>? getVersion, string matchName)
|
||||
{
|
||||
var matchers = new List<PathMatch>();
|
||||
foreach (var n in needles)
|
||||
@@ -44,27 +44,27 @@ namespace SabreTools.Matching.Paths
|
||||
|
||||
Matchers = matchers;
|
||||
GetVersion = getVersion;
|
||||
ProtectionName = protectionName;
|
||||
MatchName = matchName;
|
||||
}
|
||||
#else
|
||||
public PathMatchSet(List<string> needles, Func<string, IEnumerable<string>?, string?>? getVersion, string protectionName)
|
||||
: this(needles.Select(n => new PathMatch(n)).ToList(), getVersion, protectionName) { }
|
||||
public PathMatchSet(List<string> needles, Func<string, IEnumerable<string>?, string?>? getVersion, string matchName)
|
||||
: this(needles.Select(n => new PathMatch(n)).ToList(), getVersion, matchName) { }
|
||||
#endif
|
||||
|
||||
public PathMatchSet(PathMatch needle, string protectionName)
|
||||
: this(new List<PathMatch>() { needle }, null, protectionName) { }
|
||||
public PathMatchSet(PathMatch needle, string matchName)
|
||||
: this([needle], null, matchName) { }
|
||||
|
||||
public PathMatchSet(List<PathMatch> needles, string protectionName)
|
||||
: this(needles, null, protectionName) { }
|
||||
public PathMatchSet(List<PathMatch> needles, string matchName)
|
||||
: this(needles, null, matchName) { }
|
||||
|
||||
public PathMatchSet(PathMatch needle, Func<string, IEnumerable<string>?, string?>? getVersion, string protectionName)
|
||||
: this(new List<PathMatch>() { needle }, getVersion, protectionName) { }
|
||||
public PathMatchSet(PathMatch needle, Func<string, IEnumerable<string>?, string?>? getVersion, string matchName)
|
||||
: this([needle], getVersion, matchName) { }
|
||||
|
||||
public PathMatchSet(List<PathMatch> needles, Func<string, IEnumerable<string>?, string?>? getVersion, string protectionName)
|
||||
public PathMatchSet(List<PathMatch> needles, Func<string, IEnumerable<string>?, string?>? getVersion, string matchName)
|
||||
{
|
||||
Matchers = needles;
|
||||
GetVersion = getVersion;
|
||||
ProtectionName = protectionName;
|
||||
MatchName = matchName;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>1.3.2</Version>
|
||||
<Version>1.3.3</Version>
|
||||
|
||||
<!-- Package Properties -->
|
||||
<Authors>Matt Nadareski</Authors>
|
||||
|
||||
Reference in New Issue
Block a user