mirror of
https://github.com/SabreTools/SabreTools.Serialization.git
synced 2026-09-23 07:14:57 +00:00
Keep tweaking extraction
This commit is contained in:
@@ -118,7 +118,8 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// <param name="outDir">Path to the output directory</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>Indicates if all files were able to be extracted</returns>
|
||||
public static bool ExtractAll(string filename, string outDir, bool includeDebug)
|
||||
/// <remarks>Will extract all items found in the set with forward-only reading</remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract a cabinet to an output directory, if possible
|
||||
/// </summary>
|
||||
/// <param name="filename">Filename for one cabinet in the set</param>
|
||||
/// <param name="outDir">Path to the output directory</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>Indicates if all files were able to be extracted</returns>
|
||||
/// <remarks>Will read spanned folders but won't attempt to extract unrelated folders</remarks>
|
||||
public bool ExtractAll(string filename, string outDir, bool includeDebug)
|
||||
=> ExtractCabinet(filename, outDir, forwardOnly: false, includeDebug);
|
||||
|
||||
/// <summary>
|
||||
/// Extract a cabinet file to an output directory, if possible
|
||||
/// </summary>
|
||||
/// <param name="filename">Filename for one cabinet in the set</param>
|
||||
/// <param name="outDir">Path to the output directory</param>
|
||||
/// <param name="forwardOnly">Indicates if the cabinet set should only be read forward</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <param name="forwardOnly">Indicates if decompression should be done forward-only</param>
|
||||
/// <returns>Indicates if all files were able to be extracted</returns>
|
||||
private bool ExtractCabinet(string filename, string outDir, bool forwardOnly, bool includeDebug)
|
||||
{
|
||||
@@ -183,9 +195,14 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// <param name="outDir">Path to the output directory</param>
|
||||
/// <param name="folder">Folder containing the blocks to decompress</param>
|
||||
/// <param name="folderIndex">Index of the folder in the cabinet</param>
|
||||
/// <param name="forwardOnly">Indicates if the cabinet set should only be read forward</param>
|
||||
/// <param name="forwardOnly">Indicates if decompression should be done forward-only</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
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
|
||||
/// <param name="filename">Filename for one cabinet in the set</param>
|
||||
/// <param name="folder">Folder containing the blocks to decompress</param>
|
||||
/// <param name="folderIndex">Index of the folder in the cabinet</param>
|
||||
/// <param name="forwardOnly">Indicates if the cabinet set should only be read forward</param>
|
||||
/// <param name="forwardOnly">Indicates if decompression should be done forward-only</param>
|
||||
/// <returns>Stream representing the decompressed data on success, null otherwise</returns>
|
||||
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];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the set of data blocks for a folder using forward reading only
|
||||
/// </summary>
|
||||
/// <param name="filename">Filename for one cabinet in the set</param>
|
||||
/// <param name="folder">Folder containing the blocks to decompress</param>
|
||||
/// <param name="folderIndex">Index of the folder in the cabinet</param>
|
||||
/// <returns>Array of data blocks on success, null otherwise</returns>
|
||||
private CFDATA[]? GetDataBlocksForward(string filename, CFFOLDER? folder, int folderIndex)
|
||||
=> GetDataBlocks(filename, folder, folderIndex, skipPrev: true, skipNext: false);
|
||||
|
||||
/// <summary>
|
||||
/// Get all files for the current folder index
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user