diff --git a/SabreTools.Serialization/Wrappers/MicrosoftCabinet.cs b/SabreTools.Serialization/Wrappers/MicrosoftCabinet.cs
index 3bd8de58..496eba64 100644
--- a/SabreTools.Serialization/Wrappers/MicrosoftCabinet.cs
+++ b/SabreTools.Serialization/Wrappers/MicrosoftCabinet.cs
@@ -118,7 +118,8 @@ namespace SabreTools.Serialization.Wrappers
/// Path to the output directory
/// True to include debug data, false otherwise
/// Indicates if all files were able to be extracted
- public static bool ExtractAll(string filename, string outDir, bool includeDebug)
+ /// Will extract all items found in the set with forward-only reading
+ public static bool ExtractSet(string filename, string outDir, bool includeDebug)
{
// Get a wrapper for the set
var current = OpenSet(filename);
@@ -144,13 +145,24 @@ namespace SabreTools.Serialization.Wrappers
return true;
}
+ ///
+ /// Extract a cabinet to an output directory, if possible
+ ///
+ /// Filename for one cabinet in the set
+ /// Path to the output directory
+ /// True to include debug data, false otherwise
+ /// Indicates if all files were able to be extracted
+ /// Will read spanned folders but won't attempt to extract unrelated folders
+ public bool ExtractAll(string filename, string outDir, bool includeDebug)
+ => ExtractCabinet(filename, outDir, forwardOnly: false, includeDebug);
+
///
/// Extract a cabinet file to an output directory, if possible
///
/// Filename for one cabinet in the set
/// Path to the output directory
- /// Indicates if the cabinet set should only be read forward
/// True to include debug data, false otherwise
+ /// Indicates if decompression should be done forward-only
/// Indicates if all files were able to be extracted
private bool ExtractCabinet(string filename, string outDir, bool forwardOnly, bool includeDebug)
{
@@ -183,9 +195,14 @@ namespace SabreTools.Serialization.Wrappers
/// Path to the output directory
/// Folder containing the blocks to decompress
/// Index of the folder in the cabinet
- /// Indicates if the cabinet set should only be read forward
+ /// Indicates if decompression should be done forward-only
/// True to include debug data, false otherwise
- private void ExtractFolder(string filename, string outDir, CFFOLDER? folder, int folderIndex, bool forwardOnly, bool includeDebug)
+ private void ExtractFolder(string filename,
+ string outDir,
+ CFFOLDER? folder,
+ int folderIndex,
+ bool forwardOnly,
+ bool includeDebug)
{
// Decompress the blocks, if possible
using var blockStream = DecompressBlocks(filename, folder, folderIndex, forwardOnly);
@@ -448,12 +465,14 @@ namespace SabreTools.Serialization.Wrappers
/// Filename for one cabinet in the set
/// Folder containing the blocks to decompress
/// Index of the folder in the cabinet
- /// Indicates if the cabinet set should only be read forward
+ /// Indicates if decompression should be done forward-only
/// Stream representing the decompressed data on success, null otherwise
public Stream? DecompressBlocks(string filename, CFFOLDER? folder, int folderIndex, bool forwardOnly)
{
// Ensure data blocks
- var dataBlocks = GetDataBlocks(filename, folder, folderIndex, skipPrev: forwardOnly, skipNext: false);
+ var dataBlocks = forwardOnly
+ ? GetDataBlocksForward(filename, folder, folderIndex)
+ : GetDataBlocks(filename, folder, folderIndex);
if (dataBlocks == null || dataBlocks.Length == 0)
return null;
@@ -481,15 +500,15 @@ namespace SabreTools.Serialization.Wrappers
// MS-ZIP
case CompressionType.TYPE_MSZIP:
- long position = ms.Position;
+ long preMsZipPosition = ms.Position;
mszip.CopyTo(db.CompressedData, ms);
- long decompressedSize = ms.Position - position;
+ long msZipDecompressedSize = ms.Position - preMsZipPosition;
// Pad to the correct size but throw a warning about this
- if (decompressedSize < db.UncompressedSize)
+ if (msZipDecompressedSize < db.UncompressedSize)
{
- Console.Error.WriteLine($"Data block {i} in folder {folderIndex} had mismatching sizes. Expected: {db.UncompressedSize}, Got: {decompressedSize}");
- byte[] padding = new byte[db.UncompressedSize - decompressedSize];
+ 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);
}
@@ -580,6 +599,16 @@ namespace SabreTools.Serialization.Wrappers
return [.. prevBlocks, .. folder.DataBlocks, .. nextBlocks];
}
+ ///
+ /// Get the set of data blocks for a folder using forward reading only
+ ///
+ /// Filename for one cabinet in the set
+ /// Folder containing the blocks to decompress
+ /// Index of the folder in the cabinet
+ /// Array of data blocks on success, null otherwise
+ private CFDATA[]? GetDataBlocksForward(string filename, CFFOLDER? folder, int folderIndex)
+ => GetDataBlocks(filename, folder, folderIndex, skipPrev: true, skipNext: false);
+
///
/// Get all files for the current folder index
///