Add more ISAv3 stuff

This commit is contained in:
Matt Nadareski
2024-12-11 13:56:01 -05:00
parent 3de92de225
commit ba97381b99
6 changed files with 267 additions and 2 deletions

View File

@@ -0,0 +1,61 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Wrappers;
using Xunit;
namespace SabreTools.Serialization.Test.Wrappers
{
public class InstallShieldArchiveV3Tests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var actual = InstallShieldArchiveV3.Create(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var actual = InstallShieldArchiveV3.Create(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var actual = InstallShieldArchiveV3.Create(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var actual = InstallShieldArchiveV3.Create(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var actual = InstallShieldArchiveV3.Create(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var actual = InstallShieldArchiveV3.Create(data);
Assert.Null(actual);
}
}
}

View File

@@ -42,6 +42,7 @@ namespace SabreTools.Serialization
Wrapper.CHD item => item.PrettyPrint(),
Wrapper.CIA item => item.PrettyPrint(),
Wrapper.GCF item => item.PrettyPrint(),
Wrapper.InstallShieldArchiveV3 item => item.PrettyPrint(),
Wrapper.InstallShieldCabinet item => item.PrettyPrint(),
Wrapper.IRD item => item.PrettyPrint(),
Wrapper.LinearExecutable item => item.PrettyPrint(),
@@ -90,6 +91,7 @@ namespace SabreTools.Serialization
Wrapper.CHD item => item.ExportJSON(),
Wrapper.CIA item => item.ExportJSON(),
Wrapper.GCF item => item.ExportJSON(),
Wrapper.InstallShieldArchiveV3 item => item.ExportJSON(),
Wrapper.InstallShieldCabinet item => item.ExportJSON(),
Wrapper.IRD item => item.ExportJSON(),
Wrapper.LinearExecutable item => item.ExportJSON(),
@@ -205,6 +207,16 @@ namespace SabreTools.Serialization
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>
private static StringBuilder PrettyPrint(this Wrapper.InstallShieldArchiveV3 item)
{
var builder = new StringBuilder();
InstallShieldArchiveV3.Print(builder, item.Model);
return builder;
}
/// <summary>
/// Export the item information as pretty-printed text
/// </summary>

View File

@@ -0,0 +1,114 @@
using System.Text;
using SabreTools.Models.InstallShieldArchiveV3;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Printers
{
public class InstallShieldArchiveV3 : IPrinter<Archive>
{
/// <inheritdoc/>
public void PrintInformation(StringBuilder builder, Archive model)
=> Print(builder, model);
public static void Print(StringBuilder builder, Archive archive)
{
builder.AppendLine("InstallShield Archive V3 Information:");
builder.AppendLine("-------------------------");
builder.AppendLine();
Print(builder, archive.Header);
Print(builder, archive.Directories);
Print(builder, archive.Files);
}
private static void Print(StringBuilder builder, Header? header)
{
builder.AppendLine(" Header Information:");
builder.AppendLine(" -------------------------");
if (header == null)
{
builder.AppendLine(" No header");
builder.AppendLine();
return;
}
builder.AppendLine(header.Signature1, " Signature 1");
builder.AppendLine(header.Signature2, " Signature 2");
builder.AppendLine(header.Reserved0, " Reserved 0");
builder.AppendLine(header.IsMultivolume, " Is multivolume");
builder.AppendLine(header.FileCount, " File count");
builder.AppendLine(header.DateTime, " Datetime");
builder.AppendLine(header.CompressedSize, " Compressed size");
builder.AppendLine(header.UncompressedSize, " Uncompressed size");
builder.AppendLine(header.Reserved1, " Reserved 1");
builder.AppendLine(header.VolumeTotal, " Volume total");
builder.AppendLine(header.VolumeNumber, " Volume number");
builder.AppendLine(header.Reserved2, " Reserved 2");
builder.AppendLine(header.SplitBeginAddress, " Split begin address");
builder.AppendLine(header.SplitEndAddress, " Split end address");
builder.AppendLine(header.TocAddress, " TOC address");
builder.AppendLine(header.Reserved3, " Reserved 3");
builder.AppendLine(header.DirCount, " Dir count");
builder.AppendLine(header.Reserved4, " Reserved 4");
builder.AppendLine(header.Reserved5, " Reserved 5");
builder.AppendLine();
}
private static void Print(StringBuilder builder, Directory[]? entries)
{
builder.AppendLine(" Directories:");
builder.AppendLine(" -------------------------");
if (entries == null || entries.Length == 0)
{
builder.AppendLine(" No directories");
builder.AppendLine();
return;
}
for (int i = 0; i < entries.Length; i++)
{
var entry = entries[i];
builder.AppendLine($" Directory {i}");
builder.AppendLine(entry.FileCount, " File count");
builder.AppendLine(entry.ChunkSize, " Chunk size");
builder.AppendLine(entry.NameLength, " Name length");
builder.AppendLine(entry.Name, " Name");
}
builder.AppendLine();
}
private static void Print(StringBuilder builder, File[]? entries)
{
builder.AppendLine(" Files:");
builder.AppendLine(" -------------------------");
if (entries == null || entries.Length == 0)
{
builder.AppendLine(" No files");
builder.AppendLine();
return;
}
for (int i = 0; i < entries.Length; i++)
{
var entry = entries[i];
builder.AppendLine($" File {i}");
builder.AppendLine(entry.VolumeEnd, " Volume end");
builder.AppendLine(entry.Index, " Index");
builder.AppendLine(entry.UncompressedSize, " Uncompressed size");
builder.AppendLine(entry.CompressedSize, " Compressed size");
builder.AppendLine(entry.Offset, " Offset");
builder.AppendLine(entry.DateTime, " Datetime");
builder.AppendLine(entry.Reserved0, " Reserved 0");
builder.AppendLine(entry.ChunkSize, " Chunk size");
builder.AppendLine($" Attrib: {entry.Attrib} (0x{entry.Attrib:X})");
builder.AppendLine(entry.IsSplit, " Is split");
builder.AppendLine(entry.Reserved1, " Reserved 1");
builder.AppendLine(entry.VolumeStart, " Volume start");
builder.AppendLine(entry.Name, " Name");
}
builder.AppendLine();
}
}
}

View File

@@ -0,0 +1,79 @@
using System.IO;
using SabreTools.Models.InstallShieldArchiveV3;
namespace SabreTools.Serialization.Wrappers
{
public partial class InstallShieldArchiveV3 : WrapperBase<Archive>
{
#region Descriptive Properties
/// <inheritdoc/>
public override string DescriptionString => "InstallShield Archive V3";
#endregion
#region Constructors
/// <inheritdoc/>
public InstallShieldArchiveV3(Archive? model, byte[]? data, int offset)
: base(model, data, offset)
{
// All logic is handled by the base class
}
/// <inheritdoc/>
public InstallShieldArchiveV3(Archive? model, Stream? data)
: base(model, data)
{
// All logic is handled by the base class
}
/// <summary>
/// Create an InstallShield Archive V3 from a byte array and offset
/// </summary>
/// <param name="data">Byte array representing the archive</param>
/// <param name="offset">Offset within the array to parse</param>
/// <returns>A archive wrapper on success, null on failure</returns>
public static InstallShieldArchiveV3? Create(byte[]? data, int offset)
{
// If the data is invalid
if (data == null || data.Length == 0)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and use that
var dataStream = new MemoryStream(data, offset, data.Length - offset);
return Create(dataStream);
}
/// <summary>
/// Create a InstallShield Archive V3 from a Stream
/// </summary>
/// <param name="data">Stream representing the archive</param>
/// <returns>A archive wrapper on success, null on failure</returns>
public static InstallShieldArchiveV3? Create(Stream? data)
{
// If the data is invalid
if (data == null || !data.CanRead)
return null;
try
{
var archive = Deserializers.InstallShieldArchiveV3.DeserializeStream(data);
if (archive == null)
return null;
return new InstallShieldArchiveV3(archive, data);
}
catch
{
return null;
}
}
#endregion
}
}

View File

@@ -28,7 +28,7 @@ namespace SabreTools.Serialization.Wrappers
WrapperType.GCF => GCF.Create(data),
WrapperType.GZIP => null,// TODO: Implement wrapper
WrapperType.IniFile => null,// TODO: Implement wrapper
WrapperType.InstallShieldArchiveV3 => null,// TODO: Implement wrapper
WrapperType.InstallShieldArchiveV3 => InstallShieldArchiveV3.Create(data),
WrapperType.InstallShieldCAB => InstallShieldCabinet.Create(data),
WrapperType.LDSCRYPT => null,// TODO: Implement wrapper
WrapperType.LZKWAJ => LZKWAJ.Create(data),

View File

@@ -77,7 +77,6 @@ namespace SabreTools.Serialization.Wrappers
/// <summary>
/// InstallShield archive v3
/// </summary>
/// <remarks>Currently has no IWrapper implementation</remarks>
InstallShieldArchiveV3,
/// <summary>