mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-07-08 18:06:34 +00:00
Split out MS-ZIP handling for cleaner code
This commit is contained in:
@@ -265,50 +265,65 @@ namespace BinaryObjectScanner.FileType
|
||||
if (db?.CompressedData == null)
|
||||
continue;
|
||||
|
||||
switch (compressionType)
|
||||
// Get the uncompressed data block
|
||||
byte[] data = compressionType switch
|
||||
{
|
||||
// Uncompressed data
|
||||
case CompressionType.TYPE_NONE:
|
||||
ms.Write(db.CompressedData, 0, db.CompressedData.Length);
|
||||
ms.Flush();
|
||||
break;
|
||||
CompressionType.TYPE_NONE => db.CompressedData,
|
||||
CompressionType.TYPE_MSZIP => DecompressMSZIPBlock(folderIndex, mszip, i, db),
|
||||
|
||||
// MS-ZIP
|
||||
case CompressionType.TYPE_MSZIP:
|
||||
long preMsZipPosition = ms.Position;
|
||||
mszip.CopyTo(db.CompressedData, ms);
|
||||
long msZipDecompressedSize = ms.Position - preMsZipPosition;
|
||||
// TODO: Unsupported
|
||||
CompressionType.TYPE_QUANTUM => [],
|
||||
CompressionType.TYPE_LZX => [],
|
||||
|
||||
// Pad to the correct size but throw a warning about this
|
||||
if (msZipDecompressedSize < db.UncompressedSize)
|
||||
{
|
||||
Console.Error.WriteLine($"Data block {i} in folder {folderIndex} had mismatching sizes. Expected: {db.UncompressedSize}, Got: {msZipDecompressedSize}");
|
||||
byte[] padding = new byte[db.UncompressedSize - msZipDecompressedSize];
|
||||
ms.Write(padding, 0, padding.Length);
|
||||
}
|
||||
// Should be impossible
|
||||
_ => [],
|
||||
};
|
||||
|
||||
break;
|
||||
|
||||
// Quantum
|
||||
case CompressionType.TYPE_QUANTUM:
|
||||
// TODO: Unsupported
|
||||
break;
|
||||
|
||||
// LZX
|
||||
case CompressionType.TYPE_LZX:
|
||||
// TODO: Unsupported
|
||||
break;
|
||||
}
|
||||
// Write the uncompressed data block
|
||||
ms.Write(data, 0, data.Length);
|
||||
ms.Flush();
|
||||
}
|
||||
|
||||
return ms;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decompress an MS-ZIP block using an existing decompressor
|
||||
/// </summary>
|
||||
/// <param name="folderIndex">Index of the folder in the cabinet</param>
|
||||
/// <param name="mszip">MS-ZIP decompressor with persistent state</param>
|
||||
/// <param name="blockIndex">Index of the block within the folder</param>
|
||||
/// <param name="block">Block data to be used for decompression</param>
|
||||
/// <returns>Byte array representing the decompressed data, empty on error</returns>
|
||||
/// TODO: Remove once Serialization is updated
|
||||
private static byte[] DecompressMSZIPBlock(int folderIndex, SabreTools.Compression.MSZIP.Decompressor mszip, int blockIndex, CFDATA block)
|
||||
{
|
||||
// Ignore invalid blocks
|
||||
if (block.CompressedData == null)
|
||||
return [];
|
||||
|
||||
// Decompress to a temporary stream
|
||||
using var stream = new MemoryStream();
|
||||
mszip.CopyTo(block.CompressedData, stream);
|
||||
|
||||
// Pad to the correct size but throw a warning about this
|
||||
if (stream.Length < block.UncompressedSize)
|
||||
{
|
||||
Console.Error.WriteLine($"Data block {blockIndex} in folder {folderIndex} had mismatching sizes. Expected: {block.UncompressedSize}, Got: {stream.Length}");
|
||||
byte[] padding = new byte[block.UncompressedSize - stream.Length];
|
||||
stream.Write(padding, 0, padding.Length);
|
||||
}
|
||||
|
||||
// Return the byte array data
|
||||
return stream.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the unmasked compression type for a folder
|
||||
/// </summary>
|
||||
/// <param name="folder">Folder to get the compression type for</param>
|
||||
/// <returns>Compression type on success, <see cref="ushort.MaxValue"/> on error</returns>
|
||||
/// TODO: Remove once Serialization is updated
|
||||
private static CompressionType GetCompressionType(CFFOLDER folder)
|
||||
{
|
||||
if ((folder!.CompressionType & CompressionType.MASK_TYPE) == CompressionType.TYPE_NONE)
|
||||
|
||||
Reference in New Issue
Block a user