diff --git a/BurnOutSharp/External/libmspack/BaseDecompressState.cs b/BurnOutSharp/External/libmspack/BaseDecompressState.cs
new file mode 100644
index 00000000..2cfc4c5e
--- /dev/null
+++ b/BurnOutSharp/External/libmspack/BaseDecompressState.cs
@@ -0,0 +1,36 @@
+/* This file is part of libmspack.
+ * (C) 2003-2004 Stuart Caie.
+ *
+ * libmspack is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License (LGPL) version 2.1
+ *
+ * For further details, see the file COPYING.LIB distributed with libmspack
+ */
+
+using System.IO;
+
+namespace LibMSPackSharp
+{
+ public abstract class BaseDecompressState
+ {
+ ///
+ /// System wrapper for I/O operations
+ ///
+ public SystemImpl System { get; set; }
+
+ ///
+ /// Persistent error state of the state
+ ///
+ public Error Error { get; set; }
+
+ ///
+ /// Input file handle
+ ///
+ public FileStream InputFileHandle { get; set; }
+
+ ///
+ /// Output file handle
+ ///
+ public FileStream OutputFileHandle { get; set; }
+ }
+}
diff --git a/BurnOutSharp/External/libmspack/BaseDecompressor.cs b/BurnOutSharp/External/libmspack/BaseDecompressor.cs
new file mode 100644
index 00000000..42c7f477
--- /dev/null
+++ b/BurnOutSharp/External/libmspack/BaseDecompressor.cs
@@ -0,0 +1,32 @@
+/* This file is part of libmspack.
+ * (C) 2003-2004 Stuart Caie.
+ *
+ * libmspack is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License (LGPL) version 2.1
+ *
+ * For further details, see the file COPYING.LIB distributed with libmspack
+ */
+
+namespace LibMSPackSharp
+{
+ ///
+ /// Set of common fields shared by all decompressors
+ ///
+ public abstract class BaseDecompressor
+ {
+ ///
+ /// System wrapper for I/O operations
+ ///
+ public SystemImpl System { get; set; }
+
+ ///
+ /// Persistent error state of the decompressor
+ ///
+ public Error Error { get; set; }
+
+ ///
+ /// Size of the internal buffer
+ ///
+ public int BufferSize { get; set; }
+ }
+}
diff --git a/BurnOutSharp/External/libmspack/HLP/Implementation.cs b/BurnOutSharp/External/libmspack/BaseHeader.cs
similarity index 67%
rename from BurnOutSharp/External/libmspack/HLP/Implementation.cs
rename to BurnOutSharp/External/libmspack/BaseHeader.cs
index 81d2717f..458d7540 100644
--- a/BurnOutSharp/External/libmspack/HLP/Implementation.cs
+++ b/BurnOutSharp/External/libmspack/BaseHeader.cs
@@ -7,9 +7,10 @@
* For further details, see the file COPYING.LIB distributed with libmspack
*/
-namespace LibMSPackSharp.HLP
+namespace LibMSPackSharp
{
- public class Implementation
- {
- }
+ ///
+ /// Base class for decompressor-used objects
+ ///
+ public abstract class BaseHeader { }
}
diff --git a/BurnOutSharp/External/libmspack/CAB/Cabinet.cs b/BurnOutSharp/External/libmspack/CAB/Cabinet.cs
index 7f4c42d1..d7c6a57a 100644
--- a/BurnOutSharp/External/libmspack/CAB/Cabinet.cs
+++ b/BurnOutSharp/External/libmspack/CAB/Cabinet.cs
@@ -72,7 +72,7 @@ namespace LibMSPackSharp.CAB
///
///
///
- public class Cabinet
+ public class Cabinet : BaseHeader
{
#region Internal
diff --git a/BurnOutSharp/External/libmspack/CAB/Constants.cs b/BurnOutSharp/External/libmspack/CAB/Constants.cs
deleted file mode 100644
index 522c61f2..00000000
--- a/BurnOutSharp/External/libmspack/CAB/Constants.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-/* This file is part of libmspack.
- * (C) 2003-2018 Stuart Caie.
- *
- * libmspack is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
- *
- * For further details, see the file COPYING.LIB distributed with libmspack
- */
-
-/* Cabinet (.CAB) files are a form of file archive. Each cabinet contains
- * "folders", which are compressed spans of data. Each cabinet has
- * "files", whose metadata is in the cabinet header, but whose actual data
- * is stored compressed in one of the "folders". Cabinets can span more
- * than one physical file on disk, in which case they are a "cabinet set",
- * and usually the last folder of each cabinet extends into the next
- * cabinet.
- *
- * For a complete description of the format, see the MSDN site:
- * http://msdn.microsoft.com/en-us/library/bb267310.aspx
- */
-
-/* Notes on compliance with cabinet specification:
- *
- * One of the main changes between cabextract 0.6 and libmspack's cab
- * decompressor is the move from block-oriented decompression to
- * stream-oriented decompression.
- *
- * cabextract would read one data block from disk, decompress it with the
- * appropriate method, then write the decompressed data. The CAB
- * specification is specifically designed to work like this, as it ensures
- * compression matches do not span the maximum decompressed block size
- * limit of 32kb.
- *
- * However, the compression algorithms used are stream oriented, with
- * specific hacks added to them to enforce the "individual 32kb blocks"
- * rule in CABs. In other file formats, they do not have this limitation.
- *
- * In order to make more generalised decompressors, libmspack's CAB
- * decompressor has moved from being block-oriented to more stream
- * oriented. This also makes decompression slightly faster.
- *
- * However, this leads to incompliance with the CAB specification. The
- * CAB controller can no longer ensure each block of input given to the
- * decompressors is matched with their output. The "decompressed size" of
- * each individual block is thrown away.
- *
- * Each CAB block is supposed to be seen as individually compressed. This
- * means each consecutive data block can have completely different
- * "uncompressed" sizes, ranging from 1 to 32768 bytes. However, in
- * reality, all data blocks in a folder decompress to exactly 32768 bytes,
- * excepting the final block.
- *
- * Given this situation, the decompression algorithms are designed to
- * realign their input bitstreams on 32768 output-byte boundaries, and
- * various other special cases have been made. libmspack will not
- * correctly decompress LZX or Quantum compressed folders where the blocks
- * do not follow this "32768 bytes until last block" pattern. It could be
- * implemented if needed, but hopefully this is not necessary -- it has
- * not been seen in over 3Gb of CAB archives.
- */
-
-namespace LibMSPackSharp.CAB
-{
- public static class Constants
- {
- // CAB data blocks are <= 32768 bytes in uncompressed form.Uncompressed
- // blocks have zero growth. MSZIP guarantees that it won't grow above
- // uncompressed size by more than 12 bytes.LZX guarantees it won't grow
- // more than 6144 bytes.Quantum has no documentation, but the largest
- // block seen in the wild is 337 bytes above uncompressed size.
-
- public const int CAB_BLOCKMAX = 32768;
- public const int CAB_INPUTMAX = CAB_BLOCKMAX + 6144;
-
- // input buffer needs to be CAB_INPUTMAX + 1 byte to allow for max-sized block
- // plus 1 trailer byte added by cabd_sys_read_block() for Quantum alignment.
- //
- // When MSCABD_PARAM_SALVAGE is set, block size is not checked so can be
- // up to 65535 bytes, so max input buffer size needed is 65535 + 1
-
- public const int CAB_INPUTMAX_SALVAGE = 65535;
- public const int CAB_INPUTBUF = CAB_INPUTMAX_SALVAGE + 1;
-
- // There are no more than 65535 data blocks per folder, so a folder cannot
- // be more than 32768*65535 bytes in length.As files cannot span more than
- // one folder, this is also their max offset, length and offset+length limit.
-
- public const int CAB_FOLDERMAX = 65535;
- public const int CAB_LENGTHMAX = CAB_BLOCKMAX * CAB_FOLDERMAX;
- }
-}
diff --git a/BurnOutSharp/External/libmspack/CAB/DecompressState.cs b/BurnOutSharp/External/libmspack/CAB/DecompressState.cs
index 94cceab6..08b14cd7 100644
--- a/BurnOutSharp/External/libmspack/CAB/DecompressState.cs
+++ b/BurnOutSharp/External/libmspack/CAB/DecompressState.cs
@@ -8,11 +8,10 @@
*/
using System;
-using System.IO;
namespace LibMSPackSharp.CAB
{
- public class DecompressState
+ public class DecompressState : BaseDecompressState
{
///
/// Current folder we're extracting from
@@ -39,11 +38,6 @@ namespace LibMSPackSharp.CAB
///
public long Outlen { get; set; }
- ///
- /// Special I/O code for decompressor
- ///
- public SystemImpl Sys { get; set; }
-
///
/// Type of compression used by folder
///
@@ -57,23 +51,13 @@ namespace LibMSPackSharp.CAB
///
/// Decompressor state
///
- public object DecompressorState { get; set; }
+ public BaseDecompressState DecompressorState { get; set; }
///
/// Cabinet where input data comes from
///
public Cabinet InputCabinet { get; set; }
- ///
- /// Input file handle
- ///
- public FileStream InputFileHandle { get; set; }
-
- ///
- /// Output file handle
- ///
- public FileStream OutputFileHandle { get; set; }
-
///
/// Input data consumed
///
diff --git a/BurnOutSharp/External/libmspack/CAB/Decompressor.cs b/BurnOutSharp/External/libmspack/CAB/Decompressor.cs
index 57e1492d..78665750 100644
--- a/BurnOutSharp/External/libmspack/CAB/Decompressor.cs
+++ b/BurnOutSharp/External/libmspack/CAB/Decompressor.cs
@@ -18,7 +18,7 @@ using System;
using System.IO;
using System.Text;
using LibMSPackSharp.Compression;
-using static LibMSPackSharp.CAB.Constants;
+using static LibMSPackSharp.Constants;
namespace LibMSPackSharp.CAB
{
@@ -29,24 +29,18 @@ namespace LibMSPackSharp.CAB
///
///
///
- public class Decompressor
+ public class Decompressor : BaseDecompressor
{
#region Fields
public DecompressState State { get; set; }
- public SystemImpl System { get; set; }
-
- public int BufferSize { get; set; }
-
public int SearchBufferSize { get; set; }
public bool FixMSZip { get; set; }
public bool Salvage { get; set; }
- public Error Error { get; set; }
-
public Error ReadError { get; set; }
#endregion
@@ -294,6 +288,7 @@ namespace LibMSPackSharp.CAB
///
public Error Prepend(Cabinet cab, Cabinet prevcab) => Merge(prevcab, cab);
+ ///
///
/// Extracts a file from a cabinet or cabinet set.
///
@@ -367,7 +362,7 @@ namespace LibMSPackSharp.CAB
Block = 0,
Outlen = 0,
- Sys = System,
+ System = System,
InputCabinet = fol.Data.Cab,
InputFileHandle = System.Open(fol.Data.Cab.Filename, OpenMode.MSPACK_SYS_OPEN_READ),
@@ -376,8 +371,8 @@ namespace LibMSPackSharp.CAB
InputEnd = 0,
};
- State.Sys.Read = SysRead;
- State.Sys.Write = SysWrite;
+ State.System.Read = SysRead;
+ State.System.Write = SysWrite;
if (State.InputFileHandle == null)
return Error = Error.MSPACK_ERR_OPEN;
@@ -501,22 +496,22 @@ namespace LibMSPackSharp.CAB
{
case CompressionType.COMPTYPE_NONE:
State.Decompress = None.Decompress;
- State.DecompressorState = None.Init(State.Sys, State.InputFileHandle, State.OutputFileHandle, BufferSize);
+ State.DecompressorState = None.Init(State.System, State.InputFileHandle, State.OutputFileHandle, BufferSize);
break;
case CompressionType.COMPTYPE_MSZIP:
State.Decompress = MSZIP.Decompress;
- State.DecompressorState = MSZIP.Init(State.Sys, State.InputFileHandle, State.OutputFileHandle, BufferSize, FixMSZip);
+ State.DecompressorState = MSZIP.Init(State.System, State.InputFileHandle, State.OutputFileHandle, BufferSize, FixMSZip);
break;
case CompressionType.COMPTYPE_QUANTUM:
State.Decompress = QTM.Decompress;
- State.DecompressorState = QTM.Init(State.Sys, State.InputFileHandle, State.OutputFileHandle, ((ushort)ct >> 8) & 0x1f, BufferSize);
+ State.DecompressorState = QTM.Init(State.System, State.InputFileHandle, State.OutputFileHandle, ((ushort)ct >> 8) & 0x1f, BufferSize);
break;
case CompressionType.COMPTYPE_LZX:
State.Decompress = LZX.Decompress;
- State.DecompressorState = LZX.Init(State.Sys, State.InputFileHandle, State.OutputFileHandle, ((ushort)ct >> 8) & 0x1f, 0, BufferSize, 0, false);
+ State.DecompressorState = LZX.Init(State.System, State.InputFileHandle, State.OutputFileHandle, ((ushort)ct >> 8) & 0x1f, 0, BufferSize, 0, false);
break;
default:
@@ -534,19 +529,10 @@ namespace LibMSPackSharp.CAB
switch (State.CompressionType & CompressionType.COMPTYPE_MASK)
{
case CompressionType.COMPTYPE_NONE:
- (State.DecompressorState as NoneState).Output = State.OutputFileHandle;
- break;
-
case CompressionType.COMPTYPE_MSZIP:
- (State.DecompressorState as MSZIPDStream).Output = State.OutputFileHandle;
- break;
-
case CompressionType.COMPTYPE_QUANTUM:
- (State.DecompressorState as QTMDStream).Output = State.OutputFileHandle;
- break;
-
case CompressionType.COMPTYPE_LZX:
- (State.DecompressorState as LZXDStream).Output = State.OutputFileHandle;
+ State.DecompressorState.OutputFileHandle = State.OutputFileHandle;
break;
default:
diff --git a/BurnOutSharp/External/libmspack/CHM/CHM.cs b/BurnOutSharp/External/libmspack/CHM/CHM.cs
index 6a0c33c2..50bf541a 100644
--- a/BurnOutSharp/External/libmspack/CHM/CHM.cs
+++ b/BurnOutSharp/External/libmspack/CHM/CHM.cs
@@ -21,7 +21,7 @@ namespace LibMSPackSharp.CHM
///
/// All fields are READ ONLY.
///
- public class CHM
+ public class CHM : BaseHeader
{
#region Internal
diff --git a/BurnOutSharp/External/libmspack/CHM/Constants.cs b/BurnOutSharp/External/libmspack/CHM/Constants.cs
deleted file mode 100644
index aeb7856a..00000000
--- a/BurnOutSharp/External/libmspack/CHM/Constants.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-/* This file is part of libmspack.
- * (C) 2003-2004 Stuart Caie.
- *
- * libmspack is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
- *
- * For further details, see the file COPYING.LIB distributed with libmspack
- */
-
-namespace LibMSPackSharp.CHM
-{
- public class Constants
- {
- // _PMGHeader
- internal const int pmgl_Signature = 0x0000;
- internal const int pmgl_QuickRefSize = 0x0004;
- internal const int pmgl_PMGIEntries = 0x0008; // Unknown1 in PMGL
- internal const int pmgl_PrevChunk = 0x000C; // Not in PMGI
- internal const int pmgl_NextChunk = 0x0010; // Not in PMGI
- internal const int pmgl_PMGLEntries = 0x0014; // Not in PMGI
- internal const int pmgl_headerSIZEOF = 0x0014;
- internal const int pmgi_headerSIZEOF = 0x000C;
-
- // _LZXControlData
- internal const int lzxcd_Length = 0x0000;
- internal const int lzxcd_Signature = 0x0004;
- internal const int lzxcd_Version = 0x0008;
- internal const int lzxcd_ResetInterval = 0x000C;
- internal const int lzxcd_WindowSize = 0x0010;
- internal const int lzxcd_CacheSize = 0x0014;
- internal const int lzxcd_Unknown1 = 0x0018;
- internal const int lzxcd_SIZEOF = 0x001C;
-
- // _LZXResetTable
- internal const int lzxrt_Unknown1 = 0x0000;
- internal const int lzxrt_NumEntries = 0x0004;
- internal const int lzxrt_EntrySize = 0x0008;
- internal const int lzxrt_TableOffset = 0x000C;
- internal const int lzxrt_UncompLen = 0x0010;
- internal const int lzxrt_CompLen = 0x0018;
- internal const int lzxrt_FrameLen = 0x0020;
- internal const int lzxrt_Entries = 0x0028;
- internal const int lzxrt_headerSIZEOF = 0x0028;
-
- // Filenames of the system files used for decompression.
- // - Content and ControlData are essential.
- // - ResetTable is preferred, but SpanInfo can be used if not available
- internal const string ContentName = "::DataSpace/Storage/MSCompressed/Content";
- internal const string ControlName = "::DataSpace/Storage/MSCompressed/ControlData";
- internal const string SpanInfoName = "::DataSpace/Storage/MSCompressed/SpanInfo";
- internal const string ResetTableName = "::DataSpace/Storage/MSCompressed/Transform/{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}/InstanceData/ResetTable";
- }
-}
diff --git a/BurnOutSharp/External/libmspack/CHM/DecompressState.cs b/BurnOutSharp/External/libmspack/CHM/DecompressState.cs
index 7c916af2..ab76a42b 100644
--- a/BurnOutSharp/External/libmspack/CHM/DecompressState.cs
+++ b/BurnOutSharp/External/libmspack/CHM/DecompressState.cs
@@ -7,12 +7,11 @@
* For further details, see the file COPYING.LIB distributed with libmspack
*/
-using System.IO;
using LibMSPackSharp.Compression;
namespace LibMSPackSharp.CHM
{
- public class DecompressState
+ public class DecompressState : BaseDecompressState
{
///
/// CHM file being decompressed
@@ -33,20 +32,5 @@ namespace LibMSPackSharp.CHM
/// LZX decompressor state
///
public LZXDStream State { get; set; }
-
- ///
- /// Special I/O code for decompressor
- ///
- public SystemImpl Sys { get; set; }
-
- ///
- /// Input file handle
- ///
- public FileStream InputFileHandle { get; set; }
-
- ///
- /// Output file handle
- ///
- public FileStream OutputFileHandle { get; set; }
}
}
diff --git a/BurnOutSharp/External/libmspack/CHM/Decompressor.cs b/BurnOutSharp/External/libmspack/CHM/Decompressor.cs
index bd5a99b4..ce45be21 100644
--- a/BurnOutSharp/External/libmspack/CHM/Decompressor.cs
+++ b/BurnOutSharp/External/libmspack/CHM/Decompressor.cs
@@ -18,7 +18,7 @@ using System;
using System.IO;
using System.Text;
using LibMSPackSharp.Compression;
-using static LibMSPackSharp.CHM.Constants;
+using static LibMSPackSharp.Constants;
namespace LibMSPackSharp.CHM
{
@@ -29,16 +29,12 @@ namespace LibMSPackSharp.CHM
///
///
///
- public class Decompressor
+ public class Decompressor : BaseDecompressor
{
#region Fields
- public SystemImpl System { get; set; }
-
public DecompressState State { get; set; }
- public Error Error { get; set; }
-
#endregion
#region Public Functionality
@@ -62,10 +58,7 @@ namespace LibMSPackSharp.CHM
///
/// a pointer to a mschmd_header structure, or NULL on failure
///
- public CHM Open(string filename)
- {
- return RealOpen(filename, true);
- }
+ public CHM Open(string filename) => RealOpen(filename, true);
///
/// Closes a previously opened CHM helpfile.
@@ -137,8 +130,8 @@ namespace LibMSPackSharp.CHM
State.Header = chm;
State.Offset = 0;
State.State = null;
- State.Sys = System;
- State.Sys.Write = SysWrite;
+ State.System = System;
+ State.System.Write = SysWrite;
State.InputFileHandle = null;
State.OutputFileHandle = null;
}
@@ -279,10 +272,7 @@ namespace LibMSPackSharp.CHM
///
///
///
- public CHM FastOpen(string filename)
- {
- return RealOpen(filename, false);
- }
+ public CHM FastOpen(string filename) => RealOpen(filename, false);
///
/// Finds file details quickly.
@@ -587,7 +577,7 @@ namespace LibMSPackSharp.CHM
length -= State.Offset;
// Initialise LZX stream
- State.State = LZX.Init(State.Sys, State.InputFileHandle, State.OutputFileHandle, window_bits, reset_interval / LZX.LZX_FRAME_SIZE, 4096, length, false);
+ State.State = LZX.Init(State.System, State.InputFileHandle, State.OutputFileHandle, window_bits, reset_interval / LZX.LZX_FRAME_SIZE, 4096, length, false);
if (State.State == null)
Error = Error.MSPACK_ERR_NOMEMORY;
diff --git a/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs b/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs
index 75599476..fad21319 100644
--- a/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs
+++ b/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs
@@ -11,33 +11,15 @@
*/
using System;
-using System.IO;
namespace LibMSPackSharp.Compression
{
- public abstract class CompressionStream
+ public abstract class CompressionStream : BaseDecompressState
{
private const int CHAR_BIT = 8;
public const int BITBUF_WIDTH = 4 * CHAR_BIT;
- ///
- /// I/O routines
- ///
- public SystemImpl Sys { get; set; }
-
- ///
- /// Input file handle
- ///
- public FileStream Input { get; set; }
-
- ///
- /// Output file handle
- ///
- public FileStream Output { get; set; }
-
- public Error Error { get; set; }
-
#region I/O buffering
public byte[] InputBuffer { get; set; }
@@ -135,7 +117,7 @@ namespace LibMSPackSharp.Compression
public Error ReadInput()
{
- int read = Sys.Read(Input, InputBuffer, 0, (int)InputBufferSize);
+ int read = System.Read(InputFileHandle, InputBuffer, 0, (int)InputBufferSize);
if (read < 0)
return Error = Error.MSPACK_ERR_READ;
diff --git a/BurnOutSharp/External/libmspack/KWAJ/Implementation.cs b/BurnOutSharp/External/libmspack/Compression/LZHKWAJ.cs
similarity index 71%
rename from BurnOutSharp/External/libmspack/KWAJ/Implementation.cs
rename to BurnOutSharp/External/libmspack/Compression/LZHKWAJ.cs
index c07bd21d..b4c87fa3 100644
--- a/BurnOutSharp/External/libmspack/KWAJ/Implementation.cs
+++ b/BurnOutSharp/External/libmspack/Compression/LZHKWAJ.cs
@@ -7,415 +7,39 @@
* For further details, see the file COPYING.LIB distributed with libmspack
*/
-using System;
using System.IO;
-using System.Text;
-using LibMSPackSharp.Compression;
+using LibMSPackSharp.KWAJ;
+using static LibMSPackSharp.Constants;
-namespace LibMSPackSharp.KWAJ
+namespace LibMSPackSharp.Compression
{
- public class Implementation
+ ///
+ /// In the KWAJ LZH format, there is no special 'eof' marker, it just
+ /// ends. Depending on how many bits are left in the final byte when
+ /// the stream ends, that might be enough to start another literal or
+ /// match. The only easy way to detect that we've come to an end is to
+ /// guard all bit-reading. We allow fake bits to be read once we reach
+ /// the end of the stream, but we check if we then consumed any of
+ /// those fake bits, after doing the READ_BITS / READ_HUFFSYM. This
+ /// isn't how the default ReadInput works (it simply lets
+ /// 2 fake bytes in then stops), so we implement our own.
+ ///
+ public class LZHKWAJ
{
- #region Generic KWAJ Definitions
-
- private const byte kwajh_Signature1 = 0x00;
- private const byte kwajh_Signature2 = 0x04;
- private const byte kwajh_CompMethod = 0x08;
- private const byte kwajh_DataOffset = 0x0a;
- private const byte kwajh_Flags = 0x0c;
- private const byte kwajh_SIZEOF = 0x0e;
-
- #endregion
-
- #region KWAJ Decompression Definitions
-
- // Input buffer size during decompression - not worth parameterising IMHO
- private const int KWAJ_INPUT_SIZE = (2048);
-
- // Huffman codes that are 9 bits or less are decoded immediately
- public const int KWAJ_TABLEBITS = (9);
-
- // Number of codes in each huffman table
-
- public const int KWAJ_MATCHLEN1_SYMS = (16);
- public const int KWAJ_MATCHLEN2_SYMS = (16);
- public const int KWAJ_LITLEN_SYMS = (32);
- public const int KWAJ_OFFSET_SYMS = (64);
- public const int KWAJ_LITERAL_SYMS = (256);
-
- // Define decoding table sizes
-
- public const int KWAJ_TABLESIZE = (1 << KWAJ_TABLEBITS);
-
- //public const int KWAJ_MATCHLEN1_TBLSIZE = (KWAJ_MATCHLEN1_SYMS * 4);
- public const int KWAJ_MATCHLEN1_TBLSIZE = (KWAJ_TABLESIZE + (KWAJ_MATCHLEN1_SYMS * 2));
-
- //public const int KWAJ_MATCHLEN2_TBLSIZE = (KWAJ_MATCHLEN2_SYMS * 4);
- public const int KWAJ_MATCHLEN2_TBLSIZE = (KWAJ_TABLESIZE + (KWAJ_MATCHLEN2_SYMS * 2));
-
- //public const int KWAJ_LITLEN_TBLSIZE = (KWAJ_LITLEN_SYMS * 4);
- public const int KWAJ_LITLEN_TBLSIZE = (KWAJ_TABLESIZE + (KWAJ_LITLEN_SYMS * 2));
-
- //public const int KWAJ_OFFSET_TBLSIZE = (KWAJ_OFFSET_SYMS * 4);
- public const int KWAJ_OFFSET_TBLSIZE = (KWAJ_TABLESIZE + (KWAJ_OFFSET_SYMS * 2));
-
- //public const int KWAJ_LITERAL_TBLSIZE = (KWAJ_LITERAL_SYMS * 4);
- public const int KWAJ_LITERAL_TBLSIZE = (KWAJ_TABLESIZE + (KWAJ_LITERAL_SYMS * 2));
-
- #endregion
-
- #region KWAJD_OPEN
-
- ///
- /// Opens a KWAJ file without decompressing, reads header
- ///
- public static Header Open(Decompressor d, string filename)
- {
- DecompressorImpl self = d as DecompressorImpl;
- if (self == null)
- return null;
-
- SystemImpl sys = self.System;
-
- FileStream fh = sys.Open(filename, OpenMode.MSPACK_SYS_OPEN_READ);
- HeaderImpl hdr = new HeaderImpl();
- if (fh != null && hdr != null)
- {
- hdr.FileHandle = fh;
- self.Error = ReadHeaders(sys, fh, hdr);
- }
- else
- {
- if (fh == null)
- self.Error = Error.MSPACK_ERR_OPEN;
- if (hdr == null)
- self.Error = Error.MSPACK_ERR_NOMEMORY;
- }
-
- if (self.Error != Error.MSPACK_ERR_OK)
- {
- if (fh != null)
- sys.Close(fh);
-
- hdr = null;
- }
-
- return hdr;
- }
-
- #endregion
-
- #region KWAJD_CLOSE
-
- ///
- /// Closes a KWAJ file
- ///
- public static void Close(Decompressor d, Header hdr)
- {
- DecompressorImpl self = d as DecompressorImpl;
- HeaderImpl hdr_p = hdr as HeaderImpl;
-
- if (self?.System == null || hdr_p == null)
- return;
-
- // Close the file handle associated
- self.System.Close(hdr_p.FileHandle);
-
- self.Error = Error.MSPACK_ERR_OK;
- }
-
- #endregion
-
- #region KWAJD_READ_HEADERS
-
- ///
- /// Reads the headers of a KWAJ format file
- ///
- public static Error ReadHeaders(SystemImpl sys, FileStream fh, Header hdr)
- {
- int i;
-
- // Read in the header
- byte[] buf = new byte[16];
- if (sys.Read(fh, buf, 0, kwajh_SIZEOF) != kwajh_SIZEOF)
- {
- return Error.MSPACK_ERR_READ;
- }
-
- // Check for "KWAJ" signature
- if ((BitConverter.ToUInt32(buf, kwajh_Signature1) != 0x4A41574B) ||
- (BitConverter.ToUInt32(buf, kwajh_Signature2) != 0xD127F088))
- {
- return Error.MSPACK_ERR_SIGNATURE;
- }
-
- // Basic header fields
- hdr.CompressionType = (CompressionType)BitConverter.ToUInt16(buf, kwajh_CompMethod);
- hdr.DataOffset = BitConverter.ToUInt16(buf, kwajh_DataOffset);
- hdr.Headers = (OptionalHeaderFlag)BitConverter.ToUInt16(buf, kwajh_Flags);
- hdr.Length = 0;
- hdr.Filename = null;
- hdr.Extra = null;
- hdr.ExtraLength = 0;
-
- // Optional headers
-
- // 4 bytes: length of unpacked file
- if (hdr.Headers.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASLENGTH))
- {
- if (sys.Read(fh, buf, 0, 4) != 4)
- return Error.MSPACK_ERR_READ;
-
- hdr.Length = BitConverter.ToUInt32(buf, 0);
- }
-
- // 2 bytes: unknown purpose
- if (hdr.Headers.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASUNKNOWN1))
- {
- if (sys.Read(fh, buf, 0, 2) != 2)
- return Error.MSPACK_ERR_READ;
- }
-
- // 2 bytes: length of section, then [length] bytes: unknown purpose
- if (hdr.Headers.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASUNKNOWN2))
- {
- if (sys.Read(fh, buf, 0, 2) != 2)
- return Error.MSPACK_ERR_READ;
-
- i = BitConverter.ToUInt16(buf, 0);
- if (sys.Seek(fh, i, SeekMode.MSPACK_SYS_SEEK_CUR))
- return Error.MSPACK_ERR_SEEK;
- }
-
- // Filename and extension
- if (hdr.Headers.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASFILENAME) || hdr.Headers.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASFILEEXT))
- {
- int len;
-
- // Allocate memory for maximum length filename
- char[] fn = new char[13];
- int fnPtr = 0;
-
- // Copy filename if present
- if (hdr.Headers.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASFILENAME))
- {
- // Read and copy up to 9 bytes of a null terminated string
- if ((len = sys.Read(fh, buf, 0, 9)) < 2)
- return Error.MSPACK_ERR_READ;
-
- for (i = 0; i < len; i++)
- {
- if ((fn[fnPtr++] = (char)buf[i]) == '\0')
- break;
- }
-
- // If string was 9 bytes with no null terminator, reject it
- if (i == 9 && buf[8] != '\0')
- return Error.MSPACK_ERR_DATAFORMAT;
-
- // Seek to byte after string ended in file
- if (sys.Seek(fh, i + 1 - len, SeekMode.MSPACK_SYS_SEEK_CUR))
- return Error.MSPACK_ERR_SEEK;
-
- fnPtr--; // Remove the null terminator
- }
-
- // Copy extension if present
- if (hdr.Headers.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASFILEEXT))
- {
- fn[fnPtr++] = '.';
-
- // Read and copy up to 4 bytes of a null terminated string
- if ((len = sys.Read(fh, buf, 0, 4)) < 2)
- return Error.MSPACK_ERR_READ;
-
- for (i = 0; i < len; i++)
- {
- if ((fn[fnPtr++] = (char)buf[i]) == '\0')
- break;
- }
-
- // If string was 4 bytes with no null terminator, reject it
- if (i == 4 && buf[3] != '\0')
- return Error.MSPACK_ERR_DATAFORMAT;
-
- // Seek to byte after string ended in file
- if (sys.Seek(fh, i + 1 - len, SeekMode.MSPACK_SYS_SEEK_CUR))
- return Error.MSPACK_ERR_SEEK;
-
- fnPtr--; // Remove the null terminator
- }
-
- fn[fnPtr] = '\0';
- }
-
- // 2 bytes: extra text length then [length] bytes of extra text data
- if (hdr.Headers.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASEXTRATEXT))
- {
- if (sys.Read(fh, buf, 0, 2) != 2)
- return Error.MSPACK_ERR_READ;
-
- i = BitConverter.ToUInt16(buf, 0);
- byte[] extra = new byte[i + 1];
- if (sys.Read(fh, extra, 0, i) != i)
- return Error.MSPACK_ERR_READ;
-
- extra[i] = 0x00;
- hdr.Extra = Encoding.ASCII.GetString(extra, 0, extra.Length);
- hdr.ExtraLength = (ushort)i;
- }
-
- return Error.MSPACK_ERR_OK;
- }
-
- #endregion
-
- #region KWAJD_EXTRACT
-
- ///
- /// Decompresses a KWAJ file
- ///
- public static Error Extract(Decompressor d, Header hdr, string filename)
- {
- DecompressorImpl self = d as DecompressorImpl;
- if (self == null)
- return Error.MSPACK_ERR_ARGS;
- if (hdr == null)
- return self.Error = Error.MSPACK_ERR_ARGS;
-
- SystemImpl sys = self.System;
- FileStream fh = (hdr as HeaderImpl)?.FileHandle;
- if (fh == null)
- return Error.MSPACK_ERR_ARGS;
-
- // Seek to the compressed data
- if (sys.Seek(fh, hdr.DataOffset, SeekMode.MSPACK_SYS_SEEK_START))
- return self.Error = Error.MSPACK_ERR_SEEK;
-
- // Open file for output
- FileStream outfh;
- if ((outfh = sys.Open(filename, OpenMode.MSPACK_SYS_OPEN_WRITE)) == null)
- return self.Error = Error.MSPACK_ERR_OPEN;
-
- self.Error = Error.MSPACK_ERR_OK;
-
- // Decompress based on format
- if (hdr.CompressionType == CompressionType.MSKWAJ_COMP_NONE ||
- hdr.CompressionType == CompressionType.MSKWAJ_COMP_XOR)
- {
- // NONE is a straight copy. XOR is a copy xored with 0xFF
- byte[] buf = new byte[KWAJ_INPUT_SIZE];
-
- int read, i;
- while ((read = sys.Read(fh, buf, 0, KWAJ_INPUT_SIZE)) > 0)
- {
- if (hdr.CompressionType == CompressionType.MSKWAJ_COMP_XOR)
- {
- for (i = 0; i < read; i++)
- {
- buf[i] ^= 0xFF;
- }
- }
-
- if (sys.Write(outfh, buf, 0, read) != read)
- {
- self.Error = Error.MSPACK_ERR_WRITE;
- break;
- }
- }
-
- if (read < 0)
- self.Error = Error.MSPACK_ERR_READ;
- }
- else if (hdr.CompressionType == CompressionType.MSKWAJ_COMP_SZDD)
- {
- self.Error = LZSS.Decompress(sys, fh, outfh, KWAJ_INPUT_SIZE, LZSSMode.LZSS_MODE_EXPAND);
- }
- else if (hdr.CompressionType == CompressionType.MSKWAJ_COMP_LZH)
- {
- LZHKWAJStream lzh = LZHInit(sys, fh, outfh);
- self.Error = (lzh != null) ? LZHDecompress(lzh) : Error.MSPACK_ERR_NOMEMORY;
- }
- else if (hdr.CompressionType == CompressionType.MSKWAJ_COMP_MSZIP)
- {
- MSZIPDStream zip = MSZIP.Init(sys, fh, outfh, KWAJ_INPUT_SIZE, false);
- self.Error = (zip != null) ? MSZIP.DecompressKWAJ(zip) : Error.MSPACK_ERR_NOMEMORY;
- }
- else
- {
- self.Error = Error.MSPACK_ERR_DATAFORMAT;
- }
-
- // Close output file
- sys.Close(outfh);
-
- return self.Error;
- }
-
- #endregion
-
- #region KWAJD_DECOMPRESS
-
- ///
- /// Unpacks directly from input to output
- ///
- public static Error Decompress(Decompressor d, string input, string output)
- {
- DecompressorImpl self = d as DecompressorImpl;
- if (self == null)
- return Error.MSPACK_ERR_ARGS;
-
- Header hdr;
- if ((hdr = Open(d, input)) == null)
- return self.Error;
-
- Error error = Extract(d, hdr, output);
- Close(d, hdr);
- return self.Error = error;
- }
-
- #endregion
-
- #region KWAJD_ERROR
-
- ///
- /// Returns the last error that occurred
- ///
- public static Error LastError(Decompressor d)
- {
- DecompressorImpl self = d as DecompressorImpl;
- return (self != null) ? self.Error : Error.MSPACK_ERR_ARGS;
- }
-
- #endregion
-
- #region LZH_INIT, LZH_DECOMPRESS, LZH_FREE
-
- /* In the KWAJ LZH format, there is no special 'eof' marker, it just
- * ends. Depending on how many bits are left in the final byte when
- * the stream ends, that might be enough to start another literal or
- * match. The only easy way to detect that we've come to an end is to
- * guard all bit-reading. We allow fake bits to be read once we reach
- * the end of the stream, but we check if we then consumed any of
- * those fake bits, after doing the READ_BITS / READ_HUFFSYM. This
- * isn't how the default readbits.h read_input() works (it simply lets
- * 2 fake bytes in then stops), so we implement our own.
- */
-
- private static LZHKWAJStream LZHInit(SystemImpl sys, FileStream input, FileStream output)
+ public static LZHKWAJStream Init(SystemImpl sys, FileStream input, FileStream output)
{
if (sys == null || input == null || output == null)
return null;
return new LZHKWAJStream()
{
- Sys = sys,
- Input = input,
- Output = output,
+ System = sys,
+ InputFileHandle = input,
+ OutputFileHandle = output,
};
}
- private static Error LZHDecompress(LZHKWAJStream lzh)
+ public static Error Decompress(LZHKWAJStream lzh)
{
uint bit_buffer;
int bits_left, i;
@@ -464,7 +88,7 @@ namespace LibMSPackSharp.KWAJ
{
if (i_ptr >= i_end)
{
- if ((err = LZHReadInput(lzh)) != Error.MSPACK_ERR_OK)
+ if ((err = ReadInput(lzh)) != Error.MSPACK_ERR_OK)
return err;
i_ptr = lzh.InputPointer;
@@ -506,7 +130,7 @@ namespace LibMSPackSharp.KWAJ
lzh.BitsLeft = bits_left;
}
- err = LZHReadLens(lzh, types[0], KWAJ_MATCHLEN1_SYMS, lzh.MATCHLEN1_len);
+ err = ReadLens(lzh, types[0], KWAJ_MATCHLEN1_SYMS, lzh.MATCHLEN1_len);
if (err != Error.MSPACK_ERR_OK)
return err;
@@ -532,7 +156,7 @@ namespace LibMSPackSharp.KWAJ
lzh.BitsLeft = bits_left;
}
- err = LZHReadLens(lzh, types[1], KWAJ_MATCHLEN2_SYMS, lzh.MATCHLEN2_len);
+ err = ReadLens(lzh, types[1], KWAJ_MATCHLEN2_SYMS, lzh.MATCHLEN2_len);
if (err != Error.MSPACK_ERR_OK)
return err;
@@ -558,7 +182,7 @@ namespace LibMSPackSharp.KWAJ
lzh.BitsLeft = bits_left;
}
- err = LZHReadLens(lzh, types[2], KWAJ_LITLEN_SYMS, lzh.LITLEN_len);
+ err = ReadLens(lzh, types[2], KWAJ_LITLEN_SYMS, lzh.LITLEN_len);
if (err != Error.MSPACK_ERR_OK)
return err;
@@ -584,7 +208,7 @@ namespace LibMSPackSharp.KWAJ
lzh.BitsLeft = bits_left;
}
- err = LZHReadLens(lzh, types[3], KWAJ_OFFSET_SYMS, lzh.OFFSET_len);
+ err = ReadLens(lzh, types[3], KWAJ_OFFSET_SYMS, lzh.OFFSET_len);
if (err != Error.MSPACK_ERR_OK)
return err;
@@ -610,7 +234,7 @@ namespace LibMSPackSharp.KWAJ
lzh.BitsLeft = bits_left;
}
- err = LZHReadLens(lzh, types[4], KWAJ_LITERAL_SYMS, lzh.LITERAL_len);
+ err = ReadLens(lzh, types[4], KWAJ_LITERAL_SYMS, lzh.LITERAL_len);
if (err != Error.MSPACK_ERR_OK)
return err;
@@ -642,7 +266,7 @@ namespace LibMSPackSharp.KWAJ
{
if (i_ptr >= i_end)
{
- if ((err = LZHReadInput(lzh)) != Error.MSPACK_ERR_OK)
+ if ((err = ReadInput(lzh)) != Error.MSPACK_ERR_OK)
return err;
i_ptr = lzh.InputPointer;
@@ -702,7 +326,7 @@ namespace LibMSPackSharp.KWAJ
{
if (i_ptr >= i_end)
{
- if ((err = LZHReadInput(lzh)) != Error.MSPACK_ERR_OK)
+ if ((err = ReadInput(lzh)) != Error.MSPACK_ERR_OK)
return err;
i_ptr = lzh.InputPointer;
@@ -766,7 +390,7 @@ namespace LibMSPackSharp.KWAJ
{
if (i_ptr >= i_end)
{
- if ((err = LZHReadInput(lzh)) != Error.MSPACK_ERR_OK)
+ if ((err = ReadInput(lzh)) != Error.MSPACK_ERR_OK)
return err;
i_ptr = lzh.InputPointer;
@@ -826,7 +450,7 @@ namespace LibMSPackSharp.KWAJ
{
if (i_ptr >= i_end)
{
- if ((err = LZHReadInput(lzh)) != Error.MSPACK_ERR_OK)
+ if ((err = ReadInput(lzh)) != Error.MSPACK_ERR_OK)
return err;
i_ptr = lzh.InputPointer;
@@ -864,7 +488,7 @@ namespace LibMSPackSharp.KWAJ
//WRITE_BYTE
{
- if (lzh.Sys.Write(lzh.Output, lzh.Window, pos, 1) != 1)
+ if (lzh.System.Write(lzh.OutputFileHandle, lzh.Window, pos, 1) != 1)
return Error.MSPACK_ERR_WRITE;
}
@@ -886,7 +510,7 @@ namespace LibMSPackSharp.KWAJ
{
if (i_ptr >= i_end)
{
- if ((err = LZHReadInput(lzh)) != Error.MSPACK_ERR_OK)
+ if ((err = ReadInput(lzh)) != Error.MSPACK_ERR_OK)
return err;
i_ptr = lzh.InputPointer;
@@ -948,7 +572,7 @@ namespace LibMSPackSharp.KWAJ
{
if (i_ptr >= i_end)
{
- if ((err = LZHReadInput(lzh)) != Error.MSPACK_ERR_OK)
+ if ((err = ReadInput(lzh)) != Error.MSPACK_ERR_OK)
return err;
i_ptr = lzh.InputPointer;
@@ -999,7 +623,7 @@ namespace LibMSPackSharp.KWAJ
//WRITE_BYTE
{
- if (lzh.Sys.Write(lzh.Output, lzh.Window, pos, 1) != 1)
+ if (lzh.System.Write(lzh.OutputFileHandle, lzh.Window, pos, 1) != 1)
return Error.MSPACK_ERR_WRITE;
}
@@ -1011,7 +635,7 @@ namespace LibMSPackSharp.KWAJ
return Error.MSPACK_ERR_OK;
}
- public static Error LZHReadLens(LZHKWAJStream lzh, uint type, uint numsyms, byte[] lens)
+ private static Error ReadLens(LZHKWAJStream lzh, uint type, uint numsyms, byte[] lens)
{
uint bit_buffer;
int bits_left;
@@ -1052,7 +676,7 @@ namespace LibMSPackSharp.KWAJ
{
if (i_ptr >= i_end)
{
- if ((err = LZHReadInput(lzh)) != Error.MSPACK_ERR_OK)
+ if ((err = ReadInput(lzh)) != Error.MSPACK_ERR_OK)
return err;
i_ptr = lzh.InputPointer;
@@ -1096,7 +720,7 @@ namespace LibMSPackSharp.KWAJ
{
if (i_ptr >= i_end)
{
- if ((err = LZHReadInput(lzh)) != Error.MSPACK_ERR_OK)
+ if ((err = ReadInput(lzh)) != Error.MSPACK_ERR_OK)
return err;
i_ptr = lzh.InputPointer;
@@ -1143,7 +767,7 @@ namespace LibMSPackSharp.KWAJ
{
if (i_ptr >= i_end)
{
- if ((err = LZHReadInput(lzh)) != Error.MSPACK_ERR_OK)
+ if ((err = ReadInput(lzh)) != Error.MSPACK_ERR_OK)
return err;
i_ptr = lzh.InputPointer;
@@ -1190,7 +814,7 @@ namespace LibMSPackSharp.KWAJ
{
if (i_ptr >= i_end)
{
- if ((err = LZHReadInput(lzh)) != Error.MSPACK_ERR_OK)
+ if ((err = ReadInput(lzh)) != Error.MSPACK_ERR_OK)
return err;
i_ptr = lzh.InputPointer;
@@ -1239,7 +863,7 @@ namespace LibMSPackSharp.KWAJ
{
if (i_ptr >= i_end)
{
- if ((err = LZHReadInput(lzh)) != Error.MSPACK_ERR_OK)
+ if ((err = ReadInput(lzh)) != Error.MSPACK_ERR_OK)
return err;
i_ptr = lzh.InputPointer;
@@ -1283,7 +907,7 @@ namespace LibMSPackSharp.KWAJ
{
if (i_ptr >= i_end)
{
- if ((err = LZHReadInput(lzh)) != Error.MSPACK_ERR_OK)
+ if ((err = ReadInput(lzh)) != Error.MSPACK_ERR_OK)
return err;
i_ptr = lzh.InputPointer;
@@ -1326,7 +950,7 @@ namespace LibMSPackSharp.KWAJ
{
if (i_ptr >= i_end)
{
- if ((err = LZHReadInput(lzh)) != Error.MSPACK_ERR_OK)
+ if ((err = ReadInput(lzh)) != Error.MSPACK_ERR_OK)
return err;
i_ptr = lzh.InputPointer;
@@ -1380,7 +1004,7 @@ namespace LibMSPackSharp.KWAJ
{
if (i_ptr >= i_end)
{
- if ((err = LZHReadInput(lzh)) != Error.MSPACK_ERR_OK)
+ if ((err = ReadInput(lzh)) != Error.MSPACK_ERR_OK)
return err;
i_ptr = lzh.InputPointer;
@@ -1426,7 +1050,7 @@ namespace LibMSPackSharp.KWAJ
return Error.MSPACK_ERR_OK;
}
- public static Error LZHReadInput(LZHKWAJStream lzh)
+ private static Error ReadInput(LZHKWAJStream lzh)
{
int read;
if (lzh.InputEnd != 0)
@@ -1437,7 +1061,7 @@ namespace LibMSPackSharp.KWAJ
}
else
{
- read = lzh.Sys.Read(lzh.Input, lzh.InputBuffer, 0, KWAJ_INPUT_SIZE);
+ read = lzh.System.Read(lzh.InputFileHandle, lzh.InputBuffer, 0, KWAJ_INPUT_SIZE);
if (read < 0)
return Error.MSPACK_ERR_READ;
@@ -1454,7 +1078,5 @@ namespace LibMSPackSharp.KWAJ
lzh.InputLength = read;
return Error.MSPACK_ERR_OK;
}
-
- #endregion
}
}
diff --git a/BurnOutSharp/External/libmspack/KWAJ/LZHKWAJStream.cs b/BurnOutSharp/External/libmspack/Compression/LZHKWAJStream.cs
similarity index 54%
rename from BurnOutSharp/External/libmspack/KWAJ/LZHKWAJStream.cs
rename to BurnOutSharp/External/libmspack/Compression/LZHKWAJStream.cs
index 36442df1..c7bd28d1 100644
--- a/BurnOutSharp/External/libmspack/KWAJ/LZHKWAJStream.cs
+++ b/BurnOutSharp/External/libmspack/Compression/LZHKWAJStream.cs
@@ -7,27 +7,27 @@
* For further details, see the file COPYING.LIB distributed with libmspack
*/
-using LibMSPackSharp.Compression;
+using static LibMSPackSharp.Constants;
-namespace LibMSPackSharp.KWAJ
+namespace LibMSPackSharp.Compression
{
public class LZHKWAJStream : CompressionStream
{
// Huffman code lengths
- public byte[] MATCHLEN1_len { get; set; } = new byte[Implementation.KWAJ_MATCHLEN1_SYMS];
- public byte[] MATCHLEN2_len { get; set; } = new byte[Implementation.KWAJ_MATCHLEN2_SYMS];
- public byte[] LITLEN_len { get; set; } = new byte[Implementation.KWAJ_LITLEN_SYMS];
- public byte[] OFFSET_len { get; set; } = new byte[Implementation.KWAJ_OFFSET_SYMS];
- public byte[] LITERAL_len { get; set; } = new byte[Implementation.KWAJ_LITERAL_SYMS];
+ public byte[] MATCHLEN1_len { get; set; } = new byte[KWAJ_MATCHLEN1_SYMS];
+ public byte[] MATCHLEN2_len { get; set; } = new byte[KWAJ_MATCHLEN2_SYMS];
+ public byte[] LITLEN_len { get; set; } = new byte[KWAJ_LITLEN_SYMS];
+ public byte[] OFFSET_len { get; set; } = new byte[KWAJ_OFFSET_SYMS];
+ public byte[] LITERAL_len { get; set; } = new byte[KWAJ_LITERAL_SYMS];
// Huffman decoding tables
- public ushort[] MATCHLEN1_table { get; set; } = new ushort[Implementation.KWAJ_MATCHLEN1_TBLSIZE];
- public ushort[] MATCHLEN2_table { get; set; } = new ushort[Implementation.KWAJ_MATCHLEN2_TBLSIZE];
- public ushort[] LITLEN_table { get; set; } = new ushort[Implementation.KWAJ_LITLEN_TBLSIZE];
- public ushort[] OFFSET_table { get; set; } = new ushort[Implementation.KWAJ_OFFSET_TBLSIZE];
- public ushort[] LITERAL_table { get; set; } = new ushort[Implementation.KWAJ_LITERAL_TBLSIZE];
+ public ushort[] MATCHLEN1_table { get; set; } = new ushort[KWAJ_MATCHLEN1_TBLSIZE];
+ public ushort[] MATCHLEN2_table { get; set; } = new ushort[KWAJ_MATCHLEN2_TBLSIZE];
+ public ushort[] LITLEN_table { get; set; } = new ushort[KWAJ_LITLEN_TBLSIZE];
+ public ushort[] OFFSET_table { get; set; } = new ushort[KWAJ_OFFSET_TBLSIZE];
+ public ushort[] LITERAL_table { get; set; } = new ushort[KWAJ_LITERAL_TBLSIZE];
// History window
diff --git a/BurnOutSharp/External/libmspack/Compression/LZX.cs b/BurnOutSharp/External/libmspack/Compression/LZX.cs
index 3c4e0633..9bb464a6 100644
--- a/BurnOutSharp/External/libmspack/Compression/LZX.cs
+++ b/BurnOutSharp/External/libmspack/Compression/LZX.cs
@@ -191,8 +191,6 @@ namespace LibMSPackSharp.Compression
private static void ResetState(LZXDStream lzx)
{
- int i;
-
lzx.R0 = 1;
lzx.R1 = 1;
lzx.R2 = 1;
@@ -201,12 +199,12 @@ namespace LibMSPackSharp.Compression
lzx.BlockType = LZXBlockType.LZX_BLOCKTYPE_INVALID0;
// Initialise tables to 0 (because deltas will be applied to them)
- for (i = 0; i < LZX_MAINTREE_MAXSYMBOLS; i++)
+ for (int i = 0; i < LZX_MAINTREE_MAXSYMBOLS; i++)
{
lzx.MAINTREE_len[i] = 0;
}
- for (i = 0; i < LZX_LENGTH_MAXSYMBOLS; i++)
+ for (int i = 0; i < LZX_LENGTH_MAXSYMBOLS; i++)
{
lzx.LENGTH_len[i] = 0;
}
@@ -307,9 +305,9 @@ namespace LibMSPackSharp.Compression
Window = new byte[window_size],
InputBuffer = new byte[input_buffer_size],
- Sys = system,
- Input = input,
- Output = output,
+ System = system,
+ InputFileHandle = input,
+ OutputFileHandle = output,
Offset = 0,
Length = output_length,
@@ -472,7 +470,7 @@ namespace LibMSPackSharp.Compression
if (i != 0)
{
- try { lzx.Sys.Write(lzx.Output, lzx.e8_buf, lzx.OutputPointer, i); }
+ try { lzx.System.Write(lzx.OutputFileHandle, lzx.e8_buf, lzx.OutputPointer, i); }
catch { return lzx.Error = Error.MSPACK_ERR_WRITE; }
lzx.OutputPointer += i;
@@ -512,7 +510,7 @@ namespace LibMSPackSharp.Compression
Console.WriteLine($"{lzx.BlockRemaining} bytes remaining at reset interval");
if (warned == 0)
{
- lzx.Sys.Message(null, "WARNING; invalid reset interval detected during LZX decompression");
+ lzx.System.Message(null, "WARNING; invalid reset interval detected during LZX decompression");
warned++;
}
}
@@ -577,182 +575,6 @@ namespace LibMSPackSharp.Compression
}
}
- // Read header if necessary
- if (lzx.HeaderRead == 0)
- {
- // Read 1 bit. if bit=0, intel_filesize = 0.
- // if bit=1, read intel filesize (32 bits)
- j = 0;
-
- //READ_BITS(i, 1)
- {
- //ENSURE_BITS(1)
- {
- while (bits_left < (1))
- {
- //READ_BYTES
- {
- //READ_IF_NEEDED
- {
- if (i_ptr >= i_end)
- {
- if (lzx.ReadInput() != Error.MSPACK_ERR_OK)
- return lzx.Error;
-
- i_ptr = lzx.InputPointer;
- i_end = lzx.InputLength;
- }
- }
-
- byte b0 = lzx.InputBuffer[i_ptr++];
-
- //READ_IF_NEEDED
- {
- if (i_ptr >= i_end)
- {
- if (lzx.ReadInput() != Error.MSPACK_ERR_OK)
- return lzx.Error;
-
- i_ptr = lzx.InputPointer;
- i_end = lzx.InputLength;
- }
- }
-
- byte b1 = lzx.InputBuffer[i_ptr++];
-
- //INJECT_BITS((b1 << 8) | b0, 16)
- {
- bit_buffer |= (uint)((b1 << 8) | b0) << (CompressionStream.BITBUF_WIDTH - (16) - bits_left);
- bits_left += (16);
- }
- }
- }
- }
-
- (i) = (int)(bit_buffer >> (CompressionStream.BITBUF_WIDTH - (1))); //PEEK_BITS(1)
-
- //REMOVE_BITS(1)
- {
- bit_buffer <<= (1);
- bits_left -= (1);
- }
- }
-
- if (i != 0)
- {
- //READ_BITS(i, 16)
- {
- //ENSURE_BITS(16)
- {
- while (bits_left < (16))
- {
- //READ_BYTES
- {
- //READ_IF_NEEDED
- {
- if (i_ptr >= i_end)
- {
- if (lzx.ReadInput() != Error.MSPACK_ERR_OK)
- return lzx.Error;
-
- i_ptr = lzx.InputPointer;
- i_end = lzx.InputLength;
- }
- }
-
- byte b0 = lzx.InputBuffer[i_ptr++];
-
- //READ_IF_NEEDED
- {
- if (i_ptr >= i_end)
- {
- if (lzx.ReadInput() != Error.MSPACK_ERR_OK)
- return lzx.Error;
-
- i_ptr = lzx.InputPointer;
- i_end = lzx.InputLength;
- }
- }
-
- byte b1 = lzx.InputBuffer[i_ptr++];
-
- //INJECT_BITS((b1 << 8) | b0, 16)
- {
- bit_buffer |= (uint)((b1 << 8) | b0) << (CompressionStream.BITBUF_WIDTH - (16) - bits_left);
- bits_left += (16);
- }
- }
- }
- }
-
- (i) = (int)(bit_buffer >> (CompressionStream.BITBUF_WIDTH - (16))); //PEEK_BITS(16)
-
- //REMOVE_BITS(16)
- {
- bit_buffer <<= (16);
- bits_left -= (16);
- }
- }
-
- //READ_BITS(j, 16)
- {
- //ENSURE_BITS(16)
- {
- while (bits_left < (16))
- {
- //READ_BYTES
- {
- //READ_IF_NEEDED
- {
- if (i_ptr >= i_end)
- {
- if (lzx.ReadInput() != Error.MSPACK_ERR_OK)
- return lzx.Error;
-
- i_ptr = lzx.InputPointer;
- i_end = lzx.InputLength;
- }
- }
-
- byte b0 = lzx.InputBuffer[i_ptr++];
-
- //READ_IF_NEEDED
- {
- if (i_ptr >= i_end)
- {
- if (lzx.ReadInput() != Error.MSPACK_ERR_OK)
- return lzx.Error;
-
- i_ptr = lzx.InputPointer;
- i_end = lzx.InputLength;
- }
- }
-
- byte b1 = lzx.InputBuffer[i_ptr++];
-
- //INJECT_BITS((b1 << 8) | b0, 16)
- {
- bit_buffer |= (uint)((b1 << 8) | b0) << (CompressionStream.BITBUF_WIDTH - (16) - bits_left);
- bits_left += (16);
- }
- }
- }
- }
-
- (j) = (int)(bit_buffer >> (CompressionStream.BITBUF_WIDTH - (16))); //PEEK_BITS(16)
-
- //REMOVE_BITS(16)
- {
- bit_buffer <<= (16);
- bits_left -= (16);
- }
- }
- }
-
- lzx.IntelFileSize = (i << 16) | j;
- lzx.HeaderRead = 1;
- }
-
// Calculate size of frame: all frames are 32k except the final frame
// which is 32kb or less. this can only be calculated when lzx.Length
// has been filled in.
@@ -789,7 +611,7 @@ namespace LibMSPackSharp.Compression
//READ_BITS(lzx.BlockType, 3)
{
- //ENSURE_BITS(3)
+ //ENSURE_BITS(3) // THIS IS NOT 3 BECAUSE OF OTHER CODE I FOUND
{
while (bits_left < (3))
{
@@ -841,6 +663,182 @@ namespace LibMSPackSharp.Compression
}
}
+ // Read header if necessary
+ if (lzx.HeaderRead == 0)
+ {
+ // Read 1 bit. if bit=0, intel_filesize = 0.
+ // if bit=1, read intel filesize (32 bits)
+ j = 0;
+
+ //READ_BITS(i, 1)
+ {
+ //ENSURE_BITS(1)
+ {
+ while (bits_left < (1))
+ {
+ //READ_BYTES
+ {
+ //READ_IF_NEEDED
+ {
+ if (i_ptr >= i_end)
+ {
+ if (lzx.ReadInput() != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
+ i_ptr = lzx.InputPointer;
+ i_end = lzx.InputLength;
+ }
+ }
+
+ byte b0 = lzx.InputBuffer[i_ptr++];
+
+ //READ_IF_NEEDED
+ {
+ if (i_ptr >= i_end)
+ {
+ if (lzx.ReadInput() != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
+ i_ptr = lzx.InputPointer;
+ i_end = lzx.InputLength;
+ }
+ }
+
+ byte b1 = lzx.InputBuffer[i_ptr++];
+
+ //INJECT_BITS((b1 << 8) | b0, 16)
+ {
+ bit_buffer |= (uint)((b1 << 8) | b0) << (CompressionStream.BITBUF_WIDTH - (16) - bits_left);
+ bits_left += (16);
+ }
+ }
+ }
+ }
+
+ (i) = (int)(bit_buffer >> (CompressionStream.BITBUF_WIDTH - (1))); //PEEK_BITS(1)
+
+ //REMOVE_BITS(1)
+ {
+ bit_buffer <<= (1);
+ bits_left -= (1);
+ }
+ }
+
+ if (i != 0)
+ {
+ //READ_BITS(i, 16)
+ {
+ //ENSURE_BITS(16)
+ {
+ while (bits_left < (16))
+ {
+ //READ_BYTES
+ {
+ //READ_IF_NEEDED
+ {
+ if (i_ptr >= i_end)
+ {
+ if (lzx.ReadInput() != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
+ i_ptr = lzx.InputPointer;
+ i_end = lzx.InputLength;
+ }
+ }
+
+ byte b0 = lzx.InputBuffer[i_ptr++];
+
+ //READ_IF_NEEDED
+ {
+ if (i_ptr >= i_end)
+ {
+ if (lzx.ReadInput() != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
+ i_ptr = lzx.InputPointer;
+ i_end = lzx.InputLength;
+ }
+ }
+
+ byte b1 = lzx.InputBuffer[i_ptr++];
+
+ //INJECT_BITS((b1 << 8) | b0, 16)
+ {
+ bit_buffer |= (uint)((b1 << 8) | b0) << (CompressionStream.BITBUF_WIDTH - (16) - bits_left);
+ bits_left += (16);
+ }
+ }
+ }
+ }
+
+ (i) = (int)(bit_buffer >> (CompressionStream.BITBUF_WIDTH - (16))); //PEEK_BITS(16)
+
+ //REMOVE_BITS(16)
+ {
+ bit_buffer <<= (16);
+ bits_left -= (16);
+ }
+ }
+
+ //READ_BITS(j, 16)
+ {
+ //ENSURE_BITS(16)
+ {
+ while (bits_left < (16))
+ {
+ //READ_BYTES
+ {
+ //READ_IF_NEEDED
+ {
+ if (i_ptr >= i_end)
+ {
+ if (lzx.ReadInput() != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
+ i_ptr = lzx.InputPointer;
+ i_end = lzx.InputLength;
+ }
+ }
+
+ byte b0 = lzx.InputBuffer[i_ptr++];
+
+ //READ_IF_NEEDED
+ {
+ if (i_ptr >= i_end)
+ {
+ if (lzx.ReadInput() != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
+ i_ptr = lzx.InputPointer;
+ i_end = lzx.InputLength;
+ }
+ }
+
+ byte b1 = lzx.InputBuffer[i_ptr++];
+
+ //INJECT_BITS((b1 << 8) | b0, 16)
+ {
+ bit_buffer |= (uint)((b1 << 8) | b0) << (CompressionStream.BITBUF_WIDTH - (16) - bits_left);
+ bits_left += (16);
+ }
+ }
+ }
+ }
+
+ (j) = (int)(bit_buffer >> (CompressionStream.BITBUF_WIDTH - (16))); //PEEK_BITS(16)
+
+ //REMOVE_BITS(16)
+ {
+ bit_buffer <<= (16);
+ bits_left -= (16);
+ }
+ }
+ }
+
+ lzx.IntelFileSize = (i << 16) | j;
+ lzx.HeaderRead = 1;
+ }
+
//READ_BITS(i, 16)
{
//ENSURE_BITS(16)
@@ -2415,7 +2413,7 @@ namespace LibMSPackSharp.Compression
// Write a frame
i = (int)((out_bytes < frame_size) ? out_bytes : frame_size);
- try { lzx.Output.Write(lzx.e8_buf, lzx.OutputPointer, i); }
+ try { lzx.System.Write(lzx.OutputFileHandle, lzx.e8_buf, lzx.OutputPointer, i); }
catch { return lzx.Error = Error.MSPACK_ERR_WRITE; }
}
else
@@ -2425,7 +2423,7 @@ namespace LibMSPackSharp.Compression
// Write a frame
i = (int)((out_bytes < frame_size) ? out_bytes : frame_size);
- try { lzx.Output.Write(lzx.Window, lzx.OutputPointer, i); }
+ try { lzx.System.Write(lzx.OutputFileHandle, lzx.Window, lzx.OutputPointer, i); }
catch { return lzx.Error = Error.MSPACK_ERR_WRITE; }
}
diff --git a/BurnOutSharp/External/libmspack/Compression/MSZIP.cs b/BurnOutSharp/External/libmspack/Compression/MSZIP.cs
index 42e3827d..f6a160c0 100644
--- a/BurnOutSharp/External/libmspack/Compression/MSZIP.cs
+++ b/BurnOutSharp/External/libmspack/Compression/MSZIP.cs
@@ -112,9 +112,9 @@ namespace LibMSPackSharp.Compression
InputBuffer = new byte[input_buffer_size],
// Initialise decompression state
- Sys = system,
- Input = input,
- Output = output,
+ System = system,
+ InputFileHandle = input,
+ OutputFileHandle = output,
InputBufferSize = (uint)input_buffer_size,
InputEnd = 0,
Error = Error.MSPACK_ERR_OK,
@@ -176,7 +176,7 @@ namespace LibMSPackSharp.Compression
if (i != 0)
{
- if (zip.Sys.Write(zip.Output, zip.Window, zip.OutputPointer, i) != i)
+ if (zip.System.Write(zip.OutputFileHandle, zip.Window, zip.OutputPointer, i) != i)
return zip.Error = Error.MSPACK_ERR_WRITE;
zip.OutputPointer += i;
@@ -279,7 +279,7 @@ namespace LibMSPackSharp.Compression
if (zip.BytesOutput == 0 && zip.WindowPosition > 0)
zip.FlushWindow(zip, zip.WindowPosition);
- zip.Sys.Message(null, $"MSZIP error, {MSZIP_FRAME_SIZE - zip.BytesOutput} bytes of data lost.");
+ zip.System.Message(null, $"MSZIP error, {MSZIP_FRAME_SIZE - zip.BytesOutput} bytes of data lost.");
for (i = zip.BytesOutput; i < MSZIP_FRAME_SIZE; i++)
{
zip.Window[i] = 0x00;
@@ -298,7 +298,7 @@ namespace LibMSPackSharp.Compression
// Write a frame
i = (out_bytes < zip.BytesOutput) ? (int)out_bytes : zip.BytesOutput;
- if (zip.Sys.Write(zip.Output, zip.Window, zip.OutputPointer, i) != i)
+ if (zip.System.Write(zip.OutputFileHandle, zip.Window, zip.OutputPointer, i) != i)
return zip.Error = Error.MSPACK_ERR_WRITE;
// mspack errors (i.e. read errors) are fatal and can't be recovered
@@ -536,7 +536,7 @@ namespace LibMSPackSharp.Compression
}
// Write inflated block
- try { zip.Sys.Write(zip.Output, zip.Window, 0, zip.BytesOutput); }
+ try { zip.System.Write(zip.OutputFileHandle, zip.Window, 0, zip.BytesOutput); }
catch { return zip.Error = Error.MSPACK_ERR_WRITE; }
}
diff --git a/BurnOutSharp/External/libmspack/Compression/None.cs b/BurnOutSharp/External/libmspack/Compression/None.cs
index 3d26968a..eacb7740 100644
--- a/BurnOutSharp/External/libmspack/Compression/None.cs
+++ b/BurnOutSharp/External/libmspack/Compression/None.cs
@@ -17,9 +17,9 @@ namespace LibMSPackSharp.Compression
{
return new NoneState()
{
- Sys = sys,
- Input = input,
- Output = output,
+ System = sys,
+ InputFileHandle = input,
+ OutputFileHandle = output,
Buffer = new byte[bufsize],
BufferSize = bufsize,
};
@@ -36,10 +36,10 @@ namespace LibMSPackSharp.Compression
{
run = (bytes > state.BufferSize) ? state.BufferSize : (int)bytes;
- if (state.Sys.Read(state.Input, state.Buffer, 0, run) != run)
+ if (state.System.Read(state.InputFileHandle, state.Buffer, 0, run) != run)
return Error.MSPACK_ERR_READ;
- if (state.Sys.Write(state.Output, state.Buffer, 0, run) != run)
+ if (state.System.Write(state.OutputFileHandle, state.Buffer, 0, run) != run)
return Error.MSPACK_ERR_WRITE;
bytes -= run;
diff --git a/BurnOutSharp/External/libmspack/Compression/NoneState.cs b/BurnOutSharp/External/libmspack/Compression/NoneState.cs
index ccbba111..b98ae342 100644
--- a/BurnOutSharp/External/libmspack/Compression/NoneState.cs
+++ b/BurnOutSharp/External/libmspack/Compression/NoneState.cs
@@ -7,21 +7,13 @@
* For further details, see the file COPYING.LIB distributed with libmspack
*/
-using System.IO;
-
namespace LibMSPackSharp.Compression
{
///
/// The "not compressed" method decompressor
///
- public class NoneState
+ public class NoneState : BaseDecompressState
{
- public SystemImpl Sys { get; set; }
-
- public FileStream Input { get; set; }
-
- public FileStream Output { get; set; }
-
public byte[] Buffer { get; set; }
public int BufferSize { get; set; }
diff --git a/BurnOutSharp/External/libmspack/Compression/QTM.cs b/BurnOutSharp/External/libmspack/Compression/QTM.cs
index 0a6ca78c..288347bf 100644
--- a/BurnOutSharp/External/libmspack/Compression/QTM.cs
+++ b/BurnOutSharp/External/libmspack/Compression/QTM.cs
@@ -116,9 +116,9 @@ namespace LibMSPackSharp.Compression
InputBuffer = new byte[input_buffer_size],
// Initialise decompression state
- Sys = system,
- Input = input,
- Output = output,
+ System = system,
+ InputFileHandle = input,
+ OutputFileHandle = output,
InputBufferSize = (uint)input_buffer_size,
WindowSize = window_size,
WindowPosition = 0,
@@ -203,7 +203,7 @@ namespace LibMSPackSharp.Compression
if (i != 0)
{
- if (qtm.Sys.Write(qtm.Output, qtm.Window, qtm.OutputPointer, i) != i)
+ if (qtm.System.Write(qtm.OutputFileHandle, qtm.Window, qtm.OutputPointer, i) != i)
return qtm.Error = Error.MSPACK_ERR_WRITE;
qtm.OutputPointer += i;
@@ -1223,7 +1223,7 @@ namespace LibMSPackSharp.Compression
return qtm.Error = Error.MSPACK_ERR_DECRUNCH;
}
- if (qtm.Sys.Write(qtm.Output, window, qtm.OutputPointer, i) != i)
+ if (qtm.System.Write(qtm.OutputFileHandle, window, qtm.OutputPointer, i) != i)
return qtm.Error = Error.MSPACK_ERR_WRITE;
out_bytes -= i;
@@ -1388,7 +1388,7 @@ namespace LibMSPackSharp.Compression
if (i >= out_bytes)
break;
- if (qtm.Sys.Write(qtm.Output, window, qtm.OutputPointer, i) != i)
+ if (qtm.System.Write(qtm.OutputFileHandle, window, qtm.OutputPointer, i) != i)
return qtm.Error = Error.MSPACK_ERR_WRITE;
out_bytes -= i;
@@ -1403,7 +1403,7 @@ namespace LibMSPackSharp.Compression
{
i = (int)out_bytes;
- if (qtm.Sys.Write(qtm.Output, window, qtm.OutputPointer, i) != i)
+ if (qtm.System.Write(qtm.OutputFileHandle, window, qtm.OutputPointer, i) != i)
return qtm.Error = Error.MSPACK_ERR_WRITE;
qtm.OutputPointer += i;
diff --git a/BurnOutSharp/External/libmspack/Constants.cs b/BurnOutSharp/External/libmspack/Constants.cs
new file mode 100644
index 00000000..eedc7346
--- /dev/null
+++ b/BurnOutSharp/External/libmspack/Constants.cs
@@ -0,0 +1,196 @@
+/* This file is part of libmspack.
+ * (C) 2003-2004 Stuart Caie.
+ *
+ * libmspack is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License (LGPL) version 2.1
+ *
+ * For further details, see the file COPYING.LIB distributed with libmspack
+ */
+
+namespace LibMSPackSharp
+{
+ internal class Constants
+ {
+ #region CAB
+
+ // CAB data blocks are <= 32768 bytes in uncompressed form.Uncompressed
+ // blocks have zero growth. MSZIP guarantees that it won't grow above
+ // uncompressed size by more than 12 bytes.LZX guarantees it won't grow
+ // more than 6144 bytes.Quantum has no documentation, but the largest
+ // block seen in the wild is 337 bytes above uncompressed size.
+
+ public const int CAB_BLOCKMAX = 32768;
+ public const int CAB_INPUTMAX = CAB_BLOCKMAX + 6144;
+
+ // input buffer needs to be CAB_INPUTMAX + 1 byte to allow for max-sized block
+ // plus 1 trailer byte added by cabd_sys_read_block() for Quantum alignment.
+ //
+ // When MSCABD_PARAM_SALVAGE is set, block size is not checked so can be
+ // up to 65535 bytes, so max input buffer size needed is 65535 + 1
+
+ public const int CAB_INPUTMAX_SALVAGE = 65535;
+ public const int CAB_INPUTBUF = CAB_INPUTMAX_SALVAGE + 1;
+
+ // There are no more than 65535 data blocks per folder, so a folder cannot
+ // be more than 32768*65535 bytes in length.As files cannot span more than
+ // one folder, this is also their max offset, length and offset+length limit.
+
+ public const int CAB_FOLDERMAX = 65535;
+ public const int CAB_LENGTHMAX = CAB_BLOCKMAX * CAB_FOLDERMAX;
+
+ #endregion
+
+ #region CHM
+
+ // _PMGHeader
+ public const int pmgl_Signature = 0x0000;
+ public const int pmgl_QuickRefSize = 0x0004;
+ public const int pmgl_PMGIEntries = 0x0008; // Unknown1 in PMGL
+ public const int pmgl_PrevChunk = 0x000C; // Not in PMGI
+ public const int pmgl_NextChunk = 0x0010; // Not in PMGI
+ public const int pmgl_PMGLEntries = 0x0014; // Not in PMGI
+ public const int pmgl_headerSIZEOF = 0x0014;
+ public const int pmgi_headerSIZEOF = 0x000C;
+
+ // _LZXControlData
+ public const int lzxcd_Length = 0x0000;
+ public const int lzxcd_Signature = 0x0004;
+ public const int lzxcd_Version = 0x0008;
+ public const int lzxcd_ResetInterval = 0x000C;
+ public const int lzxcd_WindowSize = 0x0010;
+ public const int lzxcd_CacheSize = 0x0014;
+ public const int lzxcd_Unknown1 = 0x0018;
+ public const int lzxcd_SIZEOF = 0x001C;
+
+ // _LZXResetTable
+ public const int lzxrt_Unknown1 = 0x0000;
+ public const int lzxrt_NumEntries = 0x0004;
+ public const int lzxrt_EntrySize = 0x0008;
+ public const int lzxrt_TableOffset = 0x000C;
+ public const int lzxrt_UncompLen = 0x0010;
+ public const int lzxrt_CompLen = 0x0018;
+ public const int lzxrt_FrameLen = 0x0020;
+ public const int lzxrt_Entries = 0x0028;
+ public const int lzxrt_headerSIZEOF = 0x0028;
+
+ // Filenames of the system files used for decompression.
+ // - Content and ControlData are essential.
+ // - ResetTable is preferred, but SpanInfo can be used if not available
+ public const string ContentName = "::DataSpace/Storage/MSCompressed/Content";
+ public const string ControlName = "::DataSpace/Storage/MSCompressed/ControlData";
+ public const string SpanInfoName = "::DataSpace/Storage/MSCompressed/SpanInfo";
+ public const string ResetTableName = "::DataSpace/Storage/MSCompressed/Transform/{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}/InstanceData/ResetTable";
+
+ #endregion
+
+ #region HLP
+
+ // None currently
+
+ #endregion
+
+ #region KWAJ
+
+ public const byte kwajh_Signature1 = 0x00;
+ public const byte kwajh_Signature2 = 0x04;
+ public const byte kwajh_CompMethod = 0x08;
+ public const byte kwajh_DataOffset = 0x0a;
+ public const byte kwajh_Flags = 0x0c;
+ public const byte kwajh_SIZEOF = 0x0e;
+
+ // Input buffer size during decompression - not worth parameterising IMHO
+ public const int KWAJ_INPUT_SIZE = (2048);
+
+ // Huffman codes that are 9 bits or less are decoded immediately
+ public const int KWAJ_TABLEBITS = (9);
+
+ // Number of codes in each huffman table
+
+ public const int KWAJ_MATCHLEN1_SYMS = (16);
+ public const int KWAJ_MATCHLEN2_SYMS = (16);
+ public const int KWAJ_LITLEN_SYMS = (32);
+ public const int KWAJ_OFFSET_SYMS = (64);
+ public const int KWAJ_LITERAL_SYMS = (256);
+
+ // Define decoding table sizes
+
+ public const int KWAJ_TABLESIZE = (1 << KWAJ_TABLEBITS);
+
+ //public const int KWAJ_MATCHLEN1_TBLSIZE = (KWAJ_MATCHLEN1_SYMS * 4);
+ public const int KWAJ_MATCHLEN1_TBLSIZE = (KWAJ_TABLESIZE + (KWAJ_MATCHLEN1_SYMS * 2));
+
+ //public const int KWAJ_MATCHLEN2_TBLSIZE = (KWAJ_MATCHLEN2_SYMS * 4);
+ public const int KWAJ_MATCHLEN2_TBLSIZE = (KWAJ_TABLESIZE + (KWAJ_MATCHLEN2_SYMS * 2));
+
+ //public const int KWAJ_LITLEN_TBLSIZE = (KWAJ_LITLEN_SYMS * 4);
+ public const int KWAJ_LITLEN_TBLSIZE = (KWAJ_TABLESIZE + (KWAJ_LITLEN_SYMS * 2));
+
+ //public const int KWAJ_OFFSET_TBLSIZE = (KWAJ_OFFSET_SYMS * 4);
+ public const int KWAJ_OFFSET_TBLSIZE = (KWAJ_TABLESIZE + (KWAJ_OFFSET_SYMS * 2));
+
+ //public const int KWAJ_LITERAL_TBLSIZE = (KWAJ_LITERAL_SYMS * 4);
+ public const int KWAJ_LITERAL_TBLSIZE = (KWAJ_TABLESIZE + (KWAJ_LITERAL_SYMS * 2));
+
+ #endregion
+
+ #region LIT
+
+ // None currently
+
+ #endregion
+
+ #region OAB
+
+ // _Header
+ public const int oabhead_VersionHi = 0x0000;
+ public const int oabhead_VersionLo = 0x0004;
+ public const int oabhead_BlockMax = 0x0008;
+ public const int oabhead_TargetSize = 0x000c;
+ public const int oabhead_SIZEOF = 0x0010;
+
+ // _Block
+ public const int oabblk_Flags = 0x0000;
+ public const int oabblk_CompSize = 0x0004;
+ public const int oabblk_UncompSize = 0x0008;
+ public const int oabblk_CRC = 0x000c;
+ public const int oabblk_SIZEOF = 0x0010;
+
+ // _PatchHeader
+ public const int patchhead_VersionHi = 0x0000;
+ public const int patchhead_VersionLo = 0x0004;
+ public const int patchhead_BlockMax = 0x0008;
+ public const int patchhead_SourceSize = 0x000c;
+ public const int patchhead_TargetSize = 0x0010;
+ public const int patchhead_SourceCRC = 0x0014;
+ public const int patchhead_TargetCRC = 0x0018;
+ public const int patchhead_SIZEOF = 0x001c;
+
+ // _PatchBlock
+ public const int patchblk_PatchSize = 0x0000;
+ public const int patchblk_TargetSize = 0x0004;
+ public const int patchblk_SourceSize = 0x0008;
+ public const int patchblk_CRC = 0x000c;
+ public const int patchblk_SIZEOF = 0x0010;
+
+ #endregion
+
+ #region SZDD
+
+ ///
+ /// Input buffer size during decompression - not worth parameterising IMHO
+ ///
+ public const int SZDD_INPUT_SIZE = 2048;
+
+ public static readonly byte[] expandSignature = new byte[8]
+ {
+ 0x53, 0x5A, 0x44, 0x44, 0x88, 0xF0, 0x27, 0x33
+ };
+
+ public static readonly byte[] qbasicSignature = new byte[8]
+ {
+ 0x53, 0x5A, 0x20, 0x88, 0xF0, 0x27, 0x33, 0xD1
+ };
+
+ #endregion
+ }
+}
diff --git a/BurnOutSharp/External/libmspack/HLP/Compressor.cs b/BurnOutSharp/External/libmspack/HLP/Compressor.cs
index 47ea0671..0f5efbb5 100644
--- a/BurnOutSharp/External/libmspack/HLP/Compressor.cs
+++ b/BurnOutSharp/External/libmspack/HLP/Compressor.cs
@@ -16,8 +16,11 @@
namespace LibMSPackSharp.HLP
{
+ // TODO
public class Compressor
{
+ public SystemImpl System { get; set; }
+
public int Dummy { get; set; }
}
}
diff --git a/BurnOutSharp/External/libmspack/HLP/CompressorImpl.cs b/BurnOutSharp/External/libmspack/HLP/CompressorImpl.cs
deleted file mode 100644
index 9505c83a..00000000
--- a/BurnOutSharp/External/libmspack/HLP/CompressorImpl.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-/* This file is part of libmspack.
- * (C) 2003-2004 Stuart Caie.
- *
- * libmspack is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
- *
- * For further details, see the file COPYING.LIB distributed with libmspack
- */
-
-namespace LibMSPackSharp.HLP
-{
- public class CompressorImpl : Compressor
- {
- public SystemImpl System { get; set; }
-
- // TODO
- }
-}
diff --git a/BurnOutSharp/External/libmspack/HLP/Decompressor.cs b/BurnOutSharp/External/libmspack/HLP/Decompressor.cs
index 2b498d0b..82fa31c7 100644
--- a/BurnOutSharp/External/libmspack/HLP/Decompressor.cs
+++ b/BurnOutSharp/External/libmspack/HLP/Decompressor.cs
@@ -16,8 +16,8 @@
namespace LibMSPackSharp.HLP
{
- public class Decompressor
+ public class Decompressor : BaseDecompressor
{
- public int Dummy { get; set; }
+ // TODO
}
}
diff --git a/BurnOutSharp/External/libmspack/HLP/DecompressorImpl.cs b/BurnOutSharp/External/libmspack/HLP/DecompressorImpl.cs
deleted file mode 100644
index 534edc6d..00000000
--- a/BurnOutSharp/External/libmspack/HLP/DecompressorImpl.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-/* This file is part of libmspack.
- * (C) 2003-2004 Stuart Caie.
- *
- * libmspack is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
- *
- * For further details, see the file COPYING.LIB distributed with libmspack
- */
-
-namespace LibMSPackSharp.HLP
-{
- public class DecompressorImpl : Decompressor
- {
- public SystemImpl System { get; set; }
-
- // TODO
- }
-}
diff --git a/BurnOutSharp/External/libmspack/KWAJ/Compressor.cs b/BurnOutSharp/External/libmspack/KWAJ/Compressor.cs
index c86d55ff..16389d3d 100644
--- a/BurnOutSharp/External/libmspack/KWAJ/Compressor.cs
+++ b/BurnOutSharp/External/libmspack/KWAJ/Compressor.cs
@@ -27,6 +27,19 @@ namespace LibMSPackSharp.KWAJ
///
public class Compressor
{
+ #region Fields
+
+ public SystemImpl System { get; set; }
+
+ ///
+ /// !!! MATCH THIS TO NUM OF PARAMS IN MSPACK.H !!!
+ ///
+ public int[] Param { get; set; } = new int[2];
+
+ public Error Error { get; set; }
+
+ #endregion
+
///
/// Reads an input file and creates a compressed output file in the
/// KWAJ compressed file format.The KWAJ compression format is quick
diff --git a/BurnOutSharp/External/libmspack/KWAJ/CompressorImpl.cs b/BurnOutSharp/External/libmspack/KWAJ/CompressorImpl.cs
deleted file mode 100644
index 65f0eaa5..00000000
--- a/BurnOutSharp/External/libmspack/KWAJ/CompressorImpl.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-/* This file is part of libmspack.
- * (C) 2003-2010 Stuart Caie.
- *
- * libmspack is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
- *
- * For further details, see the file COPYING.LIB distributed with libmspack
- */
-
-namespace LibMSPackSharp.KWAJ
-{
- public class CompressorImpl : Compressor
- {
- public SystemImpl System { get; set; }
-
- // TODO
-
- ///
- /// !!! MATCH THIS TO NUM OF PARAMS IN MSPACK.H !!!
- ///
- public int[] Param { get; set; } = new int[2];
-
- public Error Error { get; set; }
- }
-}
diff --git a/BurnOutSharp/External/libmspack/KWAJ/Decompressor.cs b/BurnOutSharp/External/libmspack/KWAJ/Decompressor.cs
index 3ef07706..7cd37b67 100644
--- a/BurnOutSharp/External/libmspack/KWAJ/Decompressor.cs
+++ b/BurnOutSharp/External/libmspack/KWAJ/Decompressor.cs
@@ -15,6 +15,10 @@
*/
using System;
+using System.IO;
+using System.Text;
+using LibMSPackSharp.Compression;
+using static LibMSPackSharp.Constants;
namespace LibMSPackSharp.KWAJ
{
@@ -25,8 +29,10 @@ namespace LibMSPackSharp.KWAJ
///
///
///
- public class Decompressor
+ public class Decompressor : BaseDecompressor
{
+ #region Public Functionality
+
///
/// Opens a KWAJ file and reads the header.
///
@@ -39,17 +45,37 @@ namespace LibMSPackSharp.KWAJ
/// The filename pointer should be considered "in use" until close() is
/// called on the KWAJ file.
///
- ///
- /// a self-referential pointer to the mskwaj_decompressor
- /// instance being called
- ///
///
/// the filename of the KWAJ compressed file. This is
/// passed directly to mspack_system::open().
///
- /// a pointer to a mskwajd_header structure, or NULL on failure
- ///
- public Func Open;
+ /// A pointer to a mskwajd_header structure, or NULL on failure
+ ///
+ public Header Open(string filename)
+ {
+ FileStream fh = System.Open(filename, OpenMode.MSPACK_SYS_OPEN_READ);
+ Header hdr = new Header();
+ if (fh != null && hdr != null)
+ {
+ hdr.FileHandle = fh;
+ Error = ReadHeaders(fh, hdr);
+ }
+ else
+ {
+ if (fh == null)
+ Error = Error.MSPACK_ERR_OPEN;
+ if (hdr == null)
+ Error = Error.MSPACK_ERR_NOMEMORY;
+ }
+
+ if (Error != Error.MSPACK_ERR_OK)
+ {
+ System.Close(fh);
+ hdr = null;
+ }
+
+ return hdr;
+ }
///
/// Closes a previously opened KWAJ file.
@@ -58,13 +84,18 @@ namespace LibMSPackSharp.KWAJ
/// with it. The KWAJ header pointer is now invalid and cannot be
/// used again.
///
- ///
- /// a self-referential pointer to the mskwaj_decompressor
- /// instance being called
- ///
- /// the KWAJ file to close
- ///
- public Action Close;
+ /// The KWAJ file to close
+ ///
+ public void Close(Header hdr)
+ {
+ if (System == null || hdr == null)
+ return;
+
+ // Close the file handle associated
+ System.Close(hdr.FileHandle);
+
+ Error = Error.MSPACK_ERR_OK;
+ }
///
/// Extracts the compressed data from a KWAJ file.
@@ -72,17 +103,81 @@ namespace LibMSPackSharp.KWAJ
/// This decompresses the compressed KWAJ data stream and writes it to
/// an output file.
///
- ///
- /// a self-referential pointer to the mskwaj_decompressor
- /// instance being called
- ///
- /// the KWAJ file to extract data from
+ /// The KWAJ file to extract data from
///
/// the filename to write the decompressed data to. This
/// is passed directly to mspack_system::open().
///
/// an error code, or MSPACK_ERR_OK if successful
- public Func Extract;
+ public Error Extract(Header hdr, string filename)
+ {
+ FileStream fh = hdr?.FileHandle;
+ if (fh == null)
+ return Error.MSPACK_ERR_ARGS;
+
+ // Seek to the compressed data
+ if (System.Seek(fh, hdr.DataOffset, SeekMode.MSPACK_SYS_SEEK_START))
+ return Error = Error.MSPACK_ERR_SEEK;
+
+ // Open file for output
+ FileStream outfh;
+ if ((outfh = System.Open(filename, OpenMode.MSPACK_SYS_OPEN_WRITE)) == null)
+ return Error = Error.MSPACK_ERR_OPEN;
+
+ Error = Error.MSPACK_ERR_OK;
+
+ // Decompress based on format
+ if (hdr.CompressionType == CompressionType.MSKWAJ_COMP_NONE ||
+ hdr.CompressionType == CompressionType.MSKWAJ_COMP_XOR)
+ {
+ // NONE is a straight copy. XOR is a copy xored with 0xFF
+ byte[] buf = new byte[KWAJ_INPUT_SIZE];
+
+ int read, i;
+ while ((read = System.Read(fh, buf, 0, KWAJ_INPUT_SIZE)) > 0)
+ {
+ if (hdr.CompressionType == CompressionType.MSKWAJ_COMP_XOR)
+ {
+ for (i = 0; i < read; i++)
+ {
+ buf[i] ^= 0xFF;
+ }
+ }
+
+ if (System.Write(outfh, buf, 0, read) != read)
+ {
+ Error = Error.MSPACK_ERR_WRITE;
+ break;
+ }
+ }
+
+ if (read < 0)
+ Error = Error.MSPACK_ERR_READ;
+ }
+ else if (hdr.CompressionType == CompressionType.MSKWAJ_COMP_SZDD)
+ {
+ Error = LZSS.Decompress(System, fh, outfh, KWAJ_INPUT_SIZE, LZSSMode.LZSS_MODE_EXPAND);
+ }
+ else if (hdr.CompressionType == CompressionType.MSKWAJ_COMP_LZH)
+ {
+ LZHKWAJStream lzh = LZHKWAJ.Init(System, fh, outfh);
+ Error = (lzh != null) ? LZHKWAJ.Decompress(lzh) : Error.MSPACK_ERR_NOMEMORY;
+ }
+ else if (hdr.CompressionType == CompressionType.MSKWAJ_COMP_MSZIP)
+ {
+ MSZIPDStream zip = MSZIP.Init(System, fh, outfh, KWAJ_INPUT_SIZE, false);
+ Error = (zip != null) ? MSZIP.DecompressKWAJ(zip) : Error.MSPACK_ERR_NOMEMORY;
+ }
+ else
+ {
+ Error = Error.MSPACK_ERR_DATAFORMAT;
+ }
+
+ // Close output file
+ System.Close(outfh);
+
+ return Error;
+ }
///
/// Decompresses an KWAJ file to an output file in one step.
@@ -106,21 +201,159 @@ namespace LibMSPackSharp.KWAJ
/// is passed directly to mspack_system::open().
///
/// an error code, or MSPACK_ERR_OK if successful
- public Func Decompress;
+ public Error Decompress(string input, string output)
+ {
+ Header hdr = Open(input) as Header;
+ if (hdr == null)
+ return Error;
+
+ Error error = Extract(hdr, output);
+ Close(hdr);
+ return Error = error;
+ }
+
+ #endregion
+
+ #region Helpers
///
- /// Returns the error code set by the most recently called method.
- ///
- /// This is useful for open() which does not return an
- /// error code directly.
+ /// Reads the headers of a KWAJ format file
///
- ///
- /// a self-referential pointer to the mskwaj_decompressor
- /// instance being called
- ///
- /// the most recent error code
- ///
- ///
- public Func LastError;
+ private Error ReadHeaders(FileStream fh, Header hdr)
+ {
+ int i;
+
+ // Read in the header
+ byte[] buf = new byte[16];
+ if (System.Read(fh, buf, 0, kwajh_SIZEOF) != kwajh_SIZEOF)
+ return Error.MSPACK_ERR_READ;
+
+ // Check for "KWAJ" signature
+ if ((BitConverter.ToUInt32(buf, kwajh_Signature1) != 0x4A41574B) ||
+ (BitConverter.ToUInt32(buf, kwajh_Signature2) != 0xD127F088))
+ {
+ return Error.MSPACK_ERR_SIGNATURE;
+ }
+
+ // Basic header fields
+ hdr.CompressionType = (CompressionType)BitConverter.ToUInt16(buf, kwajh_CompMethod);
+ hdr.DataOffset = BitConverter.ToUInt16(buf, kwajh_DataOffset);
+ hdr.Headers = (OptionalHeaderFlag)BitConverter.ToUInt16(buf, kwajh_Flags);
+ hdr.Length = 0;
+ hdr.Filename = null;
+ hdr.Extra = null;
+ hdr.ExtraLength = 0;
+
+ // Optional headers
+
+ // 4 bytes: length of unpacked file
+ if (hdr.Headers.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASLENGTH))
+ {
+ if (System.Read(fh, buf, 0, 4) != 4)
+ return Error.MSPACK_ERR_READ;
+
+ hdr.Length = BitConverter.ToUInt32(buf, 0);
+ }
+
+ // 2 bytes: unknown purpose
+ if (hdr.Headers.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASUNKNOWN1))
+ {
+ if (System.Read(fh, buf, 0, 2) != 2)
+ return Error.MSPACK_ERR_READ;
+ }
+
+ // 2 bytes: length of section, then [length] bytes: unknown purpose
+ if (hdr.Headers.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASUNKNOWN2))
+ {
+ if (System.Read(fh, buf, 0, 2) != 2)
+ return Error.MSPACK_ERR_READ;
+
+ i = BitConverter.ToUInt16(buf, 0);
+ if (System.Seek(fh, i, SeekMode.MSPACK_SYS_SEEK_CUR))
+ return Error.MSPACK_ERR_SEEK;
+ }
+
+ // Filename and extension
+ if (hdr.Headers.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASFILENAME) || hdr.Headers.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASFILEEXT))
+ {
+ int len;
+
+ // Allocate memory for maximum length filename
+ char[] fn = new char[13];
+ int fnPtr = 0;
+
+ // Copy filename if present
+ if (hdr.Headers.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASFILENAME))
+ {
+ // Read and copy up to 9 bytes of a null terminated string
+ if ((len = System.Read(fh, buf, 0, 9)) < 2)
+ return Error.MSPACK_ERR_READ;
+
+ for (i = 0; i < len; i++)
+ {
+ if ((fn[fnPtr++] = (char)buf[i]) == '\0')
+ break;
+ }
+
+ // If string was 9 bytes with no null terminator, reject it
+ if (i == 9 && buf[8] != '\0')
+ return Error.MSPACK_ERR_DATAFORMAT;
+
+ // Seek to byte after string ended in file
+ if (System.Seek(fh, i + 1 - len, SeekMode.MSPACK_SYS_SEEK_CUR))
+ return Error.MSPACK_ERR_SEEK;
+
+ fnPtr--; // Remove the null terminator
+ }
+
+ // Copy extension if present
+ if (hdr.Headers.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASFILEEXT))
+ {
+ fn[fnPtr++] = '.';
+
+ // Read and copy up to 4 bytes of a null terminated string
+ if ((len = System.Read(fh, buf, 0, 4)) < 2)
+ return Error.MSPACK_ERR_READ;
+
+ for (i = 0; i < len; i++)
+ {
+ if ((fn[fnPtr++] = (char)buf[i]) == '\0')
+ break;
+ }
+
+ // If string was 4 bytes with no null terminator, reject it
+ if (i == 4 && buf[3] != '\0')
+ return Error.MSPACK_ERR_DATAFORMAT;
+
+ // Seek to byte after string ended in file
+ if (System.Seek(fh, i + 1 - len, SeekMode.MSPACK_SYS_SEEK_CUR))
+ return Error.MSPACK_ERR_SEEK;
+
+ fnPtr--; // Remove the null terminator
+ }
+
+ fn[fnPtr] = '\0';
+ }
+
+ // 2 bytes: extra text length then [length] bytes of extra text data
+ if (hdr.Headers.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASEXTRATEXT))
+ {
+ if (System.Read(fh, buf, 0, 2) != 2)
+ return Error.MSPACK_ERR_READ;
+
+ i = BitConverter.ToUInt16(buf, 0);
+ byte[] extra = new byte[i + 1];
+ if (System.Read(fh, extra, 0, i) != i)
+ return Error.MSPACK_ERR_READ;
+
+ extra[i] = 0x00;
+ hdr.Extra = Encoding.ASCII.GetString(extra, 0, extra.Length);
+ hdr.ExtraLength = (ushort)i;
+ }
+
+ return Error.MSPACK_ERR_OK;
+ }
+
+ #endregion
}
}
diff --git a/BurnOutSharp/External/libmspack/KWAJ/DecompressorImpl.cs b/BurnOutSharp/External/libmspack/KWAJ/DecompressorImpl.cs
deleted file mode 100644
index 538cafa7..00000000
--- a/BurnOutSharp/External/libmspack/KWAJ/DecompressorImpl.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-/* This file is part of libmspack.
- * (C) 2003-2010 Stuart Caie.
- *
- * libmspack is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
- *
- * For further details, see the file COPYING.LIB distributed with libmspack
- */
-
-namespace LibMSPackSharp.KWAJ
-{
- public class DecompressorImpl : Decompressor
- {
- public SystemImpl System { get; set; }
-
- public Error Error { get; set; }
- }
-}
diff --git a/BurnOutSharp/External/libmspack/KWAJ/Header.cs b/BurnOutSharp/External/libmspack/KWAJ/Header.cs
index a762c615..ea43c0fe 100644
--- a/BurnOutSharp/External/libmspack/KWAJ/Header.cs
+++ b/BurnOutSharp/External/libmspack/KWAJ/Header.cs
@@ -14,6 +14,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+using System.IO;
+
namespace LibMSPackSharp.KWAJ
{
///
@@ -21,7 +23,7 @@ namespace LibMSPackSharp.KWAJ
///
/// All fields are READ ONLY.
///
- public class Header
+ public class Header : BaseHeader
{
///
/// The compression type
@@ -58,5 +60,7 @@ namespace LibMSPackSharp.KWAJ
/// Length of extra uncompressed data in the header
///
public ushort ExtraLength { get; set; }
+
+ public FileStream FileHandle { get; set; }
}
}
diff --git a/BurnOutSharp/External/libmspack/KWAJ/HeaderImpl.cs b/BurnOutSharp/External/libmspack/KWAJ/HeaderImpl.cs
deleted file mode 100644
index 77e1d5b0..00000000
--- a/BurnOutSharp/External/libmspack/KWAJ/HeaderImpl.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-/* This file is part of libmspack.
- * (C) 2003-2010 Stuart Caie.
- *
- * libmspack is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
- *
- * For further details, see the file COPYING.LIB distributed with libmspack
- */
-
-using System.IO;
-
-namespace LibMSPackSharp.KWAJ
-{
- public class HeaderImpl : Header
- {
- public FileStream FileHandle { get; set; }
- }
-}
diff --git a/BurnOutSharp/External/libmspack/LIT/Compressor.cs b/BurnOutSharp/External/libmspack/LIT/Compressor.cs
index 62ab902c..99ce6edb 100644
--- a/BurnOutSharp/External/libmspack/LIT/Compressor.cs
+++ b/BurnOutSharp/External/libmspack/LIT/Compressor.cs
@@ -19,6 +19,6 @@ namespace LibMSPackSharp.LIT
// TODO
public class Compressor
{
- public int Dummy { get; set; }
+ public SystemImpl System { get; set; }
}
}
diff --git a/BurnOutSharp/External/libmspack/LIT/CompressorImpl.cs b/BurnOutSharp/External/libmspack/LIT/CompressorImpl.cs
deleted file mode 100644
index 8eab67d0..00000000
--- a/BurnOutSharp/External/libmspack/LIT/CompressorImpl.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-/* This file is part of libmspack.
- * (C) 2003-2004 Stuart Caie.
- *
- * libmspack is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
- *
- * For further details, see the file COPYING.LIB distributed with libmspack
- */
-
-namespace LibMSPackSharp.LIT
-{
- public class CompressorImpl : Compressor
- {
- public SystemImpl System { get; set; }
-
- // TODO
- }
-}
diff --git a/BurnOutSharp/External/libmspack/LIT/Decompressor.cs b/BurnOutSharp/External/libmspack/LIT/Decompressor.cs
index 8c1b31e6..02ab30ba 100644
--- a/BurnOutSharp/External/libmspack/LIT/Decompressor.cs
+++ b/BurnOutSharp/External/libmspack/LIT/Decompressor.cs
@@ -16,9 +16,8 @@
namespace LibMSPackSharp.LIT
{
- // TODO
- public class Decompressor
+ public class Decompressor : BaseDecompressor
{
- public int Dummy { get; set; }
+ // TODO
}
}
diff --git a/BurnOutSharp/External/libmspack/LIT/DecompressorImpl.cs b/BurnOutSharp/External/libmspack/LIT/DecompressorImpl.cs
deleted file mode 100644
index c8d5339a..00000000
--- a/BurnOutSharp/External/libmspack/LIT/DecompressorImpl.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-/* This file is part of libmspack.
- * (C) 2003-2004 Stuart Caie.
- *
- * libmspack is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
- *
- * For further details, see the file COPYING.LIB distributed with libmspack
- */
-
-namespace LibMSPackSharp.LIT
-{
- public class DecompressorImpl : Decompressor
- {
- public SystemImpl System { get; set; }
-
- // TODO
- }
-}
diff --git a/BurnOutSharp/External/libmspack/LIT/Implementation.cs b/BurnOutSharp/External/libmspack/LIT/Implementation.cs
deleted file mode 100644
index 06c384b7..00000000
--- a/BurnOutSharp/External/libmspack/LIT/Implementation.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-/* This file is part of libmspack.
- * (C) 2003-2004 Stuart Caie.
- *
- * libmspack is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
- *
- * For further details, see the file COPYING.LIB distributed with libmspack
- */
-
-namespace LibMSPackSharp.LIT
-{
- public class Implementation
- {
- }
-}
diff --git a/BurnOutSharp/External/libmspack/Library.cs b/BurnOutSharp/External/libmspack/Library.cs
index 4295679a..d35a79d7 100644
--- a/BurnOutSharp/External/libmspack/Library.cs
+++ b/BurnOutSharp/External/libmspack/Library.cs
@@ -374,13 +374,8 @@ namespace LibMSPackSharp
if (!SystemImpl.ValidSystem(sys))
return null;
- return new SZDD.DecompressorImpl()
+ return new SZDD.Decompressor()
{
- Open = SZDD.Implementation.Open,
- Close = SZDD.Implementation.Close,
- Extract = SZDD.Implementation.Extract,
- Decompress = SZDD.Implementation.Decompress,
- LastError = SZDD.Implementation.LastError,
System = sys,
Error = Error.MSPACK_ERR_OK,
};
@@ -428,13 +423,8 @@ namespace LibMSPackSharp
if (!SystemImpl.ValidSystem(sys))
return null;
- return new KWAJ.DecompressorImpl()
+ return new KWAJ.Decompressor()
{
- Open = KWAJ.Implementation.Open,
- Close = KWAJ.Implementation.Close,
- Extract = KWAJ.Implementation.Extract,
- Decompress = KWAJ.Implementation.Decompress,
- LastError = KWAJ.Implementation.LastError,
System = sys,
Error = Error.MSPACK_ERR_OK,
};
@@ -482,11 +472,8 @@ namespace LibMSPackSharp
if (!SystemImpl.ValidSystem(sys))
return null;
- return new OAB.DecompressorImpl()
+ return new OAB.Decompressor()
{
- Decompress = OAB.Implementation.Decompress,
- DecompressIncremental = OAB.Implementation.DecompressIncremental,
- SetParam = OAB.Implementation.Param,
System = sys,
BufferSize = 4096,
};
diff --git a/BurnOutSharp/External/libmspack/OAB/Compressor.cs b/BurnOutSharp/External/libmspack/OAB/Compressor.cs
index 6aba61a0..3d7a80a4 100644
--- a/BurnOutSharp/External/libmspack/OAB/Compressor.cs
+++ b/BurnOutSharp/External/libmspack/OAB/Compressor.cs
@@ -27,6 +27,12 @@ namespace LibMSPackSharp.OAB
///
public class Compressor
{
+ #region Fields
+
+ public SystemImpl System { get; set; }
+
+ #endregion
+
///
/// Compress a full OAB file.
///
diff --git a/BurnOutSharp/External/libmspack/OAB/CompressorImpl.cs b/BurnOutSharp/External/libmspack/OAB/CompressorImpl.cs
deleted file mode 100644
index 8abb627a..00000000
--- a/BurnOutSharp/External/libmspack/OAB/CompressorImpl.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-/* This file is part of libmspack.
- * © 2013 Intel Corporation
- *
- * libmspack is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
- *
- * For further details, see the file COPYING.LIB distributed with libmspack
- */
-
-namespace LibMSPackSharp.OAB
-{
- public class CompressorImpl : Compressor
- {
- public SystemImpl System { get; set; }
- }
-}
diff --git a/BurnOutSharp/External/libmspack/OAB/Decompressor.cs b/BurnOutSharp/External/libmspack/OAB/Decompressor.cs
index 03862a04..cde2dd4d 100644
--- a/BurnOutSharp/External/libmspack/OAB/Decompressor.cs
+++ b/BurnOutSharp/External/libmspack/OAB/Decompressor.cs
@@ -15,6 +15,9 @@
*/
using System;
+using System.IO;
+using LibMSPackSharp.Compression;
+using static LibMSPackSharp.Constants;
namespace LibMSPackSharp.OAB
{
@@ -25,8 +28,10 @@ namespace LibMSPackSharp.OAB
///
///
///
- public class Decompressor
+ public class Decompressor : BaseDecompressor
{
+ #region Public Functionality
+
///
/// Decompresses a full Offline Address Book file.
///
@@ -34,20 +39,170 @@ namespace LibMSPackSharp.OAB
/// it will be read and the decompressed contents will be written to
/// the output file.
///
- ///
- /// a self-referential pointer to the msoab_decompressor
- /// instance being called
- ///
///
- /// the filename of the input file. This is passed
+ /// The filename of the input file. This is passed
/// directly to mspack_system::open().
///
///
- /// the filename of the output file. This is passed
+ /// The filename of the output file. This is passed
/// directly to mspack_system::open().
///
- /// an error code, or MSPACK_ERR_OK if successful
- public Func Decompress;
+ /// An error code, or MSPACK_ERR_OK if successful
+ public Error Decompress(string input, string output)
+ {
+ byte[] hdrbuf = new byte[oabhead_SIZEOF];
+ LZXDStream lzx = null;
+ Error ret = Error.MSPACK_ERR_OK;
+
+ FileStream infh = System.Open(input, OpenMode.MSPACK_SYS_OPEN_READ);
+ if (infh == null)
+ {
+ ret = Error.MSPACK_ERR_OPEN;
+ System.Close(infh);
+ return ret;
+ }
+
+ if (System.Read(infh, hdrbuf, 0, oabhead_SIZEOF) != oabhead_SIZEOF)
+ {
+ ret = Error.MSPACK_ERR_READ;
+ System.Close(infh);
+ return ret;
+ }
+
+ if (BitConverter.ToUInt32(hdrbuf, oabhead_VersionHi) != 3 ||
+ BitConverter.ToUInt32(hdrbuf, oabhead_VersionLo) != 1)
+ {
+ ret = Error.MSPACK_ERR_SIGNATURE;
+ System.Close(infh);
+ return ret;
+ }
+
+ uint block_max = BitConverter.ToUInt32(hdrbuf, oabhead_BlockMax);
+ uint target_size = BitConverter.ToUInt32(hdrbuf, oabhead_TargetSize);
+
+ FileStream outfh = System.Open(output, OpenMode.MSPACK_SYS_OPEN_WRITE);
+ if (outfh == null)
+ {
+ ret = Error.MSPACK_ERR_OPEN;
+ System.Close(outfh);
+ System.Close(infh);
+ return ret;
+ }
+
+ byte[] buf = new byte[BufferSize];
+
+ SystemImpl oabd_sys = System;
+ oabd_sys.Read = SysRead;
+ oabd_sys.Write = SysWrite;
+
+ InternalFile in_ofh = new InternalFile();
+ in_ofh.OrigSys = System;
+ in_ofh.OrigFile = infh;
+
+ InternalFile out_ofh = new InternalFile();
+ out_ofh.OrigSys = System;
+ out_ofh.OrigFile = outfh;
+
+ while (target_size != 0)
+ {
+ if (System.Read(infh, buf, 0, oabblk_SIZEOF) != oabblk_SIZEOF)
+ {
+ ret = Error.MSPACK_ERR_READ;
+ System.Close(outfh);
+ System.Close(infh);
+ return ret;
+ }
+
+ uint blk_flags = BitConverter.ToUInt32(buf, oabblk_Flags);
+ uint blk_csize = BitConverter.ToUInt32(buf, oabblk_CompSize);
+ uint blk_dsize = BitConverter.ToUInt32(buf, oabblk_UncompSize);
+ uint blk_crc = BitConverter.ToUInt32(buf, oabblk_CRC);
+
+ if (blk_dsize > block_max || blk_dsize > target_size || blk_flags > 1)
+ {
+ ret = Error.MSPACK_ERR_DATAFORMAT;
+ System.Close(outfh);
+ System.Close(infh);
+ return ret;
+ }
+
+ if (blk_flags == 0)
+ {
+ // Uncompressed block
+ if (blk_dsize != blk_csize)
+ {
+ ret = Error.MSPACK_ERR_DATAFORMAT;
+ System.Close(outfh);
+ System.Close(infh);
+ return ret;
+ }
+
+ ret = CopyFileHandle(infh, outfh, (int)blk_dsize, buf, BufferSize);
+ if (ret != Error.MSPACK_ERR_OK)
+ {
+ System.Close(outfh);
+ System.Close(infh);
+ return ret;
+ }
+ }
+ else
+ {
+ // LZX compressed block
+ int window_bits = 17;
+
+ while (window_bits < 25 && (1U << window_bits) < blk_dsize)
+ {
+ window_bits++;
+ }
+
+ in_ofh.Available = (int)blk_csize;
+ out_ofh.CRC = 0xffffffff;
+
+ lzx = LZX.Init(oabd_sys, in_ofh.OrigFile, out_ofh.OrigFile, window_bits, 0, BufferSize, blk_dsize, true);
+ if (lzx == null)
+ {
+ ret = Error.MSPACK_ERR_NOMEMORY;
+ System.Close(outfh);
+ System.Close(infh);
+ return ret;
+ }
+
+ ret = LZX.Decompress(lzx, blk_dsize);
+ if (ret != Error.MSPACK_ERR_OK)
+ {
+ System.Close(outfh);
+ System.Close(infh);
+ return ret;
+ }
+
+ lzx = null;
+
+ // Consume any trailing padding bytes before the next block
+ ret = CopyFileHandle(infh, null, in_ofh.Available, buf, BufferSize);
+ if (ret != Error.MSPACK_ERR_OK)
+ {
+ System.Close(outfh);
+ System.Close(infh);
+ return ret;
+ }
+
+ if (out_ofh.CRC != blk_crc)
+ {
+ ret = Error.MSPACK_ERR_CHECKSUM;
+ System.Close(outfh);
+ System.Close(infh);
+ return ret;
+ }
+ }
+
+ target_size -= blk_dsize;
+ }
+
+ System.Close(outfh);
+ System.Close(infh);
+
+ return ret;
+ }
///
/// Decompresses an Offline Address Book with an incremental patch file.
@@ -63,25 +218,184 @@ namespace LibMSPackSharp.OAB
/// in incorrect data being decompressed, which will then fail a checksum
/// test.
///
- ///
- /// a self-referential pointer to the msoab_decompressor
- /// instance being called
- ///
///
- /// the filename of the input file. This is passed
+ /// The filename of the input file. This is passed
/// directly to mspack_system::open().
///
- ///
- /// the filename of the base file to which the
+ ///
+ /// The filename of the base file to which the
/// incremental patch shall be applied. This is passed
/// directly to mspack_system::open().
///
///
- /// the filename of the output file. This is passed
+ /// The filename of the output file. This is passed
/// directly to mspack_system::open().
///
- /// an error code, or MSPACK_ERR_OK if successful
- public Func DecompressIncremental;
+ /// An error code, or MSPACK_ERR_OK if successful
+ public Error DecompressIncremental(string input, string basePath, string output)
+ {
+ byte[] hdrbuf = new byte[patchhead_SIZEOF];
+ LZXDStream lzx = null;
+ int window_bits;
+ uint window_size;
+ Error ret = Error.MSPACK_ERR_OK;
+
+ FileStream infh = System.Open(input, OpenMode.MSPACK_SYS_OPEN_READ);
+ if (infh == null)
+ {
+ ret = Error.MSPACK_ERR_OPEN;
+ System.Close(infh);
+ return ret;
+ }
+
+ if (System.Read(infh, hdrbuf, 0, patchhead_SIZEOF) != patchhead_SIZEOF)
+ {
+ ret = Error.MSPACK_ERR_READ;
+ System.Close(infh);
+ return ret;
+ }
+
+ if (BitConverter.ToUInt32(hdrbuf, patchhead_VersionHi) != 3 ||
+ BitConverter.ToUInt32(hdrbuf, patchhead_VersionLo) != 2)
+ {
+ ret = Error.MSPACK_ERR_SIGNATURE;
+ System.Close(infh);
+ return ret;
+ }
+
+ uint block_max = BitConverter.ToUInt32(hdrbuf, patchhead_BlockMax);
+ uint target_size = BitConverter.ToUInt32(hdrbuf, patchhead_TargetSize);
+
+ // We use it for reading block headers too
+ if (block_max < patchblk_SIZEOF)
+ block_max = patchblk_SIZEOF;
+
+ FileStream basefh = System.Open(basePath, OpenMode.MSPACK_SYS_OPEN_READ);
+ if (basefh == null)
+ {
+ ret = Error.MSPACK_ERR_OPEN;
+ System.Close(basefh);
+ System.Close(infh);
+ return ret;
+ }
+
+ FileStream outfh = System.Open(output, OpenMode.MSPACK_SYS_OPEN_WRITE);
+ if (outfh == null)
+ {
+ ret = Error.MSPACK_ERR_OPEN;
+ System.Close(outfh);
+ System.Close(basefh);
+ System.Close(infh);
+ return ret;
+ }
+
+ byte[] buf = new byte[BufferSize];
+
+ SystemImpl oabd_sys = System;
+ oabd_sys.Read = SysRead;
+ oabd_sys.Write = SysWrite;
+
+ InternalFile in_ofh = new InternalFile();
+ in_ofh.OrigSys = System;
+ in_ofh.OrigFile = infh;
+
+ InternalFile out_ofh = new InternalFile();
+ out_ofh.OrigSys = System;
+ out_ofh.OrigFile = outfh;
+
+ while (target_size != 0)
+ {
+ if (System.Read(infh, buf, 0, patchblk_SIZEOF) != patchblk_SIZEOF)
+ {
+ ret = Error.MSPACK_ERR_READ;
+ System.Close(outfh);
+ System.Close(basefh);
+ System.Close(infh);
+ return ret;
+ }
+
+ uint blk_csize = BitConverter.ToUInt32(buf, patchblk_PatchSize);
+ uint blk_dsize = BitConverter.ToUInt32(buf, patchblk_TargetSize);
+ uint blk_ssize = BitConverter.ToUInt32(buf, patchblk_SourceSize);
+ uint blk_crc = BitConverter.ToUInt32(buf, patchblk_CRC);
+
+ if (blk_dsize > block_max || blk_dsize > target_size || blk_ssize > block_max)
+ {
+ ret = Error.MSPACK_ERR_DATAFORMAT;
+ System.Close(outfh);
+ System.Close(basefh);
+ System.Close(infh);
+ return ret;
+ }
+
+ window_size = (uint)((blk_ssize + 32767) & ~32767);
+ window_size += blk_dsize;
+ window_bits = 17;
+
+ while (window_bits < 25 && (1U << window_bits) < window_size)
+ window_bits++;
+
+ in_ofh.Available = (int)blk_csize;
+ out_ofh.CRC = 0xffffffff;
+
+ lzx = LZX.Init(oabd_sys, in_ofh.OrigFile, out_ofh.OrigFile, window_bits, 0, 4096, blk_dsize, true);
+ if (lzx == null)
+ {
+ ret = Error.MSPACK_ERR_NOMEMORY;
+ System.Close(outfh);
+ System.Close(basefh);
+ System.Close(infh);
+ return ret;
+ }
+
+ ret = LZX.SetReferenceData(lzx, System, basefh, blk_ssize);
+ if (ret != Error.MSPACK_ERR_OK)
+ {
+ System.Close(outfh);
+ System.Close(basefh);
+ System.Close(infh);
+ return ret;
+ }
+
+ ret = LZX.Decompress(lzx, blk_dsize);
+ if (ret != Error.MSPACK_ERR_OK)
+ {
+ System.Close(outfh);
+ System.Close(basefh);
+ System.Close(infh);
+ return ret;
+ }
+
+ lzx = null;
+
+ // Consume any trailing padding bytes before the next block
+ ret = CopyFileHandle(infh, null, in_ofh.Available, buf, BufferSize);
+ if (ret != Error.MSPACK_ERR_OK)
+ {
+ System.Close(outfh);
+ System.Close(basefh);
+ System.Close(infh);
+ return ret;
+ }
+
+ if (out_ofh.CRC != blk_crc)
+ {
+ ret = Error.MSPACK_ERR_CHECKSUM;
+ System.Close(outfh);
+ System.Close(basefh);
+ System.Close(infh);
+ return ret;
+ }
+
+ target_size -= blk_dsize;
+ }
+
+ System.Close(outfh);
+ System.Close(basefh);
+ System.Close(infh);
+
+ return ret;
+ }
///
/// Sets an OAB decompression engine parameter. Available only in OAB
@@ -91,16 +405,95 @@ namespace LibMSPackSharp.OAB
/// buffer by decompressors? The minimum value is 16. The default value
/// is 4096.
///
- ///
- /// a self-referential pointer to the msoab_decompressor
- /// instance being called
- ///
- /// the parameter to set
- /// the value to set the parameter to
+ /// The parameter to set
+ /// The value to set the parameter to
///
/// MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there
/// is a problem with either parameter or value.
///
- public Func SetParam;
+ public Error SetParam(Parameters param, int value)
+ {
+ if (param == Parameters.MSOABD_PARAM_DECOMPBUF && value >= 16)
+ {
+ // Must be at least 16 bytes (patchblk_SIZEOF, oabblk_SIZEOF)
+ BufferSize = value;
+ return Error.MSPACK_ERR_OK;
+ }
+
+ return Error.MSPACK_ERR_ARGS;
+ }
+
+ #endregion
+
+ #region I/O Methods
+
+ private static int SysRead(object baseFile, byte[] buf, int pointer, int size)
+ {
+ InternalFile file = baseFile as InternalFile;
+ if (file == null)
+ return 0;
+
+ int bytes_read;
+
+ if (size > file.Available)
+ size = file.Available;
+
+ bytes_read = file.OrigSys.Read(file.OrigFile, buf, pointer, size);
+ if (bytes_read < 0)
+ return bytes_read;
+
+ file.Available -= bytes_read;
+ return bytes_read;
+ }
+
+ private static int SysWrite(object baseFile, byte[] buf, int pointer, int size)
+ {
+ // Null output file means skip those bytes
+ if (baseFile == null)
+ {
+ return size;
+ }
+ else if (baseFile is InternalFile file)
+ {
+ int bytes_written = file.OrigSys.Write(file.OrigFile, buf, pointer, size);
+ if (bytes_written > 0)
+ file.CRC = Checksum.CRC32(buf, 0, bytes_written, file.CRC);
+
+ return bytes_written;
+ }
+ else if (baseFile is FileStream impl)
+ {
+ return SystemImpl.DefaultSystem.Write(impl, buf, pointer, size);
+ }
+
+ // Unknown file to write to
+ return -1;
+ }
+
+ #endregion
+
+ #region Helpers
+
+ private Error CopyFileHandle(FileStream infh, FileStream outfh, int bytes_to_copy, byte[] buf, int buf_size)
+ {
+ while (bytes_to_copy != 0)
+ {
+ int run = buf_size;
+ if (run > bytes_to_copy)
+ run = bytes_to_copy;
+
+ if (System.Read(infh, buf, 0, run) != run)
+ return Error.MSPACK_ERR_READ;
+
+ if (outfh != null && System.Write(outfh, buf, 0, run) != run)
+ return Error.MSPACK_ERR_WRITE;
+
+ bytes_to_copy -= run;
+ }
+
+ return Error.MSPACK_ERR_OK;
+ }
+
+ #endregion
}
}
diff --git a/BurnOutSharp/External/libmspack/OAB/DecompressorImpl.cs b/BurnOutSharp/External/libmspack/OAB/DecompressorImpl.cs
deleted file mode 100644
index 4309d503..00000000
--- a/BurnOutSharp/External/libmspack/OAB/DecompressorImpl.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-/* This file is part of libmspack.
- * © 2013 Intel Corporation
- *
- * libmspack is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
- *
- * For further details, see the file COPYING.LIB distributed with libmspack
- */
-
-namespace LibMSPackSharp.OAB
-{
- public class DecompressorImpl : Decompressor
- {
- public SystemImpl System { get; set; }
-
- public int BufferSize { get; set; }
-
- // TODO
- }
-}
diff --git a/BurnOutSharp/External/libmspack/OAB/Implementation.cs b/BurnOutSharp/External/libmspack/OAB/Implementation.cs
deleted file mode 100644
index 828c20ee..00000000
--- a/BurnOutSharp/External/libmspack/OAB/Implementation.cs
+++ /dev/null
@@ -1,491 +0,0 @@
-/* This file is part of libmspack.
- * © 2013 Intel Corporation
- *
- * libmspack is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
- *
- * For further details, see the file COPYING.LIB distributed with libmspack
- */
-
-/* The Exchange Online Addressbook (OAB or sometimes OAL) is distributed
- * as a .LZX file in one of two forms. Either a "full download" containing
- * the entire address list, or an incremental binary patch which should be
- * applied to a previous version of the full decompressed data.
- *
- * The contents and format of the decompressed OAB are not handled here.
- *
- * For a complete description of the format, see the MSDN site:
- *
- * http://msdn.microsoft.com/en-us/library/cc463914 - [MS-OXOAB].pdf
- * http://msdn.microsoft.com/en-us/library/cc483133 - [MS-PATCH].pdf
- */
-
-using System;
-using System.IO;
-using LibMSPackSharp.Compression;
-
-namespace LibMSPackSharp.OAB
-{
- public class Implementation
- {
- #region OAB decompression definitions
-
- private const int oabhead_VersionHi = 0x0000;
- private const int oabhead_VersionLo = 0x0004;
- private const int oabhead_BlockMax = 0x0008;
- private const int oabhead_TargetSize = 0x000c;
- private const int oabhead_SIZEOF = 0x0010;
-
- private const int oabblk_Flags = 0x0000;
- private const int oabblk_CompSize = 0x0004;
- private const int oabblk_UncompSize = 0x0008;
- private const int oabblk_CRC = 0x000c;
- private const int oabblk_SIZEOF = 0x0010;
-
- private const int patchhead_VersionHi = 0x0000;
- private const int patchhead_VersionLo = 0x0004;
- private const int patchhead_BlockMax = 0x0008;
- private const int patchhead_SourceSize = 0x000c;
- private const int patchhead_TargetSize = 0x0010;
- private const int patchhead_SourceCRC = 0x0014;
- private const int patchhead_TargetCRC = 0x0018;
- private const int patchhead_SIZEOF = 0x001c;
-
- private const int patchblk_PatchSize = 0x0000;
- private const int patchblk_TargetSize = 0x0004;
- private const int patchblk_SourceSize = 0x0008;
- private const int patchblk_CRC = 0x000c;
- private const int patchblk_SIZEOF = 0x0010;
-
- #endregion
-
- #region OABD_SYS_READ
-
- private static int SysRead(object baseFile, byte[] buf, int pointer, int size)
- {
- InternalFile file = baseFile as InternalFile;
- if (file == null)
- return 0;
-
- int bytes_read;
-
- if (size > file.Available)
- size = file.Available;
-
- bytes_read = file.OrigSys.Read(file.OrigFile, buf, pointer, size);
- if (bytes_read < 0)
- return bytes_read;
-
- file.Available -= bytes_read;
- return bytes_read;
- }
-
- #endregion
-
- #region OABD_SYS_WRITE
-
- private static int SysWrite(object baseFile, byte[] buf, int pointer, int size)
- {
- // Null output file means skip those bytes
- if (baseFile == null)
- {
- return size;
- }
- else if (baseFile is InternalFile file)
- {
- int bytes_written = file.OrigSys.Write(file.OrigFile, buf, pointer, size);
- if (bytes_written > 0)
- file.CRC = Checksum.CRC32(buf, 0, bytes_written, file.CRC);
-
- return bytes_written;
- }
- else if (baseFile is FileStream impl)
- {
- return SystemImpl.DefaultSystem.Write(impl, buf, pointer, size);
- }
-
- // Unknown file to write to
- return -1;
- }
-
- #endregion
-
- #region OABD_DECOMPRESS
-
- public static Error Decompress(Decompressor d, string input, string output)
- {
- DecompressorImpl self = d as DecompressorImpl;
- byte[] hdrbuf = new byte[oabhead_SIZEOF];
- LZXDStream lzx = null;
- Error ret = Error.MSPACK_ERR_OK;
-
- if (self == null)
- return Error.MSPACK_ERR_ARGS;
-
- SystemImpl sys = self.System;
-
- FileStream infh = sys.Open(input, OpenMode.MSPACK_SYS_OPEN_READ);
- if (infh == null)
- {
- ret = Error.MSPACK_ERR_OPEN;
- sys.Close(infh);
- return ret;
- }
-
- if (sys.Read(infh, hdrbuf, 0, oabhead_SIZEOF) != oabhead_SIZEOF)
- {
- ret = Error.MSPACK_ERR_READ;
- sys.Close(infh);
- return ret;
- }
-
- if (BitConverter.ToUInt32(hdrbuf, oabhead_VersionHi) != 3 ||
- BitConverter.ToUInt32(hdrbuf, oabhead_VersionLo) != 1)
- {
- ret = Error.MSPACK_ERR_SIGNATURE;
- sys.Close(infh);
- return ret;
- }
-
- uint block_max = BitConverter.ToUInt32(hdrbuf, oabhead_BlockMax);
- uint target_size = BitConverter.ToUInt32(hdrbuf, oabhead_TargetSize);
-
- FileStream outfh = sys.Open(output, OpenMode.MSPACK_SYS_OPEN_WRITE);
- if (outfh == null)
- {
- ret = Error.MSPACK_ERR_OPEN;
- sys.Close(outfh);
- sys.Close(infh);
- return ret;
- }
-
- byte[] buf = new byte[self.BufferSize];
-
- SystemImpl oabd_sys = sys;
- oabd_sys.Read = SysRead;
- oabd_sys.Write = SysWrite;
-
- InternalFile in_ofh = new InternalFile();
- in_ofh.OrigSys = sys;
- in_ofh.OrigFile = infh;
-
- InternalFile out_ofh = new InternalFile();
- out_ofh.OrigSys = sys;
- out_ofh.OrigFile = outfh;
-
- while (target_size != 0)
- {
- if (sys.Read(infh, buf, 0, oabblk_SIZEOF) != oabblk_SIZEOF)
- {
- ret = Error.MSPACK_ERR_READ;
- sys.Close(outfh);
- sys.Close(infh);
- return ret;
- }
-
- uint blk_flags = BitConverter.ToUInt32(buf, oabblk_Flags);
- uint blk_csize = BitConverter.ToUInt32(buf, oabblk_CompSize);
- uint blk_dsize = BitConverter.ToUInt32(buf, oabblk_UncompSize);
- uint blk_crc = BitConverter.ToUInt32(buf, oabblk_CRC);
-
- if (blk_dsize > block_max || blk_dsize > target_size || blk_flags > 1)
- {
- ret = Error.MSPACK_ERR_DATAFORMAT;
- sys.Close(outfh);
- sys.Close(infh);
- return ret;
- }
-
- if (blk_flags == 0)
- {
- // Uncompressed block
- if (blk_dsize != blk_csize)
- {
- ret = Error.MSPACK_ERR_DATAFORMAT;
- sys.Close(outfh);
- sys.Close(infh);
- return ret;
- }
-
- ret = CopyFileHandle(sys, infh, outfh, (int)blk_dsize, buf, self.BufferSize);
- if (ret != Error.MSPACK_ERR_OK)
- {
- sys.Close(outfh);
- sys.Close(infh);
- return ret;
- }
- }
- else
- {
- // LZX compressed block
- int window_bits = 17;
-
- while (window_bits < 25 && (1U << window_bits) < blk_dsize)
- {
- window_bits++;
- }
-
- in_ofh.Available = (int)blk_csize;
- out_ofh.CRC = 0xffffffff;
-
- lzx = LZX.Init(oabd_sys, in_ofh.OrigFile, out_ofh.OrigFile, window_bits, 0, self.BufferSize, blk_dsize, true);
- if (lzx == null)
- {
- ret = Error.MSPACK_ERR_NOMEMORY;
- sys.Close(outfh);
- sys.Close(infh);
- return ret;
- }
-
- ret = LZX.Decompress(lzx, blk_dsize);
- if (ret != Error.MSPACK_ERR_OK)
- {
- sys.Close(outfh);
- sys.Close(infh);
- return ret;
- }
-
- lzx = null;
-
- // Consume any trailing padding bytes before the next block
- ret = CopyFileHandle(sys, infh, null, in_ofh.Available, buf, self.BufferSize);
- if (ret != Error.MSPACK_ERR_OK)
- {
- sys.Close(outfh);
- sys.Close(infh);
- return ret;
- }
-
- if (out_ofh.CRC != blk_crc)
- {
- ret = Error.MSPACK_ERR_CHECKSUM;
- sys.Close(outfh);
- sys.Close(infh);
- return ret;
- }
- }
-
- target_size -= blk_dsize;
- }
-
- sys.Close(outfh);
- sys.Close(infh);
-
- return ret;
- }
-
- #endregion
-
- #region OABD_DECOMPRESS_INCREMENTAL
-
- public static Error DecompressIncremental(Decompressor d, string input, string basePath, string output)
- {
- DecompressorImpl self = d as DecompressorImpl;
- byte[] hdrbuf = new byte[patchhead_SIZEOF];
- LZXDStream lzx = null;
- int window_bits;
- uint window_size;
- Error ret = Error.MSPACK_ERR_OK;
-
- if (self == null)
- return Error.MSPACK_ERR_ARGS;
-
- SystemImpl sys = self.System;
-
- FileStream infh = sys.Open(input, OpenMode.MSPACK_SYS_OPEN_READ);
- if (infh == null)
- {
- ret = Error.MSPACK_ERR_OPEN;
- sys.Close(infh);
- return ret;
- }
-
- if (sys.Read(infh, hdrbuf, 0, patchhead_SIZEOF) != patchhead_SIZEOF)
- {
- ret = Error.MSPACK_ERR_READ;
- sys.Close(infh);
- return ret;
- }
-
- if (BitConverter.ToUInt32(hdrbuf, patchhead_VersionHi) != 3 ||
- BitConverter.ToUInt32(hdrbuf, patchhead_VersionLo) != 2)
- {
- ret = Error.MSPACK_ERR_SIGNATURE;
- sys.Close(infh);
- return ret;
- }
-
- uint block_max = BitConverter.ToUInt32(hdrbuf, patchhead_BlockMax);
- uint target_size = BitConverter.ToUInt32(hdrbuf, patchhead_TargetSize);
-
- // We use it for reading block headers too
- if (block_max < patchblk_SIZEOF)
- block_max = patchblk_SIZEOF;
-
- FileStream basefh = sys.Open(basePath, OpenMode.MSPACK_SYS_OPEN_READ);
- if (basefh == null)
- {
- ret = Error.MSPACK_ERR_OPEN;
- sys.Close(basefh);
- sys.Close(infh);
- return ret;
- }
-
- FileStream outfh = sys.Open(output, OpenMode.MSPACK_SYS_OPEN_WRITE);
- if (outfh == null)
- {
- ret = Error.MSPACK_ERR_OPEN;
- sys.Close(outfh);
- sys.Close(basefh);
- sys.Close(infh);
- return ret;
- }
-
- byte[] buf = new byte[self.BufferSize];
-
- SystemImpl oabd_sys = sys;
- oabd_sys.Read = SysRead;
- oabd_sys.Write = SysWrite;
-
- InternalFile in_ofh = new InternalFile();
- in_ofh.OrigSys = sys;
- in_ofh.OrigFile = infh;
-
- InternalFile out_ofh = new InternalFile();
- out_ofh.OrigSys = sys;
- out_ofh.OrigFile = outfh;
-
- while (target_size != 0)
- {
- if (sys.Read(infh, buf, 0, patchblk_SIZEOF) != patchblk_SIZEOF)
- {
- ret = Error.MSPACK_ERR_READ;
- sys.Close(outfh);
- sys.Close(basefh);
- sys.Close(infh);
- return ret;
- }
-
- uint blk_csize = BitConverter.ToUInt32(buf, patchblk_PatchSize);
- uint blk_dsize = BitConverter.ToUInt32(buf, patchblk_TargetSize);
- uint blk_ssize = BitConverter.ToUInt32(buf, patchblk_SourceSize);
- uint blk_crc = BitConverter.ToUInt32(buf, patchblk_CRC);
-
- if (blk_dsize > block_max || blk_dsize > target_size || blk_ssize > block_max)
- {
- ret = Error.MSPACK_ERR_DATAFORMAT;
- sys.Close(outfh);
- sys.Close(basefh);
- sys.Close(infh);
- return ret;
- }
-
- window_size = (uint)((blk_ssize + 32767) & ~32767);
- window_size += blk_dsize;
- window_bits = 17;
-
- while (window_bits < 25 && (1U << window_bits) < window_size)
- window_bits++;
-
- in_ofh.Available = (int)blk_csize;
- out_ofh.CRC = 0xffffffff;
-
- lzx = LZX.Init(oabd_sys, in_ofh.OrigFile, out_ofh.OrigFile, window_bits, 0, 4096, blk_dsize, true);
- if (lzx == null)
- {
- ret = Error.MSPACK_ERR_NOMEMORY;
- sys.Close(outfh);
- sys.Close(basefh);
- sys.Close(infh);
- return ret;
- }
-
- ret = LZX.SetReferenceData(lzx, sys, basefh, blk_ssize);
- if (ret != Error.MSPACK_ERR_OK)
- {
- sys.Close(outfh);
- sys.Close(basefh);
- sys.Close(infh);
- return ret;
- }
-
- ret = LZX.Decompress(lzx, blk_dsize);
- if (ret != Error.MSPACK_ERR_OK)
- {
- sys.Close(outfh);
- sys.Close(basefh);
- sys.Close(infh);
- return ret;
- }
-
- lzx = null;
-
- // Consume any trailing padding bytes before the next block
- ret = CopyFileHandle(sys, infh, null, in_ofh.Available, buf, self.BufferSize);
- if (ret != Error.MSPACK_ERR_OK)
- {
- sys.Close(outfh);
- sys.Close(basefh);
- sys.Close(infh);
- return ret;
- }
-
- if (out_ofh.CRC != blk_crc)
- {
- ret = Error.MSPACK_ERR_CHECKSUM;
- sys.Close(outfh);
- sys.Close(basefh);
- sys.Close(infh);
- return ret;
- }
-
- target_size -= blk_dsize;
- }
-
- sys.Close(outfh);
- sys.Close(basefh);
- sys.Close(infh);
-
- return ret;
- }
-
- private static Error CopyFileHandle(SystemImpl sys, FileStream infh, FileStream outfh, int bytes_to_copy, byte[] buf, int buf_size)
- {
- while (bytes_to_copy != 0)
- {
- int run = buf_size;
- if (run > bytes_to_copy)
- run = bytes_to_copy;
-
- if (sys.Read(infh, buf, 0, run) != run)
- return Error.MSPACK_ERR_READ;
-
- if (outfh != null && sys.Write(outfh, buf, 0, run) != run)
- return Error.MSPACK_ERR_WRITE;
-
- bytes_to_copy -= run;
- }
-
- return Error.MSPACK_ERR_OK;
- }
-
- #endregion
-
- #region OABD_PARAM
-
- public static Error Param(Decompressor d, Parameters param, int value)
- {
- DecompressorImpl self = d as DecompressorImpl;
- if (self != null && param == Parameters.MSOABD_PARAM_DECOMPBUF && value >= 16)
- {
- // must be at least 16 bytes (patchblk_SIZEOF, oabblk_SIZEOF)
- self.BufferSize = value;
- return Error.MSPACK_ERR_OK;
- }
-
- return Error.MSPACK_ERR_ARGS;
- }
-
- #endregion
- }
-}
diff --git a/BurnOutSharp/External/libmspack/SZDD/Compressor.cs b/BurnOutSharp/External/libmspack/SZDD/Compressor.cs
index 18520701..f28b984b 100644
--- a/BurnOutSharp/External/libmspack/SZDD/Compressor.cs
+++ b/BurnOutSharp/External/libmspack/SZDD/Compressor.cs
@@ -27,6 +27,14 @@ namespace LibMSPackSharp.SZDD
///
public class Compressor
{
+ #region Fields
+
+ public SystemImpl System { get; set; }
+
+ public Error Error { get; set; }
+
+ #endregion
+
///
/// Reads an input file and creates a compressed output file in the
/// SZDD compressed file format. The SZDD compression format is quick
diff --git a/BurnOutSharp/External/libmspack/SZDD/CompressorImpl.cs b/BurnOutSharp/External/libmspack/SZDD/CompressorImpl.cs
deleted file mode 100644
index 60b2495f..00000000
--- a/BurnOutSharp/External/libmspack/SZDD/CompressorImpl.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-/* This file is part of libmspack.
- * (C) 2003-2004 Stuart Caie.
- *
- * libmspack is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
- *
- * For further details, see the file COPYING.LIB distributed with libmspack
- */
-
-namespace LibMSPackSharp.SZDD
-{
- public class CompressorImpl : Compressor
- {
- public SystemImpl System { get; set; }
-
- public Error Error { get; set; }
- }
-}
diff --git a/BurnOutSharp/External/libmspack/SZDD/Decompressor.cs b/BurnOutSharp/External/libmspack/SZDD/Decompressor.cs
index 537ae425..72bffb97 100644
--- a/BurnOutSharp/External/libmspack/SZDD/Decompressor.cs
+++ b/BurnOutSharp/External/libmspack/SZDD/Decompressor.cs
@@ -15,6 +15,10 @@
*/
using System;
+using System.IO;
+using System.Linq;
+using LibMSPackSharp.Compression;
+using static LibMSPackSharp.Constants;
namespace LibMSPackSharp.SZDD
{
@@ -25,8 +29,10 @@ namespace LibMSPackSharp.SZDD
///
///
///
- public class Decompressor
+ public class Decompressor : BaseDecompressor
{
+ #region Public Functionality
+
///
/// Opens a SZDD file and reads the header.
///
@@ -39,17 +45,37 @@ namespace LibMSPackSharp.SZDD
/// The filename pointer should be considered "in use" until close() is
/// called on the SZDD file.
///
- ///
- /// a self-referential pointer to the msszdd_decompressor
- /// instance being called
- ///
///
- /// the filename of the SZDD compressed file. This is
+ /// The filename of the SZDD compressed file. This is
/// passed directly to mspack_system::open().
///
- /// a pointer to a msszddd_header structure, or NULL on failure
- ///
- public Func Open;
+ /// A pointer to a msszddd_header structure, or NULL on failure
+ ///
+ public Header Open(string filename)
+ {
+ FileStream fh = System.Open(filename, OpenMode.MSPACK_SYS_OPEN_READ);
+ Header hdr = new Header();
+ if (fh != null && hdr != null)
+ {
+ hdr.FileHandle = fh;
+ Error = ReadHeaders(fh, hdr);
+ }
+ else
+ {
+ if (fh == null)
+ Error = Error.MSPACK_ERR_OPEN;
+ if (hdr == null)
+ Error = Error.MSPACK_ERR_NOMEMORY;
+ }
+
+ if (Error != Error.MSPACK_ERR_OK)
+ {
+ System.Close(fh);
+ hdr = null;
+ }
+
+ return hdr;
+ }
///
/// Closes a previously opened SZDD file.
@@ -59,13 +85,18 @@ namespace LibMSPackSharp.SZDD
///
/// The SZDD header pointer is now invalid and cannot be used again.
///
- ///
- /// a self-referential pointer to the msszdd_decompressor
- /// instance being called
- ///
- /// the SZDD file to close
- ///
- public Action Close;
+ /// The SZDD file to close
+ ///
+ public void Close(Header hdr)
+ {
+ if (System == null || hdr == null)
+ return;
+
+ // Close the file handle associated
+ System.Close(hdr.FileHandle);
+
+ Error = Error.MSPACK_ERR_OK;
+ }
///
/// Extracts the compressed data from a SZDD file.
@@ -73,17 +104,46 @@ namespace LibMSPackSharp.SZDD
/// This decompresses the compressed SZDD data stream and writes it to
/// an output file.
///
- ///
- /// a self-referential pointer to the msszdd_decompressor
- /// instance being called
- ///
- /// the SZDD file to extract data from
+ /// The SZDD file to extract data from
///
- /// filename the filename to write the decompressed data to. This
+ /// The filename to write the decompressed data to. This
/// is passed directly to mspack_system::open().
///
- /// an error code, or MSPACK_ERR_OK if successful
- public Func Extract;
+ /// An error code, or MSPACK_ERR_OK if successful
+ public Error Extract(Header hdr, string filename)
+ {
+ if (hdr == null)
+ return Error = Error.MSPACK_ERR_ARGS;
+
+ FileStream fh = hdr.FileHandle;
+ if (fh == null)
+ return Error.MSPACK_ERR_ARGS;
+
+ // Seek to the compressed data
+ long dataOffset = (hdr.Format == Format.MSSZDD_FMT_NORMAL) ? 14 : 12;
+ if (System.Seek(fh, dataOffset, SeekMode.MSPACK_SYS_SEEK_START))
+ return Error = Error.MSPACK_ERR_SEEK;
+
+ // Open file for output
+ FileStream outfh = System.Open(filename, OpenMode.MSPACK_SYS_OPEN_WRITE);
+ if (outfh == null)
+ return Error = Error.MSPACK_ERR_OPEN;
+
+ // Decompress the data
+ Error = LZSS.Decompress(
+ System,
+ fh,
+ outfh,
+ SZDD_INPUT_SIZE,
+ hdr.Format == Format.MSSZDD_FMT_NORMAL
+ ? LZSSMode.LZSS_MODE_EXPAND
+ : LZSSMode.LZSS_MODE_QBASIC);
+
+ // Close output file
+ System.Close(outfh);
+
+ return Error;
+ }
///
/// Decompresses an SZDD file to an output file in one step.
@@ -94,35 +154,73 @@ namespace LibMSPackSharp.SZDD
/// open() then extract() then close(), if you do not need to know the
/// SZDD output size or missing character.
///
- ///
- /// a self-referential pointer to the msszdd_decompressor
- /// instance being called
- ///
///
- /// the filename of the input SZDD file. This is passed
+ /// The filename of the input SZDD file. This is passed
/// directly to mspack_system::open().
///
///
- /// the filename to write the decompressed data to. This
+ /// The filename to write the decompressed data to. This
/// is passed directly to mspack_system::open().
///
- /// an error code, or MSPACK_ERR_OK if successful
- public Func Decompress;
+ /// An error code, or MSPACK_ERR_OK if successful
+ public Error Decompress(string input, string output)
+ {
+ Header hdr = Open(input) as Header;
+ if (hdr == null)
+ return Error;
+
+ Error error = Extract(hdr, output);
+ Close(hdr);
+ return Error = error;
+ }
+
+ #endregion
+
+ #region Helpers
///
- /// Returns the error code set by the most recently called method.
- ///
- /// This is useful for open() which does not return an
- /// error code directly.
+ /// Reads the headers of an SZDD format file
///
- ///
- /// a self-referential pointer to the msszdd_decompressor
- /// instance being called
- ///
- /// the most recent error code
- ///
- ///
- ///
- public Func LastError;
+ private Error ReadHeaders(FileStream fh, Header hdr)
+ {
+ // Read and check signature
+ byte[] buf = new byte[8];
+ if (System.Read(fh, buf, 0, 8) != 8)
+ return Error.MSPACK_ERR_READ;
+
+ if (buf.SequenceEqual(expandSignature))
+ {
+ // Common SZDD
+ hdr.Format = Format.MSSZDD_FMT_NORMAL;
+
+ // Read the rest of the header
+ if (System.Read(fh, buf, 0, 6) != 6)
+ return Error.MSPACK_ERR_READ;
+
+ if (buf[0] != 0x41)
+ return Error.MSPACK_ERR_DATAFORMAT;
+
+ hdr.MissingChar = (char)buf[1];
+ hdr.Length = BitConverter.ToUInt32(buf, 2);
+ }
+ if (buf.SequenceEqual(qbasicSignature))
+ {
+ // Special QBasic SZDD
+ hdr.Format = Format.MSSZDD_FMT_QBASIC;
+ if (System.Read(fh, buf, 0, 4) != 4)
+ return Error.MSPACK_ERR_READ;
+
+ hdr.MissingChar = '\0';
+ hdr.Length = BitConverter.ToUInt32(buf, 0);
+ }
+ else
+ {
+ return Error.MSPACK_ERR_SIGNATURE;
+ }
+
+ return Error.MSPACK_ERR_OK;
+ }
+
+ #endregion
}
}
diff --git a/BurnOutSharp/External/libmspack/SZDD/DecompressorImpl.cs b/BurnOutSharp/External/libmspack/SZDD/DecompressorImpl.cs
deleted file mode 100644
index 161e8797..00000000
--- a/BurnOutSharp/External/libmspack/SZDD/DecompressorImpl.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-/* This file is part of libmspack.
- * (C) 2003-2004 Stuart Caie.
- *
- * libmspack is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
- *
- * For further details, see the file COPYING.LIB distributed with libmspack
- */
-
-namespace LibMSPackSharp.SZDD
-{
- public class DecompressorImpl : Decompressor
- {
- public SystemImpl System { get; set; }
-
- public Error Error { get; set; }
- }
-}
diff --git a/BurnOutSharp/External/libmspack/SZDD/Header.cs b/BurnOutSharp/External/libmspack/SZDD/Header.cs
index 96767497..6536e1e0 100644
--- a/BurnOutSharp/External/libmspack/SZDD/Header.cs
+++ b/BurnOutSharp/External/libmspack/SZDD/Header.cs
@@ -14,6 +14,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+using System.IO;
+
namespace LibMSPackSharp.SZDD
{
///
@@ -21,7 +23,7 @@ namespace LibMSPackSharp.SZDD
///
/// All fields are READ ONLY.
///
- public class Header
+ public class Header : BaseHeader
{
///
/// The file format
@@ -41,5 +43,7 @@ namespace LibMSPackSharp.SZDD
/// an MS-DOS filename (except ".") are valid.
///
public char MissingChar { get; set; }
+
+ public FileStream FileHandle { get; set; }
}
}
diff --git a/BurnOutSharp/External/libmspack/SZDD/HeaderImpl.cs b/BurnOutSharp/External/libmspack/SZDD/HeaderImpl.cs
deleted file mode 100644
index 57a4dee1..00000000
--- a/BurnOutSharp/External/libmspack/SZDD/HeaderImpl.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-/* This file is part of libmspack.
- * (C) 2003-2004 Stuart Caie.
- *
- * libmspack is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
- *
- * For further details, see the file COPYING.LIB distributed with libmspack
- */
-
-using System.IO;
-
-namespace LibMSPackSharp.SZDD
-{
- public class HeaderImpl : Header
- {
- public FileStream FileHandle { get; set; }
- }
-}
diff --git a/BurnOutSharp/External/libmspack/SZDD/Implementation.cs b/BurnOutSharp/External/libmspack/SZDD/Implementation.cs
deleted file mode 100644
index a2b1d138..00000000
--- a/BurnOutSharp/External/libmspack/SZDD/Implementation.cs
+++ /dev/null
@@ -1,223 +0,0 @@
-/* This file is part of libmspack.
- * (C) 2003-2004 Stuart Caie.
- *
- * libmspack is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
- *
- * For further details, see the file COPYING.LIB distributed with libmspack
- */
-
-using System;
-using System.IO;
-using System.Linq;
-using LibMSPackSharp.Compression;
-
-namespace LibMSPackSharp.SZDD
-{
- public class Implementation
- {
- ///
- /// Input buffer size during decompression - not worth parameterising IMHO
- ///
- private const int SZDD_INPUT_SIZE = 2048;
-
- #region SZDDD_OPEN
-
- ///
- /// Opens an SZDD file without decompressing, reads header
- ///
- public static Header Open(Decompressor d, string filename)
- {
- DecompressorImpl self = d as DecompressorImpl;
- if (self == null)
- return null;
-
- SystemImpl sys = self.System;
-
- FileStream fh = sys.Open(filename, OpenMode.MSPACK_SYS_OPEN_READ);
- HeaderImpl hdr = new HeaderImpl();
- if (fh != null && hdr != null)
- {
- hdr.FileHandle = fh;
- self.Error = ReadHeaders(sys, fh, hdr);
- }
- else
- {
- if (fh == null)
- self.Error = Error.MSPACK_ERR_OPEN;
- if (hdr == null)
- self.Error = Error.MSPACK_ERR_NOMEMORY;
- }
-
- if (self.Error != Error.MSPACK_ERR_OK)
- {
- sys.Close(fh);
- hdr = null;
- }
-
- return hdr;
- }
-
- #endregion
-
- #region SZDDD_CLOSE
-
- ///
- /// Closes an SZDD file
- ///
- public static void Close(Decompressor d, Header hdr)
- {
- DecompressorImpl self = d as DecompressorImpl;
- HeaderImpl hdr_p = hdr as HeaderImpl;
-
- if (self?.System == null || hdr == null)
- return;
-
- // Close the file handle associated
- self.System.Close(hdr_p.FileHandle);
-
- self.Error = Error.MSPACK_ERR_OK;
- }
-
- #endregion
-
- #region SZDDD_READ_HEADERS
-
- private static byte[] expandSignature = new byte[8]
- {
- 0x53, 0x5A, 0x44, 0x44, 0x88, 0xF0, 0x27, 0x33
- };
-
- private static byte[] qbasicSignature = new byte[8]
- {
- 0x53, 0x5A, 0x20, 0x88, 0xF0, 0x27, 0x33, 0xD1
- };
-
- ///
- /// Reads the headers of an SZDD format file
- ///
- public static Error ReadHeaders(SystemImpl sys, FileStream fh, Header hdr)
- {
- // Read and check signature
- byte[] buf = new byte[8];
- if (sys.Read(fh, buf, 0, 8) != 8)
- return Error.MSPACK_ERR_READ;
-
- if (buf.SequenceEqual(expandSignature))
- {
- // Common SZDD
- hdr.Format = Format.MSSZDD_FMT_NORMAL;
-
- // Read the rest of the header
- if (sys.Read(fh, buf, 0, 6) != 6)
- return Error.MSPACK_ERR_READ;
-
- if (buf[0] != 0x41)
- return Error.MSPACK_ERR_DATAFORMAT;
-
- hdr.MissingChar = (char)buf[1];
- hdr.Length = BitConverter.ToUInt32(buf, 2);
- }
- if (buf.SequenceEqual(qbasicSignature))
- {
- // Special QBasic SZDD
- hdr.Format = Format.MSSZDD_FMT_QBASIC;
- if (sys.Read(fh, buf, 0, 4) != 4)
- return Error.MSPACK_ERR_READ;
-
- hdr.MissingChar = '\0';
- hdr.Length = BitConverter.ToUInt32(buf, 0);
- }
- else
- {
- return Error.MSPACK_ERR_SIGNATURE;
- }
-
- return Error.MSPACK_ERR_OK;
- }
-
- #endregion
-
- #region SZDDD_EXTRACT
-
- ///
- /// Decompresses an SZDD file
- ///
- public static Error Extract(Decompressor d, Header hdr, string filename)
- {
- DecompressorImpl self = d as DecompressorImpl;
- if (self == null)
- return Error.MSPACK_ERR_ARGS;
- if (hdr == null)
- return self.Error = Error.MSPACK_ERR_ARGS;
-
- SystemImpl sys = self.System;
-
- FileStream fh = (hdr as HeaderImpl)?.FileHandle;
- if (fh == null)
- return Error.MSPACK_ERR_ARGS;
-
- // Seek to the compressed data
- long dataOffset = (hdr.Format == Format.MSSZDD_FMT_NORMAL) ? 14 : 12;
- if (sys.Seek(fh, dataOffset, SeekMode.MSPACK_SYS_SEEK_START))
- return self.Error = Error.MSPACK_ERR_SEEK;
-
- // Open file for output
- FileStream outfh;
- if ((outfh = sys.Open(filename, OpenMode.MSPACK_SYS_OPEN_WRITE)) == null)
- return self.Error = Error.MSPACK_ERR_OPEN;
-
- // Decompress the data
- self.Error = LZSS.Decompress(
- sys,
- fh,
- outfh,
- SZDD_INPUT_SIZE,
- hdr.Format == Format.MSSZDD_FMT_NORMAL
- ? LZSSMode.LZSS_MODE_EXPAND
- : LZSSMode.LZSS_MODE_QBASIC);
-
- // Close output file
- sys.Close(outfh);
-
- return self.Error;
- }
-
- #endregion
-
- #region SZDDD_DECOMPRESS
-
- ///
- /// Unpacks directly from input to output
- ///
- public static Error Decompress(Decompressor d, string input, string output)
- {
- DecompressorImpl self = d as DecompressorImpl;
- if (self == null)
- return Error.MSPACK_ERR_ARGS;
-
- Header hdr;
- if ((hdr = Open(d, input)) == null)
- return self.Error;
-
- Error error = Extract(d, hdr, output);
- Close(d, hdr);
- return self.Error = error;
- }
-
- #endregion
-
- #region SZDDD_ERROR
-
- ///
- /// Returns the last error that occurred
- ///
- public static Error LastError(Decompressor d)
- {
- DecompressorImpl self = d as DecompressorImpl;
- return (self != null) ? self.Error : Error.MSPACK_ERR_ARGS;
- }
-
- #endregion
- }
-}