[ArchiveTools] Fix TorrentZip write

Apparently, only a very specific version of Zlib stuff will work for TZIP. This implementation is copied from RomVault for full compatibility.
This commit is contained in:
Matt Nadareski
2016-10-07 12:16:33 -07:00
parent da0b25bd78
commit 67564aef1a
16 changed files with 8797 additions and 8750 deletions

View File

@@ -27,9 +27,10 @@
using System;
using Interop = System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
namespace Ionic.Crc
namespace SabreTools.Helper
{
/// <summary>
/// Computes a CRC-32. The CRC-32 algorithm is parameterized - you
@@ -42,10 +43,10 @@ namespace Ionic.Crc
/// archive files.
/// </remarks>
[Interop.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000C")]
[Interop.ComVisible(true)]
[Guid("ebc25cf6-9120-4283-b972-0e5520d0000C")]
[System.Runtime.InteropServices.ComVisible(true)]
#if !NETCF
[Interop.ClassInterface(Interop.ClassInterfaceType.AutoDispatch)]
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.AutoDispatch)]
#endif
public class CRC32
{
@@ -70,6 +71,14 @@ namespace Ionic.Crc
return unchecked((Int32)(~_register));
}
}
public uint Crc32ResultU
{
get
{
return ~_register;
}
}
/// <summary>
/// Returns the CRC32 for the specified stream.
@@ -362,7 +371,8 @@ namespace Ionic.Crc
// apply len2 zeros to crc1 (first square will put the operator for one
// zero byte, eight zero bits, in even)
do {
do
{
// apply zeros operator for this bit of len2
gf2_matrix_square(even, odd);
@@ -395,7 +405,8 @@ namespace Ionic.Crc
/// Create an instance of the CRC32 class using the default settings: no
/// bit reversal, and a polynomial of 0xEDB88320.
/// </summary>
public CRC32() : this(false)
public CRC32()
: this(false)
{
}
@@ -811,4 +822,35 @@ namespace Ionic.Crc
}
public class CRC32Hash : HashAlgorithm
{
private CRC32 _Crc32=new CRC32();
public override void Initialize()
{
_Crc32.Reset();
}
protected override void HashCore(byte[] buffer, int start, int length)
{
_Crc32.SlurpBlock(buffer, start, length);
}
protected override byte[] HashFinal()
{
uint crcValue =(uint) _Crc32.Crc32Result;
HashValue = new[]
{
(byte) ((crcValue >> 24) & 0xff),
(byte) ((crcValue >> 16) & 0xff),
(byte) ((crcValue >> 8) & 0xff),
(byte) (crcValue & 0xff)
};
return HashValue;
}
public override int HashSize
{
get { return 32; }
}
}
}

View File

@@ -69,7 +69,7 @@
using System;
namespace Ionic.Zlib
namespace SabreTools.Helper
{
internal enum BlockState
@@ -725,6 +725,15 @@ namespace Ionic.Zlib
dyn_dtree[Tree.DistanceCode(dist) * 2]++;
}
/* ************************************************************
* *
* this code is not turned on by default in ZLIB Trrntzip code *
* *
* *************************************************************
*/
/*
if (false) //CompSettings
{
if ((last_lit & 0x1fff) == 0 && (int)compressionLevel > 2)
{
// Compute an upper bound for the compressed length
@@ -739,6 +748,8 @@ namespace Ionic.Zlib
if ((matches < (last_lit / 2)) && out_length < in_length / 2)
return true;
}
}
*/
return (last_lit == lit_bufsize - 1) || (last_lit == lit_bufsize);
// dinoch - wraparound?

View File

@@ -27,7 +27,7 @@
using System;
namespace Ionic.Zlib
namespace SabreTools.Helper
{
/// <summary>
/// A class for compressing and decompressing streams using the Deflate algorithm.
@@ -520,9 +520,9 @@ namespace Ionic.Zlib
{
get
{
if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Writer)
if (this._baseStream._streamMode == ZlibBaseStream.StreamMode.Writer)
return this._baseStream._z.TotalBytesOut;
if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Reader)
if (this._baseStream._streamMode == ZlibBaseStream.StreamMode.Reader)
return this._baseStream._z.TotalBytesIn;
return 0;
}

