Files
SabreTools/SabreTools.Skippers/Detector.cs
Matt Nadareski 01ce52ec35 Complete overhaul on Skippers
This change involves safety updates for serialization, better definitions of various classes, renames of some classes for accuracy, missing enum decoration, and various fixes.
2023-04-04 18:31:19 -04:00

100 lines
2.9 KiB
C#

using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace SabreTools.Skippers
{
[XmlRoot("detector")]
public class Detector
{
#region Fields
/// <summary>
/// Detector name
/// </summary>
[XmlElement("name")]
public string? Name { get; set; }
/// <summary>
/// Author names
/// </summary>
[XmlElement("author")]
public string? Author { get; set; }
/// <summary>
/// File version
/// </summary>
[XmlElement("version")]
public string? Version { get; set; }
/// <summary>
/// Set of all rules in the skipper
/// </summary>
[XmlElement("rule")]
public Rule[]? Rules { get; set; }
/// <summary>
/// Filename the skipper lives in
/// </summary>
[XmlIgnore]
public string? SourceFile { get; set; }
#endregion
#region Matching
/// <summary>
/// Get the Rule associated with a given stream
/// </summary>
/// <param name="input">Stream to be checked</param>
/// <param name="skipperName">Name of the skipper to be used, blank to find a matching skipper</param>
/// <returns>The Rule that matched the stream, null otherwise</returns>
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;
}
/// <summary>
/// Get the matching Rule from all Rules, if possible
/// </summary>
/// <param name="input">Stream to be checked</param>
/// <returns>The Rule that matched the stream, null otherwise</returns>
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
}
}