using System; using System.Text; namespace Kaitai { public abstract class KaitaiStruct { protected KaitaiStream m_io; public KaitaiStream M_Io { get { return m_io; } } public KaitaiStruct(KaitaiStream io) { m_io = io; } } /// /// A custom decoder interface. Implementing classes can be called from /// inside a .ksy file using `process: XXX` syntax. /// public interface CustomDecoder { /// /// Decodes a given byte array, according to some custom algorithm /// (specific to implementing class) and parameters given in the /// constructor, returning another byte array. /// /// Source byte array. byte[] Decode(byte[] src); } /// /// Error that occurs when default endianness should be decided with a /// switch, but nothing matches (although using endianness expression /// implies that there should be some positive result). /// public class UndecidedEndiannessError : Exception { public UndecidedEndiannessError() : base("Unable to decide on endianness") { } public UndecidedEndiannessError(string msg) : base(msg) { } public UndecidedEndiannessError(string msg, Exception inner) : base(msg, inner) { } } /// /// Common ancestor for all error originating from Kaitai Struct usage. /// Stores KSY source path, pointing to an element supposedly guilty of /// an error. /// public class KaitaiStructError : Exception { public KaitaiStructError(string msg, string srcPath) : base(srcPath + ": " + msg) { this.srcPath = srcPath; } protected string srcPath; } /// /// Common ancestor for all validation failures. Stores pointer to /// KaitaiStream IO object which was involved in an error. /// public class ValidationFailedError : KaitaiStructError { public ValidationFailedError(string msg, KaitaiStream io, string srcPath) : base("at pos " + io.Pos + ": validation failed: " + msg, srcPath) { this.io = io; } protected KaitaiStream io; protected static string ByteArrayToHex(byte[] arr) { StringBuilder sb = new StringBuilder("["); for (int i = 0; i < arr.Length; i++) { if (i > 0) { sb.Append(' '); } sb.Append(string.Format("{0:X2}", arr[i])); } sb.Append(']'); return sb.ToString(); } } /// /// Signals validation failure: we required "actual" value to be equal to /// "expected", but it turned out that it's not. /// public class ValidationNotEqualError : ValidationFailedError { public ValidationNotEqualError(byte[] expected, byte[] actual, KaitaiStream io, string srcPath) : base("not equal, expected " + ByteArrayToHex(expected) + ", but got " + ByteArrayToHex(actual), io, srcPath) { this.expected = expected; this.actual = actual; } public ValidationNotEqualError(Object expected, Object actual, KaitaiStream io, string srcPath) : base("not equal, expected " + expected + ", but got " + actual, io, srcPath) { this.expected = expected; this.actual = actual; } protected Object expected; protected Object actual; } public class ValidationLessThanError : ValidationFailedError { public ValidationLessThanError(byte[] min, byte[] actual, KaitaiStream io, string srcPath) : base("not in range, min " + ByteArrayToHex(min) + ", but got " + ByteArrayToHex(actual), io, srcPath) { this.min = min; this.actual = actual; } public ValidationLessThanError(Object min, Object actual, KaitaiStream io, string srcPath) : base("not in range, min " + min + ", but got " + actual, io, srcPath) { this.min = min; this.actual = actual; } protected Object min; protected Object actual; } public class ValidationGreaterThanError : ValidationFailedError { public ValidationGreaterThanError(byte[] max, byte[] actual, KaitaiStream io, string srcPath) : base("not in range, max " + ByteArrayToHex(max) + ", but got " + ByteArrayToHex(actual), io, srcPath) { this.max = max; this.actual = actual; } public ValidationGreaterThanError(Object max, Object actual, KaitaiStream io, string srcPath) : base("not in range, max " + max + ", but got " + actual, io, srcPath) { this.max = max; this.actual = actual; } protected Object max; protected Object actual; } public class ValidationNotAnyOfError : ValidationFailedError { public ValidationNotAnyOfError(Object actual, KaitaiStream io, string srcPath) : base("not any of the list, got " + actual, io, srcPath) { this.actual = actual; } protected Object actual; } public class ValidationExprError : ValidationFailedError { public ValidationExprError(Object actual, KaitaiStream io, string srcPath) : base("not matching the expression, got " + actual, io, srcPath) { this.actual = actual; } protected Object actual; } }