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
}
}