View File

@@ -15,7 +15,7 @@
// ------------------------------------------------------------------
//
// last saved (in emacs):
// Time-stamp: <2011-July-11 21:42:34>
// Time-stamp: <2011-August-08 18:14:39>
//
// ------------------------------------------------------------------
//
@@ -30,7 +30,7 @@
using System;
using System.IO;
namespace Ionic.Zlib
namespace SabreTools.Helper
{
/// <summary>
/// A class for compressing and decompressing GZIP streams.
@@ -728,9 +728,9 @@ namespace Ionic.Zlib
{
get
{
if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Writer)
if (this._baseStream._streamMode == ZlibBaseStream.StreamMode.Writer)
return this._baseStream._z.TotalBytesOut + _headerByteCount;
if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Reader)
if (this._baseStream._streamMode == ZlibBaseStream.StreamMode.Reader)
return this._baseStream._z.TotalBytesIn + this._baseStream._gzipHeaderByteCount;
return 0;
}
@@ -833,7 +833,7 @@ namespace Ionic.Zlib
public override void Write(byte[] buffer, int offset, int count)
{
if (_disposed) throw new ObjectDisposedException("GZipStream");
if (_baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Undefined)
if (_baseStream._streamMode == ZlibBaseStream.StreamMode.Undefined)
{
//Console.WriteLine("GZipStream: First write");
if (_baseStream._wantCompress)
@@ -853,7 +853,11 @@ namespace Ionic.Zlib
internal static readonly System.DateTime _unixEpoch = new System.DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
#if SILVERLIGHT || NETCF
internal static readonly System.Text.Encoding iso8859dash1 = new Ionic.Encoding.Iso8859Dash1Encoding();
#else
internal static readonly System.Text.Encoding iso8859dash1 = System.Text.Encoding.GetEncoding("iso-8859-1");
#endif
private int EmitHeader()

View File

@@ -60,9 +60,9 @@
// -----------------------------------------------------------------------
using System;
namespace Ionic.Zlib
namespace SabreTools.Helper
{
sealed class InfTree

View File

@@ -63,7 +63,8 @@
using System;
namespace Ionic.Zlib
namespace SabreTools.Helper
{
sealed class InflateBlocks
{

View File

@@ -27,11 +27,10 @@
using System;
using System.Collections.Generic;
using System.Threading;
using Ionic.Zlib;
using System.IO;
namespace Ionic.Zlib
namespace SabreTools.Helper
{
internal class WorkItem
{
@@ -45,7 +44,7 @@ namespace Ionic.Zlib
public ZlibCodec compressor;
public WorkItem(int size,
Ionic.Zlib.CompressionLevel compressLevel,
CompressionLevel compressLevel,
CompressionStrategy strategy,
int ix)
{
@@ -121,12 +120,12 @@ namespace Ionic.Zlib
private int _lastWritten;
private int _latestCompressed;
private int _Crc32;
private Ionic.Crc.CRC32 _runningCrc;
private CRC32 _runningCrc;
private object _latestLock = new object();
private System.Collections.Generic.Queue<int> _toWrite;
private System.Collections.Generic.Queue<int> _toFill;
private Int64 _totalBytesProcessed;
private Ionic.Zlib.CompressionLevel _compressLevel;
private CompressionLevel _compressLevel;
private volatile Exception _pendingException;
private bool _handlingException;
private object _eLock = new Object(); // protects _pendingException
@@ -488,7 +487,7 @@ namespace Ionic.Zlib
}
_newlyCompressedBlob = new AutoResetEvent(false);
_runningCrc = new Ionic.Crc.CRC32();
_runningCrc = new CRC32();
_currentlyFilling = -1;
_lastFilled = -1;
_lastWritten = -1;
@@ -856,7 +855,7 @@ namespace Ionic.Zlib
_firstWriteDone = false;
_totalBytesProcessed = 0L;
_runningCrc = new Ionic.Crc.CRC32();
_runningCrc = new CRC32();
_isClosed= false;
_currentlyFilling = -1;
_lastFilled = -1;
@@ -1155,7 +1154,7 @@ namespace Ionic.Zlib
try
{
int myItem = workitem.index;
Ionic.Crc.CRC32 crc = new Ionic.Crc.CRC32();
CRC32 crc = new CRC32();
// calc CRC on the buffer
crc.SlurpBlock(workitem.buffer, 0, workitem.inputBytesAvailable);

View File

@@ -61,9 +61,7 @@
// -----------------------------------------------------------------------
using System;
namespace Ionic.Zlib
namespace SabreTools.Helper
{
sealed class Tree
{

View File

@@ -87,11 +87,9 @@
// -----------------------------------------------------------------------
using System.Runtime.InteropServices;
using System;
using Interop=System.Runtime.InteropServices;
namespace Ionic.Zlib
namespace SabreTools.Helper
{
/// <summary>
@@ -262,7 +260,7 @@ namespace Ionic.Zlib
/// <summary>
/// A general purpose exception class for exceptions in the Zlib library.
/// </summary>
[Interop.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000E")]
[Guid("ebc25cf6-9120-4283-b972-0e5520d0000E")]
public class ZlibException : System.Exception
{
/// <summary>

View File

@@ -27,7 +27,7 @@
using System;
using System.IO;
namespace Ionic.Zlib
namespace SabreTools.Helper
{
internal enum ZlibStreamFlavor { ZLIB = 1950, DEFLATE = 1951, GZIP = 1952 }
@@ -50,7 +50,7 @@ namespace Ionic.Zlib
protected internal CompressionStrategy Strategy = CompressionStrategy.Default;
// workitem 7159
Ionic.Crc.CRC32 crc;
CRC32 crc;
protected internal string _GzipFileName;
protected internal string _GzipComment;
protected internal DateTime _GzipMtime;
@@ -75,7 +75,7 @@ namespace Ionic.Zlib
// workitem 7159
if (flavor == ZlibStreamFlavor.GZIP)
{
this.crc = new Ionic.Crc.CRC32();
this.crc = new CRC32();
}
}

View File

@@ -65,9 +65,9 @@
using System;
using Interop=System.Runtime.InteropServices;
using System.Runtime.InteropServices;
namespace Ionic.Zlib
namespace SabreTools.Helper
{
/// <summary>
/// Encoder and Decoder for ZLIB and DEFLATE (IETF RFC1950 and RFC1951).
@@ -79,10 +79,10 @@ namespace Ionic.Zlib
/// href="http://www.ietf.org/rfc/rfc1950.txt">RFC 1950 - ZLIB</see> and <see
/// href="http://www.ietf.org/rfc/rfc1951.txt">RFC 1951 - DEFLATE</see>.
/// </remarks>
[Interop.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000D")]
[Interop.ComVisible(true)]
[Guid("ebc25cf6-9120-4283-b972-0e5520d0000D")]
[System.Runtime.InteropServices.ComVisible(true)]
#if !NETCF
[Interop.ClassInterface(Interop.ClassInterfaceType.AutoDispatch)]
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.AutoDispatch)]
#endif
sealed public class ZlibCodec
{

View File

@@ -61,9 +61,7 @@
// -----------------------------------------------------------------------
using System;
namespace Ionic.Zlib
namespace SabreTools.Helper
{
/// <summary>
/// A bunch of constants used in the Zlib interface.

View File

@@ -28,7 +28,7 @@
using System;
using System.IO;
namespace Ionic.Zlib
namespace SabreTools.Helper
{
/// <summary>
@@ -500,9 +500,9 @@ namespace Ionic.Zlib
{
get
{
if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Writer)
if (this._baseStream._streamMode == ZlibBaseStream.StreamMode.Writer)
return this._baseStream._z.TotalBytesOut;
if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Reader)
if (this._baseStream._streamMode == ZlibBaseStream.StreamMode.Reader)
return this._baseStream._z.TotalBytesIn;
return 0;
}

View File

@@ -88,7 +88,7 @@ namespace SabreTools.Helper
}
public bool Contains(string n)
{
return _entries.Contains(new ZipFileEntry(new MemoryStream(), n, true));
return _entries.Contains(new ZipFileEntry(new MemoryStream(), n));
}
#endregion

View File

@@ -1,6 +1,4 @@
using OCRC;
using Ionic.Crc;
using Ionic.Zlib;
using System;
using System.Collections.Generic;
using System.IO;
@@ -137,20 +135,16 @@ namespace SabreTools.Helper
/// </summary>
/// <param name="zipstream">Stream representing the entry</param>
/// <param name="filename">Internal filename to use</param>
/// <param name="torrentZip">True if the file should be set with TorrentZip defaults (default), false otherwise</param>
public ZipFileEntry(Stream zipstream, string filename, bool torrentZip = true)
public ZipFileEntry(Stream zipstream, string filename)
{
_zip64 = false;
_zipstream = zipstream;
_generalPurposeBitFlag = GeneralPurposeBitFlag.DeflatingMaximumCompression;
_compressionMethod = CompressionMethod.Deflated;
FileName = filename;
if (torrentZip)
{
_lastModFileTime = 48128;
_lastModFileDate = 8600;
}
FileName = filename;
}
#endregion

View File

@@ -13,6 +13,8 @@ namespace SabreTools.Helper
{
public class ArchiveTools
{
private const int _bufferSize = 4096 * 128;
#region Archive-to-Archive Handling
/// <summary>
@@ -759,7 +761,7 @@ namespace SabreTools.Helper
// If the archive doesn't already contain the entry, add it
if (outarchive.GetEntry(rom.Name) == null)
{
ZipArchiveEntry ae = outarchive.CreateEntry(rom.Name, CompressionLevel.Optimal);
ZipArchiveEntry ae = outarchive.CreateEntry(rom.Name);
Stream outputStream = ae.Open();
inputStreams[i].CopyTo(outputStream);
outputStream.Flush();
@@ -888,9 +890,9 @@ namespace SabreTools.Helper
zipReturn = zipFile.OpenWriteStream(false, true, rom.Name, streamSize, CompressionMethod.Deflated, out writeStream);
// Copy the input stream to the output
byte[] buffer = new byte[8 * 1024];
byte[] buffer = new byte[_bufferSize];
int len;
while ((len = fs.Read(buffer, 0, buffer.Length)) > 0)
while ((len = fs.Read(buffer, 0, _bufferSize)) > 0)
{
writeStream.Write(buffer, 0, len);
}
@@ -956,9 +958,9 @@ namespace SabreTools.Helper
zipFile.OpenWriteStream(false, true, roms[-index - 1].Name, istreamSize, CompressionMethod.Deflated, out writeStream);
// Copy the input stream to the output
byte[] ibuffer = new byte[8 * 1024];
byte[] ibuffer = new byte[_bufferSize];
int ilen;
while ((ilen = freadStream.Read(ibuffer, 0, ibuffer.Length)) > 0)
while ((ilen = freadStream.Read(ibuffer, 0, _bufferSize)) > 0)
{
writeStream.Write(ibuffer, 0, ilen);
}
@@ -977,9 +979,9 @@ namespace SabreTools.Helper
zipFile.OpenWriteStream(false, true, oldZipFile.Filename(index), istreamSize, CompressionMethod.Deflated, out writeStream);
// Copy the input stream to the output
byte[] ibuffer = new byte[8 * 1024];
byte[] ibuffer = new byte[_bufferSize];
int ilen;
while ((ilen = zreadStream.Read(ibuffer, 0, ibuffer.Length)) > 0)
while ((ilen = zreadStream.Read(ibuffer, 0, _bufferSize)) > 0)
{
writeStream.Write(ibuffer, 0, ilen);
}