Skip to content

Commit ba97381

Browse files
committed
Add more ISAv3 stuff
1 parent 3de92de commit ba97381

File tree

6 files changed

+267
-2
lines changed

6 files changed

+267
-2
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using System.IO;
2+
using System.Linq;
3+
using SabreTools.Serialization.Wrappers;
4+
using Xunit;
5+
6+
namespace SabreTools.Serialization.Test.Wrappers
7+
{
8+
public class InstallShieldArchiveV3Tests
9+
{
10+
[Fact]
11+
public void NullArray_Null()
12+
{
13+
byte[]? data = null;
14+
int offset = 0;
15+
var actual = InstallShieldArchiveV3.Create(data, offset);
16+
Assert.Null(actual);
17+
}
18+
19+
[Fact]
20+
public void EmptyArray_Null()
21+
{
22+
byte[]? data = [];
23+
int offset = 0;
24+
var actual = InstallShieldArchiveV3.Create(data, offset);
25+
Assert.Null(actual);
26+
}
27+
28+
[Fact]
29+
public void InvalidArray_Null()
30+
{
31+
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
32+
int offset = 0;
33+
var actual = InstallShieldArchiveV3.Create(data, offset);
34+
Assert.Null(actual);
35+
}
36+
37+
[Fact]
38+
public void NullStream_Null()
39+
{
40+
Stream? data = null;
41+
var actual = InstallShieldArchiveV3.Create(data);
42+
Assert.Null(actual);
43+
}
44+
45+
[Fact]
46+
public void EmptyStream_Null()
47+
{
48+
Stream? data = new MemoryStream([]);
49+
var actual = InstallShieldArchiveV3.Create(data);
50+
Assert.Null(actual);
51+
}
52+
53+
[Fact]
54+
public void InvalidStream_Null()
55+
{
56+
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
57+
var actual = InstallShieldArchiveV3.Create(data);
58+
Assert.Null(actual);
59+
}
60+
}
61+
}

SabreTools.Serialization/Printer.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public static void PrintToConsole(this IWrapper wrapper)
4242
Wrapper.CHD item => item.PrettyPrint(),
4343
Wrapper.CIA item => item.PrettyPrint(),
4444
Wrapper.GCF item => item.PrettyPrint(),
45+
Wrapper.InstallShieldArchiveV3 item => item.PrettyPrint(),
4546
Wrapper.InstallShieldCabinet item => item.PrettyPrint(),
4647
Wrapper.IRD item => item.PrettyPrint(),
4748
Wrapper.LinearExecutable item => item.PrettyPrint(),
@@ -90,6 +91,7 @@ public static string ExportJSON(this IWrapper wrapper)
9091
Wrapper.CHD item => item.ExportJSON(),
9192
Wrapper.CIA item => item.ExportJSON(),
9293
Wrapper.GCF item => item.ExportJSON(),
94+
Wrapper.InstallShieldArchiveV3 item => item.ExportJSON(),
9395
Wrapper.InstallShieldCabinet item => item.ExportJSON(),
9496
Wrapper.IRD item => item.ExportJSON(),
9597
Wrapper.LinearExecutable item => item.ExportJSON(),
@@ -205,6 +207,16 @@ private static StringBuilder PrettyPrint(this Wrapper.GCF item)
205207
return builder;
206208
}
207209

