Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions SabreTools.Serialization.Test/Deserializers/AppPkgHeaderTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Deserializers;
using Xunit;

namespace SabreTools.Serialization.Test.Deserializers
{
public class AppPkgHeaderTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new AppPkgHeader();

var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}

[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new AppPkgHeader();

var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}

[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new AppPkgHeader();

var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}

[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new AppPkgHeader();

var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}

[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new AppPkgHeader();

var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}

[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new AppPkgHeader();

var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}
79 changes: 79 additions & 0 deletions SabreTools.Serialization/Deserializers/AppPkgHeader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using System.IO;
using System.Text;
using SabreTools.IO.Extensions;
using static SabreTools.Models.PlayStation4.Constants;

namespace SabreTools.Serialization.Deserializers
{
public class AppPkgHeader : BaseBinaryDeserializer<Models.PlayStation4.AppPkgHeader>
{
/// <inheritdoc/>
public override Models.PlayStation4.AppPkgHeader? Deserialize(Stream? data)
{
// If the data is invalid
if (data == null || !data.CanRead)
return null;

try
{
// Create a new app.pkg header to fill
var appPkgHeader = new Models.PlayStation4.AppPkgHeader();

appPkgHeader.Magic = data.ReadUInt32BigEndian();
if (appPkgHeader.Magic != AppPkgMagic)
return null;

appPkgHeader.Type = data.ReadUInt32BigEndian();
appPkgHeader.PKGUnknown = data.ReadUInt32BigEndian();
appPkgHeader.FileCount = data.ReadUInt32BigEndian();
appPkgHeader.EntryCount = data.ReadUInt32BigEndian();
appPkgHeader.SCEntryCount = data.ReadUInt16BigEndian();
appPkgHeader.EntryCount2 = data.ReadUInt16BigEndian();
appPkgHeader.TableOffset = data.ReadUInt32BigEndian();
appPkgHeader.EntryDataSize = data.ReadUInt32BigEndian();
appPkgHeader.BodyOffset = data.ReadUInt64BigEndian();
appPkgHeader.BodySize = data.ReadUInt64BigEndian();
appPkgHeader.ContentOffset = data.ReadUInt64BigEndian();
appPkgHeader.ContentSize = data.ReadUInt64BigEndian();
byte[] contentID = data.ReadBytes(0x24);
appPkgHeader.ContentID = Encoding.ASCII.GetString(contentID).TrimEnd('\0');
appPkgHeader.ContentZeroes = data.ReadBytes(0xC);
appPkgHeader.DRMType = data.ReadUInt32BigEndian();
appPkgHeader.ContentType = data.ReadUInt32BigEndian();
appPkgHeader.ContentFlags = data.ReadUInt32BigEndian();
appPkgHeader.PromoteSize = data.ReadUInt32BigEndian();
appPkgHeader.VersionDate = data.ReadUInt32BigEndian();
appPkgHeader.VersionHash = data.ReadUInt32BigEndian();
appPkgHeader.Zeroes1 = data.ReadBytes(0x78);
appPkgHeader.MainEntry1SHA256 = data.ReadBytes(0x20);
appPkgHeader.MainEntry2SHA256 = data.ReadBytes(0x20);
appPkgHeader.DigestTableSHA256 = data.ReadBytes(0x20);
appPkgHeader.MainTableSHA256 = data.ReadBytes(0x20);
appPkgHeader.Zeroes2 = data.ReadBytes(0x280);
appPkgHeader.PFSUnknown = data.ReadUInt32BigEndian();
appPkgHeader.PFSImageCount = data.ReadUInt32BigEndian();
appPkgHeader.PFSImageFlags = data.ReadUInt64BigEndian();
appPkgHeader.PFSImageOffset = data.ReadUInt64BigEndian();
appPkgHeader.PFSImageSize = data.ReadUInt64BigEndian();
appPkgHeader.MountImageOffset = data.ReadUInt64BigEndian();
appPkgHeader.MountImageSize = data.ReadUInt64BigEndian();
appPkgHeader.PKGSize = data.ReadUInt64BigEndian();
appPkgHeader.PKGSignedSize = data.ReadUInt32BigEndian();
appPkgHeader.PKGCacheSize = data.ReadUInt32BigEndian();
appPkgHeader.PFSImageSHA256 = data.ReadBytes(0x20);
appPkgHeader.PFSSignedSHA256 = data.ReadBytes(0x20);
appPkgHeader.PFSSplitSize0 = data.ReadUInt64BigEndian();
appPkgHeader.PFSSplitSize1 = data.ReadUInt64BigEndian();
appPkgHeader.Zeroes3 = data.ReadBytes(0xB50);
appPkgHeader.PKGSHA256 = data.ReadBytes(0x20);

return appPkgHeader;
}
catch
{
// Ignore the actual error
return null;
}
}
}
}
Loading