using System; using System.Globalization; using System.IO; namespace SabreTools.Skippers { /// /// Individual test that applies to a Rule /// public abstract class Test { /// /// Check if a stream passes the test /// /// Stream to check rule against /// The Stream is assumed to be in the proper position for a given test public abstract bool Passes(Stream input); #region Helpers /// /// Prase a hex string into a byte array /// /// protected static byte[]? ParseByteArrayFromHex(string? hex) { // If we have an invalid string if (string.IsNullOrWhiteSpace(hex)) return null; var ret = new byte[hex.Length / 2]; for (int index = 0; index < ret.Length; index++) { string byteValue = hex.Substring(index * 2, 2); ret[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture); } return ret; } /// /// Seek an input stream based on the test value /// /// Stream to seek /// Offset to seek to /// True if the stream could seek, false on error protected static bool Seek(Stream input, long? offset) { try { // Null offset means EOF if (offset == null) input.Seek(0, SeekOrigin.End); // Positive offset means from beginning else if (offset >= 0 && offset <= input.Length) input.Seek(offset.Value, SeekOrigin.Begin); // Negative offset means from end else if (offset < 0 && Math.Abs(offset.Value) <= input.Length) input.Seek(offset.Value, SeekOrigin.End); return true; } catch { return false; } } #endregion } }