namespace BurnOutSharp.Matching { /// /// Content matching criteria /// public class ContentMatch : IMatch { /// /// Content to match /// public byte?[] Needle { get; set; } /// /// Starting index for matching /// public int Start { get; set; } /// /// Ending index for matching /// public int End { get; set; } /// /// Constructor /// /// Byte array representing the search /// Optional starting index /// Optional ending index public ContentMatch(byte?[] needle, int start = -1, int end = -1) { Needle = needle; Start = start; End = end; } #region Matching /// /// Get if this match can be found in a stack /// /// Array to search for the given content /// True to search from the end of the array, false from the start /// Tuple of success and found position public (bool success, int position) Match(byte[] stack, bool reverse = false) { // If either array is null or empty, we can't do anything if (stack == null || stack.Length == 0 || Needle == null || Needle.Length == 0) return (false, -1); // If the needle array is larger than the stack array, it can't be contained within if (Needle.Length > stack.Length) return (false, -1); // If start or end are not set properly, set them to defaults if (Start < 0) Start = 0; if (End < 0) End = stack.Length - Needle.Length; for (int i = reverse ? End : Start; reverse ? i > Start : i < End; i += reverse ? -1 : 1) { // If we somehow have an invalid end and we haven't matched, return if (i > stack.Length) return (false, -1); // Check to see if the values are equal if (EqualAt(stack, i)) return (true, i); } return (false, -1); } /// /// Get if a stack at a certain index is equal to a needle /// /// Array to search for the given content /// Starting index to check equality /// True if the needle matches the stack at a given index private bool EqualAt(byte[] stack, int index) { // If the index is invalid, we can't do anything if (index < 0) return false; // If we're too close to the end of the stack, return false if (Needle.Length >= stack.Length - index) return false; for (int i = 0; i < Needle.Length; i++) { // A null value is a wildcard if (Needle[i] == null) continue; else if (stack[i + index] != Needle[i]) return false; } return true; } #endregion } }