mirror of
https://github.com/SabreTools/SabreTools.Serialization.git
synced 2026-02-04 05:36:12 +00:00
Add more ISAv3 stuff
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
114
SabreTools.Serialization/Printers/InstallShieldArchiveV3.cs
Normal file
114
SabreTools.Serialization/Printers/InstallShieldArchiveV3.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
79
SabreTools.Serialization/Wrappers/InstallShieldArchiveV3.cs
Normal file
79
SabreTools.Serialization/Wrappers/InstallShieldArchiveV3.cs
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
|
||||
@@ -77,7 +77,6 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// <summary>
|
||||
/// InstallShield archive v3
|
||||
/// </summary>
|
||||
/// <remarks>Currently has no IWrapper implementation</remarks>
|
||||
InstallShieldArchiveV3,
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user