using System; using System.IO; using System.Text; namespace BinaryObjectScanner.Wrappers { public class NewExecutable : WrapperBase { #region Descriptive Properties /// public override string DescriptionString => "New Executable (NE)"; #endregion #region Constructors /// #if NET48 public NewExecutable(SabreTools.Models.NewExecutable.Executable model, byte[] data, int offset) #else public NewExecutable(SabreTools.Models.NewExecutable.Executable? model, byte[]? data, int offset) #endif : base(model, data, offset) { // All logic is handled by the base class } /// #if NET48 public NewExecutable(SabreTools.Models.NewExecutable.Executable model, Stream data) #else public NewExecutable(SabreTools.Models.NewExecutable.Executable? model, Stream? data) #endif : base(model, data) { // All logic is handled by the base class } /// /// Create an NE executable from a byte array and offset /// /// Byte array representing the executable /// Offset within the array to parse /// An NE executable wrapper on success, null on failure #if NET48 public static NewExecutable Create(byte[] data, int offset) #else public static NewExecutable? Create(byte[]? data, int offset) #endif { // If the data is invalid if (data == null) return null; // If the offset is out of bounds if (offset < 0 || offset >= data.Length) return null; // Create a memory stream and use that MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset); return Create(dataStream); } /// /// Create an NE executable from a Stream /// /// Stream representing the executable /// An NE executable wrapper on success, null on failure #if NET48 public static NewExecutable Create(Stream data) #else public static NewExecutable? Create(Stream? data) #endif { // If the data is invalid if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead) return null; var executable = new SabreTools.Serialization.Streams.NewExecutable().Deserialize(data); if (executable == null) return null; try { return new NewExecutable(executable, data); } catch { return null; } } #endregion #region Printing /// public override StringBuilder PrettyPrint() { StringBuilder builder = new StringBuilder(); Printing.NewExecutable.Print(builder, this.Model); return builder; } #endregion #region REMOVE -- DO NOT USE /// /// Read an arbitrary range from the source /// /// The start of where to read data from, -1 means start of source /// How many bytes to read, -1 means read until end /// Byte array representing the range, null on error [Obsolete] #if NET48 public byte[] ReadArbitraryRange(int rangeStart = -1, int length = -1) #else public byte[]? ReadArbitraryRange(int rangeStart = -1, int length = -1) #endif { // If we have an unset range start, read from the start of the source if (rangeStart == -1) rangeStart = 0; // If we have an unset length, read the whole source if (length == -1) { switch (_dataSource) { case DataSource.ByteArray: #if NET48 length = _byteArrayData.Length - _byteArrayOffset; #else length = _byteArrayData!.Length - _byteArrayOffset; #endif break; case DataSource.Stream: #if NET48 length = (int)_streamData.Length; #else length = (int)_streamData!.Length; #endif break; } } return ReadFromDataSource(rangeStart, length); } #endregion } }