210+
/// <summary>
211+
/// Export the item information as pretty-printed text
212+
/// </summary>
213+
private static StringBuilder PrettyPrint(this Wrapper.InstallShieldArchiveV3 item)
214+
{
215+
var builder = new StringBuilder();
216+
InstallShieldArchiveV3.Print(builder, item.Model);
217+
return builder;
218+
}
219+
208220
/// <summary>
209221
/// Export the item information as pretty-printed text
210222
/// </summary>
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
using System.Text;
2+
using SabreTools.Models.InstallShieldArchiveV3;
3+
using SabreTools.Serialization.Interfaces;
4+
5+
namespace SabreTools.Serialization.Printers
6+
{
7+
public class InstallShieldArchiveV3 : IPrinter<Archive>
8+
{
9+
/// <inheritdoc/>
10+
public void PrintInformation(StringBuilder builder, Archive model)
11+
=> Print(builder, model);
12+
13+
public static void Print(StringBuilder builder, Archive archive)
14+
{
15+
builder.AppendLine("InstallShield Archive V3 Information:");
16+
builder.AppendLine("-------------------------");
17+
builder.AppendLine();
18+
19+
Print(builder, archive.Header);
20+
Print(builder, archive.Directories);
21+
Print(builder, archive.Files);
22+
}
23+
24+
private static void Print(StringBuilder builder, Header? header)
25+
{
26+
builder.AppendLine(" Header Information:");
27+
builder.AppendLine(" -------------------------");
28+
if (header == null)
29+
{
30+
builder.AppendLine(" No header");
31+
builder.AppendLine();
32+
return;
33+
}
34+
35+
builder.AppendLine(header.Signature1, " Signature 1");
36+
builder.AppendLine(header.Signature2, " Signature 2");
37+
builder.AppendLine(header.Reserved0, " Reserved 0");
38+
builder.AppendLine(header.IsMultivolume, " Is multivolume");
39+
builder.AppendLine(header.FileCount, " File count");
40+
builder.AppendLine(header.DateTime, " Datetime");
41+
builder.AppendLine(header.CompressedSize, " Compressed size");
42+
builder.AppendLine(header.UncompressedSize, " Uncompressed size");
43+
builder.AppendLine(header.Reserved1, " Reserved 1");
44+
builder.AppendLine(header.VolumeTotal, " Volume total");
45+
builder.AppendLine(header.VolumeNumber, " Volume number");
46+
builder.AppendLine(header.Reserved2, " Reserved 2");
47+
builder.AppendLine(header.SplitBeginAddress, " Split begin address");
48+
builder.AppendLine(header.SplitEndAddress, " Split end address");
49+
builder.AppendLine(header.TocAddress, " TOC address");
50+
builder.AppendLine(header.Reserved3, " Reserved 3");
51+
builder.AppendLine(header.DirCount, " Dir count");
52+
builder.AppendLine(header.Reserved4, " Reserved 4");
53+
builder.AppendLine(header.Reserved5, " Reserved 5");
54+
builder.AppendLine();
55+
}
56+
57+
private static void Print(StringBuilder builder, Directory[]? entries)
58+
{
59+
builder.AppendLine(" Directories:");
60+
builder.AppendLine(" -------------------------");
61+
if (entries == null || entries.Length == 0)
62+
{
63+
builder.AppendLine(" No directories");
64+
builder.AppendLine();
65+
return;
66+
}
67+
68+
for (int i = 0; i < entries.Length; i++)
69+
{
70+
var entry = entries[i];
71+
builder.AppendLine($" Directory {i}");
72+
builder.AppendLine(entry.FileCount, " File count");
73+
builder.AppendLine(entry.ChunkSize, " Chunk size");
74+
builder.AppendLine(entry.NameLength, " Name length");
75+
builder.AppendLine(entry.Name, " Name");
76+
}
77+
78+
builder.AppendLine();
79+
}
80+
81+
private static void Print(StringBuilder builder, File[]? entries)
82+
{
83+
builder.AppendLine(" Files:");
84+
builder.AppendLine(" -------------------------");
85+
if (entries == null || entries.Length == 0)
86+
{
87+
builder.AppendLine(" No files");
88+
builder.AppendLine();
89+
return;
90+
}
91+
92+
for (int i = 0; i < entries.Length; i++)
93+
{
94+
var entry = entries[i];
95+
builder.AppendLine($" File {i}");
96+
builder.AppendLine(entry.VolumeEnd, " Volume end");
97+
builder.AppendLine(entry.Index, " Index");
98+
builder.AppendLine(entry.UncompressedSize, " Uncompressed size");
99+
builder.AppendLine(entry.CompressedSize, " Compressed size");
100+
builder.AppendLine(entry.Offset, " Offset");
101+
builder.AppendLine(entry.DateTime, " Datetime");
102+
builder.AppendLine(entry.Reserved0, " Reserved 0");
103+
builder.AppendLine(entry.ChunkSize, " Chunk size");
104+
builder.AppendLine($" Attrib: {entry.Attrib} (0x{entry.Attrib:X})");
105+
builder.AppendLine(entry.IsSplit, " Is split");
106+
builder.AppendLine(entry.Reserved1, " Reserved 1");
107+
builder.AppendLine(entry.VolumeStart, " Volume start");
108+
builder.AppendLine(entry.Name, " Name");
109+
}
110+
111+
builder.AppendLine();
112+
}
113+
}
114+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
using System.IO;
2+
using SabreTools.Models.InstallShieldArchiveV3;
3+
4+
namespace SabreTools.Serialization.Wrappers
5+
{
6+
public partial class InstallShieldArchiveV3 : WrapperBase<Archive>
7+
{
8+
#region Descriptive Properties
9+
10+
/// <inheritdoc/>
11+
public override string DescriptionString => "InstallShield Archive V3";
12+
13+
#endregion
14+
15+
#region Constructors
16+
17+
/// <inheritdoc/>
18+
public InstallShieldArchiveV3(Archive? model, byte[]? data, int offset)
19+
: base(model, data, offset)
20+
{
21+
// All logic is handled by the base class
22+
}
23+
24+
/// <inheritdoc/>
25+
public InstallShieldArchiveV3(Archive? model, Stream? data)
26+
: base(model, data)
27+
{
28+
// All logic is handled by the base class
29+
}
30+
31+
/// <summary>
32+
/// Create an InstallShield Archive V3 from a byte array and offset
33+
/// </summary>
34+
/// <param name="data">Byte array representing the archive</param>
35+
/// <param name="offset">Offset within the array to parse</param>
36+
/// <returns>A archive wrapper on success, null on failure</returns>
37+
public static InstallShieldArchiveV3? Create(byte[]? data, int offset)
38+
{
39+
// If the data is invalid
40+
if (data == null || data.Length == 0)
41+
return null;
42+
43+
// If the offset is out of bounds
44+
if (offset < 0 || offset >= data.Length)
45+
return null;
46+
47+
// Create a memory stream and use that
48+
var dataStream = new MemoryStream(data, offset, data.Length - offset);
49+
return Create(dataStream);
50+
}
51+
52+
/// <summary>
53+
/// Create a InstallShield Archive V3 from a Stream
54+
/// </summary>
55+
/// <param name="data">Stream representing the archive</param>
56+
/// <returns>A archive wrapper on success, null on failure</returns>
57+
public static InstallShieldArchiveV3? Create(Stream? data)
58+
{
59+
// If the data is invalid
60+
if (data == null || !data.CanRead)
61+
return null;
62+
63+
try
64+
{
65+
var archive = Deserializers.InstallShieldArchiveV3.DeserializeStream(data);
66+
if (archive == null)
67+
return null;
68+
69+
return new InstallShieldArchiveV3(archive, data);
70+
}
71+
catch
72+
{
73+
return null;
74+
}
75+
}
76+
77+
#endregion
78+
}
79+
}

SabreTools.Serialization/Wrappers/WrapperFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public static class WrapperFactory
2828
WrapperType.GCF => GCF.Create(data),
2929
WrapperType.GZIP => null,// TODO: Implement wrapper
3030
WrapperType.IniFile => null,// TODO: Implement wrapper
31-
WrapperType.InstallShieldArchiveV3 => null,// TODO: Implement wrapper
31+
WrapperType.InstallShieldArchiveV3 => InstallShieldArchiveV3.Create(data),
3232
WrapperType.InstallShieldCAB => InstallShieldCabinet.Create(data),
3333
WrapperType.LDSCRYPT => null,// TODO: Implement wrapper
3434
WrapperType.LZKWAJ => LZKWAJ.Create(data),

SabreTools.Serialization/Wrappers/WrapperType.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ public enum WrapperType
7777
/// <summary>
7878
/// InstallShield archive v3
7979
/// </summary>
80-
/// <remarks>Currently has no IWrapper implementation</remarks>
8180
InstallShieldArchiveV3,
8281

8382
/// <summary>

0 commit comments

Comments
 (0)