diff --git a/SabreTools.Serialization/Wrappers/AACSMediaKeyBlock.cs b/SabreTools.Serialization/Wrappers/AACSMediaKeyBlock.cs index 63438f7c..20607e73 100644 --- a/SabreTools.Serialization/Wrappers/AACSMediaKeyBlock.cs +++ b/SabreTools.Serialization/Wrappers/AACSMediaKeyBlock.cs @@ -12,6 +12,15 @@ namespace SabreTools.Serialization.Wrappers #endregion + #region Extension Properties + + /// + /// Media key block records + /// + public Record?[] Records => Model.Records ?? []; + + #endregion + #region Constructors /// diff --git a/SabreTools.Serialization/Wrappers/BDPlusSVM.cs b/SabreTools.Serialization/Wrappers/BDPlusSVM.cs index 19de47d3..4d429f35 100644 --- a/SabreTools.Serialization/Wrappers/BDPlusSVM.cs +++ b/SabreTools.Serialization/Wrappers/BDPlusSVM.cs @@ -12,6 +12,15 @@ namespace SabreTools.Serialization.Wrappers #endregion + #region Extension Properties + + /// + /// Human-readable version of the date + /// + public string Date => $"{Model.Year:0000}-{Model.Month:00}-{Model.Day:00}"; + + #endregion + #region Constructors /// diff --git a/SabreTools.Serialization/Wrappers/SGA.cs b/SabreTools.Serialization/Wrappers/SGA.cs index c41e75db..4b227783 100644 --- a/SabreTools.Serialization/Wrappers/SGA.cs +++ b/SabreTools.Serialization/Wrappers/SGA.cs @@ -1,3 +1,4 @@ +using System; using System.IO; namespace SabreTools.Serialization.Wrappers @@ -11,6 +12,49 @@ namespace SabreTools.Serialization.Wrappers #endregion + #region Extension Properties + + /// + /// Directory data + /// + public Models.SGA.Directory? Directory => Model.Directory; + + /// + /// Number of files in the directory + /// + public int FileCount + { + get + { + return Directory switch + { + Models.SGA.Directory4 d4 => d4.Files?.Length ?? 0, + Models.SGA.Directory5 d5 => d5.Files?.Length ?? 0, + Models.SGA.Directory6 d6 => d6.Files?.Length ?? 0, + Models.SGA.Directory7 d7 => d7.Files?.Length ?? 0, + _ => 0, + }; + } + } + + /// + /// Offset to the file data + /// + public long FileDataOffset + { + get + { + return Model.Header switch + { + Models.SGA.Header4 h4 => h4.FileDataOffset, + Models.SGA.Header6 h6 => h6.FileDataOffset, + _ => -1, + }; + } + } + + #endregion + #region Constructors /// @@ -74,5 +118,112 @@ namespace SabreTools.Serialization.Wrappers } #endregion + + #region File + + /// + /// Get the compressed size of a file + /// + public long GetCompressedSize(int index) + { + // If the index is invalid + if (index < 0 || index >= FileCount) + return -1; + + // Get the file and return the name + var file = GetFile(index); + return file?.Size ?? -1L; + } + + /// + /// Get the uncompressed size of a file + /// + public long GetUncompressedSize(int index) + { + // If the index is invalid + if (index < 0 || index >= FileCount) + return -1; + + // Get the file and return the name + var file = GetFile(index); + return file?.SizeOnDisk ?? -1L; + } + + /// + /// Get a file header from the archive + /// + public Models.SGA.File4? GetFile(int index) + { + // If the index is invalid + if (index < 0 || index >= FileCount) + return null; + + return Directory switch + { + Models.SGA.Directory4 d4 => d4.Files![index], + Models.SGA.Directory5 d5 => d5.Files![index], + Models.SGA.Directory6 d6 => d6.Files![index], + Models.SGA.Directory7 d7 => d7.Files![index], + _ => null, + }; + } + + /// + /// Get a file name from the archive + /// + public string? GetFileName(int index) + { + // If the index is invalid + if (index < 0 || index >= FileCount) + return null; + + // Get the file and return the name + var file = GetFile(index); + return file?.Name; + } + + /// + /// Get a file offset from the archive + /// + public long GetFileOffset(int index) + { + // If the index is invalid + if (index < 0 || index >= FileCount) + return -1; + + // Get the file and return the name + var file = GetFile(index); + return file?.Offset ?? -1L; + } + + /// + /// Get the parent name for a file + /// + public string? GetParentName(int index) + { + // If the index is invalid + if (index < 0 || index >= FileCount) + return null; + + // Get the folder + object? folder = Directory switch + { + Models.SGA.Directory4 d4 => Array.Find(d4.Folders ?? [], f => f != null && index >= f.FileStartIndex && index <= f.FileEndIndex), + Models.SGA.Directory5 d5 => Array.Find(d5.Folders ?? [], f => f != null && index >= f.FileStartIndex && index <= f.FileEndIndex), + Models.SGA.Directory6 d6 => Array.Find(d6.Folders ?? [], f => f != null && index >= f.FileStartIndex && index <= f.FileEndIndex), + Models.SGA.Directory7 d7 => Array.Find(d7.Folders ?? [], f => f != null && index >= f.FileStartIndex && index <= f.FileEndIndex), + _ => default, + }; + + // Get the folder name + return folder switch + { + Models.SGA.Folder4 f4 => f4.Name, + Models.SGA.Folder5 f5 => f5.Name, + _ => null, + }; + } + + #endregion } } \ No newline at end of file