diff --git a/SabreTools.Compression/Quantum/Decompressor.cs b/SabreTools.Compression/Quantum/Decompressor.cs index 00b08ac..49e156b 100644 --- a/SabreTools.Compression/Quantum/Decompressor.cs +++ b/SabreTools.Compression/Quantum/Decompressor.cs @@ -83,32 +83,25 @@ namespace SabreTools.Compression.Quantum #endregion - /// - /// Create a new Decompressor from a byte array - /// - /// Byte array to decompress - /// Number of bits in the sliding window - public Decompressor(byte[]? input, uint windowBits) - : this(new MemoryStream(input ?? []), windowBits) - { } + #region Constructors /// /// Create a new Decompressor from a Stream /// - /// Stream to decompress + /// Stream to decompress /// Number of bits in the sliding window - public Decompressor(Stream? input, uint windowBits) + private Decompressor(Stream source, uint windowBits) { - // If we have an invalid stream - if (input == null || !input.CanRead || !input.CanSeek) - throw new ArgumentException(nameof(input)); - - // If we have an invalid value for the window bits + // Validate the inputs + if (source.Length == 0) + throw new ArgumentOutOfRangeException(nameof(source)); + if (!source.CanRead) + throw new InvalidOperationException(nameof(source)); if (windowBits < 10 || windowBits > 21) throw new ArgumentOutOfRangeException(nameof(windowBits)); // Wrap the stream in a ReadOnlyBitStream - _bitStream = new ReadOnlyBitStream(input); + _bitStream = new ReadOnlyBitStream(source); // Initialize literal models _model0 = CreateModel(0, 64); @@ -132,6 +125,20 @@ namespace SabreTools.Compression.Quantum CS_C = 0; } + /// + /// Create a Quantum decompressor + /// + public static Decompressor Create(byte[] source, uint windowBits) + => Create(new MemoryStream(source), windowBits); + + /// + /// Create a Quantum decompressor + /// + public static Decompressor Create(Stream source, uint windowBits) + => new(source, windowBits); + + #endregion + /// /// Process the stream and return the decompressed output /// @@ -218,7 +225,7 @@ namespace SabreTools.Compression.Quantum } } - return bytes.ToArray(); + return [.. bytes]; } /// diff --git a/Test/Program.cs b/Test/Program.cs index 9652700..1367bc5 100644 --- a/Test/Program.cs +++ b/Test/Program.cs @@ -1,7 +1,7 @@ using System; using System.IO; using System.Text; -using SabreTools.Compression.MSZIP; +using SabreTools.Compression.Quantum; using SabreTools.IO.Extensions; using SabreTools.Models.MicrosoftCabinet; using static SabreTools.Models.MicrosoftCabinet.Constants; @@ -13,11 +13,12 @@ namespace Test public static void Main(string[] args) { // No implementation, used for experimentation + READMSZIPTEST(); } private static void READMSZIPTEST() { - using var fs = File.OpenRead("INFILE.cab"); + using var fs = File.OpenRead("/mnt/b/BurnOutSharp Testing Files/FileType/Microsoft CAB/Quantum/WORDWEB_10.CAB"); var cab = Deserialize(fs); if (cab == null || cab.Folders == null || cab.Files == null) return; @@ -28,7 +29,7 @@ namespace Test if (folder?.DataBlocks == null || folder.DataBlocks.Length == 0) continue; - var decomp = Decompressor.Create(); + uint windowBits = (uint)(((ushort)folder.CompressionType >> 8) & 0x1f); var ms = new MemoryStream(); foreach (var db in folder.DataBlocks) @@ -36,7 +37,10 @@ namespace Test if (db?.CompressedData == null) continue; - decomp.CopyTo(db.CompressedData, ms); + var decomp = Decompressor.Create(db.CompressedData, windowBits); + byte[] data = decomp.Process(); + ms.Write(data); + ms.Flush(); } if (cab?.Files == null || cab.Files.Length == 0) @@ -50,7 +54,7 @@ namespace Test byte[] fileData = new byte[file.FileSize]; Array.Copy(ms.ToArray(), file.FolderStartOffset, fileData, 0, file.FileSize); - using var of = File.OpenWrite(Path.Combine("OUTDIR", file.Name)); + using var of = File.OpenWrite(Path.Combine("/mnt/b/BurnOutSharp Testing Files/FileType/Microsoft CAB/Quantum/WORDWEB_10/", file.Name)); of.Write(fileData); of.Flush(); } @@ -220,7 +224,7 @@ namespace Test folder.CabStartOffset = data.ReadUInt32(); folder.DataCount = data.ReadUInt16(); - folder.CompressionType = (CompressionType)data.ReadUInt16() & CompressionType.MASK_TYPE; + folder.CompressionType = (CompressionType)data.ReadUInt16(); if (header.FolderReservedSize > 0) folder.ReservedData = data.ReadBytes(header.FolderReservedSize);