using System; using System.IO; using System.Xml; using System.Xml.Serialization; namespace SabreTools.Skippers { [XmlRoot("detector")] public class Detector { #region Fields /// /// Detector name /// [XmlElement("name")] public string? Name { get; set; } /// /// Author names /// [XmlElement("author")] public string? Author { get; set; } /// /// File version /// [XmlElement("version")] public string? Version { get; set; } /// /// Set of all rules in the skipper /// [XmlElement("rule")] public Rule[]? Rules { get; set; } /// /// Filename the skipper lives in /// [XmlIgnore] public string? SourceFile { get; set; } #endregion #region Matching /// /// Get the Rule associated with a given stream /// /// Stream to be checked /// Name of the skipper to be used, blank to find a matching skipper /// The Rule that matched the stream, null otherwise public Rule? GetMatchingRule(Stream input, string skipperName) { // If we have no name supplied, try to blindly match if (string.IsNullOrWhiteSpace(skipperName)) return GetMatchingRule(input); // If the name matches the internal name of the skipper else if (string.Equals(skipperName, Name, StringComparison.OrdinalIgnoreCase)) return GetMatchingRule(input); // If the name matches the source file name of the skipper else if (string.Equals(skipperName, SourceFile, StringComparison.OrdinalIgnoreCase)) return GetMatchingRule(input); // Otherwise, nothing matches by default return null; } /// /// Get the matching Rule from all Rules, if possible /// /// Stream to be checked /// The Rule that matched the stream, null otherwise private Rule? GetMatchingRule(Stream input) { // If we have no rules if (Rules == null) return null; // Loop through the rules until one is found that works foreach (Rule rule in Rules) { // Always reset the stream back to the original place input.Seek(0, SeekOrigin.Begin); // If all tests in the rule pass if (rule.PassesAllTests(input)) return rule; } // If nothing passed return null; } #endregion } }