diff --git a/SabreTools.Core/Tools/Utilities.cs b/SabreTools.Core/Tools/Utilities.cs index 9b3d3f52..a6b4b3b9 100644 --- a/SabreTools.Core/Tools/Utilities.cs +++ b/SabreTools.Core/Tools/Utilities.cs @@ -107,7 +107,7 @@ namespace SabreTools.Core.Tools /// /// Adapted from 7-zip Source Code: CPP/Windows/TimeUtils.cpp:FileTimeToDosTime /// - public static uint ConvertDateTimeToMsDosTimeFormat(DateTime dateTime) + public static long ConvertDateTimeToMsDosTimeFormat(DateTime dateTime) { uint year = (uint)((dateTime.Year - 1980) % 128); uint mon = (uint)dateTime.Month; diff --git a/SabreTools.FileTypes/Archives/SevenZipArchive.cs b/SabreTools.FileTypes/Archives/SevenZipArchive.cs index 9ebcbc37..2a4cec50 100644 --- a/SabreTools.FileTypes/Archives/SevenZipArchive.cs +++ b/SabreTools.FileTypes/Archives/SevenZipArchive.cs @@ -7,6 +7,7 @@ using SabreTools.Core; using SabreTools.Core.Tools; using Compress; using Compress.SevenZip; +using Compress.Utils; using Compress.ZipFile; using NaturalSort; @@ -74,7 +75,7 @@ namespace SabreTools.FileTypes.Archives ZipReturn zr = zf.ZipFileOpen(this.Filename, -1, true); if (zr != ZipReturn.ZipGood) { - throw new Exception(ZipFile.ZipErrorMessageText(zr)); + throw new Exception(ZipUtils.ZipErrorMessageText(zr)); } for (int i = 0; i < zf.LocalFilesCount() && zr == ZipReturn.ZipGood; i++) @@ -197,7 +198,7 @@ namespace SabreTools.FileTypes.Archives ZipReturn zr = zf.ZipFileOpen(this.Filename, -1, true); if (zr != ZipReturn.ZipGood) { - throw new Exception(ZipFile.ZipErrorMessageText(zr)); + throw new Exception(ZipUtils.ZipErrorMessageText(zr)); } for (int i = 0; i < zf.LocalFilesCount() && zr == ZipReturn.ZipGood; i++) @@ -266,7 +267,7 @@ namespace SabreTools.FileTypes.Archives ZipReturn zr = zf.ZipFileOpen(this.Filename, -1, true); if (zr != ZipReturn.ZipGood) { - throw new Exception(ZipFile.ZipErrorMessageText(zr)); + throw new Exception(ZipUtils.ZipErrorMessageText(zr)); } for (int i = 0; i < zf.LocalFilesCount(); i++) @@ -336,7 +337,7 @@ namespace SabreTools.FileTypes.Archives ZipReturn zr = zf.ZipFileOpen(this.Filename, -1, true); if (zr != ZipReturn.ZipGood) { - throw new Exception(ZipFile.ZipErrorMessageText(zr)); + throw new Exception(ZipUtils.ZipErrorMessageText(zr)); } List<(string, bool)> zipEntries = new List<(string, bool)>(); @@ -380,7 +381,7 @@ namespace SabreTools.FileTypes.Archives ZipReturn zr = zf.ZipFileOpen(this.Filename, -1, true); if (zr != ZipReturn.ZipGood) { - throw new Exception(ZipFile.ZipErrorMessageText(zr)); + throw new Exception(ZipUtils.ZipErrorMessageText(zr)); } return zf.ZipStatus == ZipStatus.Trrnt7Zip; @@ -441,12 +442,13 @@ namespace SabreTools.FileTypes.Archives DateTime dt = DateTime.Now; if (UseDates && !string.IsNullOrWhiteSpace(baseFile.Date) && DateTime.TryParse(baseFile.Date.Replace('\\', '/'), out dt)) { - uint msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(dt); - zipFile.ZipFileOpenWriteStream(false, false, baseFile.Filename.Replace('\\', '/'), istreamSize, 0, msDosDateTime, out writeStream); + long msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(dt); + TimeStamps ts = new TimeStamps { ModTime = msDosDateTime }; + zipFile.ZipFileOpenWriteStream(false, false, baseFile.Filename.Replace('\\', '/'), istreamSize, 0, out writeStream, ts); } else { - zipFile.ZipFileOpenWriteStream(false, true, baseFile.Filename.Replace('\\', '/'), istreamSize, 0, null, out writeStream); + zipFile.ZipFileOpenWriteStream(false, true, baseFile.Filename.Replace('\\', '/'), istreamSize, 0, out writeStream, null); } // Copy the input stream to the output @@ -499,7 +501,7 @@ namespace SabreTools.FileTypes.Archives // Get the order for the entries with the new file List keys = inputIndexMap.Keys.ToList(); - keys.Sort(ZipFile.TrrntZipStringCompare); + keys.Sort(ZipUtils.TrrntZipStringCompare); // Copy over all files to the new archive foreach (string key in keys) @@ -516,12 +518,13 @@ namespace SabreTools.FileTypes.Archives DateTime dt = DateTime.Now; if (UseDates && !string.IsNullOrWhiteSpace(baseFile.Date) && DateTime.TryParse(baseFile.Date.Replace('\\', '/'), out dt)) { - uint msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(dt); - zipFile.ZipFileOpenWriteStream(false, false, baseFile.Filename.Replace('\\', '/'), istreamSize, 0, msDosDateTime, out writeStream); + long msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(dt); + TimeStamps ts = new TimeStamps { ModTime = msDosDateTime }; + zipFile.ZipFileOpenWriteStream(false, false, baseFile.Filename.Replace('\\', '/'), istreamSize, 0, out writeStream, ts); } else { - zipFile.ZipFileOpenWriteStream(false, true, baseFile.Filename.Replace('\\', '/'), istreamSize, 0, null, out writeStream); + zipFile.ZipFileOpenWriteStream(false, true, baseFile.Filename.Replace('\\', '/'), istreamSize, 0, out writeStream, null); } // Copy the input stream to the output @@ -541,7 +544,7 @@ namespace SabreTools.FileTypes.Archives { // Instantiate the streams oldZipFile.ZipFileOpenReadStream(index, out Stream zreadStream, out ulong istreamSize); - zipFile.ZipFileOpenWriteStream(false, true, oldZipFile.Filename(index), istreamSize, 0, null, out writeStream); + zipFile.ZipFileOpenWriteStream(false, true, oldZipFile.Filename(index), istreamSize, 0, out writeStream, null); // Copy the input stream to the output byte[] ibuffer = new byte[_bufferSize]; @@ -640,7 +643,7 @@ namespace SabreTools.FileTypes.Archives // Sort the keys in TZIP order List keys = inputIndexMap.Keys.ToList(); - keys.Sort(ZipFile.TrrntZipStringCompare); + keys.Sort(ZipUtils.TrrntZipStringCompare); // Now add all of the files in order foreach (string key in keys) @@ -655,12 +658,13 @@ namespace SabreTools.FileTypes.Archives DateTime dt = DateTime.Now; if (UseDates && !string.IsNullOrWhiteSpace(baseFiles[index].Date) && DateTime.TryParse(baseFiles[index].Date.Replace('\\', '/'), out dt)) { - uint msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(dt); - zipFile.ZipFileOpenWriteStream(false, false, baseFiles[index].Filename.Replace('\\', '/'), istreamSize, 0, msDosDateTime, out writeStream); + long msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(dt); + TimeStamps ts = new TimeStamps { ModTime = msDosDateTime }; + zipFile.ZipFileOpenWriteStream(false, false, baseFiles[index].Filename.Replace('\\', '/'), istreamSize, 0, out writeStream, ts); } else { - zipFile.ZipFileOpenWriteStream(false, true, baseFiles[index].Filename.Replace('\\', '/'), istreamSize, 0, null, out writeStream); + zipFile.ZipFileOpenWriteStream(false, true, baseFiles[index].Filename.Replace('\\', '/'), istreamSize, 0, out writeStream, null); } // Copy the input stream to the output @@ -720,7 +724,7 @@ namespace SabreTools.FileTypes.Archives // Get the order for the entries with the new file List keys = inputIndexMap.Keys.ToList(); - keys.Sort(ZipFile.TrrntZipStringCompare); + keys.Sort(ZipUtils.TrrntZipStringCompare); // Copy over all files to the new archive foreach (string key in keys) @@ -738,12 +742,13 @@ namespace SabreTools.FileTypes.Archives DateTime dt = DateTime.Now; if (UseDates && !string.IsNullOrWhiteSpace(baseFiles[-index - 1].Date) && DateTime.TryParse(baseFiles[-index - 1].Date.Replace('\\', '/'), out dt)) { - uint msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(dt); - zipFile.ZipFileOpenWriteStream(false, false, baseFiles[-index - 1].Filename.Replace('\\', '/'), istreamSize, 0, msDosDateTime, out writeStream); + long msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(dt); + TimeStamps ts = new TimeStamps { ModTime = msDosDateTime }; + zipFile.ZipFileOpenWriteStream(false, false, baseFiles[-index - 1].Filename.Replace('\\', '/'), istreamSize, 0, out writeStream, ts); } else { - zipFile.ZipFileOpenWriteStream(false, true, baseFiles[-index - 1].Filename.Replace('\\', '/'), istreamSize, 0, null, out writeStream); + zipFile.ZipFileOpenWriteStream(false, true, baseFiles[-index - 1].Filename.Replace('\\', '/'), istreamSize, 0, out writeStream, null); } // Copy the input stream to the output @@ -763,7 +768,7 @@ namespace SabreTools.FileTypes.Archives { // Instantiate the streams oldZipFile.ZipFileOpenReadStream(index, out Stream zreadStream, out ulong istreamSize); - zipFile.ZipFileOpenWriteStream(false, true, oldZipFile.Filename(index), istreamSize, 0, null, out writeStream); + zipFile.ZipFileOpenWriteStream(false, true, oldZipFile.Filename(index), istreamSize, 0, out writeStream, null); // Copy the input stream to the output byte[] ibuffer = new byte[_bufferSize]; diff --git a/SabreTools.FileTypes/Archives/TapeArchive.cs b/SabreTools.FileTypes/Archives/TapeArchive.cs index f7e78e22..41605973 100644 --- a/SabreTools.FileTypes/Archives/TapeArchive.cs +++ b/SabreTools.FileTypes/Archives/TapeArchive.cs @@ -330,7 +330,7 @@ namespace SabreTools.FileTypes.Archives // Get the order for the entries with the new file List keys = inputIndexMap.Keys.ToList(); - keys.Sort(ZipFile.TrrntZipStringCompare); + keys.Sort(ZipUtils.TrrntZipStringCompare); // Copy over all files to the new archive foreach (string key in keys) @@ -444,7 +444,7 @@ namespace SabreTools.FileTypes.Archives // Sort the keys in TZIP order List keys = inputIndexMap.Keys.ToList(); - keys.Sort(ZipFile.TrrntZipStringCompare); + keys.Sort(ZipUtils.TrrntZipStringCompare); // Now add all of the files in order foreach (string key in keys) @@ -499,7 +499,7 @@ namespace SabreTools.FileTypes.Archives // Get the order for the entries with the new file List keys = inputIndexMap.Keys.ToList(); - keys.Sort(ZipFile.TrrntZipStringCompare); + keys.Sort(ZipUtils.TrrntZipStringCompare); // Copy over all files to the new archive foreach (string key in keys) diff --git a/SabreTools.FileTypes/Archives/ZipArchive.cs b/SabreTools.FileTypes/Archives/ZipArchive.cs index 7accea69..5ca0cd93 100644 --- a/SabreTools.FileTypes/Archives/ZipArchive.cs +++ b/SabreTools.FileTypes/Archives/ZipArchive.cs @@ -6,6 +6,7 @@ using System.Linq; using SabreTools.Core; using SabreTools.Core.Tools; using Compress; +using Compress.Utils; using Compress.ZipFile; using NaturalSort; @@ -79,11 +80,11 @@ namespace SabreTools.FileTypes.Archives Directory.CreateDirectory(outDir); // Extract all files to the temp directory - ZipFile zf = new ZipFile(); + Zip zf = new Zip(); ZipReturn zr = zf.ZipFileOpen(this.Filename, -1, true); if (zr != ZipReturn.ZipGood) { - throw new Exception(ZipFile.ZipErrorMessageText(zr)); + throw new Exception(ZipUtils.ZipErrorMessageText(zr)); } for (int i = 0; i < zf.LocalFilesCount() && zr == ZipReturn.ZipGood; i++) @@ -204,11 +205,11 @@ namespace SabreTools.FileTypes.Archives try { - ZipFile zf = new ZipFile(); + Zip zf = new Zip(); ZipReturn zr = zf.ZipFileOpen(this.Filename, -1, true); if (zr != ZipReturn.ZipGood) { - throw new Exception(ZipFile.ZipErrorMessageText(zr)); + throw new Exception(ZipUtils.ZipErrorMessageText(zr)); } for (int i = 0; i < zf.LocalFilesCount() && zr == ZipReturn.ZipGood; i++) @@ -273,11 +274,11 @@ namespace SabreTools.FileTypes.Archives try { - ZipFile zf = new ZipFile(); + Zip zf = new Zip(); ZipReturn zr = zf.ZipFileOpen(this.Filename, -1, true); if (zr != ZipReturn.ZipGood) { - throw new Exception(ZipFile.ZipErrorMessageText(zr)); + throw new Exception(ZipUtils.ZipErrorMessageText(zr)); } for (int i = 0; i < zf.LocalFilesCount(); i++) @@ -344,11 +345,11 @@ namespace SabreTools.FileTypes.Archives try { - ZipFile zf = new ZipFile(); + Zip zf = new Zip(); ZipReturn zr = zf.ZipFileOpen(this.Filename, -1, true); if (zr != ZipReturn.ZipGood) { - throw new Exception(ZipFile.ZipErrorMessageText(zr)); + throw new Exception(ZipUtils.ZipErrorMessageText(zr)); } List<(string, bool)> zipEntries = new List<(string, bool)>(); @@ -388,11 +389,11 @@ namespace SabreTools.FileTypes.Archives /// public override bool IsTorrent() { - ZipFile zf = new ZipFile(); + Zip zf = new Zip(); ZipReturn zr = zf.ZipFileOpen(this.Filename, -1, true); if (zr != ZipReturn.ZipGood) { - throw new Exception(ZipFile.ZipErrorMessageText(zr)); + throw new Exception(ZipUtils.ZipErrorMessageText(zr)); } return zf.ZipStatus == ZipStatus.TrrntZip; @@ -431,8 +432,8 @@ namespace SabreTools.FileTypes.Archives // Set internal variables Stream writeStream = null; - ZipFile oldZipFile = new ZipFile(); - ZipFile zipFile = new ZipFile(); + Zip oldZipFile = new Zip(); + Zip zipFile = new Zip(); ZipReturn zipReturn = ZipReturn.ZipGood; try @@ -453,12 +454,13 @@ namespace SabreTools.FileTypes.Archives DateTime dt = DateTime.Now; if (UseDates && !string.IsNullOrWhiteSpace(baseFile.Date) && DateTime.TryParse(baseFile.Date.Replace('\\', '/'), out dt)) { - uint msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(dt); - zipFile.ZipFileOpenWriteStream(false, false, baseFile.Filename.Replace('\\', '/'), istreamSize, (ushort)CompressionMethod.Deflated, msDosDateTime, out writeStream); + long msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(dt); + TimeStamps ts = new TimeStamps { ModTime = msDosDateTime }; + zipFile.ZipFileOpenWriteStream(false, false, baseFile.Filename.Replace('\\', '/'), istreamSize, (ushort)CompressionMethod.Deflated, out writeStream, ts); } else { - zipFile.ZipFileOpenWriteStream(false, true, baseFile.Filename.Replace('\\', '/'), istreamSize, (ushort)CompressionMethod.Deflated, null, out writeStream); + zipFile.ZipFileOpenWriteStream(false, true, baseFile.Filename.Replace('\\', '/'), istreamSize, (ushort)CompressionMethod.Deflated, out writeStream, null); } // Copy the input stream to the output @@ -509,7 +511,7 @@ namespace SabreTools.FileTypes.Archives // Get the order for the entries with the new file List keys = inputIndexMap.Keys.ToList(); - keys.Sort(ZipFile.TrrntZipStringCompare); + keys.Sort(ZipUtils.TrrntZipStringCompare); // Copy over all files to the new archive foreach (string key in keys) @@ -526,12 +528,13 @@ namespace SabreTools.FileTypes.Archives DateTime dt = DateTime.Now; if (UseDates && !string.IsNullOrWhiteSpace(baseFile.Date) && DateTime.TryParse(baseFile.Date.Replace('\\', '/'), out dt)) { - uint msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(dt); - zipFile.ZipFileOpenWriteStream(false, false, baseFile.Filename.Replace('\\', '/'), istreamSize, (ushort)CompressionMethod.Deflated, msDosDateTime, out writeStream); + long msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(dt); + TimeStamps ts = new TimeStamps { ModTime = msDosDateTime }; + zipFile.ZipFileOpenWriteStream(false, false, baseFile.Filename.Replace('\\', '/'), istreamSize, (ushort)CompressionMethod.Deflated, out writeStream, ts); } else { - zipFile.ZipFileOpenWriteStream(false, true, baseFile.Filename.Replace('\\', '/'), istreamSize, (ushort)CompressionMethod.Deflated, null, out writeStream); + zipFile.ZipFileOpenWriteStream(false, true, baseFile.Filename.Replace('\\', '/'), istreamSize, (ushort)CompressionMethod.Deflated, out writeStream, null); } // Copy the input stream to the output @@ -551,8 +554,9 @@ namespace SabreTools.FileTypes.Archives { // Instantiate the streams oldZipFile.ZipFileOpenReadStream(index, false, out Stream zreadStream, out ulong istreamSize, out ushort icompressionMethod); - uint msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(oldZipFile.LastModified(index)); - zipFile.ZipFileOpenWriteStream(false, true, oldZipFile.Filename(index), istreamSize, (ushort)CompressionMethod.Deflated, msDosDateTime, out writeStream); + long msDosDateTime = oldZipFile.LastModified(index); + TimeStamps ts = new TimeStamps { ModTime = msDosDateTime }; + zipFile.ZipFileOpenWriteStream(false, true, oldZipFile.Filename(index), istreamSize, (ushort)CompressionMethod.Deflated, out writeStream, ts); // Copy the input stream to the output byte[] ibuffer = new byte[_bufferSize]; @@ -625,8 +629,8 @@ namespace SabreTools.FileTypes.Archives // Set internal variables Stream writeStream = null; - ZipFile oldZipFile = new ZipFile(); - ZipFile zipFile = new ZipFile(); + Zip oldZipFile = new Zip(); + Zip zipFile = new Zip(); ZipReturn zipReturn = ZipReturn.ZipGood; try @@ -651,7 +655,7 @@ namespace SabreTools.FileTypes.Archives // Sort the keys in TZIP order List keys = inputIndexMap.Keys.ToList(); - keys.Sort(ZipFile.TrrntZipStringCompare); + keys.Sort(ZipUtils.TrrntZipStringCompare); // Now add all of the files in order foreach (string key in keys) @@ -666,12 +670,13 @@ namespace SabreTools.FileTypes.Archives DateTime dt = DateTime.Now; if (UseDates && !string.IsNullOrWhiteSpace(baseFiles[index].Date) && DateTime.TryParse(baseFiles[index].Date.Replace('\\', '/'), out dt)) { - uint msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(dt); - zipFile.ZipFileOpenWriteStream(false, false, baseFiles[index].Filename.Replace('\\', '/'), istreamSize, (ushort)CompressionMethod.Deflated, msDosDateTime, out writeStream); + long msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(dt); + TimeStamps ts = new TimeStamps { ModTime = msDosDateTime }; + zipFile.ZipFileOpenWriteStream(false, false, baseFiles[index].Filename.Replace('\\', '/'), istreamSize, (ushort)CompressionMethod.Deflated, out writeStream, ts); } else { - zipFile.ZipFileOpenWriteStream(false, true, baseFiles[index].Filename.Replace('\\', '/'), istreamSize, (ushort)CompressionMethod.Deflated, null, out writeStream); + zipFile.ZipFileOpenWriteStream(false, true, baseFiles[index].Filename.Replace('\\', '/'), istreamSize, (ushort)CompressionMethod.Deflated, out writeStream, null); } // Copy the input stream to the output @@ -731,7 +736,7 @@ namespace SabreTools.FileTypes.Archives // Get the order for the entries with the new file List keys = inputIndexMap.Keys.ToList(); - keys.Sort(ZipFile.TrrntZipStringCompare); + keys.Sort(ZipUtils.TrrntZipStringCompare); // Copy over all files to the new archive foreach (string key in keys) @@ -749,12 +754,13 @@ namespace SabreTools.FileTypes.Archives DateTime dt = DateTime.Now; if (UseDates && !string.IsNullOrWhiteSpace(baseFiles[-index - 1].Date) && DateTime.TryParse(baseFiles[-index - 1].Date.Replace('\\', '/'), out dt)) { - uint msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(dt); - zipFile.ZipFileOpenWriteStream(false, false, baseFiles[-index - 1].Filename.Replace('\\', '/'), istreamSize, (ushort)CompressionMethod.Deflated, msDosDateTime, out writeStream); + long msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(dt); + TimeStamps ts = new TimeStamps { ModTime = msDosDateTime }; + zipFile.ZipFileOpenWriteStream(false, false, baseFiles[-index - 1].Filename.Replace('\\', '/'), istreamSize, (ushort)CompressionMethod.Deflated, out writeStream, ts); } else { - zipFile.ZipFileOpenWriteStream(false, true, baseFiles[-index - 1].Filename.Replace('\\', '/'), istreamSize, (ushort)CompressionMethod.Deflated, null, out writeStream); + zipFile.ZipFileOpenWriteStream(false, true, baseFiles[-index - 1].Filename.Replace('\\', '/'), istreamSize, (ushort)CompressionMethod.Deflated, out writeStream, null); } // Copy the input stream to the output @@ -774,8 +780,9 @@ namespace SabreTools.FileTypes.Archives { // Instantiate the streams oldZipFile.ZipFileOpenReadStream(index, false, out Stream zreadStream, out ulong istreamSize, out ushort icompressionMethod); - uint msDosDateTime = Utilities.ConvertDateTimeToMsDosTimeFormat(oldZipFile.LastModified(index)); - zipFile.ZipFileOpenWriteStream(false, true, oldZipFile.Filename(index), istreamSize, (ushort)CompressionMethod.Deflated, msDosDateTime, out writeStream); + long msDosDateTime = oldZipFile.LastModified(index); + TimeStamps ts = new TimeStamps { ModTime = msDosDateTime }; + zipFile.ZipFileOpenWriteStream(false, true, oldZipFile.Filename(index), istreamSize, (ushort)CompressionMethod.Deflated, out writeStream, ts); // Copy the input stream to the output byte[] ibuffer = new byte[_bufferSize]; diff --git a/SabreTools.FileTypes/Compress/File/File.cs b/SabreTools.FileTypes/Compress/File/File.cs index 3456bcbf..18eecac1 100644 --- a/SabreTools.FileTypes/Compress/File/File.cs +++ b/SabreTools.FileTypes/Compress/File/File.cs @@ -13,7 +13,7 @@ namespace Compress.File private Stream _inStream; private byte[] _crc; - public string ZipFilename => _fileInfo?.FullName ?? string.Empty; + public string ZipFilename => _fileInfo?.FullName ?? ""; public long TimeStamp => _fileInfo?.LastWriteTime ?? 0; @@ -39,7 +39,7 @@ namespace Compress.File public ulong UncompressedSize(int i) { - return _fileInfo != null ? (ulong)_fileInfo.Length : 0; + return _fileInfo != null ? (ulong)_fileInfo.Length : (ulong)_inStream.Length; } public ulong? LocalHeader(int i) @@ -57,6 +57,11 @@ namespace Compress.File return _crc; } + public long LastModified(int i) + { + return _fileInfo.LastWriteTime; + } + public ZipReturn ZipFileCreate(string newFilename) { if (ZipOpen != ZipOpenType.Closed) @@ -87,20 +92,27 @@ namespace Compress.File if (ZipOpen == ZipOpenType.OpenRead) { - if (_inStream != null) + // if FileInfo is valid (not null), then we created the stream and need to close it. + // if we open from a stream, then FileInfo will be null, and we do not need to close the stream. + if (_fileInfo != null && _inStream != null) { _inStream.Close(); _inStream.Dispose(); + _inStream = null; } ZipOpen = ZipOpenType.Closed; return; } - _inStream.Flush(); - _inStream.Close(); - _inStream.Dispose(); - _fileInfo = new FileInfo(_fileInfo.FullName); - ZipOpen = ZipOpenType.Closed; + if (ZipOpen == ZipOpenType.OpenWrite) + { + _inStream.Flush(); + _inStream.Close(); + _inStream.Dispose(); + _inStream = null; + _fileInfo = new FileInfo(_fileInfo.FullName); + ZipOpen = ZipOpenType.Closed; + } } @@ -151,7 +163,6 @@ namespace Compress.File return ZipReturn.ZipGood; } - //return ZipFileReadHeaders(); return ZipReturn.ZipGood; } @@ -191,11 +202,11 @@ namespace Compress.File { _inStream.Position = 0; stream = _inStream; - streamSize = (ulong)_fileInfo.Length; + streamSize = (ulong)_inStream.Length; return ZipReturn.ZipGood; } - public ZipReturn ZipFileOpenWriteStream(bool raw, bool trrntzip, string filename, ulong uncompressedSize, ushort compressionMethod, uint? datetime, out Stream stream) + public ZipReturn ZipFileOpenWriteStream(bool raw, bool trrntzip, string filename, ulong uncompressedSize, ushort compressionMethod, out Stream stream, TimeStamps dateTime) { _inStream.Position = 0; stream = _inStream; @@ -206,9 +217,5 @@ namespace Compress.File { return ZipReturn.ZipGood; } - - - - } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/ICompress.cs b/SabreTools.FileTypes/Compress/ICompress.cs index 4c6d0687..8b81fe2a 100644 --- a/SabreTools.FileTypes/Compress/ICompress.cs +++ b/SabreTools.FileTypes/Compress/ICompress.cs @@ -1,4 +1,6 @@ -using System.IO; +using System; +using System.IO; +using Compress.Utils; namespace Compress { @@ -11,6 +13,8 @@ namespace Compress ulong UncompressedSize(int i); byte[] CRC32(int i); + long LastModified(int i); + bool IsDirectory(int i); ZipOpenType ZipOpen { get; } @@ -21,7 +25,7 @@ namespace Compress void ZipFileClose(); ZipReturn ZipFileOpenReadStream(int index, out Stream stream, out ulong streamSize); - ZipReturn ZipFileOpenWriteStream(bool raw, bool trrntzip, string filename, ulong uncompressedSize, ushort compressionMethod, uint? datetime, out Stream stream); + ZipReturn ZipFileOpenWriteStream(bool raw, bool trrntzip, string filename, ulong uncompressedSize, ushort compressionMethod, out Stream stream, TimeStamps dateTime = null); ZipReturn ZipFileCloseReadStream(); @@ -37,4 +41,4 @@ namespace Compress void ZipFileCloseFailed(); } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Common/ICoder.cs b/SabreTools.FileTypes/Compress/SevenZip/Common/ICoder.cs index 022fbc62..2677e52f 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Common/ICoder.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Common/ICoder.cs @@ -60,8 +60,8 @@ namespace Compress.SevenZip.Common public interface ICoder2 { void Code(ISequentialInStream []inStreams, - const UInt64 []inSizes, - ISequentialOutStream []outStreams, + const UInt64 []inSizes, + ISequentialOutStream []outStreams, UInt64 []outSizes, ICodeProgress progress); }; @@ -149,4 +149,4 @@ namespace Compress.SevenZip.Common { void SetDecoderProperties(byte[] properties); } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/BZip2/BZip2Constants.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/BZip2/BZip2Constants.cs index b44c2d31..c945d571 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/BZip2/BZip2Constants.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/BZip2/BZip2Constants.cs @@ -97,4 +97,4 @@ namespace Compress.SevenZip.Compress.BZip2 936, 638 }; } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/BZip2/CBZip2InputStream.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/BZip2/CBZip2InputStream.cs index 110f0b47..da697686 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/BZip2/CBZip2InputStream.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/BZip2/CBZip2InputStream.cs @@ -1130,4 +1130,4 @@ namespace Compress.SevenZip.Compress.BZip2 } } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/BZip2/CBZip2OutputStream.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/BZip2/CBZip2OutputStream.cs index 71a833b5..24b763d7 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/BZip2/CBZip2OutputStream.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/BZip2/CBZip2OutputStream.cs @@ -1982,4 +1982,4 @@ namespace Compress.SevenZip.Compress.BZip2 } } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/BZip2/CRC.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/BZip2/CRC.cs index e99aa57a..e6457051 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/BZip2/CRC.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/BZip2/CRC.cs @@ -135,4 +135,4 @@ namespace Compress.SevenZip.Compress.BZip2 internal int globalCrc; } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/LZ/LzBinTree.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/LZ/LzBinTree.cs index 5d4f579e..4ce018eb 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/LZ/LzBinTree.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/LZ/LzBinTree.cs @@ -363,4 +363,4 @@ namespace Compress.SevenZip.Compress.LZ public void SetCutValue(UInt32 cutValue) { _cutValue = cutValue; } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/LZ/LzInWindow.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/LZ/LzInWindow.cs index 322e27d3..2fd6642a 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/LZ/LzInWindow.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/LZ/LzInWindow.cs @@ -145,4 +145,4 @@ namespace Compress.SevenZip.Compress.LZ } } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/LZ/LzOutWindow.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/LZ/LzOutWindow.cs index 03cd34c8..f5b4a9f8 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/LZ/LzOutWindow.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/LZ/LzOutWindow.cs @@ -183,4 +183,4 @@ namespace Compress.SevenZip.Compress.LZ } } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/LZMA/LzmaBase.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/LZMA/LzmaBase.cs index 15d3af58..a24fd1f5 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/LZMA/LzmaBase.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/LZMA/LzmaBase.cs @@ -71,4 +71,4 @@ namespace Compress.SevenZip.Compress.LZMA (1 << kNumHighLenBits); public const uint kMatchMaxLen = kMatchMinLen + kNumLenSymbols - 1; } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/LZMA/LzmaDecoder.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/LZMA/LzmaDecoder.cs index 9e704ac4..42705b2a 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/LZMA/LzmaDecoder.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/LZMA/LzmaDecoder.cs @@ -387,7 +387,7 @@ namespace Compress.SevenZip.Compress.LZMA set { } } public override void Flush() { } - public override int Read(byte[] buffer, int offset, int count) + public override int Read(byte[] buffer, int offset, int count) { return 0; } @@ -401,4 +401,4 @@ namespace Compress.SevenZip.Compress.LZMA public override void SetLength(long value) {} */ } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/LZMA/LzmaEncoder.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/LZMA/LzmaEncoder.cs index dc7c98ed..61340432 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/LZMA/LzmaEncoder.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/LZMA/LzmaEncoder.cs @@ -876,7 +876,7 @@ namespace Compress.SevenZip.Compress.LZMA } } - UInt32 startLen = 2; // speed optimization + UInt32 startLen = 2; // speed optimization for (UInt32 repIndex = 0; repIndex < Base.kNumRepDistances; repIndex++) { @@ -1418,7 +1418,7 @@ namespace Compress.SevenZip.Compress.LZMA } - static string[] kMatchFinderIDs = + static string[] kMatchFinderIDs = { "BT2", "BT4", @@ -1544,4 +1544,4 @@ namespace Compress.SevenZip.Compress.LZMA } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/LZMA/LzmaEncoderProperties.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/LZMA/LzmaEncoderProperties.cs index 9a51f9f0..db866ebf 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/LZMA/LzmaEncoderProperties.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/LZMA/LzmaEncoderProperties.cs @@ -54,4 +54,4 @@ namespace Compress.SevenZip.Compress.LZMA }; } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/LZMA/LzmaStream.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/LZMA/LzmaStream.cs index a6be2672..564e162a 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/LZMA/LzmaStream.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/LZMA/LzmaStream.cs @@ -181,11 +181,11 @@ namespace Compress.SevenZip.Compress.LZMA toProcess = (int)availableBytes; outWindow.SetLimit(toProcess); - if (uncompressedChunk) + if(uncompressedChunk) { inputPosition += outWindow.CopyStream(inputStream, toProcess); } - else if (decoder.Code(dictionarySize, outWindow, rangeDecoder) + else if(decoder.Code(dictionarySize, outWindow, rangeDecoder) && outputSize < 0) { availableBytes = outWindow.AvailableBytes; @@ -281,10 +281,10 @@ namespace Compress.SevenZip.Compress.LZMA public override long Seek(long offset, SeekOrigin origin) { - if (origin != SeekOrigin.Current) - throw new NotImplementedException(); + if (origin!=SeekOrigin.Current) + throw new NotImplementedException(); - byte[] tmpBuff = new byte[1024]; + byte[] tmpBuff=new byte[1024]; long sizeToGo = offset; while (sizeToGo > 0) { @@ -292,7 +292,7 @@ namespace Compress.SevenZip.Compress.LZMA Read(tmpBuff, 0, sizenow); sizeToGo -= sizenow; } - + return offset; } @@ -315,4 +315,4 @@ namespace Compress.SevenZip.Compress.LZMA } } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/H/ModelPPM.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/H/ModelPPM.cs index 424709f1..081a70d5 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/H/ModelPPM.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/H/ModelPPM.cs @@ -883,7 +883,7 @@ namespace Compress.SevenZip.Compress.PPmd.H charMask[rs.Symbol] = 0; prevSuccess = 0; } - for (; ; ) + for (;;) { State s = tempState1.Initialize(Heap); int i; @@ -920,7 +920,7 @@ namespace Compress.SevenZip.Compress.PPmd.H { byte symbol; State ps = tempState2.Initialize(Heap); - for (hiCnt = 0, i = 0, ps.Address = minContext.ps[i]; (hiCnt += ps.Freq) <= count; i++, ps.Address = minContext.ps[i]) ; + for (hiCnt = 0, i = 0, ps.Address = minContext.ps[i]; (hiCnt += ps.Freq) <= count; i++, ps.Address = minContext.ps[i]); s.Address = ps.Address; decoder.Decode((uint)(hiCnt - s.Freq), (uint)s.Freq); see.update(); diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/H/PPMContext.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/H/PPMContext.cs index 21cb6af1..10cc6be4 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/H/PPMContext.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/H/PPMContext.cs @@ -305,7 +305,7 @@ namespace Compress.SevenZip.Compress.PPmd.H // byte[] bytes = model.getSubAlloc().getHeap(); // int p1 = state1.Address; // int p2 = state2.Address; - // + // // for (int i = 0; i < StatePtr.size; i++) { // byte temp = bytes[p1+i]; // bytes[p1+i] = bytes[p2+i]; diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/H/RangeCoder.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/H/RangeCoder.cs index a40813a6..da085256 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/H/RangeCoder.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/H/RangeCoder.cs @@ -73,7 +73,7 @@ namespace Compress.SevenZip.Compress.PPmd.H internal void AriDecNormalize() { - // while ((low ^ (low + range)) < TOP || range < BOT && ((range = -low & (BOT - 1)) != 0 ? true : true)) + // while ((low ^ (low + range)) < TOP || range < BOT && ((range = -low & (BOT - 1)) != 0 ? true : true)) // { // code = ((code << 8) | unpackRead.getChar()&0xff)&uintMask; // range = (range << 8)&uintMask; diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/H/SubAllocator.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/H/SubAllocator.cs index e5a3af55..957b8205 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/H/SubAllocator.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/H/SubAllocator.cs @@ -206,7 +206,7 @@ namespace Compress.SevenZip.Compress.PPmd.H // Bug fixed freeListPos = heapStart + allocSize; //UPGRADE_ISSUE: The following fragment of code could not be parsed and was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1156'" - //assert(realAllocSize - tempMemBlockPos == RarMemBlock.size): realAllocSize + //assert(realAllocSize - tempMemBlockPos == RarMemBlock.size): realAllocSize //+ + tempMemBlockPos + + RarMemBlock.size; // Init freeList diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/Allocator.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/Allocator.cs index 5a9b9d71..e85afa88 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/Allocator.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/Allocator.cs @@ -454,4 +454,4 @@ namespace Compress.SevenZip.Compress.PPmd.I1 #endregion } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/Coder.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/Coder.cs index 3f9db375..c243ae60 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/Coder.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/Coder.cs @@ -33,9 +33,9 @@ namespace Compress.SevenZip.Compress.PPmd.I1 public void RangeEncoderNormalize(Stream stream) { - while ((low ^ (low + range)) < RangeTop || range < RangeBottom && ((range = (uint)-low & (RangeBottom - 1)) != 0 || true)) + while ((low ^ (low + range)) < RangeTop || range < RangeBottom && ((range = (uint) -low & (RangeBottom - 1)) != 0 || true)) { - stream.WriteByte((byte)(low >> 24)); + stream.WriteByte((byte) (low >> 24)); range <<= 8; low <<= 8; } @@ -57,7 +57,7 @@ namespace Compress.SevenZip.Compress.PPmd.I1 { for (uint index = 0; index < 4; index++) { - stream.WriteByte((byte)(low >> 24)); + stream.WriteByte((byte) (low >> 24)); low <<= 8; } } @@ -68,14 +68,14 @@ namespace Compress.SevenZip.Compress.PPmd.I1 code = 0; range = uint.MaxValue; for (uint index = 0; index < 4; index++) - code = (code << 8) | (byte)stream.ReadByte(); + code = (code << 8) | (byte) stream.ReadByte(); } public void RangeDecoderNormalize(Stream stream) { - while ((low ^ (low + range)) < RangeTop || range < RangeBottom && ((range = (uint)-low & (RangeBottom - 1)) != 0 || true)) + while ((low ^ (low + range)) < RangeTop || range < RangeBottom && ((range = (uint) -low & (RangeBottom - 1)) != 0 || true)) { - code = (code << 8) | (byte)stream.ReadByte(); + code = (code << 8) | (byte) stream.ReadByte(); range <<= 8; low <<= 8; } @@ -97,4 +97,4 @@ namespace Compress.SevenZip.Compress.PPmd.I1 range *= HighCount - LowCount; } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/MemoryNode.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/MemoryNode.cs index 923381b9..bde225f8 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/MemoryNode.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/MemoryNode.cs @@ -48,13 +48,13 @@ namespace Compress.SevenZip.Compress.PPmd.I1 /// public uint Stamp { - get { return ((uint)Memory[Address]) | ((uint)Memory[Address + 1]) << 8 | ((uint)Memory[Address + 2]) << 16 | ((uint)Memory[Address + 3]) << 24; } + get { return ((uint) Memory[Address]) | ((uint) Memory[Address + 1]) << 8 | ((uint) Memory[Address + 2]) << 16 | ((uint) Memory[Address + 3]) << 24; } set { - Memory[Address] = (byte)value; - Memory[Address + 1] = (byte)(value >> 8); - Memory[Address + 2] = (byte)(value >> 16); - Memory[Address + 3] = (byte)(value >> 24); + Memory[Address] = (byte) value; + Memory[Address + 1] = (byte) (value >> 8); + Memory[Address + 2] = (byte) (value >> 16); + Memory[Address + 3] = (byte) (value >> 24); } } @@ -63,13 +63,13 @@ namespace Compress.SevenZip.Compress.PPmd.I1 /// public MemoryNode Next { - get { return new MemoryNode(((uint)Memory[Address + 4]) | ((uint)Memory[Address + 5]) << 8 | ((uint)Memory[Address + 6]) << 16 | ((uint)Memory[Address + 7]) << 24, Memory); } + get { return new MemoryNode(((uint) Memory[Address + 4]) | ((uint) Memory[Address + 5]) << 8 | ((uint) Memory[Address + 6]) << 16 | ((uint) Memory[Address + 7]) << 24, Memory); } set { - Memory[Address + 4] = (byte)value.Address; - Memory[Address + 5] = (byte)(value.Address >> 8); - Memory[Address + 6] = (byte)(value.Address >> 16); - Memory[Address + 7] = (byte)(value.Address >> 24); + Memory[Address + 4] = (byte) value.Address; + Memory[Address + 5] = (byte) (value.Address >> 8); + Memory[Address + 6] = (byte) (value.Address >> 16); + Memory[Address + 7] = (byte) (value.Address >> 24); } } @@ -78,13 +78,13 @@ namespace Compress.SevenZip.Compress.PPmd.I1 /// public uint UnitCount { - get { return ((uint)Memory[Address + 8]) | ((uint)Memory[Address + 9]) << 8 | ((uint)Memory[Address + 10]) << 16 | ((uint)Memory[Address + 11]) << 24; } + get { return ((uint) Memory[Address + 8]) | ((uint) Memory[Address + 9]) << 8 | ((uint) Memory[Address + 10]) << 16 | ((uint) Memory[Address + 11]) << 24; } set { - Memory[Address + 8] = (byte)value; - Memory[Address + 9] = (byte)(value >> 8); - Memory[Address + 10] = (byte)(value >> 16); - Memory[Address + 11] = (byte)(value >> 24); + Memory[Address + 8] = (byte) value; + Memory[Address + 9] = (byte) (value >> 8); + Memory[Address + 10] = (byte) (value >> 16); + Memory[Address + 11] = (byte) (value >> 24); } } @@ -157,7 +157,7 @@ namespace Compress.SevenZip.Compress.PPmd.I1 /// public static MemoryNode operator +(MemoryNode memoryNode, int offset) { - memoryNode.Address = (uint)(memoryNode.Address + offset * Size); + memoryNode.Address = (uint) (memoryNode.Address + offset * Size); return memoryNode; } @@ -181,7 +181,7 @@ namespace Compress.SevenZip.Compress.PPmd.I1 /// public static MemoryNode operator -(MemoryNode memoryNode, int offset) { - memoryNode.Address = (uint)(memoryNode.Address - offset * Size); + memoryNode.Address = (uint) (memoryNode.Address - offset * Size); return memoryNode; } @@ -228,7 +228,7 @@ namespace Compress.SevenZip.Compress.PPmd.I1 { if (obj is MemoryNode) { - MemoryNode memoryNode = (MemoryNode)obj; + MemoryNode memoryNode = (MemoryNode) obj; return memoryNode.Address == Address; } return base.Equals(obj); @@ -243,4 +243,4 @@ namespace Compress.SevenZip.Compress.PPmd.I1 return Address.GetHashCode(); } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/Model.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/Model.cs index 5b531535..f464c626 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/Model.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/Model.cs @@ -816,4 +816,4 @@ namespace Compress.SevenZip.Compress.PPmd.I1 #endregion } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/ModelRestorationMethod.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/ModelRestorationMethod.cs index 892dabf2..e7a7cdef 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/ModelRestorationMethod.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/ModelRestorationMethod.cs @@ -26,4 +26,4 @@ namespace Compress.SevenZip.Compress.PPmd.I1 /// Freeze = 2 } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/Pointer.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/Pointer.cs index 330c8e99..2df401a0 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/Pointer.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/Pointer.cs @@ -45,18 +45,18 @@ namespace Compress.SevenZip.Compress.PPmd.I1 { get { -#if DEBUG + #if DEBUG if (Address == 0) throw new InvalidOperationException("The pointer being indexed is a null pointer."); -#endif + #endif return Memory[Address + offset]; } set { -#if DEBUG + #if DEBUG if (Address == 0) throw new InvalidOperationException("The pointer being indexed is a null pointer."); -#endif + #endif Memory[Address + offset] = value; } } @@ -99,11 +99,11 @@ namespace Compress.SevenZip.Compress.PPmd.I1 /// public static Pointer operator +(Pointer pointer, int offset) { -#if DEBUG + #if DEBUG if (pointer.Address == 0) throw new InvalidOperationException("The pointer is a null pointer."); -#endif - pointer.Address = (uint)(pointer.Address + offset); + #endif + pointer.Address = (uint) (pointer.Address + offset); return pointer; } @@ -115,10 +115,10 @@ namespace Compress.SevenZip.Compress.PPmd.I1 /// public static Pointer operator +(Pointer pointer, uint offset) { -#if DEBUG + #if DEBUG if (pointer.Address == 0) throw new InvalidOperationException("The pointer is a null pointer."); -#endif + #endif pointer.Address += offset; return pointer; } @@ -130,10 +130,10 @@ namespace Compress.SevenZip.Compress.PPmd.I1 /// public static Pointer operator ++(Pointer pointer) { -#if DEBUG + #if DEBUG if (pointer.Address == 0) throw new InvalidOperationException("The pointer being incremented is a null pointer."); -#endif + #endif pointer.Address++; return pointer; } @@ -146,11 +146,11 @@ namespace Compress.SevenZip.Compress.PPmd.I1 /// public static Pointer operator -(Pointer pointer, int offset) { -#if DEBUG + #if DEBUG if (pointer.Address == 0) throw new InvalidOperationException("The pointer is a null pointer."); -#endif - pointer.Address = (uint)(pointer.Address - offset); + #endif + pointer.Address = (uint) (pointer.Address - offset); return pointer; } @@ -162,10 +162,10 @@ namespace Compress.SevenZip.Compress.PPmd.I1 /// public static Pointer operator -(Pointer pointer, uint offset) { -#if DEBUG + #if DEBUG if (pointer.Address == 0) throw new InvalidOperationException("The pointer is a null pointer."); -#endif + #endif pointer.Address -= offset; return pointer; } @@ -177,10 +177,10 @@ namespace Compress.SevenZip.Compress.PPmd.I1 /// public static Pointer operator --(Pointer pointer) { -#if DEBUG + #if DEBUG if (pointer.Address == 0) throw new InvalidOperationException("The pointer being decremented is a null pointer."); -#endif + #endif pointer.Address--; return pointer; } @@ -193,12 +193,12 @@ namespace Compress.SevenZip.Compress.PPmd.I1 /// The number of bytes between the two pointers. public static uint operator -(Pointer pointer1, Pointer pointer2) { -#if DEBUG + #if DEBUG if (pointer1.Address == 0) throw new InvalidOperationException("The pointer to the left of the subtraction operator is a null pointer."); if (pointer2.Address == 0) throw new InvalidOperationException("The pointer to the right of the subtraction operator is a null pointer."); -#endif + #endif return pointer1.Address - pointer2.Address; } @@ -210,12 +210,12 @@ namespace Compress.SevenZip.Compress.PPmd.I1 /// public static bool operator <(Pointer pointer1, Pointer pointer2) { -#if DEBUG + #if DEBUG if (pointer1.Address == 0) throw new InvalidOperationException("The pointer to the left of the less than operator is a null pointer."); if (pointer2.Address == 0) throw new InvalidOperationException("The pointer to the right of the less than operator is a null pointer."); -#endif + #endif return pointer1.Address < pointer2.Address; } @@ -227,12 +227,12 @@ namespace Compress.SevenZip.Compress.PPmd.I1 /// public static bool operator <=(Pointer pointer1, Pointer pointer2) { -#if DEBUG + #if DEBUG if (pointer1.Address == 0) throw new InvalidOperationException("The pointer to the left of the less than or equal to operator is a null pointer."); if (pointer2.Address == 0) throw new InvalidOperationException("The pointer to the right of the less than or equal to operator is a null pointer."); -#endif + #endif return pointer1.Address <= pointer2.Address; } @@ -244,12 +244,12 @@ namespace Compress.SevenZip.Compress.PPmd.I1 /// public static bool operator >(Pointer pointer1, Pointer pointer2) { -#if DEBUG + #if DEBUG if (pointer1.Address == 0) throw new InvalidOperationException("The pointer to the left of the greater than operator is a null pointer."); if (pointer2.Address == 0) throw new InvalidOperationException("The pointer to the right of the greater than operator is a null pointer."); -#endif + #endif return pointer1.Address > pointer2.Address; } @@ -261,12 +261,12 @@ namespace Compress.SevenZip.Compress.PPmd.I1 /// public static bool operator >=(Pointer pointer1, Pointer pointer2) { -#if DEBUG + #if DEBUG if (pointer1.Address == 0) throw new InvalidOperationException("The pointer to the left of the greater than or equal to operator is a null pointer."); if (pointer2.Address == 0) throw new InvalidOperationException("The pointer to the right of the greater than or equal to operator is a null pointer."); -#endif + #endif return pointer1.Address >= pointer2.Address; } @@ -301,7 +301,7 @@ namespace Compress.SevenZip.Compress.PPmd.I1 { if (obj is Pointer) { - Pointer pointer = (Pointer)obj; + Pointer pointer = (Pointer) obj; return pointer.Address == Address; } return base.Equals(obj); @@ -316,4 +316,4 @@ namespace Compress.SevenZip.Compress.PPmd.I1 return Address.GetHashCode(); } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/PpmContext.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/PpmContext.cs index 2164bf72..81aad5e1 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/PpmContext.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/PpmContext.cs @@ -377,7 +377,7 @@ namespace Compress.SevenZip.Compress.PPmd.I1 Coder.LowCount = lowCount; lowCount += state.Frequency; Coder.HighCount = lowCount; - for (PpmState p1 = state; --index != 0;) + for (PpmState p1 = state; --index != 0; ) { do { @@ -784,4 +784,4 @@ namespace Compress.SevenZip.Compress.PPmd.I1 return context; } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/PpmState.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/PpmState.cs index 38001ef0..79b509f6 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/PpmState.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/PpmState.cs @@ -58,13 +58,13 @@ namespace Compress.SevenZip.Compress.PPmd.I1 /// public Model.PpmContext Successor { - get { return new Model.PpmContext(((uint)Memory[Address + 2]) | ((uint)Memory[Address + 3]) << 8 | ((uint)Memory[Address + 4]) << 16 | ((uint)Memory[Address + 5]) << 24, Memory); } + get { return new Model.PpmContext(((uint) Memory[Address + 2]) | ((uint) Memory[Address + 3]) << 8 | ((uint) Memory[Address + 4]) << 16 | ((uint) Memory[Address + 5]) << 24, Memory); } set { - Memory[Address + 2] = (byte)value.Address; - Memory[Address + 3] = (byte)(value.Address >> 8); - Memory[Address + 4] = (byte)(value.Address >> 16); - Memory[Address + 5] = (byte)(value.Address >> 24); + Memory[Address + 2] = (byte) value.Address; + Memory[Address + 3] = (byte) (value.Address >> 8); + Memory[Address + 4] = (byte) (value.Address >> 16); + Memory[Address + 5] = (byte) (value.Address >> 24); } } @@ -76,7 +76,7 @@ namespace Compress.SevenZip.Compress.PPmd.I1 /// public PpmState this[int offset] { - get { return new PpmState((uint)(Address + offset * Size), Memory); } + get { return new PpmState((uint) (Address + offset * Size), Memory); } } /// @@ -97,7 +97,7 @@ namespace Compress.SevenZip.Compress.PPmd.I1 /// public static PpmState operator +(PpmState state, int offset) { - state.Address = (uint)(state.Address + offset * Size); + state.Address = (uint) (state.Address + offset * Size); return state; } @@ -120,7 +120,7 @@ namespace Compress.SevenZip.Compress.PPmd.I1 /// public static PpmState operator -(PpmState state, int offset) { - state.Address = (uint)(state.Address - offset * Size); + state.Address = (uint) (state.Address - offset * Size); return state; } @@ -188,7 +188,7 @@ namespace Compress.SevenZip.Compress.PPmd.I1 { if (obj is PpmState) { - PpmState state = (PpmState)obj; + PpmState state = (PpmState) obj; return state.Address == Address; } return base.Equals(obj); @@ -203,4 +203,4 @@ namespace Compress.SevenZip.Compress.PPmd.I1 return Address.GetHashCode(); } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/See2Context.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/See2Context.cs index 1650d856..970a0889 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/See2Context.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/I1/See2Context.cs @@ -32,15 +32,15 @@ namespace Compress.SevenZip.Compress.PPmd.I1 public void Initialize(uint initialValue) { Shift = PeriodBitCount - 4; - Summary = (ushort)(initialValue << Shift); + Summary = (ushort) (initialValue << Shift); Count = 7; } public uint Mean() { - uint value = (uint)(Summary >> Shift); - Summary = (ushort)(Summary - value); - return (uint)(value + ((value == 0) ? 1 : 0)); + uint value = (uint) (Summary >> Shift); + Summary = (ushort) (Summary - value); + return (uint) (value + ((value == 0) ? 1 : 0)); } public void Update() @@ -48,8 +48,8 @@ namespace Compress.SevenZip.Compress.PPmd.I1 if (Shift < PeriodBitCount && --Count == 0) { Summary += Summary; - Count = (byte)(3 << Shift++); + Count = (byte) (3 << Shift++); } } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/PpmdProperties.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/PpmdProperties.cs index 501331cd..2e5adbfd 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/PpmdProperties.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/PpmdProperties.cs @@ -78,4 +78,4 @@ namespace Compress.SevenZip.Compress.PPmd } } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/PpmdStream.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/PpmdStream.cs index b5c11980..f5db7540 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/PpmdStream.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/PpmdStream.cs @@ -151,4 +151,4 @@ namespace Compress.SevenZip.Compress.PPmd model.EncodeBlock(stream, new MemoryStream(buffer, offset, count), false); } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/Utility.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/Utility.cs index bda8e9f0..934f4fbb 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/Utility.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/PPmd/Utility.cs @@ -119,7 +119,7 @@ namespace Compress.SevenZip.Compress.PPmd } /// Read a int value from the byte array at the given position (Big Endian) - /// + /// /// /// the array to read from /// @@ -142,7 +142,7 @@ namespace Compress.SevenZip.Compress.PPmd /// Read a short value from the byte array at the given position (little /// Endian) - /// + /// /// /// the array to read from /// @@ -157,7 +157,7 @@ namespace Compress.SevenZip.Compress.PPmd /// Read an int value from the byte array at the given position (little /// Endian) - /// + /// /// /// the array to read from /// @@ -171,7 +171,7 @@ namespace Compress.SevenZip.Compress.PPmd } /// Write an int value into the byte array at the given position (Big endian) - /// + /// /// /// the array /// @@ -189,7 +189,7 @@ namespace Compress.SevenZip.Compress.PPmd /// Write a short value into the byte array at the given position (little /// endian) - /// + /// /// /// the array /// @@ -221,7 +221,7 @@ namespace Compress.SevenZip.Compress.PPmd /// Write an int value into the byte array at the given position (little /// endian) - /// + /// /// /// the array /// @@ -464,4 +464,4 @@ namespace Compress.SevenZip.Compress.PPmd } #endif } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/RangeCoder/RangeCoder.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/RangeCoder/RangeCoder.cs index 6c45c58a..10f2e09f 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/RangeCoder/RangeCoder.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/RangeCoder/RangeCoder.cs @@ -244,4 +244,4 @@ namespace Compress.SevenZip.Compress.RangeCoder // ulong GetProcessedSize() {return Stream.GetProcessedSize(); } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/RangeCoder/RangeCoderBit.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/RangeCoder/RangeCoderBit.cs index 9ff1ac16..357a3e79 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/RangeCoder/RangeCoderBit.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/RangeCoder/RangeCoderBit.cs @@ -116,4 +116,4 @@ namespace Compress.SevenZip.Compress.RangeCoder } } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/RangeCoder/RangeCoderBitTree.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/RangeCoder/RangeCoderBitTree.cs index 9ad382b0..06a814ef 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/RangeCoder/RangeCoderBitTree.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/RangeCoder/RangeCoderBitTree.cs @@ -22,7 +22,7 @@ namespace Compress.SevenZip.Compress.RangeCoder public void Encode(Encoder rangeEncoder, UInt32 symbol) { UInt32 m = 1; - for (int bitIndex = NumBitLevels; bitIndex > 0;) + for (int bitIndex = NumBitLevels; bitIndex > 0; ) { bitIndex--; UInt32 bit = (symbol >> bitIndex) & 1; @@ -47,7 +47,7 @@ namespace Compress.SevenZip.Compress.RangeCoder { UInt32 price = 0; UInt32 m = 1; - for (int bitIndex = NumBitLevels; bitIndex > 0;) + for (int bitIndex = NumBitLevels; bitIndex > 0; ) { bitIndex--; UInt32 bit = (symbol >> bitIndex) & 1; @@ -154,4 +154,4 @@ namespace Compress.SevenZip.Compress.RangeCoder return symbol; } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/ZSTD/ZstandardDictionary.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/ZSTD/ZstandardDictionary.cs index e2fb1c50..7705c5a2 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/ZSTD/ZstandardDictionary.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/ZSTD/ZstandardDictionary.cs @@ -3,9 +3,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; -using Interop = Zstandard.Net.ZstandardInterop; +using Interop = Compress.SevenZip.Compress.ZSTD.ZstandardInterop; -namespace Zstandard.Net +namespace Compress.SevenZip.Compress.ZSTD { /// /// A Zstandard dictionary improves the compression ratio and speed on small data dramatically. @@ -38,7 +38,7 @@ namespace Zstandard.Net /// The dictionary path. public ZstandardDictionary(string dictionaryPath) { - this.dictionary = File.ReadAllBytes(dictionaryPath); + this.dictionary = System.IO.File.ReadAllBytes(dictionaryPath); } /// diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/ZSTD/ZstandardInterop.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/ZSTD/ZstandardInterop.cs index 03abe7a9..df469631 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/ZSTD/ZstandardInterop.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/ZSTD/ZstandardInterop.cs @@ -2,7 +2,7 @@ using System.IO; using System.Runtime.InteropServices; -namespace Zstandard.Net +namespace Compress.SevenZip.Compress.ZSTD { internal static class ZstandardInterop { diff --git a/SabreTools.FileTypes/Compress/SevenZip/Compress/ZSTD/ZstandardStream.cs b/SabreTools.FileTypes/Compress/SevenZip/Compress/ZSTD/ZstandardStream.cs index 5d36f335..8f76ae57 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Compress/ZSTD/ZstandardStream.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Compress/ZSTD/ZstandardStream.cs @@ -2,9 +2,9 @@ using System.IO; using System.IO.Compression; using System.Runtime.InteropServices; -using Interop = Zstandard.Net.ZstandardInterop; +using Interop = Compress.SevenZip.Compress.ZSTD.ZstandardInterop; -namespace Zstandard.Net +namespace Compress.SevenZip.Compress.ZSTD { /// /// Provides methods and properties for compressing and decompressing streams by using the Zstandard algorithm. @@ -32,7 +32,7 @@ namespace Zstandard.Net private Interop.Buffer outputBuffer = new Interop.Buffer(); private Interop.Buffer inputBuffer = new Interop.Buffer(); - + /// /// Initializes a new instance of the class by using the specified stream and compression mode, and optionally leaves the stream open. /// @@ -238,7 +238,7 @@ namespace Zstandard.Net { var inputSize = this.dataSize - this.dataPosition; - // read data from input stream + // read data from input stream if (inputSize <= 0 && !this.dataDepleted && !this.dataSkipRead) { this.dataSize = this.stream.Read(this.data, 0, (int)this.zstreamInputSize); diff --git a/SabreTools.FileTypes/Compress/SevenZip/Filters/BCJ2Filter.cs b/SabreTools.FileTypes/Compress/SevenZip/Filters/BCJ2Filter.cs index 4ea96fa4..09664ee5 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Filters/BCJ2Filter.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Filters/BCJ2Filter.cs @@ -51,7 +51,7 @@ namespace Compress.SevenZip.Filters code = 0; range = 0xFFFFFFFF; - byte[] controlbuf = new byte[5]; + byte[] controlbuf=new byte[5]; control.Read(controlbuf, 0, 5); for (i = 0; i < 5; i++) @@ -139,7 +139,7 @@ namespace Compress.SevenZip.Filters if (range < kTopValue) { range <<= 8; - code = (code << 8) | (byte)control.ReadByte(); + code = (code << 8) | (byte)control.ReadByte(); } prevByte = b; } @@ -201,4 +201,4 @@ namespace Compress.SevenZip.Filters throw new NotImplementedException(); } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Filters/BCJFilter.cs b/SabreTools.FileTypes/Compress/SevenZip/Filters/BCJFilter.cs index e2aaae64..666ce0ce 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Filters/BCJFilter.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Filters/BCJFilter.cs @@ -4,7 +4,7 @@ namespace Compress.SevenZip.Filters { public class BCJFilter : Filter { - private static readonly bool[] MASK_TO_ALLOWED_STATUS = new bool[] { true, true, true, false, true, false, false, false }; + private static readonly bool[] MASK_TO_ALLOWED_STATUS = new bool[] {true, true, true, false, true, false, false, false}; private static readonly int[] MASK_TO_BIT_NUMBER = new int[] { 0, 1, 2, 2, 3, 3, 3, 3 }; private int pos; @@ -26,24 +26,18 @@ namespace Compress.SevenZip.Filters int end = offset + count - 5; int i; - for (i = offset; i <= end; ++i) - { + for (i = offset; i <= end; ++i) { if ((buffer[i] & 0xFE) != 0xE8) continue; prevPos = i - prevPos; - if ((prevPos & ~3) != 0) - { // (unsigned)prevPos > 3 + if ((prevPos & ~3) != 0) { // (unsigned)prevPos > 3 prevMask = 0; - } - else - { + } else { prevMask = (prevMask << (prevPos - 1)) & 7; - if (prevMask != 0) - { + if (prevMask != 0) { if (!MASK_TO_ALLOWED_STATUS[prevMask] || test86MSByte( - buffer[i + 4 - MASK_TO_BIT_NUMBER[prevMask]])) - { + buffer[i + 4 - MASK_TO_BIT_NUMBER[prevMask]])) { prevPos = i; prevMask = (prevMask << 1) | 1; continue; @@ -53,15 +47,13 @@ namespace Compress.SevenZip.Filters prevPos = i; - if (test86MSByte(buffer[i + 4])) - { + if (test86MSByte(buffer[i + 4])) { int src = buffer[i + 1] | (buffer[i + 2] << 8) | (buffer[i + 3] << 16) | (buffer[i + 4] << 24); int dest; - while (true) - { + while (true) { if (isEncoder) dest = src + (pos + i - offset); else @@ -82,9 +74,7 @@ namespace Compress.SevenZip.Filters buffer[i + 3] = (byte)(dest >> 16); buffer[i + 4] = (byte)(~(((dest >> 24) & 1) - 1)); i += 4; - } - else - { + } else { prevMask = (prevMask << 1) | 1; } } @@ -97,4 +87,4 @@ namespace Compress.SevenZip.Filters return i; } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Filters/Delta.cs b/SabreTools.FileTypes/Compress/SevenZip/Filters/Delta.cs index ce102e54..400e03a4 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Filters/Delta.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Filters/Delta.cs @@ -97,4 +97,4 @@ namespace Compress.SevenZip.Filters } } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Filters/Filter.cs b/SabreTools.FileTypes/Compress/SevenZip/Filters/Filter.cs index e9443eda..cd1f80d9 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Filters/Filter.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Filters/Filter.cs @@ -149,7 +149,7 @@ namespace Compress.SevenZip.Filters while (seekToGo > 0) { long get = seekToGo > bufferSize ? bufferSize : seekToGo; - Read(seekBuffer, 0, (int)get); + Read(seekBuffer, 0, (int) get); seekToGo -= get; } return position; @@ -168,4 +168,4 @@ namespace Compress.SevenZip.Filters protected abstract int Transform(byte[] buffer, int offset, int count); } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/SevenZip.cs b/SabreTools.FileTypes/Compress/SevenZip/SevenZip.cs index 8eccdfa4..55565ad8 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/SevenZip.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/SevenZip.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.IO; using System.Text; using Compress.SevenZip.Structure; @@ -29,6 +30,7 @@ namespace Compress.SevenZip public byte[] CRC; public int StreamIndex; public ulong StreamOffset; + public long LastModified; public ZipReturn FileStatus = ZipReturn.ZipUntested; } @@ -46,7 +48,7 @@ namespace Compress.SevenZip private long _baseOffset; - public string ZipFilename => _zipFileInfo != null ? _zipFileInfo.FullName : string.Empty; + public string ZipFilename => _zipFileInfo != null ? _zipFileInfo.FullName : ""; public long TimeStamp => _zipFileInfo?.LastWriteTime ?? 0; @@ -89,6 +91,11 @@ namespace Compress.SevenZip return _localFiles[i].CRC; } + public long LastModified(int i) + { + return _localFiles[i].LastModified; + } + public void ZipFileCloseFailed() { switch (ZipOpen) diff --git a/SabreTools.FileTypes/Compress/SevenZip/SevenZipOpen.cs b/SabreTools.FileTypes/Compress/SevenZip/SevenZipRead.cs similarity index 95% rename from SabreTools.FileTypes/Compress/SevenZip/SevenZipOpen.cs rename to SabreTools.FileTypes/Compress/SevenZip/SevenZipRead.cs index 1199c080..16dbfa48 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/SevenZipOpen.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/SevenZipRead.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; using Compress.SevenZip.Structure; @@ -161,10 +162,15 @@ namespace Compress.SevenZip } } + if (_header.FileInfo.TimeLastWrite != null) + { + lf.LastModified = DateTime.FromFileTimeUtc((long)_header.FileInfo.TimeLastWrite[i]).Ticks; + } + localFiles.Add(lf); } } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/SevenZipOpenRead.cs b/SabreTools.FileTypes/Compress/SevenZip/SevenZipReadStream.cs similarity index 93% rename from SabreTools.FileTypes/Compress/SevenZip/SevenZipOpenRead.cs rename to SabreTools.FileTypes/Compress/SevenZip/SevenZipReadStream.cs index 8ce2d7ae..90df92f9 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/SevenZipOpenRead.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/SevenZipReadStream.cs @@ -6,9 +6,9 @@ using System.IO.Compression; using Compress.SevenZip.Compress.BZip2; using Compress.SevenZip.Compress.LZMA; using Compress.SevenZip.Compress.PPmd; +using Compress.SevenZip.Compress.ZSTD; using Compress.SevenZip.Filters; using Compress.SevenZip.Structure; -using Zstandard.Net; using FileStream = RVIO.FileStream; namespace Compress.SevenZip @@ -50,6 +50,11 @@ namespace Compress.SevenZip ZipFileCloseReadStream(); _streamIndex = thisStreamIndex; + if (_header.StreamsInfo==null) + { + stream = null; + return ZipReturn.ZipGood; + } Folder folder = _header.StreamsInfo.Folders[_streamIndex]; @@ -192,7 +197,7 @@ namespace Compress.SevenZip return ZipReturn.ZipGood; } - catch (Exception e) + catch (Exception) { return ZipReturn.ZipErrorGettingDataStream; } @@ -224,18 +229,21 @@ namespace Compress.SevenZip { if (_streamIndex != -1) { - Folder folder = _header.StreamsInfo.Folders[_streamIndex]; - - foreach (Coder c in folder.Coders) + if (_header.StreamsInfo != null) { - Stream ds = c?.DecoderStream; - if (ds == null) + Folder folder = _header.StreamsInfo.Folders[_streamIndex]; + + foreach (Coder c in folder.Coders) { - continue; + Stream ds = c?.DecoderStream; + if (ds == null) + { + continue; + } + ds.Close(); + ds.Dispose(); + c.DecoderStream = null; } - ds.Close(); - ds.Dispose(); - c.DecoderStream = null; } } _streamIndex = -1; @@ -257,4 +265,4 @@ namespace Compress.SevenZip } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/SevenZipTorrent.cs b/SabreTools.FileTypes/Compress/SevenZip/SevenZipTorrent.cs index 51d89821..4679a5da 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/SevenZipTorrent.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/SevenZipTorrent.cs @@ -25,7 +25,7 @@ namespace Compress.SevenZip ZipStatus = ZipStatus.TrrntZip; } - private bool IsRomVault7Z(long testBaseOffset, ulong testHeaderPos, ulong testHeaderLength, uint testHeaderCRC) + private bool IsRomVault7Z(long testBaseOffset,ulong testHeaderPos,ulong testHeaderLength,uint testHeaderCRC) { long length = _zipFs.Length; if (length < 32) @@ -60,7 +60,7 @@ namespace Compress.SevenZip if (headerCRC != testHeaderCRC) return false; - if (headerOffset != testHeaderPos + (ulong)testBaseOffset) + if (headerOffset != testHeaderPos+(ulong)testBaseOffset) return false; return headerSize == testHeaderLength; @@ -154,4 +154,4 @@ namespace Compress.SevenZip } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/SevenZipWrite.cs b/SabreTools.FileTypes/Compress/SevenZip/SevenZipWrite.cs index d8dca46b..f6bea2b7 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/SevenZipWrite.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/SevenZipWrite.cs @@ -99,7 +99,7 @@ namespace Compress.SevenZip // do nothing here for 7zip } - public ZipReturn ZipFileOpenWriteStream(bool raw, bool trrntzip, string filename, ulong uncompressedSize, ushort compressionMethod, uint? datetime, out Stream stream) + public ZipReturn ZipFileOpenWriteStream(bool raw, bool trrntzip, string filename, ulong uncompressedSize, ushort compressionMethod, out Stream stream, TimeStamps dateTime) { return ZipFileOpenWriteStream(filename, uncompressedSize, out stream); } @@ -173,4 +173,4 @@ namespace Compress.SevenZip return DictionarySizes[DictionarySizes.Length - 1]; } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/SevenZipWriteClose.cs b/SabreTools.FileTypes/Compress/SevenZip/SevenZipWriteClose.cs index bbc68d7c..febb1d88 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/SevenZipWriteClose.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/SevenZipWriteClose.cs @@ -1,9 +1,9 @@ using System.IO; using System.Text; using Compress.SevenZip.Compress.LZMA; +using Compress.SevenZip.Compress.ZSTD; using Compress.SevenZip.Structure; using Compress.Utils; -using Zstandard.Net; namespace Compress.SevenZip { @@ -290,4 +290,4 @@ namespace Compress.SevenZip } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/SevenZip/Structure/FileInfo.cs b/SabreTools.FileTypes/Compress/SevenZip/Structure/FileInfo.cs index c2610dfb..5d356af1 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Structure/FileInfo.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Structure/FileInfo.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Runtime.InteropServices; using System.Text; namespace Compress.SevenZip.Structure @@ -10,6 +11,9 @@ namespace Compress.SevenZip.Structure public bool[] EmptyStreamFlags; public bool[] EmptyFileFlags; public uint[] Attributes; + public ulong[] TimeCreation; + public ulong[] TimeLastAccess; + public ulong[] TimeLastWrite; public void Read(BinaryReader br) { @@ -67,9 +71,13 @@ namespace Compress.SevenZip.Structure continue; case HeaderProperty.kCreationTime: + TimeCreation = Util.ReadUInt64Def(br, size); + continue; case HeaderProperty.kLastAccessTime: + TimeLastAccess = Util.ReadUInt64Def(br, size); + continue; case HeaderProperty.kLastWriteTime: - br.ReadBytes((int)bytessize); + TimeLastWrite = Util.ReadUInt64Def(br, size); continue; case HeaderProperty.kDummy: diff --git a/SabreTools.FileTypes/Compress/SevenZip/Structure/PackedStreamInfo.cs b/SabreTools.FileTypes/Compress/SevenZip/Structure/PackedStreamInfo.cs index 7d6030af..66d6bb03 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Structure/PackedStreamInfo.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Structure/PackedStreamInfo.cs @@ -26,9 +26,9 @@ namespace Compress.SevenZip.Structure ulong streamPosition = 0; - for (; ; ) + for (;;) { - HeaderProperty hp = (HeaderProperty)br.ReadByte(); + HeaderProperty hp = (HeaderProperty) br.ReadByte(); switch (hp) { case HeaderProperty.kSize: @@ -60,12 +60,12 @@ namespace Compress.SevenZip.Structure public static void Write(BinaryWriter bw, ulong packPosition, PackedStreamInfo[] packedStreams) { - ulong numPackStreams = (ulong)packedStreams.Length; - bw.Write((byte)HeaderProperty.kPackInfo); + ulong numPackStreams = (ulong) packedStreams.Length; + bw.Write((byte) HeaderProperty.kPackInfo); bw.WriteEncodedUInt64(packPosition); bw.WriteEncodedUInt64(numPackStreams); - bw.Write((byte)HeaderProperty.kSize); + bw.Write((byte) HeaderProperty.kSize); ulong streamPosition = 0; for (ulong i = 0; i < numPackStreams; i++) { @@ -77,14 +77,14 @@ namespace Compress.SevenZip.Structure // Only checking the first CRC assuming all the reset will be the same if (packedStreams[0].Crc != null) { - bw.Write((byte)HeaderProperty.kCRC); + bw.Write((byte) HeaderProperty.kCRC); for (ulong i = 0; i < numPackStreams; i++) { bw.WriteEncodedUInt64(packedStreams[i].Crc ?? 0); } } - bw.Write((byte)HeaderProperty.kEnd); + bw.Write((byte) HeaderProperty.kEnd); } diff --git a/SabreTools.FileTypes/Compress/SevenZip/Structure/SignatureHeader.cs b/SabreTools.FileTypes/Compress/SevenZip/Structure/SignatureHeader.cs index 54326cef..1ca52a86 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Structure/SignatureHeader.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Structure/SignatureHeader.cs @@ -5,7 +5,7 @@ namespace Compress.SevenZip.Structure { internal class SignatureHeader { - private static readonly byte[] Signature = { (byte)'7', (byte)'z', 0xBC, 0xAF, 0x27, 0x1C }; + private static readonly byte[] Signature = {(byte) '7', (byte) 'z', 0xBC, 0xAF, 0x27, 0x1C}; private byte _major; private byte _minor; @@ -38,7 +38,7 @@ namespace Compress.SevenZip.Structure long pos = br.BaseStream.Position; byte[] mainHeader = new byte[8 + 8 + 4]; br.BaseStream.Read(mainHeader, 0, mainHeader.Length); - if (!Utils.CRC.VerifyDigest(_startHeaderCRC, mainHeader, 0, (uint)mainHeader.Length)) + if (!Utils.CRC.VerifyDigest(_startHeaderCRC, mainHeader, 0, (uint) mainHeader.Length)) { return false; } @@ -61,18 +61,18 @@ namespace Compress.SevenZip.Structure //ArchiveVersion //{ - bw.Write((byte)0); // BYTE Major - bw.Write((byte)3); // BYTE Minor + bw.Write((byte) 0); // BYTE Major + bw.Write((byte) 3); // BYTE Minor //}; _crcOffset = bw.BaseStream.Position; - bw.Write((uint)0); //HeaderCRC + bw.Write((uint) 0); //HeaderCRC //StartHeader //{ - bw.Write((ulong)0); //NextHeaderOffset - bw.Write((ulong)0); //NextHeaderSize - bw.Write((uint)0); //NextHeaderCRC + bw.Write((ulong) 0); //NextHeaderOffset + bw.Write((ulong) 0); //NextHeaderSize + bw.Write((uint) 0); //NextHeaderCRC //} BaseOffset = bw.BaseStream.Position; @@ -86,9 +86,9 @@ namespace Compress.SevenZip.Structure byte[] sigHeaderBytes; using (MemoryStream sigHeaderMem = new MemoryStream()) { - using (BinaryWriter sigHeaderBw = new BinaryWriter(sigHeaderMem, Encoding.UTF8, true)) + using (BinaryWriter sigHeaderBw = new BinaryWriter(sigHeaderMem,Encoding.UTF8,true)) { - sigHeaderBw.Write((ulong)((long)headerpos - BaseOffset)); //NextHeaderOffset + sigHeaderBw.Write((ulong) ((long) headerpos - BaseOffset)); //NextHeaderOffset sigHeaderBw.Write(headerLength); //NextHeaderSize sigHeaderBw.Write(headerCRC); //NextHeaderCRC @@ -98,7 +98,7 @@ namespace Compress.SevenZip.Structure } } - uint sigHeaderCRC = Utils.CRC.CalculateDigest(sigHeaderBytes, 0, (uint)sigHeaderBytes.Length); + uint sigHeaderCRC = Utils.CRC.CalculateDigest(sigHeaderBytes, 0, (uint) sigHeaderBytes.Length); bw.BaseStream.Position = _crcOffset; bw.Write(sigHeaderCRC); //Header CRC diff --git a/SabreTools.FileTypes/Compress/SevenZip/Structure/UnpackedStreamInfo.cs b/SabreTools.FileTypes/Compress/SevenZip/Structure/UnpackedStreamInfo.cs index 65e4af11..9eceb3c7 100644 --- a/SabreTools.FileTypes/Compress/SevenZip/Structure/UnpackedStreamInfo.cs +++ b/SabreTools.FileTypes/Compress/SevenZip/Structure/UnpackedStreamInfo.cs @@ -7,7 +7,7 @@ namespace Compress.SevenZip.Structure { public ulong UnpackedSize; public uint? Crc; - + public void Report(ref StringBuilder sb) { sb.AppendLine($" Crc = {Crc.ToHex()} , Size = {UnpackedSize}"); diff --git a/SabreTools.FileTypes/Compress/ThreadReaders/ThreadCRC.cs b/SabreTools.FileTypes/Compress/ThreadReaders/ThreadCRC.cs index 35341179..5be20fe8 100644 --- a/SabreTools.FileTypes/Compress/ThreadReaders/ThreadCRC.cs +++ b/SabreTools.FileTypes/Compress/ThreadReaders/ThreadCRC.cs @@ -5,7 +5,7 @@ namespace Compress.ThreadReaders { public class ThreadCRC : IDisposable { - private Utils.CRC crc; + private Utils.CRC crc; private readonly AutoResetEvent _waitEvent; private readonly AutoResetEvent _outEvent; private readonly Thread _tWorker; @@ -17,7 +17,7 @@ namespace Compress.ThreadReaders public ThreadCRC() { - crc = new Utils.CRC(); + crc=new Utils.CRC(); _waitEvent = new AutoResetEvent(false); _outEvent = new AutoResetEvent(false); _finished = false; @@ -44,7 +44,7 @@ namespace Compress.ThreadReaders break; } - crc.SlurpBlock(_buffer, 0, _size); + crc.SlurpBlock(_buffer,0,_size); _outEvent.Set(); } diff --git a/SabreTools.FileTypes/Compress/Utils/CRCStream.cs b/SabreTools.FileTypes/Compress/Utils/CRCStream.cs index 5f266fd2..5c416e82 100644 --- a/SabreTools.FileTypes/Compress/Utils/CRCStream.cs +++ b/SabreTools.FileTypes/Compress/Utils/CRCStream.cs @@ -340,4 +340,4 @@ namespace Compress.Utils } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/Utils/DirUtil.cs b/SabreTools.FileTypes/Compress/Utils/DirUtil.cs index ad67dfb0..34437626 100644 --- a/SabreTools.FileTypes/Compress/Utils/DirUtil.cs +++ b/SabreTools.FileTypes/Compress/Utils/DirUtil.cs @@ -18,22 +18,7 @@ namespace Compress.Utils return; } - - while ((strTemp.Length > 0) && !Directory.Exists(strTemp)) - { - int pos = strTemp.LastIndexOf(Path.DirectorySeparatorChar); - if (pos < 0) - { - pos = 0; - } - strTemp = strTemp.Substring(0, pos); - } - - while (sFilename.IndexOf(Path.DirectorySeparatorChar, strTemp.Length + 1) > 0) - { - strTemp = sFilename.Substring(0, sFilename.IndexOf(Path.DirectorySeparatorChar, strTemp.Length + 1)); - Directory.CreateDirectory(strTemp); - } + Directory.CreateDirectory(strTemp); } } } \ No newline at end of file diff --git a/SabreTools.FileTypes/Compress/Utils/Reporter.cs b/SabreTools.FileTypes/Compress/Utils/Reporter.cs index 3dd98e53..a6a60588 100644 --- a/SabreTools.FileTypes/Compress/Utils/Reporter.cs +++ b/SabreTools.FileTypes/Compress/Utils/Reporter.cs @@ -40,4 +40,4 @@ namespace Compress.Utils return v == null ? "NULL" : ((ulong)v).ToString("X8"); } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/Utils/TimeStamps.cs b/SabreTools.FileTypes/Compress/Utils/TimeStamps.cs new file mode 100644 index 00000000..11359f82 --- /dev/null +++ b/SabreTools.FileTypes/Compress/Utils/TimeStamps.cs @@ -0,0 +1,9 @@ +namespace Compress.Utils +{ + public class TimeStamps + { + public long? ModTime; + public long? CreateTime; + public long? AccessTime; + } +} diff --git a/SabreTools.FileTypes/Compress/ZipEnums.cs b/SabreTools.FileTypes/Compress/ZipEnums.cs index f4a89a5a..be209cfd 100644 --- a/SabreTools.FileTypes/Compress/ZipEnums.cs +++ b/SabreTools.FileTypes/Compress/ZipEnums.cs @@ -50,4 +50,4 @@ namespace Compress ExtraData = 0x2, Trrnt7Zip = 0x4 } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/ZipFile/Explode/Original.c b/SabreTools.FileTypes/Compress/ZipFile/Explode/Original.c new file mode 100644 index 00000000..5ab16589 --- /dev/null +++ b/SabreTools.FileTypes/Compress/ZipFile/Explode/Original.c @@ -0,0 +1,613 @@ +/* + Copyright (c) 1990-2007 Info-ZIP. All rights reserved. + See the accompanying file LICENSE, version 2007-Mar-04 or later + (the contents of which are also included in unzip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* explode.c -- by Mark Adler + version c17d, 01 December 2007 */ + + + /* Copyright history: + - Starting with UnZip 5.41 of 16-April-2000, this source file + is covered by the Info-Zip LICENSE cited above. + - Prior versions of this source file, found in UnZip source packages + up to UnZip 5.40, were put in the public domain. + The original copyright note by Mark Adler was: + "You can do whatever you like with this source file, + though I would prefer that if you modify it and + redistribute it that you include comments to that effect + with your name and the date. Thank you." + History: + vers date who what + ---- --------- -------------- ------------------------------------ + c1 30 Mar 92 M. Adler explode that uses huft_build from inflate + (this gives over a 70% speed improvement + over the original unimplode.c, which + decoded a bit at a time) + c2 4 Apr 92 M. Adler fixed bug for file sizes a multiple of 32k. + c3 10 Apr 92 M. Adler added a little memory tracking if DEBUG + c4 11 Apr 92 M. Adler added NOMEMCPY do kill use of memcpy() + c5 21 Apr 92 M. Adler added the WSIZE #define to allow reducing + the 32K window size for specialized + applications. + c6 31 May 92 M. Adler added typecasts to eliminate some warnings + c7 27 Jun 92 G. Roelofs added more typecasts. + c8 17 Oct 92 G. Roelofs changed ULONG/UWORD/byte to ulg/ush/uch. + c9 19 Jul 93 J. Bush added more typecasts (to return values); + made l[256] array static for Amiga. + c10 8 Oct 93 G. Roelofs added used_csize for diagnostics; added + buf and unshrink arguments to flush(); + undef'd various macros at end for Turbo C; + removed NEXTBYTE macro (now in unzip.h) + and bytebuf variable (not used); changed + memset() to memzero(). + c11 9 Jan 94 M. Adler fixed incorrect used_csize calculation. + c12 9 Apr 94 G. Roelofs fixed split comments on preprocessor lines + to avoid bug in Encore compiler. + c13 25 Aug 94 M. Adler fixed distance-length comment (orig c9 fix) + c14 22 Nov 95 S. Maxwell removed unnecessary "static" on auto array + c15 6 Jul 96 W. Haidinger added ulg typecasts to flush() calls. + c16 8 Feb 98 C. Spieler added ZCONST modifiers to const tables + and #ifdef DEBUG around debugging code. + c16b 25 Mar 98 C. Spieler modified DLL code for slide redirection. + c16d 05 Jul 99 C. Spieler take care of flush() return values and + stop processing in case of errors + c17 04 Feb 01 C. Spieler reorganized code to reduce repetitions + of large code parts; adapted huft decoding + to the changes in inflate's huft_build() + due to support of deflate64; fixed memory + leaks (huft tables were not free'd when + get_tree() failed). + c17b 16 Feb 02 C. Spieler changed type of the "extra lengths" array + "extra" from ush into uch (to save space) + c17c 10 Aug 04 NN file sizes use zoff_t. + c17d 01 Dec 07 C. Spieler type for file sizes changed from zoff_t + into zusz_t. + */ + + + /* + Explode imploded (PKZIP method 6 compressed) data. This compression + method searches for as much of the current string of bytes (up to a length + of ~320) in the previous 4K or 8K bytes. If it doesn't find any matches + (of at least length 2 or 3), it codes the next byte. Otherwise, it codes + the length of the matched string and its distance backwards from the + current position. Single bytes ("literals") are preceded by a one (a + single bit) and are either uncoded (the eight bits go directly into the + compressed stream for a total of nine bits) or Huffman coded with a + supplied literal code tree. If literals are coded, then the minimum match + length is three, otherwise it is two. + There are therefore four kinds of imploded streams: 8K search with coded + literals (min match = 3), 4K search with coded literals (min match = 3), + 8K with uncoded literals (min match = 2), and 4K with uncoded literals + (min match = 2). The kind of stream is identified in two bits of a + general purpose bit flag that is outside of the compressed stream. + Distance-length pairs for matched strings are preceded by a zero bit (to + distinguish them from literals) and are always coded. The distance comes + first and is either the low six (4K) or low seven (8K) bits of the + distance (uncoded), followed by the high six bits of the distance coded. + Then the length is six bits coded (0..63 + min match length), and if the + maximum such length is coded, then it's followed by another eight bits + (uncoded) to be added to the coded length. This gives a match length + range of 2..320 or 3..321 bytes. + The literal, length, and distance codes are all represented in a slightly + compressed form themselves. What is sent are the lengths of the codes for + each value, which is sufficient to construct the codes. Each byte of the + code representation is the code length (the low four bits representing + 1..16), and the number of values sequentially with that length (the high + four bits also representing 1..16). There are 256 literal code values (if + literals are coded), 64 length code values, and 64 distance code values, + in that order at the beginning of the compressed stream. Each set of code + values is preceded (redundantly) with a byte indicating how many bytes are + in the code description that follows, in the range 1..256. + The codes themselves are decoded using tables made by huft_build() from + the bit lengths. That routine and its comments are in the inflate.c + module. + */ + +#define __EXPLODE_C /* identifies this source module */ +#define UNZIP_INTERNAL +#include "unzip.h" /* must supply slide[] (uch) array and NEXTBYTE macro */ + +#ifndef WSIZE +# define WSIZE 0x8000 /* window size--must be a power of two, and */ +#endif /* at least 8K for zip's implode method */ + +#if (defined(DLL) && !defined(NO_SLIDE_REDIR)) +# define wszimpl (unsigned)(G._wsize) +#else +# if defined(USE_DEFLATE64) && defined(INT_16BIT) +# define wszimpl (unsigned)(WSIZE>>1) +# else /* !(USE_DEFLATE64 && INT_16BIT) */ +# define wszimpl WSIZE +# endif /* !(USE_DEFLATE64 && INT_16BIT) */ +#endif + + /* routines here */ +static int get_tree OF((__GPRO__ unsigned* l, unsigned n)); +static int explode_lit OF((__GPRO__ struct huft* tb, struct huft* tl, + struct huft* td, unsigned bb, unsigned bl, + unsigned bd, unsigned bdl)); +static int explode_nolit OF((__GPRO__ struct huft* tl, struct huft* td, + unsigned bl, unsigned bd, unsigned bdl)); +int explode OF((__GPRO)); + + +/* The implode algorithm uses a sliding 4K or 8K byte window on the + uncompressed stream to find repeated byte strings. This is implemented + here as a circular buffer. The index is updated simply by incrementing + and then and'ing with 0x0fff (4K-1) or 0x1fff (8K-1). Here, the 32K + buffer of inflate is used, and it works just as well to always have + a 32K circular buffer, so the index is anded with 0x7fff. This is + done to allow the window to also be used as the output buffer. */ + /* This must be supplied in an external module useable like "uch slide[8192];" + or "uch *slide;", where the latter would be malloc'ed. In unzip, slide[] + is actually a 32K area for use by inflate, which uses a 32K sliding window. + */ + + +#define INVALID_CODE 99 +#define IS_INVALID_CODE(c) ((c) == INVALID_CODE) + + /* Tables for length and distance */ +static ZCONST ush cplen2[] = +{ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, +18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, +35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, +52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65 }; +static ZCONST ush cplen3[] = +{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, +19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, +36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, +53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66 }; +static ZCONST uch extra[] = +{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +8 }; +static ZCONST ush cpdist4[] = +{ 1, 65, 129, 193, 257, 321, 385, 449, 513, 577, 641, 705, +769, 833, 897, 961, 1025, 1089, 1153, 1217, 1281, 1345, 1409, 1473, +1537, 1601, 1665, 1729, 1793, 1857, 1921, 1985, 2049, 2113, 2177, +2241, 2305, 2369, 2433, 2497, 2561, 2625, 2689, 2753, 2817, 2881, +2945, 3009, 3073, 3137, 3201, 3265, 3329, 3393, 3457, 3521, 3585, +3649, 3713, 3777, 3841, 3905, 3969, 4033 }; +static ZCONST ush cpdist8[] = +{ 1, 129, 257, 385, 513, 641, 769, 897, 1025, 1153, 1281, +1409, 1537, 1665, 1793, 1921, 2049, 2177, 2305, 2433, 2561, 2689, +2817, 2945, 3073, 3201, 3329, 3457, 3585, 3713, 3841, 3969, 4097, +4225, 4353, 4481, 4609, 4737, 4865, 4993, 5121, 5249, 5377, 5505, +5633, 5761, 5889, 6017, 6145, 6273, 6401, 6529, 6657, 6785, 6913, +7041, 7169, 7297, 7425, 7553, 7681, 7809, 7937, 8065 }; + + +/* Macros for inflate() bit peeking and grabbing. + The usage is: + NEEDBITS(j) + x = b & mask_bits[j]; + DUMPBITS(j) + where NEEDBITS makes sure that b has at least j bits in it, and + DUMPBITS removes the bits from b. The macros use the variable k + for the number of bits in b. Normally, b and k are register + variables for speed. + */ + +#define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE)<>=(n);k-=(n);} + +#define DECODEHUFT(htab, bits, mask) {\ + NEEDBITS((unsigned)(bits))\ + t = (htab) + ((~(unsigned)b)&(mask));\ + while (1) {\ + DUMPBITS(t->b)\ + if ((e=t->e) <= 32) break;\ + if (IS_INVALID_CODE(e)) return 1;\ + e &= 31;\ + NEEDBITS(e)\ + t = t->v.t + ((~(unsigned)b)&mask_bits[e]);\ + }\ +} + + +static int get_tree(__G__ l, n) +__GDEF +unsigned* l; /* bit lengths */ +unsigned n; /* number expected */ +/* Get the bit lengths for a code representation from the compressed + stream. If get_tree() returns 4, then there is an error in the data. + Otherwise zero is returned. */ +{ + unsigned i; /* bytes remaining in list */ + unsigned k; /* lengths entered */ + unsigned j; /* number of codes */ + unsigned b; /* bit length for those codes */ + + + /* get bit lengths */ + i = NEXTBYTE + 1; /* length/count pairs to read */ + k = 0; /* next code */ + do { + b = ((j = NEXTBYTE) & 0xf) + 1; /* bits in code (1..16) */ + j = ((j & 0xf0) >> 4) + 1; /* codes with those bits (1..16) */ + if (k + j > n) + return 4; /* don't overflow l[] */ + do { + l[k++] = b; + } while (--j); + } while (--i); + return k != n ? 4 : 0; /* should have read n of them */ +} + + + +static int explode_lit(__G__ tb, tl, td, bb, bl, bd, bdl) +__GDEF +struct huft* tb, * tl, * td; /* literal, length, and distance tables */ +unsigned bb, bl, bd; /* number of bits decoded by those */ +unsigned bdl; /* number of distance low bits */ +/* Decompress the imploded data using coded literals and a sliding + window (of size 2^(6+bdl) bytes). */ +{ + zusz_t s; /* bytes to decompress */ + register unsigned e; /* table entry flag/number of extra bits */ + unsigned n, d; /* length and index for copy */ + unsigned w; /* current window position */ + struct huft* t; /* pointer to table entry */ + unsigned mb, ml, md; /* masks for bb, bl, and bd bits */ + unsigned mdl; /* mask for bdl (distance lower) bits */ + register ulg b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + unsigned u; /* true if unflushed */ + int retval = 0; /* error code returned: initialized to "no error" */ + + + /* explode the coded data */ + b = k = w = 0; /* initialize bit buffer, window */ + u = 1; /* buffer unflushed */ + mb = mask_bits[bb]; /* precompute masks for speed */ + ml = mask_bits[bl]; + md = mask_bits[bd]; + mdl = mask_bits[bdl]; + s = G.lrec.ucsize; + while (s > 0) /* do until ucsize bytes uncompressed */ + { + NEEDBITS(1) + if (b & 1) /* then literal--decode it */ + { + DUMPBITS(1) + s--; + DECODEHUFT(tb, bb, mb) /* get coded literal */ + redirSlide[w++] = (uch)t->v.n; + if (w == wszimpl) + { + if ((retval = flush(__G__ redirSlide, (ulg)w, 0)) != 0) + return retval; + w = u = 0; + } + } + else /* else distance/length */ + { + DUMPBITS(1) + NEEDBITS(bdl) /* get distance low bits */ + d = (unsigned)b & mdl; + DUMPBITS(bdl) + DECODEHUFT(td, bd, md) /* get coded distance high bits */ + d = w - d - t->v.n; /* construct offset */ + DECODEHUFT(tl, bl, ml) /* get coded length */ + n = t->v.n; + if (e) /* get length extra bits */ + { + NEEDBITS(8) + n += (unsigned)b & 0xff; + DUMPBITS(8) + } + + /* do the copy */ + s = (s > (zusz_t)n ? s - (zusz_t)n : 0); + do { +#if (defined(DLL) && !defined(NO_SLIDE_REDIR)) + if (G.redirect_slide) { + /* &= w/ wszimpl not needed and wrong if redirect */ + if (d >= wszimpl) + return 1; + e = wszimpl - (d > w ? d : w); + } + else +#endif + e = wszimpl - ((d &= wszimpl - 1) > w ? d : w); + if (e > n) e = n; + n -= e; + if (u && w <= d) + { + memzero(redirSlide + w, e); + w += e; + d += e; + } + else +#ifndef NOMEMCPY + if (w - d >= e) /* (this test assumes unsigned comparison) */ + { + memcpy(redirSlide + w, redirSlide + d, e); + w += e; + d += e; + } + else /* do it slow to avoid memcpy() overlap */ +#endif /* !NOMEMCPY */ + do { + redirSlide[w++] = redirSlide[d++]; + } while (--e); + if (w == wszimpl) + { + if ((retval = flush(__G__ redirSlide, (ulg)w, 0)) != 0) + return retval; + w = u = 0; + } + } while (n); + } + } + + /* flush out redirSlide */ + if ((retval = flush(__G__ redirSlide, (ulg)w, 0)) != 0) + return retval; + if (G.csize + G.incnt + (k >> 3)) /* should have read csize bytes, but */ + { /* sometimes read one too many: k>>3 compensates */ + G.used_csize = G.lrec.csize - G.csize - G.incnt - (k >> 3); + return 5; + } + return 0; +} + + + +static int explode_nolit(__G__ tl, td, bl, bd, bdl) +__GDEF +struct huft* tl, * td; /* length and distance decoder tables */ +unsigned bl, bd; /* number of bits decoded by tl[] and td[] */ +unsigned bdl; /* number of distance low bits */ +/* Decompress the imploded data using uncoded literals and a sliding + window (of size 2^(6+bdl) bytes). */ +{ + zusz_t s; /* bytes to decompress */ + register unsigned e; /* table entry flag/number of extra bits */ + unsigned n, d; /* length and index for copy */ + unsigned w; /* current window position */ + struct huft* t; /* pointer to table entry */ + unsigned ml, md; /* masks for bl and bd bits */ + unsigned mdl; /* mask for bdl (distance lower) bits */ + register ulg b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + unsigned u; /* true if unflushed */ + int retval = 0; /* error code returned: initialized to "no error" */ + + + /* explode the coded data */ + b = k = w = 0; /* initialize bit buffer, window */ + u = 1; /* buffer unflushed */ + ml = mask_bits[bl]; /* precompute masks for speed */ + md = mask_bits[bd]; + mdl = mask_bits[bdl]; + s = G.lrec.ucsize; + while (s > 0) /* do until ucsize bytes uncompressed */ + { + NEEDBITS(1) + if (b & 1) /* then literal--get eight bits */ + { + DUMPBITS(1) + s--; + NEEDBITS(8) + redirSlide[w++] = (uch)b; + if (w == wszimpl) + { + if ((retval = flush(__G__ redirSlide, (ulg)w, 0)) != 0) + return retval; + w = u = 0; + } + DUMPBITS(8) + } + else /* else distance/length */ + { + DUMPBITS(1) + NEEDBITS(bdl) /* get distance low bits */ + d = (unsigned)b & mdl; + DUMPBITS(bdl) + DECODEHUFT(td, bd, md) /* get coded distance high bits */ + d = w - d - t->v.n; /* construct offset */ + DECODEHUFT(tl, bl, ml) /* get coded length */ + n = t->v.n; + if (e) /* get length extra bits */ + { + NEEDBITS(8) + n += (unsigned)b & 0xff; + DUMPBITS(8) + } + + /* do the copy */ + s = (s > (zusz_t)n ? s - (zusz_t)n : 0); + do { +#if (defined(DLL) && !defined(NO_SLIDE_REDIR)) + if (G.redirect_slide) { + /* &= w/ wszimpl not needed and wrong if redirect */ + if (d >= wszimpl) + return 1; + e = wszimpl - (d > w ? d : w); + } + else +#endif + e = wszimpl - ((d &= wszimpl - 1) > w ? d : w); + if (e > n) e = n; + n -= e; + if (u && w <= d) + { + memzero(redirSlide + w, e); + w += e; + d += e; + } + else +#ifndef NOMEMCPY + if (w - d >= e) /* (this test assumes unsigned comparison) */ + { + memcpy(redirSlide + w, redirSlide + d, e); + w += e; + d += e; + } + else /* do it slow to avoid memcpy() overlap */ +#endif /* !NOMEMCPY */ + do { + redirSlide[w++] = redirSlide[d++]; + } while (--e); + if (w == wszimpl) + { + if ((retval = flush(__G__ redirSlide, (ulg)w, 0)) != 0) + return retval; + w = u = 0; + } + } while (n); + } + } + + /* flush out redirSlide */ + if ((retval = flush(__G__ redirSlide, (ulg)w, 0)) != 0) + return retval; + if (G.csize + G.incnt + (k >> 3)) /* should have read csize bytes, but */ + { /* sometimes read one too many: k>>3 compensates */ + G.used_csize = G.lrec.csize - G.csize - G.incnt - (k >> 3); + return 5; + } + return 0; +} + + + +int explode(__G) +__GDEF +/* Explode an imploded compressed stream. Based on the general purpose + bit flag, decide on coded or uncoded literals, and an 8K or 4K sliding + window. Construct the literal (if any), length, and distance codes and + the tables needed to decode them (using huft_build() from inflate.c), + and call the appropriate routine for the type of data in the remainder + of the stream. The four routines are nearly identical, differing only + in whether the literal is decoded or simply read in, and in how many + bits are read in, uncoded, for the low distance bits. */ +{ + unsigned r; /* return codes */ + struct huft* tb; /* literal code table */ + struct huft* tl; /* length code table */ + struct huft* td; /* distance code table */ + unsigned bb; /* bits for tb */ + unsigned bl; /* bits for tl */ + unsigned bd; /* bits for td */ + unsigned bdl; /* number of uncoded lower distance bits */ + unsigned l[256]; /* bit lengths for codes */ + +#if (defined(DLL) && !defined(NO_SLIDE_REDIR)) + if (G.redirect_slide) + /* For 16-bit systems, it has already been checked at DLL entrance that + * the buffer size in G.redirect_size does not exceed unsigned range. + */ + G._wsize = G.redirect_size, redirSlide = G.redirect_buffer; + else +#if defined(USE_DEFLATE64) && defined(INT_16BIT) + /* For systems using 16-bit ints, reduce the used buffer size below + * the limit of "unsigned int" numbers range. + */ + G._wsize = WSIZE >> 1, redirSlide = slide; +#else /* !(USE_DEFLATE64 && INT_16BIT) */ + G._wsize = WSIZE, redirSlide = slide; +#endif /* !(USE_DEFLATE64 && INT_16BIT) */ +#endif /* DLL && !NO_SLIDE_REDIR */ + + /* Tune base table sizes. Note: I thought that to truly optimize speed, + I would have to select different bl, bd, and bb values for different + compressed file sizes. I was surprised to find out that the values of + 7, 7, and 9 worked best over a very wide range of sizes, except that + bd = 8 worked marginally better for large compressed sizes. */ + bl = 7; + bd = (G.csize + G.incnt) > 200000L ? 8 : 7; + +#ifdef DEBUG + G.hufts = 0; /* initialize huft's malloc'ed */ +#endif + + if (G.lrec.general_purpose_bit_flag & 4) + /* With literal tree--minimum match length is 3 */ + { + bb = 9; /* base table size for literals */ + if ((r = get_tree(__G__ l, 256)) != 0) + return (int)r; + if ((r = huft_build(__G__ l, 256, 256, NULL, NULL, &tb, &bb)) != 0) + { + if (r == 1) + huft_free(tb); + return (int)r; + } + if ((r = get_tree(__G__ l, 64)) != 0) { + huft_free(tb); + return (int)r; + } + if ((r = huft_build(__G__ l, 64, 0, cplen3, extra, &tl, &bl)) != 0) + { + if (r == 1) + huft_free(tl); + huft_free(tb); + return (int)r; + } + } + else + /* No literal tree--minimum match length is 2 */ + { + tb = (struct huft*)NULL; + if ((r = get_tree(__G__ l, 64)) != 0) + return (int)r; + if ((r = huft_build(__G__ l, 64, 0, cplen2, extra, &tl, &bl)) != 0) + { + if (r == 1) + huft_free(tl); + return (int)r; + } + } + + if ((r = get_tree(__G__ l, 64)) != 0) { + huft_free(tl); + if (tb != (struct huft*)NULL) huft_free(tb); + return (int)r; + } + if (G.lrec.general_purpose_bit_flag & 2) /* true if 8K */ + { + bdl = 7; + r = huft_build(__G__ l, 64, 0, cpdist8, extra, &td, &bd); + } + else /* else 4K */ + { + bdl = 6; + r = huft_build(__G__ l, 64, 0, cpdist4, extra, &td, &bd); + } + if (r != 0) + { + if (r == 1) + huft_free(td); + huft_free(tl); + if (tb != (struct huft*)NULL) huft_free(tb); + return (int)r; + } + + if (tb != NULL) { + r = explode_lit(__G__ tb, tl, td, bb, bl, bd, bdl); + huft_free(tb); + } + else { + r = explode_nolit(__G__ tl, td, bl, bd, bdl); + } + + huft_free(td); + huft_free(tl); + Trace((stderr, "<%u > ", G.hufts)); + return (int)r; +} + +/* so explode.c and inflate.c can be compiled together into one object: */ +#undef DECODEHUFT +#undef NEEDBITS +#undef DUMPBITS +#undef wszimpl \ No newline at end of file diff --git a/SabreTools.FileTypes/Compress/ZipFile/ZLib/Deflate.cs b/SabreTools.FileTypes/Compress/ZipFile/ZLib/Deflate.cs index ad956c1d..83830228 100644 --- a/SabreTools.FileTypes/Compress/ZipFile/ZLib/Deflate.cs +++ b/SabreTools.FileTypes/Compress/ZipFile/ZLib/Deflate.cs @@ -157,14 +157,14 @@ namespace Compress.ZipFile.ZLib { "need dictionary", "stream end", - string.Empty, + "", "file error", "stream error", "data error", "insufficient memory", "buffer error", "incompatible version", - string.Empty + "" }; // preset dictionary flag in zlib header @@ -545,10 +545,10 @@ namespace Compress.ZipFile.ZLib internal void send_tree(short[] tree, int max_code) { int n; // iterates over all tree elements - int prevlen = -1; // last emitted length + int prevlen = -1; // last emitted length int curlen; // length of current code - int nextlen = tree[0 * 2 + 1]; // length of next code - int count = 0; // repeat count of the current code + int nextlen = tree[0 * 2 + 1]; // length of next code + int count = 0; // repeat count of the current code int max_count = 7; // max repeat count int min_count = 4; // min repeat count @@ -729,7 +729,7 @@ namespace Compress.ZipFile.ZLib * * * this code is not turned on by default in ZLIB Trrntzip code * * * - * ************************************************************* + * ************************************************************* */ if (false) //CompSettings { diff --git a/SabreTools.FileTypes/Compress/ZipFile/ZLib/InfTree.cs b/SabreTools.FileTypes/Compress/ZipFile/ZLib/InfTree.cs index 502d497a..587f9c10 100644 --- a/SabreTools.FileTypes/Compress/ZipFile/ZLib/InfTree.cs +++ b/SabreTools.FileTypes/Compress/ZipFile/ZLib/InfTree.cs @@ -1,45 +1,45 @@ // Inftree.cs // ------------------------------------------------------------------ // -// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. +// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. // All rights reserved. // // This code module is part of DotNetZip, a zipfile class library. // // ------------------------------------------------------------------ // -// This code is licensed under the Microsoft Public License. +// This code is licensed under the Microsoft Public License. // See the file License.txt for the license details. // More info on: http://dotnetzip.codeplex.com // // ------------------------------------------------------------------ // -// last saved (in emacs): +// last saved (in emacs): // Time-stamp: <2009-October-28 12:43:54> // // ------------------------------------------------------------------ // // This module defines classes used in decompression. This code is derived -// from the jzlib implementation of zlib. In keeping with the license for jzlib, +// from the jzlib implementation of zlib. In keeping with the license for jzlib, // the copyright to that code is below. // // ------------------------------------------------------------------ -// +// // Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in // the documentation and/or other materials provided with the distribution. -// +// // 3. The names of the authors may not be used to endorse or promote products // derived from this software without specific prior written permission. -// +// // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, @@ -50,7 +50,7 @@ // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // ----------------------------------------------------------------------- // // This program is based on zlib-1.1.3; credit to authors @@ -64,373 +64,373 @@ using System; namespace Compress.ZipFile.ZLib { - - sealed class InfTree - { - - private const int MANY = 1440; - - private const int Z_OK = 0; - private const int Z_STREAM_END = 1; - private const int Z_NEED_DICT = 2; - private const int Z_ERRNO = -1; - private const int Z_STREAM_ERROR = -2; - private const int Z_DATA_ERROR = -3; - private const int Z_MEM_ERROR = -4; - private const int Z_BUF_ERROR = -5; - private const int Z_VERSION_ERROR = -6; - - internal const int fixed_bl = 9; - internal const int fixed_bd = 5; - - //UPGRADE_NOTE: Final was removed from the declaration of 'fixed_tl'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - internal static readonly int[] fixed_tl = new int[]{96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 176, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 216, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 236, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 162, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186, - 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 190, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 193, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 209, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 249, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 229, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 181, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 221, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, 0, 8, - 14, 0, 8, 142, 0, 8, 78, 0, 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 147, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 235, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 167, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 183, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 207, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255}; - //UPGRADE_NOTE: Final was removed from the declaration of 'fixed_td'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - internal static readonly int[] fixed_td = new int[] { 80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5, 8193, 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5, 24577, 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577 }; - - // Tables for deflate from PKZIP's appnote.txt. - //UPGRADE_NOTE: Final was removed from the declaration of 'cplens'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - internal static readonly int[] cplens = new int[] { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 }; - - // see note #13 above about 258 - //UPGRADE_NOTE: Final was removed from the declaration of 'cplext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - internal static readonly int[] cplext = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 }; - - //UPGRADE_NOTE: Final was removed from the declaration of 'cpdist'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - internal static readonly int[] cpdist = new int[] { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 }; - - //UPGRADE_NOTE: Final was removed from the declaration of 'cpdext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - internal static readonly int[] cpdext = new int[] { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 }; - - // If BMAX needs to be larger than 16, then h and x[] should be uLong. - internal const int BMAX = 15; // maximum bit length of any code - - internal int[] hn = null; // hufts used in space - internal int[] v = null; // work area for huft_build - internal int[] c = null; // bit length count table - internal int[] r = null; // table entry for structure assignment - internal int[] u = null; // table stack - internal int[] x = null; // bit offsets, then code stack - - private int huft_build(int[] b, int bindex, int n, int s, int[] d, int[] e, int[] t, int[] m, int[] hp, int[] hn, int[] v) + + sealed class InfTree { - // Given a list of code lengths and a maximum table size, make a set of - // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR - // if the given code set is incomplete (the tables are still built in this - // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of - // lengths), or Z_MEM_ERROR if not enough memory. - - int a; // counter for codes of length k - int f; // i repeats in table every f entries - int g; // maximum code length - int h; // table level - int i; // counter, current code - int j; // counter - int k; // number of bits in current code - int l; // bits per table (returned in m) - int mask; // (1 << w) - 1, to avoid cc -O bug on HP - int p; // pointer into c[], b[], or v[] - int q; // points to current table - int w; // bits before this table == (l * h) - int xp; // pointer into x - int y; // number of dummy codes added - int z; // number of entries in current table - - // Generate counts for each bit length - - p = 0; i = n; - do - { - c[b[bindex + p]]++; p++; i--; // assume all entries <= BMAX - } - while (i != 0); - - if (c[0] == n) - { - // null input--all zero length codes - t[0] = -1; - m[0] = 0; - return Z_OK; - } - - // Find minimum and maximum length, bound *m by those - l = m[0]; - for (j = 1; j <= BMAX; j++) - if (c[j] != 0) - break; - k = j; // minimum code length - if (l < j) - { - l = j; - } - for (i = BMAX; i != 0; i--) - { - if (c[i] != 0) - break; - } - g = i; // maximum code length - if (l > i) - { - l = i; - } - m[0] = l; - - // Adjust last length count to fill out codes, if needed - for (y = 1 << j; j < i; j++, y <<= 1) - { - if ((y -= c[j]) < 0) + + private const int MANY = 1440; + + private const int Z_OK = 0; + private const int Z_STREAM_END = 1; + private const int Z_NEED_DICT = 2; + private const int Z_ERRNO = - 1; + private const int Z_STREAM_ERROR = - 2; + private const int Z_DATA_ERROR = - 3; + private const int Z_MEM_ERROR = - 4; + private const int Z_BUF_ERROR = - 5; + private const int Z_VERSION_ERROR = - 6; + + internal const int fixed_bl = 9; + internal const int fixed_bd = 5; + + //UPGRADE_NOTE: Final was removed from the declaration of 'fixed_tl'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + internal static readonly int[] fixed_tl = new int[]{96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 176, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 216, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 236, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 162, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186, + 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 190, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 193, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 209, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 249, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 229, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 181, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 221, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, 0, 8, + 14, 0, 8, 142, 0, 8, 78, 0, 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 147, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 235, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 167, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 183, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 207, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255}; + //UPGRADE_NOTE: Final was removed from the declaration of 'fixed_td'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + internal static readonly int[] fixed_td = new int[]{80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5, 8193, 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5, 24577, 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577}; + + // Tables for deflate from PKZIP's appnote.txt. + //UPGRADE_NOTE: Final was removed from the declaration of 'cplens'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + internal static readonly int[] cplens = new int[]{3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + + // see note #13 above about 258 + //UPGRADE_NOTE: Final was removed from the declaration of 'cplext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + internal static readonly int[] cplext = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; + + //UPGRADE_NOTE: Final was removed from the declaration of 'cpdist'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + internal static readonly int[] cpdist = new int[]{1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; + + //UPGRADE_NOTE: Final was removed from the declaration of 'cpdext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + internal static readonly int[] cpdext = new int[]{0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; + + // If BMAX needs to be larger than 16, then h and x[] should be uLong. + internal const int BMAX = 15; // maximum bit length of any code + + internal int[] hn = null; // hufts used in space + internal int[] v = null; // work area for huft_build + internal int[] c = null; // bit length count table + internal int[] r = null; // table entry for structure assignment + internal int[] u = null; // table stack + internal int[] x = null; // bit offsets, then code stack + + private int huft_build(int[] b, int bindex, int n, int s, int[] d, int[] e, int[] t, int[] m, int[] hp, int[] hn, int[] v) { - return Z_DATA_ERROR; - } - } - if ((y -= c[i]) < 0) - { - return Z_DATA_ERROR; - } - c[i] += y; - - // Generate starting offsets into the value table for each length - x[1] = j = 0; - p = 1; xp = 2; - while (--i != 0) - { - // note that i == g from above - x[xp] = (j += c[p]); - xp++; - p++; - } - - // Make a table of values in order of bit lengths - i = 0; p = 0; - do - { - if ((j = b[bindex + p]) != 0) - { - v[x[j]++] = i; - } - p++; - } - while (++i < n); - n = x[g]; // set n to length of v - - // Generate the Huffman codes and for each, make the table entries - x[0] = i = 0; // first Huffman code is zero - p = 0; // grab values in bit order - h = -1; // no tables yet--level -1 - w = -l; // bits decoded == (l * h) - u[0] = 0; // just to keep compilers happy - q = 0; // ditto - z = 0; // ditto - - // go through the bit lengths (k already is bits in shortest code) - for (; k <= g; k++) - { - a = c[k]; - while (a-- != 0) - { - // here i is the Huffman code of length k bits for value *p - // make tables up to required level - while (k > w + l) - { - h++; - w += l; // previous table always l bits - // compute minimum size table less than or equal to l bits - z = g - w; - z = (z > l) ? l : z; // table size upper limit - if ((f = 1 << (j = k - w)) > a + 1) + // Given a list of code lengths and a maximum table size, make a set of + // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + // if the given code set is incomplete (the tables are still built in this + // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of + // lengths), or Z_MEM_ERROR if not enough memory. + + int a; // counter for codes of length k + int f; // i repeats in table every f entries + int g; // maximum code length + int h; // table level + int i; // counter, current code + int j; // counter + int k; // number of bits in current code + int l; // bits per table (returned in m) + int mask; // (1 << w) - 1, to avoid cc -O bug on HP + int p; // pointer into c[], b[], or v[] + int q; // points to current table + int w; // bits before this table == (l * h) + int xp; // pointer into x + int y; // number of dummy codes added + int z; // number of entries in current table + + // Generate counts for each bit length + + p = 0; i = n; + do { - // try a k-w bit table - // too few codes for k-w bit table - f -= (a + 1); // deduct codes from patterns left - xp = k; - if (j < z) - { - while (++j < z) + c[b[bindex + p]]++; p++; i--; // assume all entries <= BMAX + } + while (i != 0); + + if (c[0] == n) + { + // null input--all zero length codes + t[0] = - 1; + m[0] = 0; + return Z_OK; + } + + // Find minimum and maximum length, bound *m by those + l = m[0]; + for (j = 1; j <= BMAX; j++) + if (c[j] != 0) + break; + k = j; // minimum code length + if (l < j) + { + l = j; + } + for (i = BMAX; i != 0; i--) + { + if (c[i] != 0) + break; + } + g = i; // maximum code length + if (l > i) + { + l = i; + } + m[0] = l; + + // Adjust last length count to fill out codes, if needed + for (y = 1 << j; j < i; j++, y <<= 1) + { + if ((y -= c[j]) < 0) { - // try smaller tables up to z bits - if ((f <<= 1) <= c[++xp]) - break; // enough codes to use up j bits - f -= c[xp]; // else deduct codes from patterns + return Z_DATA_ERROR; } - } } - z = 1 << j; // table entries for j-bit table - - // allocate new table - if (hn[0] + z > MANY) + if ((y -= c[i]) < 0) { - // (note: doesn't matter for fixed) - return Z_DATA_ERROR; // overflow of MANY + return Z_DATA_ERROR; } - u[h] = q = hn[0]; // DEBUG - hn[0] += z; - - // connect to last table, if there is one - if (h != 0) + c[i] += y; + + // Generate starting offsets into the value table for each length + x[1] = j = 0; + p = 1; xp = 2; + while (--i != 0) { - x[h] = i; // save pattern for backing up - r[0] = (sbyte)j; // bits in this table - r[1] = (sbyte)l; // bits to dump before this table - j = SharedUtils.URShift(i, (w - l)); - r[2] = (int)(q - u[h - 1] - j); // offset to this table - Array.Copy(r, 0, hp, (u[h - 1] + j) * 3, 3); // connect to last table + // note that i == g from above + x[xp] = (j += c[p]); + xp++; + p++; + } + + // Make a table of values in order of bit lengths + i = 0; p = 0; + do + { + if ((j = b[bindex + p]) != 0) + { + v[x[j]++] = i; + } + p++; + } + while (++i < n); + n = x[g]; // set n to length of v + + // Generate the Huffman codes and for each, make the table entries + x[0] = i = 0; // first Huffman code is zero + p = 0; // grab values in bit order + h = - 1; // no tables yet--level -1 + w = - l; // bits decoded == (l * h) + u[0] = 0; // just to keep compilers happy + q = 0; // ditto + z = 0; // ditto + + // go through the bit lengths (k already is bits in shortest code) + for (; k <= g; k++) + { + a = c[k]; + while (a-- != 0) + { + // here i is the Huffman code of length k bits for value *p + // make tables up to required level + while (k > w + l) + { + h++; + w += l; // previous table always l bits + // compute minimum size table less than or equal to l bits + z = g - w; + z = (z > l)?l:z; // table size upper limit + if ((f = 1 << (j = k - w)) > a + 1) + { + // try a k-w bit table + // too few codes for k-w bit table + f -= (a + 1); // deduct codes from patterns left + xp = k; + if (j < z) + { + while (++j < z) + { + // try smaller tables up to z bits + if ((f <<= 1) <= c[++xp]) + break; // enough codes to use up j bits + f -= c[xp]; // else deduct codes from patterns + } + } + } + z = 1 << j; // table entries for j-bit table + + // allocate new table + if (hn[0] + z > MANY) + { + // (note: doesn't matter for fixed) + return Z_DATA_ERROR; // overflow of MANY + } + u[h] = q = hn[0]; // DEBUG + hn[0] += z; + + // connect to last table, if there is one + if (h != 0) + { + x[h] = i; // save pattern for backing up + r[0] = (sbyte) j; // bits in this table + r[1] = (sbyte) l; // bits to dump before this table + j = SharedUtils.URShift(i, (w - l)); + r[2] = (int) (q - u[h - 1] - j); // offset to this table + Array.Copy(r, 0, hp, (u[h - 1] + j) * 3, 3); // connect to last table + } + else + { + t[0] = q; // first table is returned result + } + } + + // set up table entry in r + r[1] = (sbyte) (k - w); + if (p >= n) + { + r[0] = 128 + 64; // out of values--invalid code + } + else if (v[p] < s) + { + r[0] = (sbyte) (v[p] < 256?0:32 + 64); // 256 is end-of-block + r[2] = v[p++]; // simple code is just the value + } + else + { + r[0] = (sbyte) (e[v[p] - s] + 16 + 64); // non-simple--look up in lists + r[2] = d[v[p++] - s]; + } + + // fill code-like entries with r + f = 1 << (k - w); + for (j = SharedUtils.URShift(i, w); j < z; j += f) + { + Array.Copy(r, 0, hp, (q + j) * 3, 3); + } + + // backwards increment the k-bit code i + for (j = 1 << (k - 1); (i & j) != 0; j = SharedUtils.URShift(j, 1)) + { + i ^= j; + } + i ^= j; + + // backup over finished tables + mask = (1 << w) - 1; // needed on HP, cc -O bug + while ((i & mask) != x[h]) + { + h--; // don't need to update q + w -= l; + mask = (1 << w) - 1; + } + } + } + // Return Z_BUF_ERROR if we were given an incomplete table + return y != 0 && g != 1?Z_BUF_ERROR:Z_OK; + } + + internal int inflate_trees_bits(int[] c, int[] bb, int[] tb, int[] hp, ZlibCodec z) + { + int result; + initWorkArea(19); + hn[0] = 0; + result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); + + if (result == Z_DATA_ERROR) + { + z.Message = "oversubscribed dynamic bit lengths tree"; + } + else if (result == Z_BUF_ERROR || bb[0] == 0) + { + z.Message = "incomplete dynamic bit lengths tree"; + result = Z_DATA_ERROR; + } + return result; + } + + internal int inflate_trees_dynamic(int nl, int nd, int[] c, int[] bl, int[] bd, int[] tl, int[] td, int[] hp, ZlibCodec z) + { + int result; + + // build literal/length tree + initWorkArea(288); + hn[0] = 0; + result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); + if (result != Z_OK || bl[0] == 0) + { + if (result == Z_DATA_ERROR) + { + z.Message = "oversubscribed literal/length tree"; + } + else if (result != Z_MEM_ERROR) + { + z.Message = "incomplete literal/length tree"; + result = Z_DATA_ERROR; + } + return result; + } + + // build distance tree + initWorkArea(288); + result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); + + if (result != Z_OK || (bd[0] == 0 && nl > 257)) + { + if (result == Z_DATA_ERROR) + { + z.Message = "oversubscribed distance tree"; + } + else if (result == Z_BUF_ERROR) + { + z.Message = "incomplete distance tree"; + result = Z_DATA_ERROR; + } + else if (result != Z_MEM_ERROR) + { + z.Message = "empty distance tree with lengths"; + result = Z_DATA_ERROR; + } + return result; + } + + return Z_OK; + } + + internal static int inflate_trees_fixed(int[] bl, int[] bd, int[][] tl, int[][] td, ZlibCodec z) + { + bl[0] = fixed_bl; + bd[0] = fixed_bd; + tl[0] = fixed_tl; + td[0] = fixed_td; + return Z_OK; + } + + private void initWorkArea(int vsize) + { + if (hn == null) + { + hn = new int[1]; + v = new int[vsize]; + c = new int[BMAX + 1]; + r = new int[3]; + u = new int[BMAX]; + x = new int[BMAX + 1]; } else { - t[0] = q; // first table is returned result + if (v.Length < vsize) + { + v = new int[vsize]; + } + Array.Clear(v,0,vsize); + Array.Clear(c,0,BMAX+1); + r[0]=0; r[1]=0; r[2]=0; + // for(int i=0; i= n) - { - r[0] = 128 + 64; // out of values--invalid code - } - else if (v[p] < s) - { - r[0] = (sbyte)(v[p] < 256 ? 0 : 32 + 64); // 256 is end-of-block - r[2] = v[p++]; // simple code is just the value - } - else - { - r[0] = (sbyte)(e[v[p] - s] + 16 + 64); // non-simple--look up in lists - r[2] = d[v[p++] - s]; - } - - // fill code-like entries with r - f = 1 << (k - w); - for (j = SharedUtils.URShift(i, w); j < z; j += f) - { - Array.Copy(r, 0, hp, (q + j) * 3, 3); - } - - // backwards increment the k-bit code i - for (j = 1 << (k - 1); (i & j) != 0; j = SharedUtils.URShift(j, 1)) - { - i ^= j; - } - i ^= j; - - // backup over finished tables - mask = (1 << w) - 1; // needed on HP, cc -O bug - while ((i & mask) != x[h]) - { - h--; // don't need to update q - w -= l; - mask = (1 << w) - 1; - } } - } - // Return Z_BUF_ERROR if we were given an incomplete table - return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; } - - internal int inflate_trees_bits(int[] c, int[] bb, int[] tb, int[] hp, ZlibCodec z) - { - int result; - initWorkArea(19); - hn[0] = 0; - result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); - - if (result == Z_DATA_ERROR) - { - z.Message = "oversubscribed dynamic bit lengths tree"; - } - else if (result == Z_BUF_ERROR || bb[0] == 0) - { - z.Message = "incomplete dynamic bit lengths tree"; - result = Z_DATA_ERROR; - } - return result; - } - - internal int inflate_trees_dynamic(int nl, int nd, int[] c, int[] bl, int[] bd, int[] tl, int[] td, int[] hp, ZlibCodec z) - { - int result; - - // build literal/length tree - initWorkArea(288); - hn[0] = 0; - result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); - if (result != Z_OK || bl[0] == 0) - { - if (result == Z_DATA_ERROR) - { - z.Message = "oversubscribed literal/length tree"; - } - else if (result != Z_MEM_ERROR) - { - z.Message = "incomplete literal/length tree"; - result = Z_DATA_ERROR; - } - return result; - } - - // build distance tree - initWorkArea(288); - result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); - - if (result != Z_OK || (bd[0] == 0 && nl > 257)) - { - if (result == Z_DATA_ERROR) - { - z.Message = "oversubscribed distance tree"; - } - else if (result == Z_BUF_ERROR) - { - z.Message = "incomplete distance tree"; - result = Z_DATA_ERROR; - } - else if (result != Z_MEM_ERROR) - { - z.Message = "empty distance tree with lengths"; - result = Z_DATA_ERROR; - } - return result; - } - - return Z_OK; - } - - internal static int inflate_trees_fixed(int[] bl, int[] bd, int[][] tl, int[][] td, ZlibCodec z) - { - bl[0] = fixed_bl; - bd[0] = fixed_bd; - tl[0] = fixed_tl; - td[0] = fixed_td; - return Z_OK; - } - - private void initWorkArea(int vsize) - { - if (hn == null) - { - hn = new int[1]; - v = new int[vsize]; - c = new int[BMAX + 1]; - r = new int[3]; - u = new int[BMAX]; - x = new int[BMAX + 1]; - } - else - { - if (v.Length < vsize) - { - v = new int[vsize]; - } - Array.Clear(v, 0, vsize); - Array.Clear(c, 0, BMAX + 1); - r[0] = 0; r[1] = 0; r[2] = 0; - // for(int i=0; i> 16) & 0xffff) != (b & 0xffff)) + if ( ( ((~b)>>16) & 0xffff) != (b & 0xffff)) { mode = InflateBlockMode.BAD; _codec.Message = "invalid stored block lengths"; @@ -533,7 +533,7 @@ namespace Compress.ZipFile.ZLib return Flush(r); } - c = (c == 16) ? blens[i - 1] : 0; + c = (c == 16) ? blens[i-1] : 0; do { blens[i++] = c; @@ -679,9 +679,9 @@ namespace Compress.ZipFile.ZLib { int nBytes; - for (int pass = 0; pass < 2; pass++) + for (int pass=0; pass < 2; pass++) { - if (pass == 0) + if (pass==0) { // compute number of bytes to copy as far as end of window nBytes = (int)((readAt <= writeAt ? writeAt : end) - readAt); @@ -752,15 +752,15 @@ namespace Compress.ZipFile.ZLib // waiting for "i:"=input, // "o:"=output, // "x:"=nothing - private const int START = 0; // x: set up for LEN - private const int LEN = 1; // i: get length/literal/eob next - private const int LENEXT = 2; // i: getting length extra (have base) - private const int DIST = 3; // i: get distance next + private const int START = 0; // x: set up for LEN + private const int LEN = 1; // i: get length/literal/eob next + private const int LENEXT = 2; // i: getting length extra (have base) + private const int DIST = 3; // i: get distance next private const int DISTEXT = 4; // i: getting distance extra - private const int COPY = 5; // o: copying bytes in window, waiting for space - private const int LIT = 6; // o: got literal, waiting for output space - private const int WASH = 7; // o: got eob, possibly still output waiting - private const int END = 8; // x: got eob and all data flushed + private const int COPY = 5; // o: copying bytes in window, waiting for space + private const int LIT = 6; // o: got literal, waiting for output space + private const int WASH = 7; // o: got eob, possibly still output waiting + private const int END = 8; // x: got eob and all data flushed private const int BADCODE = 9; // x: got error internal int mode; // current inflate_codes mode @@ -1413,19 +1413,19 @@ namespace Compress.ZipFile.ZLib private enum InflateManagerMode { METHOD = 0, // waiting for method byte - FLAG = 1, // waiting for flag byte - DICT4 = 2, // four dictionary check bytes to go - DICT3 = 3, // three dictionary check bytes to go - DICT2 = 4, // two dictionary check bytes to go - DICT1 = 5, // one dictionary check byte to go - DICT0 = 6, // waiting for inflateSetDictionary + FLAG = 1, // waiting for flag byte + DICT4 = 2, // four dictionary check bytes to go + DICT3 = 3, // three dictionary check bytes to go + DICT2 = 4, // two dictionary check bytes to go + DICT1 = 5, // one dictionary check byte to go + DICT0 = 6, // waiting for inflateSetDictionary BLOCKS = 7, // decompressing blocks CHECK4 = 8, // four check bytes to go CHECK3 = 9, // three check bytes to go CHECK2 = 10, // two check bytes to go CHECK1 = 11, // one check byte to go - DONE = 12, // finished check, done - BAD = 13, // got an error--stay here + DONE = 12, // finished check, done + BAD = 13, // got an error--stay here } private InflateManagerMode mode; // current inflate mode @@ -1518,9 +1518,9 @@ namespace Compress.ZipFile.ZLib if (_codec.InputBuffer == null) throw new ZlibException("InputBuffer is null. "); - // int f = (flush == FlushType.Finish) - // ? ZlibConstants.Z_BUF_ERROR - // : ZlibConstants.Z_OK; +// int f = (flush == FlushType.Finish) +// ? ZlibConstants.Z_BUF_ERROR +// : ZlibConstants.Z_OK; // workitem 8870 int f = ZlibConstants.Z_OK; diff --git a/SabreTools.FileTypes/Compress/ZipFile/ZLib/Tree.cs b/SabreTools.FileTypes/Compress/ZipFile/ZLib/Tree.cs index b639b67f..98441bd7 100644 --- a/SabreTools.FileTypes/Compress/ZipFile/ZLib/Tree.cs +++ b/SabreTools.FileTypes/Compress/ZipFile/ZLib/Tree.cs @@ -1,20 +1,20 @@ // Tree.cs // ------------------------------------------------------------------ // -// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. +// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. // All rights reserved. // // This code module is part of DotNetZip, a zipfile class library. // // ------------------------------------------------------------------ // -// This code is licensed under the Microsoft Public License. +// This code is licensed under the Microsoft Public License. // See the file License.txt for the license details. // More info on: http://dotnetzip.codeplex.com // // ------------------------------------------------------------------ // -// last saved (in emacs): +// last saved (in emacs): // Time-stamp: <2009-October-28 13:29:50> // // ------------------------------------------------------------------ @@ -25,22 +25,22 @@ // code is below. // // ------------------------------------------------------------------ -// +// // Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in // the documentation and/or other materials provided with the distribution. -// +// // 3. The names of the authors may not be used to endorse or promote products // derived from this software without specific prior written permission. -// +// // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, @@ -51,7 +51,7 @@ // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // ----------------------------------------------------------------------- // // This program is based on zlib-1.1.3; credit to authors @@ -66,72 +66,72 @@ namespace Compress.ZipFile.ZLib sealed class Tree { private static readonly int HEAP_SIZE = (2 * InternalConstants.L_CODES + 1); - + // extra bits for each length code internal static readonly int[] ExtraLengthBits = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 }; - + // extra bits for each distance code internal static readonly int[] ExtraDistanceBits = new int[] { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 }; - + // extra bits for each bit length code - internal static readonly int[] extra_blbits = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7 }; - - internal static readonly sbyte[] bl_order = new sbyte[] { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; - - + internal static readonly int[] extra_blbits = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; + + internal static readonly sbyte[] bl_order = new sbyte[]{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + // The lengths of the bit length codes are sent in order of decreasing // probability, to avoid transmitting the lengths for unused bit // length codes. - + internal const int Buf_size = 8 * 2; - + // see definition of array dist_code below //internal const int DIST_CODE_LEN = 512; - + private static readonly sbyte[] _dist_code = new sbyte[] { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 0, 0, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, - 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 0, 0, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, + 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 }; - + internal static readonly sbyte[] LengthCode = new sbyte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, @@ -151,14 +151,14 @@ namespace Compress.ZipFile.ZLib 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 }; - + internal static readonly int[] LengthBase = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0 }; - + internal static readonly int[] DistanceBase = new int[] { @@ -166,11 +166,11 @@ namespace Compress.ZipFile.ZLib 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 }; - + /// /// Map from a distance to a distance code. /// - /// + /// /// No side effects. _dist_code[256] and _dist_code[257] are never used. /// internal static int DistanceCode(int dist) @@ -183,7 +183,7 @@ namespace Compress.ZipFile.ZLib internal short[] dyn_tree; // the dynamic tree internal int max_code; // largest code with non zero frequency internal StaticTree staticTree; // the corresponding static tree - + // Compute the optimal bit lengths for a tree and update the total bit length // for the current block. // IN assertion: the fields freq and dad are set, heap[heap_max] and @@ -192,7 +192,7 @@ namespace Compress.ZipFile.ZLib // array bl_count contains the frequencies for each bit length. // The length opt_len is updated; static_len is also updated if stree is // not null. - internal void gen_bitlen(DeflateManager s) + internal void gen_bitlen(DeflateManager s) { short[] tree = dyn_tree; short[] stree = staticTree.treeCodes; @@ -205,14 +205,14 @@ namespace Compress.ZipFile.ZLib int xbits; // extra bits short f; // frequency int overflow = 0; // number of elements with bit length too large - + for (bits = 0; bits <= InternalConstants.MAX_BITS; bits++) s.bl_count[bits] = 0; - + // In a first pass, compute the optimal bit lengths (which may // overflow in the case of the bit length tree). tree[s.heap[s.heap_max] * 2 + 1] = 0; // root of the heap - + for (h = s.heap_max + 1; h < HEAP_SIZE; h++) { n = s.heap[h]; @@ -221,12 +221,12 @@ namespace Compress.ZipFile.ZLib { bits = max_length; overflow++; } - tree[n * 2 + 1] = (short)bits; + tree[n * 2 + 1] = (short) bits; // We overwrite tree[n*2+1] which is no longer needed - + if (n > max_code) continue; // not a leaf node - + s.bl_count[bits]++; xbits = 0; if (n >= base_Renamed) @@ -237,24 +237,24 @@ namespace Compress.ZipFile.ZLib s.static_len += f * (stree[n * 2 + 1] + xbits); } if (overflow == 0) - return; - + return ; + // This happens for example on obj2 and pic of the Calgary corpus // Find the first bit length which could increase: - do + do { bits = max_length - 1; while (s.bl_count[bits] == 0) bits--; s.bl_count[bits]--; // move one leaf down the tree - s.bl_count[bits + 1] = (short)(s.bl_count[bits + 1] + 2); // move one overflow item as its brother + s.bl_count[bits + 1] = (short) (s.bl_count[bits + 1] + 2); // move one overflow item as its brother s.bl_count[max_length]--; // The brother of the overflow item also moves one step up, // but this does not affect bl_count[max_length] overflow -= 2; } while (overflow > 0); - + for (bits = max_length; bits != 0; bits--) { n = s.bl_count[bits]; @@ -265,35 +265,35 @@ namespace Compress.ZipFile.ZLib continue; if (tree[m * 2 + 1] != bits) { - s.opt_len = (int)(s.opt_len + ((long)bits - (long)tree[m * 2 + 1]) * (long)tree[m * 2]); - tree[m * 2 + 1] = (short)bits; + s.opt_len = (int) (s.opt_len + ((long) bits - (long) tree[m * 2 + 1]) * (long) tree[m * 2]); + tree[m * 2 + 1] = (short) bits; } n--; } } } - + // Construct one Huffman tree and assigns the code bit strings and lengths. // Update the total bit length for the current block. // IN assertion: the field freq is set for all tree elements. // OUT assertions: the fields len and code are set to the optimal bit length // and corresponding code. The length opt_len is updated; static_len is // also updated if stree is not null. The field max_code is set. - internal void build_tree(DeflateManager s) + internal void build_tree(DeflateManager s) { - short[] tree = dyn_tree; + short[] tree = dyn_tree; short[] stree = staticTree.treeCodes; - int elems = staticTree.elems; + int elems = staticTree.elems; int n, m; // iterate over heap elements - int max_code = -1; // largest code with non zero frequency + int max_code = -1; // largest code with non zero frequency int node; // new node being created - + // Construct the initial heap, with least frequent element in // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. // heap[0] is not used. s.heap_len = 0; s.heap_max = HEAP_SIZE; - + for (n = 0; n < elems; n++) { if (tree[n * 2] != 0) @@ -306,14 +306,14 @@ namespace Compress.ZipFile.ZLib tree[n * 2 + 1] = 0; } } - + // The pkzip format requires that at least one distance code exists, // and that at least one bit should be sent even if there is only one // possible code. So to avoid special checks later on we force at least // two codes of non zero frequency. while (s.heap_len < 2) { - node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0); + node = s.heap[++s.heap_len] = (max_code < 2?++max_code:0); tree[node * 2] = 1; s.depth[node] = 0; s.opt_len--; @@ -322,94 +322,93 @@ namespace Compress.ZipFile.ZLib // node is 0 or 1 so it does not have extra bits } this.max_code = max_code; - + // The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, // establish sub-heaps of increasing lengths: - + for (n = s.heap_len / 2; n >= 1; n--) s.pqdownheap(tree, n); - + // Construct the Huffman tree by repeatedly combining the least two // frequent nodes. - + node = elems; // next internal node of the tree - do + do { // n = node of least frequency n = s.heap[1]; s.heap[1] = s.heap[s.heap_len--]; s.pqdownheap(tree, 1); m = s.heap[1]; // m = node of next least frequency - + s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency s.heap[--s.heap_max] = m; - + // Create a new node father of n and m - tree[node * 2] = unchecked((short)(tree[n * 2] + tree[m * 2])); - s.depth[node] = (sbyte)(System.Math.Max((byte)s.depth[n], (byte)s.depth[m]) + 1); - tree[n * 2 + 1] = tree[m * 2 + 1] = (short)node; - + tree[node * 2] = unchecked((short) (tree[n * 2] + tree[m * 2])); + s.depth[node] = (sbyte) (System.Math.Max((byte) s.depth[n], (byte) s.depth[m]) + 1); + tree[n * 2 + 1] = tree[m * 2 + 1] = (short) node; + // and insert the new node in the heap s.heap[1] = node++; s.pqdownheap(tree, 1); } while (s.heap_len >= 2); - + s.heap[--s.heap_max] = s.heap[1]; - + // At this point, the fields freq and dad are set. We can now // generate the bit lengths. - + gen_bitlen(s); - + // The field len is now set, we can generate the bit codes gen_codes(tree, max_code, s.bl_count); } - + // Generate the codes for a given tree and bit counts (which need not be // optimal). // IN assertion: the array bl_count contains the bit length statistics for // the given tree and the field len is set for all tree elements. // OUT assertion: the field code is set for all tree elements of non // zero code length. - internal static void gen_codes(short[] tree, int max_code, short[] bl_count) + internal static void gen_codes(short[] tree, int max_code, short[] bl_count) { short[] next_code = new short[InternalConstants.MAX_BITS + 1]; // next code value for each bit length short code = 0; // running code value int bits; // bit index int n; // code index - + // The distribution counts are first used to generate the code values // without bit reversal. for (bits = 1; bits <= InternalConstants.MAX_BITS; bits++) - unchecked - { - next_code[bits] = code = (short)((code + bl_count[bits - 1]) << 1); + unchecked { + next_code[bits] = code = (short) ((code + bl_count[bits - 1]) << 1); } - + // Check that the bit counts in bl_count are consistent. The last code // must be all ones. //Assert (code + bl_count[MAX_BITS]-1 == (1<>= 1; //SharedUtils.URShift(code, 1); diff --git a/SabreTools.FileTypes/Compress/ZipFile/ZLib/Zlib.cs b/SabreTools.FileTypes/Compress/ZipFile/ZLib/Zlib.cs index f2da1fd9..368a0455 100644 --- a/SabreTools.FileTypes/Compress/ZipFile/ZLib/Zlib.cs +++ b/SabreTools.FileTypes/Compress/ZipFile/ZLib/Zlib.cs @@ -145,7 +145,7 @@ namespace Compress.ZipFile.ZLib /// If you are producing ZIPs for use on Mac OSX, be aware that archives produced with CompressionLevel.None /// cannot be opened with the default zip reader. Use a different CompressionLevel. /// - None = 0, + None= 0, /// /// Same as None. /// @@ -249,7 +249,7 @@ namespace Compress.ZipFile.ZLib /// /// Used to specify that the stream should compress the data. /// - Compress = 0, + Compress= 0, /// /// Used to specify that the stream should decompress the data. /// @@ -299,24 +299,24 @@ namespace Compress.ZipFile.ZLib internal static class InternalConstants { - internal static readonly int MAX_BITS = 15; - internal static readonly int BL_CODES = 19; - internal static readonly int D_CODES = 30; - internal static readonly int LITERALS = 256; + internal static readonly int MAX_BITS = 15; + internal static readonly int BL_CODES = 19; + internal static readonly int D_CODES = 30; + internal static readonly int LITERALS = 256; internal static readonly int LENGTH_CODES = 29; - internal static readonly int L_CODES = (LITERALS + 1 + LENGTH_CODES); + internal static readonly int L_CODES = (LITERALS + 1 + LENGTH_CODES); // Bit length codes must not exceed MAX_BL_BITS bits - internal static readonly int MAX_BL_BITS = 7; + internal static readonly int MAX_BL_BITS = 7; // repeat previous bit length 3-6 times (2 bits of repeat count) - internal static readonly int REP_3_6 = 16; + internal static readonly int REP_3_6 = 16; // repeat a zero length 3-10 times (3 bits of repeat count) - internal static readonly int REPZ_3_10 = 17; + internal static readonly int REPZ_3_10 = 17; // repeat a zero length 11-138 times (7 bits of repeat count) - internal static readonly int REPZ_11_138 = 18; + internal static readonly int REPZ_11_138 = 18; } @@ -433,8 +433,8 @@ namespace Compress.ZipFile.ZLib if (buf == null) return 1; - uint s1 = (uint)(adler & 0xffff); - uint s2 = (uint)((adler >> 16) & 0xffff); + uint s1 = (uint) (adler & 0xffff); + uint s2 = (uint) ((adler >> 16) & 0xffff); while (len > 0) { diff --git a/SabreTools.FileTypes/Compress/ZipFile/ZLib/ZlibBaseStream.cs b/SabreTools.FileTypes/Compress/ZipFile/ZLib/ZlibBaseStream.cs index 1eba6572..bb48fcb6 100644 --- a/SabreTools.FileTypes/Compress/ZipFile/ZLib/ZlibBaseStream.cs +++ b/SabreTools.FileTypes/Compress/ZipFile/ZLib/ZlibBaseStream.cs @@ -321,7 +321,8 @@ namespace Compress.ZipFile.ZLib public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin) { - return _stream.Seek(offset, origin); + throw new NotImplementedException(); + //_outStream.Seek(offset, origin); } public override void SetLength(System.Int64 value) { @@ -553,4 +554,4 @@ namespace Compress.ZipFile.ZLib } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/Compress/ZipFile/ZLib/ZlibCodec.cs b/SabreTools.FileTypes/Compress/ZipFile/ZLib/ZlibCodec.cs index 29342aea..42bf00f7 100644 --- a/SabreTools.FileTypes/Compress/ZipFile/ZLib/ZlibCodec.cs +++ b/SabreTools.FileTypes/Compress/ZipFile/ZLib/ZlibCodec.cs @@ -1,20 +1,20 @@ // ZlibCodec.cs // ------------------------------------------------------------------ // -// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. +// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. // All rights reserved. // // This code module is part of DotNetZip, a zipfile class library. // // ------------------------------------------------------------------ // -// This code is licensed under the Microsoft Public License. +// This code is licensed under the Microsoft Public License. // See the file License.txt for the license details. // More info on: http://dotnetzip.codeplex.com // // ------------------------------------------------------------------ // -// last saved (in emacs): +// last saved (in emacs): // Time-stamp: <2009-November-03 15:40:51> // // ------------------------------------------------------------------ @@ -28,22 +28,22 @@ // is included below. // // ------------------------------------------------------------------ -// +// // Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in // the documentation and/or other materials provided with the distribution. -// +// // 3. The names of the authors may not be used to endorse or promote products // derived from this software without specific prior written permission. -// +// // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, @@ -54,7 +54,7 @@ // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // ----------------------------------------------------------------------- // // This program is based on zlib-1.1.3; credit to authors @@ -66,7 +66,7 @@ using System; using System.Runtime.InteropServices; -using Interop = System.Runtime.InteropServices; +using Interop=System.Runtime.InteropServices; namespace Compress.ZipFile.ZLib { @@ -82,7 +82,7 @@ namespace Compress.ZipFile.ZLib /// [Guid("ebc25cf6-9120-4283-b972-0e5520d0000D")] [Interop.ComVisible(true)] -#if !NETCF +#if !NETCF [Interop.ClassInterface(Interop.ClassInterfaceType.AutoDispatch)] #endif sealed public class ZlibCodec @@ -93,15 +93,15 @@ namespace Compress.ZipFile.ZLib public byte[] InputBuffer; /// - /// An index into the InputBuffer array, indicating where to start reading. + /// An index into the InputBuffer array, indicating where to start reading. /// public int NextIn; /// - /// The number of bytes available in the InputBuffer, starting at NextIn. + /// The number of bytes available in the InputBuffer, starting at NextIn. /// /// - /// Generally you should set this to InputBuffer.Length before the first Inflate() or Deflate() call. + /// Generally you should set this to InputBuffer.Length before the first Inflate() or Deflate() call. /// The class will update this number as calls to Inflate/Deflate are made. /// public int AvailableBytesIn; @@ -117,15 +117,15 @@ namespace Compress.ZipFile.ZLib public byte[] OutputBuffer; /// - /// An index into the OutputBuffer array, indicating where to start writing. + /// An index into the OutputBuffer array, indicating where to start writing. /// public int NextOut; /// - /// The number of bytes available in the OutputBuffer, starting at NextOut. + /// The number of bytes available in the OutputBuffer, starting at NextOut. /// /// - /// Generally you should set this to OutputBuffer.Length before the first Inflate() or Deflate() call. + /// Generally you should set this to OutputBuffer.Length before the first Inflate() or Deflate() call. /// The class will update this number as calls to Inflate/Deflate are made. /// public int AvailableBytesOut; @@ -151,13 +151,13 @@ namespace Compress.ZipFile.ZLib public CompressionLevel CompressLevel = CompressionLevel.Default; /// - /// The number of Window Bits to use. + /// The number of Window Bits to use. /// /// - /// This gauges the size of the sliding window, and hence the - /// compression effectiveness as well as memory consumption. It's best to just leave this + /// This gauges the size of the sliding window, and hence the + /// compression effectiveness as well as memory consumption. It's best to just leave this /// setting alone if you don't know what it is. The maximum value is 15 bits, which implies - /// a 32k window. + /// a 32k window. /// public int WindowBits = ZlibConstants.WindowBitsDefault; @@ -187,9 +187,9 @@ namespace Compress.ZipFile.ZLib /// Create a ZlibCodec. /// /// - /// If you use this default constructor, you will later have to explicitly call - /// InitializeInflate() or InitializeDeflate() before using the ZlibCodec to compress - /// or decompress. + /// If you use this default constructor, you will later have to explicitly call + /// InitializeInflate() or InitializeDeflate() before using the ZlibCodec to compress + /// or decompress. /// public ZlibCodec() { } @@ -215,10 +215,10 @@ namespace Compress.ZipFile.ZLib } /// - /// Initialize the inflation state. + /// Initialize the inflation state. /// /// - /// It is not necessary to call this before using the ZlibCodec to inflate data; + /// It is not necessary to call this before using the ZlibCodec to inflate data; /// It is implicitly called when you call the constructor. /// /// Z_OK if everything goes well. @@ -251,20 +251,20 @@ namespace Compress.ZipFile.ZLib } /// - /// Initialize the ZlibCodec for inflation, with the specified number of window bits. + /// Initialize the ZlibCodec for inflation, with the specified number of window bits. /// - /// The number of window bits to use. If you need to ask what that is, + /// The number of window bits to use. If you need to ask what that is, /// then you shouldn't be calling this initializer. /// Z_OK if all goes well. public int InitializeInflate(int windowBits) { - this.WindowBits = windowBits; + this.WindowBits = windowBits; return InitializeInflate(windowBits, true); } /// /// Initialize the inflation state with an explicit flag to govern the handling of - /// RFC1950 header bytes. + /// RFC1950 header bytes. /// /// /// @@ -276,9 +276,9 @@ namespace Compress.ZipFile.ZLib /// false. /// /// - /// whether to expect an RFC1950 header byte pair when reading + /// whether to expect an RFC1950 header byte pair when reading /// the stream of data to be inflated. - /// The number of window bits to use. If you need to ask what that is, + /// The number of window bits to use. If you need to ask what that is, /// then you shouldn't be calling this initializer. /// Z_OK if everything goes well. public int InitializeInflate(int windowBits, bool expectRfc1950Header) @@ -293,7 +293,7 @@ namespace Compress.ZipFile.ZLib /// Inflate the data in the InputBuffer, placing the result in the OutputBuffer. /// /// - /// You must have set InputBuffer and OutputBuffer, NextIn and NextOut, and AvailableBytesIn and + /// You must have set InputBuffer and OutputBuffer, NextIn and NextOut, and AvailableBytesIn and /// AvailableBytesOut before calling this method. /// /// @@ -303,48 +303,48 @@ namespace Compress.ZipFile.ZLib /// int bufferSize = 1024; /// byte[] buffer = new byte[bufferSize]; /// ZlibCodec decompressor = new ZlibCodec(); - /// + /// /// Console.WriteLine("\n============================================"); /// Console.WriteLine("Size of Buffer to Inflate: {0} bytes.", CompressedBytes.Length); /// MemoryStream ms = new MemoryStream(DecompressedBytes); - /// + /// /// int rc = decompressor.InitializeInflate(); - /// + /// /// decompressor.InputBuffer = CompressedBytes; /// decompressor.NextIn = 0; /// decompressor.AvailableBytesIn = CompressedBytes.Length; - /// + /// /// decompressor.OutputBuffer = buffer; - /// - /// // pass 1: inflate + /// + /// // pass 1: inflate /// do /// { /// decompressor.NextOut = 0; /// decompressor.AvailableBytesOut = buffer.Length; /// rc = decompressor.Inflate(FlushType.None); - /// + /// /// if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) /// throw new Exception("inflating: " + decompressor.Message); - /// + /// /// ms.Write(decompressor.OutputBuffer, 0, buffer.Length - decompressor.AvailableBytesOut); /// } /// while (decompressor.AvailableBytesIn > 0 || decompressor.AvailableBytesOut == 0); - /// + /// /// // pass 2: finish and flush /// do /// { /// decompressor.NextOut = 0; /// decompressor.AvailableBytesOut = buffer.Length; /// rc = decompressor.Inflate(FlushType.Finish); - /// + /// /// if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK) /// throw new Exception("inflating: " + decompressor.Message); - /// + /// /// if (buffer.Length - decompressor.AvailableBytesOut > 0) /// ms.Write(buffer, 0, buffer.Length - decompressor.AvailableBytesOut); /// } /// while (decompressor.AvailableBytesIn > 0 || decompressor.AvailableBytesOut == 0); - /// + /// /// decompressor.EndInflate(); /// } /// @@ -361,10 +361,10 @@ namespace Compress.ZipFile.ZLib /// - /// Ends an inflation session. + /// Ends an inflation session. /// /// - /// Call this after successively calling Inflate(). This will cause all buffers to be flushed. + /// Call this after successively calling Inflate(). This will cause all buffers to be flushed. /// After calling this you cannot call Inflate() without a intervening call to one of the /// InitializeInflate() overloads. /// @@ -400,32 +400,32 @@ namespace Compress.ZipFile.ZLib /// int bufferSize = 40000; /// byte[] CompressedBytes = new byte[bufferSize]; /// byte[] DecompressedBytes = new byte[bufferSize]; - /// + /// /// ZlibCodec compressor = new ZlibCodec(); - /// + /// /// compressor.InitializeDeflate(CompressionLevel.Default); - /// + /// /// compressor.InputBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(TextToCompress); /// compressor.NextIn = 0; /// compressor.AvailableBytesIn = compressor.InputBuffer.Length; - /// + /// /// compressor.OutputBuffer = CompressedBytes; /// compressor.NextOut = 0; /// compressor.AvailableBytesOut = CompressedBytes.Length; - /// + /// /// while (compressor.TotalBytesIn != TextToCompress.Length && compressor.TotalBytesOut < bufferSize) /// { /// compressor.Deflate(FlushType.None); /// } - /// + /// /// while (true) /// { /// int rc= compressor.Deflate(FlushType.Finish); /// if (rc == ZlibConstants.Z_STREAM_END) break; /// } - /// + /// /// compressor.EndDeflate(); - /// + /// /// /// /// Z_OK if all goes well. You generally don't need to check the return code. @@ -451,7 +451,7 @@ namespace Compress.ZipFile.ZLib /// - /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel, + /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel, /// and the explicit flag governing whether to emit an RFC1950 header byte pair. /// /// @@ -459,7 +459,7 @@ namespace Compress.ZipFile.ZLib /// If you want to generate a zlib stream, you should specify true for /// wantRfc1950Header. In this case, the library will emit a ZLIB /// header, as defined in RFC - /// 1950, in the compressed stream. + /// 1950, in the compressed stream. /// /// The compression level for the codec. /// whether to emit an initial RFC1950 byte pair in the compressed stream. @@ -472,8 +472,8 @@ namespace Compress.ZipFile.ZLib /// - /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel, - /// and the specified number of window bits. + /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel, + /// and the specified number of window bits. /// /// /// The codec will use the specified number of window bits and the specified CompressionLevel. @@ -527,59 +527,59 @@ namespace Compress.ZipFile.ZLib /// int bufferSize = 1024; /// byte[] buffer = new byte[bufferSize]; /// ZlibCodec compressor = new ZlibCodec(); - /// + /// /// Console.WriteLine("\n============================================"); /// Console.WriteLine("Size of Buffer to Deflate: {0} bytes.", UncompressedBytes.Length); /// MemoryStream ms = new MemoryStream(); - /// + /// /// int rc = compressor.InitializeDeflate(level); - /// + /// /// compressor.InputBuffer = UncompressedBytes; /// compressor.NextIn = 0; /// compressor.AvailableBytesIn = UncompressedBytes.Length; - /// + /// /// compressor.OutputBuffer = buffer; - /// - /// // pass 1: deflate + /// + /// // pass 1: deflate /// do /// { /// compressor.NextOut = 0; /// compressor.AvailableBytesOut = buffer.Length; /// rc = compressor.Deflate(FlushType.None); - /// + /// /// if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) /// throw new Exception("deflating: " + compressor.Message); - /// + /// /// ms.Write(compressor.OutputBuffer, 0, buffer.Length - compressor.AvailableBytesOut); /// } /// while (compressor.AvailableBytesIn > 0 || compressor.AvailableBytesOut == 0); - /// + /// /// // pass 2: finish and flush /// do /// { /// compressor.NextOut = 0; /// compressor.AvailableBytesOut = buffer.Length; /// rc = compressor.Deflate(FlushType.Finish); - /// + /// /// if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK) /// throw new Exception("deflating: " + compressor.Message); - /// + /// /// if (buffer.Length - compressor.AvailableBytesOut > 0) /// ms.Write(buffer, 0, buffer.Length - compressor.AvailableBytesOut); /// } /// while (compressor.AvailableBytesIn > 0 || compressor.AvailableBytesOut == 0); - /// + /// /// compressor.EndDeflate(); - /// + /// /// ms.Seek(0, SeekOrigin.Begin); /// CompressedBytes = new byte[compressor.TotalBytesOut]; /// ms.Read(CompressedBytes, 0, CompressedBytes.Length); /// } /// /// - /// whether to flush all data as you deflate. Generally you will want to - /// use Z_NO_FLUSH here, in a series of calls to Deflate(), and then call EndDeflate() to - /// flush everything. + /// whether to flush all data as you deflate. Generally you will want to + /// use Z_NO_FLUSH here, in a series of calls to Deflate(), and then call EndDeflate() to + /// flush everything. /// /// Z_OK if all goes well. public int Deflate(FlushType flush) @@ -677,10 +677,10 @@ namespace Compress.ZipFile.ZLib Array.Copy(dstate.pending, dstate.nextPending, OutputBuffer, NextOut, len); - NextOut += len; - dstate.nextPending += len; - TotalBytesOut += len; - AvailableBytesOut -= len; + NextOut += len; + dstate.nextPending += len; + TotalBytesOut += len; + AvailableBytesOut -= len; dstate.pendingCount -= len; if (dstate.pendingCount == 0) { diff --git a/SabreTools.FileTypes/Compress/ZipFile/ZLib/ZlibConstants.cs b/SabreTools.FileTypes/Compress/ZipFile/ZLib/ZlibConstants.cs index ec86b0a4..332684aa 100644 --- a/SabreTools.FileTypes/Compress/ZipFile/ZLib/ZlibConstants.cs +++ b/SabreTools.FileTypes/Compress/ZipFile/ZLib/ZlibConstants.cs @@ -1,20 +1,20 @@ // ZlibConstants.cs // ------------------------------------------------------------------ // -// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. +// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. // All rights reserved. // // This code module is part of DotNetZip, a zipfile class library. // // ------------------------------------------------------------------ // -// This code is licensed under the Microsoft Public License. +// This code is licensed under the Microsoft Public License. // See the file License.txt for the license details. // More info on: http://dotnetzip.codeplex.com // // ------------------------------------------------------------------ // -// last saved (in emacs): +// last saved (in emacs): // Time-stamp: <2009-November-03 18:50:19> // // ------------------------------------------------------------------ @@ -25,22 +25,22 @@ // copyright to that code is included here. // // ------------------------------------------------------------------ -// +// // Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in // the documentation and/or other materials provided with the distribution. -// +// // 3. The names of the authors may not be used to endorse or promote products // derived from this software without specific prior written permission. -// +// // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, @@ -51,7 +51,7 @@ // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // ----------------------------------------------------------------------- // // This program is based on zlib-1.1.3; credit to authors @@ -89,7 +89,7 @@ namespace Compress.ZipFile.ZLib public const int Z_STREAM_END = 1; /// - /// The operation ended in need of a dictionary. + /// The operation ended in need of a dictionary. /// public const int Z_NEED_DICT = 2; @@ -111,10 +111,10 @@ namespace Compress.ZipFile.ZLib /// /// The size of the working buffer used in the ZlibCodec class. Defaults to 8192 bytes. /// -#if NETCF +#if NETCF public const int WorkingBufferSizeDefault = 8192; #else - public const int WorkingBufferSizeDefault = 16384; + public const int WorkingBufferSizeDefault = 16384; #endif /// /// The minimum size of the working buffer used in the ZlibCodec class. Currently it is 128 bytes. @@ -123,3 +123,4 @@ namespace Compress.ZipFile.ZLib } } + diff --git a/SabreTools.FileTypes/Compress/ZipFile/Zip.cs b/SabreTools.FileTypes/Compress/ZipFile/Zip.cs new file mode 100644 index 00000000..54e95577 --- /dev/null +++ b/SabreTools.FileTypes/Compress/ZipFile/Zip.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.IO; +using FileInfo = RVIO.FileInfo; + +// UInt16 = ushort +// UInt32 = uint +// ULong = ulong + +namespace Compress.ZipFile +{ + public partial class Zip : ICompress + { + private readonly List _localFiles = new List(); + + + private FileInfo _zipFileInfo; + + + private byte[] _fileComment; + private Stream _zipFs; + + private uint _localFilesCount; + + private bool _zip64; + + public string ZipFilename => _zipFileInfo != null ? _zipFileInfo.FullName : ""; + + public long TimeStamp => _zipFileInfo?.LastWriteTime ?? 0; + + public ZipOpenType ZipOpen { get; private set; } + + + public ZipStatus ZipStatus { get; set; } + + public int LocalFilesCount() + { + return _localFiles.Count; + } + + public string Filename(int i) + { + return _localFiles[i].FileName; + } + + public ulong UncompressedSize(int i) + { + return _localFiles[i].UncompressedSize; + } + + public ulong? LocalHeader(int i) + { + return (_localFiles[i].GeneralPurposeBitFlag & 8) == 0 ? (ulong?)_localFiles[i].RelativeOffsetOfLocalHeader : null; + } + + public byte[] CRC32(int i) + { + return _localFiles[i].CRC; + } + + public bool IsDirectory(int i) + { + try + { + if (_localFiles[i].UncompressedSize != 0) + return false; + string filename = _localFiles[i].FileName; + char lastChar = filename[filename.Length - 1]; + return lastChar == '/' || lastChar == '\\'; + } + catch (Exception ex) + { + ArgumentException argEx = new ArgumentException("Error in file " + _zipFileInfo?.FullName + " : " + ex.Message, ex.InnerException); + throw argEx; + } + + } + + public long LastModified(int i) + { + return _localFiles[i].DateTime; + } + + public long? Created(int i) + { + return _localFiles[i].DateTimeCreate; + } + + public long? Accessed(int i) + { + return _localFiles[i].DateTimeAccess; + } + + public void ZipFileClose() + { + if (ZipOpen == ZipOpenType.Closed) + { + return; + } + + if (ZipOpen == ZipOpenType.OpenRead) + { + zipFileCloseRead(); + return; + } + + zipFileCloseWrite(); + } + + public byte[] Filecomment => _fileComment; + + /* + public void BreakTrrntZip(string filename) + { + _zipFs = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite); + using (BinaryReader zipBr = new BinaryReader(_zipFs,Encoding.UTF8,true)) + { + _zipFs.Position = _zipFs.Length - 22; + byte[] fileComment = zipBr.ReadBytes(22); + if (GetString(fileComment).Substring(0, 14) == "TORRENTZIPPED-") + { + _zipFs.Position = _zipFs.Length - 8; + _zipFs.WriteByte(48); _zipFs.WriteByte(48); _zipFs.WriteByte(48); _zipFs.WriteByte(48); + _zipFs.WriteByte(48); _zipFs.WriteByte(48); _zipFs.WriteByte(48); _zipFs.WriteByte(48); + } + } + _zipFs.Flush(); + _zipFs.Close(); + } + */ + + ~Zip() + { + ZipFileClose(); + } + + + + } +} diff --git a/SabreTools.FileTypes/Compress/ZipFile/ZipCentralDir.cs b/SabreTools.FileTypes/Compress/ZipFile/ZipCentralDir.cs new file mode 100644 index 00000000..e5b3e9ff --- /dev/null +++ b/SabreTools.FileTypes/Compress/ZipFile/ZipCentralDir.cs @@ -0,0 +1,239 @@ +using System.IO; +using System.Text; + +namespace Compress.ZipFile +{ + public partial class Zip + { + private const uint EndOfCentralDirSignature = 0x06054b50; + private const uint Zip64EndOfCentralDirSignature = 0x06064b50; + private const uint Zip64EndOfCentralDirectoryLocator = 0x07064b50; + + private ZipReturn FindEndOfCentralDirSignature() + { + long fileSize = _zipFs.Length; + long maxBackSearch = 0xffff; + + if (_zipFs.Length < maxBackSearch) + { + maxBackSearch = fileSize; + } + + const long buffSize = 0x400; + + byte[] buffer = new byte[buffSize + 4]; + + long backPosition = 4; + while (backPosition < maxBackSearch) + { + backPosition += buffSize; + if (backPosition > maxBackSearch) + { + backPosition = maxBackSearch; + } + + long readSize = backPosition > buffSize + 4 ? buffSize + 4 : backPosition; + + _zipFs.Position = fileSize - backPosition; + + _zipFs.Read(buffer, 0, (int)readSize); + + + for (long i = readSize - 4; i >= 0; i--) + { + if (buffer[i] != 0x50 || buffer[i + 1] != 0x4b || buffer[i + 2] != 0x05 || buffer[i + 3] != 0x06) + { + continue; + } + + _zipFs.Position = fileSize - backPosition + i; + return ZipReturn.ZipGood; + } + } + return ZipReturn.ZipCentralDirError; + } + + + private ZipReturn EndOfCentralDirRead() + { + using (BinaryReader zipBr = new BinaryReader(_zipFs, Encoding.UTF8, true)) + { + uint thisSignature = zipBr.ReadUInt32(); + if (thisSignature != EndOfCentralDirSignature) + { + return ZipReturn.ZipEndOfCentralDirectoryError; + } + + ushort tUShort = zipBr.ReadUInt16(); // NumberOfThisDisk + if (tUShort != 0) + { + return ZipReturn.ZipEndOfCentralDirectoryError; + } + + tUShort = zipBr.ReadUInt16(); // NumberOfThisDiskCenterDir + if (tUShort != 0) + { + return ZipReturn.ZipEndOfCentralDirectoryError; + } + + _localFilesCount = zipBr.ReadUInt16(); // TotalNumberOfEntriesDisk + + tUShort = zipBr.ReadUInt16(); // TotalNumber of entries in the central directory + if (tUShort != _localFilesCount) + { + return ZipReturn.ZipEndOfCentralDirectoryError; + } + + _centralDirSize = zipBr.ReadUInt32(); // SizeOfCentralDir + _centralDirStart = zipBr.ReadUInt32(); // Offset + + ushort zipFileCommentLength = zipBr.ReadUInt16(); + + _fileComment = zipBr.ReadBytes(zipFileCommentLength); + + if (_zipFs.Position != _zipFs.Length) + { + ZipStatus |= ZipStatus.ExtraData; + } + + return ZipReturn.ZipGood; + } + } + + + private void EndOfCentralDirWrite() + { + using (BinaryWriter bw = new BinaryWriter(_zipFs, Encoding.UTF8, true)) + { + bw.Write(EndOfCentralDirSignature); + bw.Write((ushort)0); // NumberOfThisDisk + bw.Write((ushort)0); // NumberOfThisDiskCenterDir + bw.Write((ushort)(_localFiles.Count >= 0xffff ? 0xffff : _localFiles.Count)); // TotalNumberOfEntriesDisk + bw.Write((ushort)(_localFiles.Count >= 0xffff ? 0xffff : _localFiles.Count)); // TotalNumber of entries in the central directory + bw.Write((uint)(_centralDirSize >= 0xffffffff ? 0xffffffff : _centralDirSize)); + bw.Write((uint)(_centralDirStart >= 0xffffffff ? 0xffffffff : _centralDirStart)); + bw.Write((ushort)_fileComment.Length); + bw.Write(_fileComment, 0, _fileComment.Length); + } + } + + + + + private ZipReturn Zip64EndOfCentralDirRead() + { + using (BinaryReader zipBr = new BinaryReader(_zipFs, Encoding.UTF8, true)) + { + uint thisSignature = zipBr.ReadUInt32(); + if (thisSignature != Zip64EndOfCentralDirSignature) + { + return ZipReturn.ZipEndOfCentralDirectoryError; + } + + //_zip64 = true; + ulong tULong = zipBr.ReadUInt64(); // Size of zip64 end of central directory record + if (tULong != 44) + { + return ZipReturn.Zip64EndOfCentralDirError; + } + + zipBr.ReadUInt16(); // version made by + + ushort tUShort = zipBr.ReadUInt16(); // version needed to extract + if (tUShort != 45) + { + return ZipReturn.Zip64EndOfCentralDirError; + } + + uint tUInt = zipBr.ReadUInt32(); // number of this disk + if (tUInt != 0) + { + return ZipReturn.Zip64EndOfCentralDirError; + } + + tUInt = zipBr.ReadUInt32(); // number of the disk with the start of the central directory + if (tUInt != 0) + { + return ZipReturn.Zip64EndOfCentralDirError; + } + + _localFilesCount = + (uint)zipBr.ReadUInt64(); // total number of entries in the central directory on this disk + + tULong = zipBr.ReadUInt64(); // total number of entries in the central directory + if (tULong != _localFilesCount) + { + return ZipReturn.Zip64EndOfCentralDirError; + } + + _zip64 = true; + _centralDirSize = zipBr.ReadUInt64(); // size of central directory + + _centralDirStart = zipBr.ReadUInt64(); // offset of start of central directory with respect to the starting disk number + + return ZipReturn.ZipGood; + } + } + + + private void Zip64EndOfCentralDirWrite() + { + using (BinaryWriter bw = new BinaryWriter(_zipFs, Encoding.UTF8, true)) + { + bw.Write(Zip64EndOfCentralDirSignature); + bw.Write((ulong)44); // Size of zip64 end of central directory record + bw.Write((ushort)45); // version made by + bw.Write((ushort)45); // version needed to extract + bw.Write((uint)0); // number of this disk + bw.Write((uint)0); // number of the disk with the start of the central directory + bw.Write((ulong)_localFiles.Count); // total number of entries in the central directory on this disk + bw.Write((ulong)_localFiles.Count); // total number of entries in the central directory + bw.Write(_centralDirSize); // size of central directory + bw.Write(_centralDirStart); // offset of start of central directory with respect to the starting disk number + } + } + + + + private ZipReturn Zip64EndOfCentralDirectoryLocatorRead() + { + using (BinaryReader zipBr = new BinaryReader(_zipFs, Encoding.UTF8, true)) + { + uint thisSignature = zipBr.ReadUInt32(); + if (thisSignature != Zip64EndOfCentralDirectoryLocator) + { + return ZipReturn.ZipEndOfCentralDirectoryError; + } + + uint tUInt = zipBr.ReadUInt32(); // number of the disk with the start of the zip64 end of central directory + if (tUInt != 0) + { + return ZipReturn.Zip64EndOfCentralDirectoryLocatorError; + } + + _endOfCenterDir64 = zipBr.ReadUInt64(); // relative offset of the zip64 end of central directory record + + tUInt = zipBr.ReadUInt32(); // total number of disks + if (tUInt != 1) + { + return ZipReturn.Zip64EndOfCentralDirectoryLocatorError; + } + + return ZipReturn.ZipGood; + } + } + + private void Zip64EndOfCentralDirectoryLocatorWrite() + { + using (BinaryWriter bw = new BinaryWriter(_zipFs, Encoding.UTF8, true)) + { + bw.Write(Zip64EndOfCentralDirectoryLocator); + bw.Write((uint)0); // number of the disk with the start of the zip64 end of central directory + bw.Write(_endOfCenterDir64); // relative offset of the zip64 end of central directory record + bw.Write((uint)1); // total number of disks + } + } + + + } +} diff --git a/SabreTools.FileTypes/Compress/ZipFile/ZipExtraField.cs b/SabreTools.FileTypes/Compress/ZipFile/ZipExtraField.cs new file mode 100644 index 00000000..33df4e78 --- /dev/null +++ b/SabreTools.FileTypes/Compress/ZipFile/ZipExtraField.cs @@ -0,0 +1,605 @@ +using System; +using System.Diagnostics; +using System.Text; +using Compress.Utils; + +namespace Compress.ZipFile +{ + internal partial class LocalFile + { + private static class ZipExtraField + { + public static ZipReturn ReadLocalExtraField(byte[] extraField, byte[] bFileName, LocalFile lf, bool centralDir) + { + int extraFieldLength = extraField.Length; + + lf.Zip64 = false; + int blockPos = 0; + while (extraFieldLength > blockPos) + { + ushort type = BitConverter.ToUInt16(extraField, blockPos); + blockPos += 2; + ushort blockLength = BitConverter.ToUInt16(extraField, blockPos); + blockPos += 2; + + int pos = blockPos; + switch (type) + { + /* + -Zip64 Extended Information Extra Field (0x0001): + =============================================== + + The following is the layout of the zip64 extended + information "extra" block. If one of the size or + offset fields in the Local or Central directory + record is too small to hold the required data, + a zip64 extended information record is created. + The order of the fields in the zip64 extended + information record is fixed, but the fields will + only appear if the corresponding Local or Central + directory record field is set to 0xFFFF or 0xFFFFFFFF. + + Note: all fields stored in Intel low-byte/high-byte order. + + Value Size Description + ----- ---- ----------- + (ZIP64) 0x0001 2 bytes Tag for this "extra" block type + Size 2 bytes Size of this "extra" block + Original + Size 8 bytes Original uncompressed file size + Compressed + Size 8 bytes Size of compressed data + Relative Header + Offset 8 bytes Offset of local header record + Disk Start + Number 4 bytes Number of the disk on which + this file starts + + This entry in the Local header must include BOTH original + and compressed file size fields. If encrypting the + central directory and bit 13 of the general purpose bit + flag is set indicating masking, the value stored in the + Local Header for the original file size will be zero. + */ + case 0x0001: + lf.Zip64 = true; + if (centralDir) + { + if (lf.UncompressedSize == 0xffffffff) + { + lf.UncompressedSize = BitConverter.ToUInt64(extraField, pos); + pos += 8; + } + if (lf._compressedSize == 0xffffffff) + { + lf._compressedSize = BitConverter.ToUInt64(extraField, pos); + pos += 8; + } + if (lf.RelativeOffsetOfLocalHeader == 0xffffffff) + { + lf.RelativeOffsetOfLocalHeader = BitConverter.ToUInt64(extraField, pos); + pos += 8; + } + } + else + { + if (lf._localHeaderUncompressedSize == 0xffffffff) + { + lf._localHeaderUncompressedSize = BitConverter.ToUInt64(extraField, pos); + pos += 8; + } + if (lf._localHeaderCompressedSize == 0xffffffff) + { + lf._localHeaderCompressedSize = BitConverter.ToUInt64(extraField, pos); + pos += 8; + } + } + + break; + + + /* PKWARE's authenticity verification */ + case 0x0007: // Not Needed + break; + + + /* + -PKWARE Win95/WinNT Extra Field (0x000a): + ======================================= + + The following description covers PKWARE's "NTFS" attributes + "extra" block, introduced with the release of PKZIP 2.50 for + Windows. (Last Revision 20001118) + + (Note: At this time the Mtime, Atime and Ctime values may + be used on any WIN32 system.) + [Info-ZIP note: In the current implementations, this field has + a fixed total data size of 32 bytes and is only stored as local + extra field.] + + Value Size Description + ----- ---- ----------- + (NTFS) 0x000a Short Tag for this "extra" block type + TSize Short Total Data Size for this block + Reserved Long for future use + Tag1 Short NTFS attribute tag value #1 + Size1 Short Size of attribute #1, in bytes + (var.) SubSize1 Attribute #1 data + . + . + . + TagN Short NTFS attribute tag value #N + SizeN Short Size of attribute #N, in bytes + (var.) SubSizeN Attribute #N data + + For NTFS, values for Tag1 through TagN are as follows: + (currently only one set of attributes is defined for NTFS) + + Tag Size Description + ----- ---- ----------- + 0x0001 2 bytes Tag for attribute #1 + Size1 2 bytes Size of attribute #1, in bytes (24) + Mtime 8 bytes 64-bit NTFS file last modification time + Atime 8 bytes 64-bit NTFS file last access time + Ctime 8 bytes 64-bit NTFS file creation time + + The total length for this block is 28 bytes, resulting in a + fixed size value of 32 for the TSize field of the NTFS block. + + The NTFS filetimes are 64-bit unsigned integers, stored in Intel + (least significant byte first) byte order. They determine the + number of 1.0E-07 seconds (1/10th microseconds!) past WinNT "epoch", + which is "01-Jan-1601 00:00:00 UTC". + */ + case 0x000a: + pos += 4; // Reserved Long for future use + int tag1 = BitConverter.ToInt16(extraField, pos); // Tag1 Short NTFS attribute tag value #1 + pos += 2; + int size1 = BitConverter.ToInt16(extraField, pos); // Size1 Short Size of attribute #1, in bytes + pos += 2; + if (tag1 == 0x0001 && size1 == 24 + ) // (currently only one set of attributes is defined for NTFS) + { + lf.mTime = ZipUtils.FileTimeToUTCTime(BitConverter.ToInt64(extraField, pos)); // Mtime 8 bytes 64-bit NTFS file last modification time + pos += 8; + lf.aTime = ZipUtils.FileTimeToUTCTime(BitConverter.ToInt64(extraField, pos)); // Atime 8 bytes 64-bit NTFS file last access time + pos += 8; + lf.cTime = ZipUtils.FileTimeToUTCTime(BitConverter.ToInt64(extraField, pos)); // Ctime 8 bytes 64-bit NTFS file creation time + pos += 8; + + Debug.WriteLine("modtime = " + new DateTime((long)lf.mTime)); + Debug.WriteLine("Acctime = " + new DateTime((long)lf.aTime)); + Debug.WriteLine("Cretime = " + new DateTime((long)lf.cTime)); + } + + break; + + + /* + -Windows NT Security Descriptor Extra Field (0x4453): + =================================================== + + The following is the layout of the NT Security Descriptor (another + type of ACL) extra block. (Last Revision 19960922) + + Local-header version: + + Value Size Description + ----- ---- ----------- + (SD) 0x4453 Short tag for this extra block type ("SD") + TSize Short total data size for this block + BSize Long uncompressed SD data size + Version Byte version of uncompressed SD data format + CType Short compression type + EACRC Long CRC value for uncompressed SD data + (var.) variable compressed SD data + + Central-header version: + + Value Size Description + ----- ---- ----------- + (SD) 0x4453 Short tag for this extra block type ("SD") + TSize Short total data size for this block (4) + BSize Long size of uncompressed local SD data + + The value of CType is interpreted according to the "compression + method" section above; i.e., 0 for stored, 8 for deflated, etc. + Version specifies how the compressed data are to be interpreted + and allows for future expansion of this extra field type. Currently + only version 0 is defined. + + For version 0, the compressed data are to be interpreted as a single + valid Windows NT SECURITY_DESCRIPTOR data structure, in self-relative + format. + + */ + case 0x4453: // Not Needed + break; + + + /* + -FWKCS MD5 Extra Field (0x4b46): + ============================== + + The FWKCS Contents_Signature System, used in automatically + identifying files independent of filename, optionally adds + and uses an extra field to support the rapid creation of + an enhanced contents_signature. + There is no local-header version; the following applies + only to the central header. (Last Revision 19961207) + + Central-header version: + + Value Size Description + ----- ---- ----------- + (MD5) 0x4b46 Short tag for this extra block type ("FK") + TSize Short total data size for this block (19) + "MD5" 3 bytes extra-field signature + MD5hash 16 bytes 128-bit MD5 hash of uncompressed data + (low byte first) + + When FWKCS revises a .ZIP file central directory to add + this extra field for a file, it also replaces the + central directory entry for that file's uncompressed + file length with a measured value. + + FWKCS provides an option to strip this extra field, if + present, from a .ZIP file central directory. In adding + this extra field, FWKCS preserves .ZIP file Authenticity + Verification; if stripping this extra field, FWKCS + preserves all versions of AV through PKZIP version 2.04g. + + FWKCS, and FWKCS Contents_Signature System, are + trademarks of Frederick W. Kantor. + + (1) R. Rivest, RFC1321.TXT, MIT Laboratory for Computer + Science and RSA Data Security, Inc., April 1992. + ll.76-77: "The MD5 algorithm is being placed in the + public domain for review and possible adoption as a + standard." + */ + case 0x4B46: // Not Needed + break; + + + /* + -Extended Timestamp Extra Field: + ============================== + + The following is the layout of the extended-timestamp extra block. + (Last Revision 19970118) + + Local-header version: + + Value Size Description + ----- ---- ----------- + (time) 0x5455 Short tag for this extra block type ("UT") + TSize Short total data size for this block + Flags Byte info bits + (ModTime) Long time of last modification (UTC/GMT) + (AcTime) Long time of last access (UTC/GMT) + (CrTime) Long time of original creation (UTC/GMT) + + Central-header version: + + Value Size Description + ----- ---- ----------- + (time) 0x5455 Short tag for this extra block type ("UT") + TSize Short total data size for this block + Flags Byte info bits (refers to local header!) + (ModTime) Long time of last modification (UTC/GMT) + + The central-header extra field contains the modification time only, + or no timestamp at all. TSize is used to flag its presence or + absence. But note: + + If "Flags" indicates that Modtime is present in the local header + field, it MUST be present in the central header field, too! + This correspondence is required because the modification time + value may be used to support trans-timezone freshening and + updating operations with zip archives. + + The time values are in standard Unix signed-long format, indicating + the number of seconds since 1 January 1970 00:00:00. The times + are relative to Coordinated Universal Time (UTC), also sometimes + referred to as Greenwich Mean Time (GMT). To convert to local time, + the software must know the local timezone offset from UTC/GMT. + + The lower three bits of Flags in both headers indicate which time- + stamps are present in the LOCAL extra field: + + bit 0 if set, modification time is present + bit 1 if set, access time is present + bit 2 if set, creation time is present + bits 3-7 reserved for additional timestamps; not set + + Those times that are present will appear in the order indicated, but + any combination of times may be omitted. (Creation time may be + present without access time, for example.) TSize should equal + (1 + 4*(number of set bits in Flags)), as the block is currently + defined. Other timestamps may be added in the future. + */ + case 0x5455: + byte flags = extraField[pos]; + pos += 1; + if ((flags & 1) == 1) + { + lf.mTime = ZipUtils.SetDateTimeFromUnixSeconds(BitConverter.ToInt32(extraField, pos)); // (ModTime) Long time of last modification (UTC/GMT) + Debug.WriteLine("Umodtime = " + new DateTime((long)lf.mTime)); + pos += 4; + } + + if (!centralDir) + { + if ((flags & 2) == 2) + { + lf.aTime = ZipUtils.SetDateTimeFromUnixSeconds(BitConverter.ToInt32(extraField, pos)); // (AcTime) Long time of last access (UTC/GMT) + Debug.WriteLine("UAcctime = " + new DateTime((long)lf.aTime)); + pos += 4; + } + + if ((flags & 4) == 4) + { + lf.cTime = ZipUtils.SetDateTimeFromUnixSeconds(BitConverter.ToInt32(extraField, pos)); // (CrTime) Long time of original creation (UTC/GMT) + Debug.WriteLine("UCretime = " + new DateTime((long)lf.cTime)); + pos += 4; + } + } + + break; + + + /* + -Info-ZIP Unix Extra Field (type 1): + ================================== + + The following is the layout of the old Info-ZIP extra block for + Unix. It has been replaced by the extended-timestamp extra block + (0x5455) and the Unix type 2 extra block (0x7855). + (Last Revision 19970118) + + Local-header version: + + Value Size Description + ----- ---- ----------- + (Unix1) 0x5855 Short tag for this extra block type ("UX") + TSize Short total data size for this block + AcTime Long time of last access (UTC/GMT) + ModTime Long time of last modification (UTC/GMT) + UID Short Unix user ID (optional) + GID Short Unix group ID (optional) + + Central-header version: + + Value Size Description + ----- ---- ----------- + (Unix1) 0x5855 Short tag for this extra block type ("UX") + TSize Short total data size for this block + AcTime Long time of last access (GMT/UTC) + ModTime Long time of last modification (GMT/UTC) + + The file access and modification times are in standard Unix signed- + long format, indicating the number of seconds since 1 January 1970 + 00:00:00. The times are relative to Coordinated Universal Time + (UTC), also sometimes referred to as Greenwich Mean Time (GMT). To + convert to local time, the software must know the local timezone + offset from UTC/GMT. The modification time may be used by non-Unix + systems to support inter-timezone freshening and updating of zip + archives. + + The local-header extra block may optionally contain UID and GID + info for the file. The local-header TSize value is the only + indication of this. Note that Unix UIDs and GIDs are usually + specific to a particular machine, and they generally require root + access to restore. + + This extra field type is obsolete, but it has been in use since + mid-1994. Therefore future archiving software should continue to + support it. Some guidelines: + + An archive member should either contain the old "Unix1" + extra field block or the new extra field types "time" and/or + "Unix2". + + If both the old "Unix1" block type and one or both of the new + block types "time" and "Unix2" are found, the "Unix1" block + should be considered invalid and ignored. + + Unarchiving software should recognize both old and new extra + field block types, but the info from new types overrides the + old "Unix1" field. + + Archiving software should recognize "Unix1" extra fields for + timestamp comparison but never create it for updated, freshened + or new archive members. When copying existing members to a new + archive, any "Unix1" extra field blocks should be converted to + the new "time" and/or "Unix2" types. + */ + case 0x5855: + lf.aTime = ZipUtils.SetDateTimeFromUnixSeconds(BitConverter.ToInt32(extraField, pos)); // AcTime Long time of last access (UTC/GMT) + Debug.WriteLine("UAcctime = " + new DateTime((long)lf.aTime)); + pos += 4; + lf.mTime = ZipUtils.SetDateTimeFromUnixSeconds(BitConverter.ToInt32(extraField, pos)); // ModTime Long time of last modification (UTC/GMT) + Debug.WriteLine("Umodtime = " + new DateTime((long)lf.mTime)); + pos += 4; + break; + + + /* + -Info-ZIP Unicode Path Extra Field: + ================================= + + Stores the UTF-8 version of the entry path as stored in the + local header and central directory header. + (Last Revision 20070912) + + Value Size Description + ----- ---- ----------- + (UPath) 0x7075 Short tag for this extra block type ("up") + TSize Short total data size for this block + Version Byte version of this extra field, currently 1 + NameCRC32 Long CRC-32 checksum of standard name field + UnicodeName variable UTF-8 version of the entry file name + + Currently Version is set to the number 1. If there is a need + to change this field, the version will be incremented. Changes + may not be backward compatible so this extra field should not be + used if the version is not recognized. + + The NameCRC32 is the standard zip CRC32 checksum of the File Name + field in the header. This is used to verify that the header + File Name field has not changed since the Unicode Path extra field + was created. This can happen if a utility renames the entry but + does not update the UTF-8 path extra field. If the CRC check fails, + this UTF-8 Path Extra Field should be ignored and the File Name field + in the header should be used instead. + + The UnicodeName is the UTF-8 version of the contents of the File + Name field in the header, without any trailing NUL. The standard + name field in the Zip entry header remains filled with the entry + name coded in the local machine's extended ASCII system charset. + As UnicodeName is defined to be UTF-8, no UTF-8 byte order mark + (BOM) is used. The length of this field is determined by + subtracting the size of the previous fields from TSize. + If both the File Name and Comment fields are UTF-8, the new General + Purpose Bit Flag, bit 11 (Language encoding flag (EFS)), should be + used to indicate that both the header File Name and Comment fields + are UTF-8 and, in this case, the Unicode Path and Unicode Comment + extra fields are not needed and should not be created. Note that, + for backward compatibility, bit 11 should only be used if the native + character set of the paths and comments being zipped up are already + in UTF-8. The same method, either general purpose bit 11 or extra + fields, should be used in both the Local and Central Directory Header + for a file. + + Utilisation rules: + 1. This field shall never be created for names consisting solely of + 7-bit ASCII characters. + 2. On a system that already uses UTF-8 as system charset, this field + shall not repeat the string pattern already stored in the Zip + entry's standard name field. Instead, a field of exactly 9 bytes + (70 75 05 00 01 and 4 bytes CRC) should be created. + In this form with 5 data bytes, the field serves as indicator + for the UTF-8 encoding of the standard Zip header's name field. + 3. This field shall not be used whenever the calculated CRC-32 of + the entry's standard name field does not match the provided + CRC checksum value. A mismatch of the CRC check indicates that + the standard name field was changed by some non-"up"-aware + utility without synchronizing this UTF-8 name e.f. block. + */ + case 0x7075: + pos += 1; + uint nameCRC32 = BitConverter.ToUInt32(extraField, pos); + pos += 4; + + CRC crcTest = new CRC(); + crcTest.SlurpBlock(bFileName, 0, bFileName.Length); + uint fCRC = crcTest.Crc32ResultU; + + if (nameCRC32 == fCRC) + { + int charLen = blockLength - 5; + if (centralDir) + lf.FileName = Encoding.UTF8.GetString(extraField, pos, charLen); + else + lf._localHeaderFilename = Encoding.UTF8.GetString(extraField, pos, charLen); + } + + break; + + + /* + -Info-ZIP UNIX Extra Field (type 2): + ================================== + + The following is the layout of the new Info-ZIP extra block for + Unix. (Last Revision 19960922) + + Local-header version: + + Value Size Description + ----- ---- ----------- + (Unix2) 0x7855 Short tag for this extra block type ("Ux") + TSize Short total data size for this block (4) + UID Short Unix user ID + GID Short Unix group ID + + Central-header version: + + Value Size Description + ----- ---- ----------- + (Unix2) 0x7855 Short tag for this extra block type ("Ux") + TSize Short total data size for this block (0) + + The data size of the central-header version is zero; it is used + solely as a flag that UID/GID info is present in the local-header + extra field. If additional fields are ever added to the local + version, the central version may be extended to indicate this. + + Note that Unix UIDs and GIDs are usually specific to a particular + machine, and they generally require root access to restore. + + */ + case 0x7855: // Not Needed + break; + + + /* + -Info-ZIP New Unix Extra Field: + ==================================== + + Currently stores Unix UIDs/GIDs up to 32 bits. + (Last Revision 20080509) + + Value Size Description + ----- ---- ----------- + (UnixN) 0x7875 Short tag for this extra block type ("ux") + TSize Short total data size for this block + Version 1 byte version of this extra field, currently 1 + UIDSize 1 byte Size of UID field + UID Variable UID for this entry + GIDSize 1 byte Size of GID field + GID Variable GID for this entry + + Currently Version is set to the number 1. If there is a need + to change this field, the version will be incremented. Changes + may not be backward compatible so this extra field should not be + used if the version is not recognized. + + UIDSize is the size of the UID field in bytes. This size should + match the size of the UID field on the target OS. + + UID is the UID for this entry in standard little endian format. + + GIDSize is the size of the GID field in bytes. This size should + match the size of the GID field on the target OS. + + GID is the GID for this entry in standard little endian format. + + If both the old 16-bit Unix extra field (tag 0x7855, Info-ZIP Unix2) + and this extra field are present, the values in this extra field + supercede the values in that extra field. + */ + case 0x7875: // Not Needed + break; + + + + /* UNKNOWN */ + case 0xe57a: + break; + + + default: + break; + } + + blockPos += blockLength; + + } + + return ZipReturn.ZipGood; + } + } + } +} \ No newline at end of file diff --git a/SabreTools.FileTypes/Compress/ZipFile/ZipFake.cs b/SabreTools.FileTypes/Compress/ZipFile/ZipFake.cs new file mode 100644 index 00000000..b59885f3 --- /dev/null +++ b/SabreTools.FileTypes/Compress/ZipFile/ZipFake.cs @@ -0,0 +1,91 @@ +using System.IO; +using Compress.Utils; + +namespace Compress.ZipFile +{ + public partial class Zip + { + + public void ZipCreateFake() + { + if (ZipOpen != ZipOpenType.Closed) + { + return; + } + + ZipOpen = ZipOpenType.OpenFakeWrite; + } + + + public void ZipFileCloseFake(ulong fileOffset, out byte[] centralDir) + { + centralDir = null; + if (ZipOpen != ZipOpenType.OpenFakeWrite) + { + return; + } + + _zip64 = false; + bool lTrrntzip = true; + + _zipFs = new MemoryStream(); + + _centralDirStart = fileOffset; + + CrcCalculatorStream crcCs = new CrcCalculatorStream(_zipFs, true); + + foreach (LocalFile t in _localFiles) + { + t.CenteralDirectoryWrite(crcCs); + lTrrntzip &= t.TrrntZip; + } + + crcCs.Flush(); + crcCs.Close(); + + _centralDirSize = (ulong)_zipFs.Position; + + _fileComment = lTrrntzip ? ZipUtils.GetBytes("TORRENTZIPPED-" + crcCs.Crc.ToString("X8")) : new byte[0]; + ZipStatus = lTrrntzip ? ZipStatus.TrrntZip : ZipStatus.None; + + crcCs.Dispose(); + + _zip64 = (_centralDirStart >= 0xffffffff) || (_centralDirSize >= 0xffffffff) || (_localFiles.Count >= 0xffff); + + if (_zip64) + { + _endOfCenterDir64 = fileOffset + (ulong)_zipFs.Position; + Zip64EndOfCentralDirWrite(); + Zip64EndOfCentralDirectoryLocatorWrite(); + } + EndOfCentralDirWrite(); + + centralDir = ((MemoryStream)_zipFs).ToArray(); + _zipFs.Close(); + _zipFs.Dispose(); + ZipOpen = ZipOpenType.Closed; + } + + + public ZipReturn ZipFileAddFake(string filename, ulong fileOffset, ulong uncompressedSize, ulong compressedSize, byte[] crc32, out byte[] localHeader) + { + localHeader = null; + + if (ZipOpen != ZipOpenType.OpenFakeWrite) + { + return ZipReturn.ZipWritingToInputFile; + } + + LocalFile lf = new LocalFile(filename); + _localFiles.Add(lf); + + MemoryStream ms = new MemoryStream(); + lf.LocalFileHeaderFake(fileOffset, uncompressedSize, compressedSize, crc32, ms); + + localHeader = ms.ToArray(); + ms.Close(); + + return ZipReturn.ZipGood; + } + } +} diff --git a/SabreTools.FileTypes/Compress/ZipFile/ZipLocalFile.cs b/SabreTools.FileTypes/Compress/ZipFile/ZipLocalFile.cs new file mode 100644 index 00000000..29600148 --- /dev/null +++ b/SabreTools.FileTypes/Compress/ZipFile/ZipLocalFile.cs @@ -0,0 +1,741 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using Compress.Utils; +using Compress.ZipFile.ZLib; + +namespace Compress.ZipFile +{ + internal partial class LocalFile + { + private const uint LocalFileHeaderSignature = 0x04034b50; + private const uint CentralDirectoryHeaderSignature = 0x02014b50; + + private ushort _compressionMethod; + + private long _lastModFileTimeDate; + private long? mTime; + private long? cTime; + private long? aTime; + + private string _localHeaderFilename; + private ulong _compressedSize; + private ulong _localHeaderCompressedSize; + private ulong _localHeaderUncompressedSize; + + public ulong RelativeOffsetOfLocalHeader; // only in centeral directory + + private ulong _crc32Location; + private ulong _extraLocation; + private ulong _dataLocation; + + public LocalFile() + { + } + + public LocalFile(string filename, TimeStamps dateTime = null) + { + Zip64 = false; + GeneralPurposeBitFlag = 2; // Maximum Compression Deflating + _compressionMethod = 8; // Compression Method Deflate + + if (dateTime?.ModTime == null) + { + _lastModFileTimeDate = ZipUtils.trrntzipDateTime; + } + else + { + _lastModFileTimeDate = (long)dateTime.ModTime; + } + + FileName = filename; + } + + public string FileName { get; private set; } + public ushort GeneralPurposeBitFlag { get; private set; } + public byte[] CRC { get; private set; } + public ulong UncompressedSize { get; private set; } + + public bool Zip64 { get; private set; } + public bool TrrntZip { get; private set; } + + public long DateTime => mTime ?? _lastModFileTimeDate; + + public long? DateTimeCreate => cTime; + public long? DateTimeAccess => aTime; + + + public ulong LocalFilePos + { + get => RelativeOffsetOfLocalHeader; + set => RelativeOffsetOfLocalHeader = value; + } + + + public ZipReturn CenteralDirectoryRead(Stream zipFs) + { + try + { + using (BinaryReader br = new BinaryReader(zipFs, Encoding.UTF8, true)) + { + uint thisSignature = br.ReadUInt32(); + if (thisSignature != CentralDirectoryHeaderSignature) + { + return ZipReturn.ZipCentralDirError; + } + + br.ReadUInt16(); // Version Made By + + br.ReadUInt16(); // Version Needed To Extract + + GeneralPurposeBitFlag = br.ReadUInt16(); + _compressionMethod = br.ReadUInt16(); + if (_compressionMethod != 8 && _compressionMethod != 0) + { + if (_compressionMethod != 6 && _compressionMethod != 5 && _compressionMethod != 1) + { + return ZipReturn.ZipUnsupportedCompression; + } + return ZipReturn.ZipUnsupportedCompression; + } + + ushort lastModFileTime = br.ReadUInt16(); + ushort lastModFileDate = br.ReadUInt16(); + _lastModFileTimeDate = ZipUtils.SetDateTime(lastModFileDate, lastModFileTime); + + CRC = ReadCRC(br); + + _compressedSize = br.ReadUInt32(); + UncompressedSize = br.ReadUInt32(); + + ushort fileNameLength = br.ReadUInt16(); + ushort extraFieldLength = br.ReadUInt16(); + ushort fileCommentLength = br.ReadUInt16(); + + br.ReadUInt16(); // diskNumberStart + br.ReadUInt16(); // internalFileAttributes + br.ReadUInt32(); // externalFileAttributes + + RelativeOffsetOfLocalHeader = br.ReadUInt32(); + + byte[] bFileName = br.ReadBytes(fileNameLength); + FileName = (GeneralPurposeBitFlag & (1 << 11)) == 0 + ? ZipUtils.GetString(bFileName) + : Encoding.UTF8.GetString(bFileName, 0, fileNameLength); + + if (extraFieldLength > 0) + { + byte[] extraField = br.ReadBytes(extraFieldLength); + + + ZipReturn zr = ZipExtraField.ReadLocalExtraField(extraField, bFileName, this, true); + if (zr != ZipReturn.ZipGood) + return zr; + } + + if (ZipUtils.IsCodePage437(FileName) != ((GeneralPurposeBitFlag & (1 << 11)) == 0)) + TrrntZip = false; + + if (fileCommentLength > 0) + { + byte[] fileComment = br.ReadBytes(fileCommentLength); + } + + return ZipReturn.ZipGood; + } + } + catch + { + return ZipReturn.ZipCentralDirError; + } + } + + public void CenteralDirectoryWrite(Stream crcStream) + { + using (BinaryWriter bw = new BinaryWriter(crcStream, Encoding.UTF8, true)) + { + const uint header = 0x2014B50; + + List extraField = new List(); + + uint cdUncompressedSize; + if (UncompressedSize >= 0xffffffff) + { + Zip64 = true; + cdUncompressedSize = 0xffffffff; + extraField.AddRange(BitConverter.GetBytes(UncompressedSize)); + } + else + { + cdUncompressedSize = (uint)UncompressedSize; + } + + uint cdCompressedSize; + if (_compressedSize >= 0xffffffff) + { + Zip64 = true; + cdCompressedSize = 0xffffffff; + extraField.AddRange(BitConverter.GetBytes(_compressedSize)); + } + else + { + cdCompressedSize = (uint)_compressedSize; + } + + uint cdRelativeOffsetOfLocalHeader; + if (RelativeOffsetOfLocalHeader >= 0xffffffff) + { + Zip64 = true; + cdRelativeOffsetOfLocalHeader = 0xffffffff; + extraField.AddRange(BitConverter.GetBytes(RelativeOffsetOfLocalHeader)); + } + else + { + cdRelativeOffsetOfLocalHeader = (uint)RelativeOffsetOfLocalHeader; + } + + + if (extraField.Count > 0) + { + ushort exfl = (ushort)extraField.Count; + extraField.InsertRange(0, BitConverter.GetBytes((ushort)0x0001)); + extraField.InsertRange(2, BitConverter.GetBytes(exfl)); + } + + ushort extraFieldLength = (ushort)extraField.Count; + + byte[] bFileName; + if (ZipUtils.IsCodePage437(FileName)) + { + bFileName = ZipUtils.GetBytes(FileName); + } + else + { + GeneralPurposeBitFlag |= 1 << 11; + bFileName = Encoding.UTF8.GetBytes(FileName); + } + + ushort fileNameLength = (ushort)bFileName.Length; + + ushort versionNeededToExtract = (ushort)(Zip64 ? 45 : 20); + + ZipUtils.SetDateTime(_lastModFileTimeDate, out ushort lastModFileDate, out ushort lastModFileTime); + + bw.Write(header); + bw.Write((ushort)0); + bw.Write(versionNeededToExtract); + bw.Write(GeneralPurposeBitFlag); + bw.Write(_compressionMethod); + bw.Write(lastModFileTime); + bw.Write(lastModFileDate); + bw.Write(CRC[3]); + bw.Write(CRC[2]); + bw.Write(CRC[1]); + bw.Write(CRC[0]); + bw.Write(cdCompressedSize); + bw.Write(cdUncompressedSize); + bw.Write(fileNameLength); + bw.Write(extraFieldLength); + bw.Write((ushort)0); // file comment length + bw.Write((ushort)0); // disk number start + bw.Write((ushort)0); // internal file attributes + bw.Write((uint)0); // external file attributes + bw.Write(cdRelativeOffsetOfLocalHeader); + + bw.Write(bFileName, 0, fileNameLength); + bw.Write(extraField.ToArray(), 0, extraFieldLength); + // No File Comment + } + } + public ZipReturn LocalFileHeaderRead(Stream zipFs) + { + try + { + using (BinaryReader br = new BinaryReader(zipFs, Encoding.UTF8, true)) + { + + TrrntZip = true; + + zipFs.Position = (long)RelativeOffsetOfLocalHeader; + uint thisSignature = br.ReadUInt32(); + if (thisSignature != LocalFileHeaderSignature) + { + return ZipReturn.ZipLocalFileHeaderError; + } + + br.ReadUInt16(); // version needed to extract + ushort generalPurposeBitFlagLocal = br.ReadUInt16(); + if (generalPurposeBitFlagLocal != GeneralPurposeBitFlag) + { + TrrntZip = false; + } + + ushort tshort = br.ReadUInt16(); + if (tshort != _compressionMethod) + { + return ZipReturn.ZipLocalFileHeaderError; + } + + ushort lastModFileTime = br.ReadUInt16(); + ushort lastModFileDate = br.ReadUInt16(); + + long tTime = ZipUtils.SetDateTime(lastModFileDate, lastModFileTime); + if (tTime != _lastModFileTimeDate) + { + return ZipReturn.ZipLocalFileHeaderError; + } + + byte[] tCRC = ReadCRC(br); + _localHeaderCompressedSize = br.ReadUInt32(); + _localHeaderUncompressedSize = br.ReadUInt32(); + + ushort fileNameLength = br.ReadUInt16(); + ushort extraFieldLength = br.ReadUInt16(); + + + byte[] bFileName = br.ReadBytes(fileNameLength); + _localHeaderFilename = (generalPurposeBitFlagLocal & (1 << 11)) == 0 + ? ZipUtils.GetString(bFileName) + : Encoding.UTF8.GetString(bFileName, 0, fileNameLength); + + + Zip64 = false; + if (extraFieldLength > 0) + { + byte[] extraField = br.ReadBytes(extraFieldLength); + + ZipReturn zr = ZipExtraField.ReadLocalExtraField(extraField, bFileName, this, false); + if (zr != ZipReturn.ZipGood) + return zr; + } + + if (!ZipUtils.CompareString(FileName, _localHeaderFilename)) + { + TrrntZip = false; + if (!ZipUtils.CompareStringSlash(FileName, _localHeaderFilename)) + { + return ZipReturn.ZipLocalFileHeaderError; + } + } + + _dataLocation = (ulong)zipFs.Position; + + if ((GeneralPurposeBitFlag & 8) == 8) + { + zipFs.Position += (long)_compressedSize; + + tCRC = ReadCRC(br); + if (!ZipUtils.ByteArrCompare(tCRC, new byte[] { 0x50, 0x4b, 0x07, 0x08 })) + { + tCRC = ReadCRC(br); + } + _localHeaderCompressedSize = br.ReadUInt32(); + _localHeaderUncompressedSize = br.ReadUInt32(); + } + + if (ZipUtils.IsCodePage437(FileName) != ((GeneralPurposeBitFlag & (1 << 11)) == 0)) + TrrntZip = false; + + if (!ZipUtils.ByteArrCompare(tCRC, CRC)) + { + return ZipReturn.ZipLocalFileHeaderError; + } + + if (_localHeaderCompressedSize != _compressedSize) + { + return ZipReturn.ZipLocalFileHeaderError; + } + + if (_localHeaderUncompressedSize != UncompressedSize) + { + return ZipReturn.ZipLocalFileHeaderError; + } + + return ZipReturn.ZipGood; + } + } + catch + { + return ZipReturn.ZipLocalFileHeaderError; + } + } + + public ZipReturn LocalFileHeaderReadQuick(Stream zipFs) + { + try + { + using (BinaryReader br = new BinaryReader(zipFs, Encoding.UTF8, true)) + { + TrrntZip = true; + + zipFs.Position = (long)RelativeOffsetOfLocalHeader; + uint thisSignature = br.ReadUInt32(); + if (thisSignature != LocalFileHeaderSignature) + { + return ZipReturn.ZipLocalFileHeaderError; + } + + br.ReadUInt16(); // version needed to extract + GeneralPurposeBitFlag = br.ReadUInt16(); + if ((GeneralPurposeBitFlag & 8) == 8) + { + return ZipReturn.ZipCannotFastOpen; + } + + _compressionMethod = br.ReadUInt16(); + + ushort lastModFileTime = br.ReadUInt16(); + ushort lastModFileDate = br.ReadUInt16(); + _lastModFileTimeDate = ZipUtils.SetDateTime(lastModFileDate, lastModFileTime); + + CRC = ReadCRC(br); + _localHeaderCompressedSize = br.ReadUInt32(); + _localHeaderUncompressedSize = br.ReadUInt32(); + + ushort fileNameLength = br.ReadUInt16(); + ushort extraFieldLength = br.ReadUInt16(); + + byte[] bFileName = br.ReadBytes(fileNameLength); + + _localHeaderFilename = (GeneralPurposeBitFlag & (1 << 11)) == 0 + ? ZipUtils.GetString(bFileName) + : Encoding.UTF8.GetString(bFileName, 0, fileNameLength); + + Zip64 = false; + if (extraFieldLength > 0) + { + byte[] extraField = br.ReadBytes(extraFieldLength); + + ZipReturn zr = ZipExtraField.ReadLocalExtraField(extraField, bFileName, this, false); + if (zr != ZipReturn.ZipGood) + return zr; + } + + + _dataLocation = (ulong)zipFs.Position; + + FileName = _localHeaderFilename; + _compressedSize = _localHeaderCompressedSize; + UncompressedSize = _localHeaderUncompressedSize; + + if (ZipUtils.IsCodePage437(FileName) != ((GeneralPurposeBitFlag & (1 << 11)) == 0)) + TrrntZip = false; + + return ZipReturn.ZipGood; + } + } + catch + { + return ZipReturn.ZipLocalFileHeaderError; + } + } + + + private void LocalFileHeaderWrite(Stream zipFs) + { + using (BinaryWriter bw = new BinaryWriter(zipFs, Encoding.UTF8, true)) + { + Zip64 = UncompressedSize >= 0xffffffff; + + byte[] bFileName; + if (ZipUtils.IsCodePage437(FileName)) + { + bFileName = ZipUtils.GetBytes(FileName); + } + else + { + GeneralPurposeBitFlag |= 1 << 11; + bFileName = Encoding.UTF8.GetBytes(FileName); + } + + ushort versionNeededToExtract = (ushort)(Zip64 ? 45 : 20); + + RelativeOffsetOfLocalHeader = (ulong)zipFs.Position; + const uint header = 0x4034B50; + bw.Write(header); + bw.Write(versionNeededToExtract); + bw.Write(GeneralPurposeBitFlag); + bw.Write(_compressionMethod); + + ZipUtils.SetDateTime(_lastModFileTimeDate, out ushort lastModFileDate, out ushort lastModFileTime); + bw.Write(lastModFileTime); + bw.Write(lastModFileDate); + + _crc32Location = (ulong)zipFs.Position; + + // these 3 values will be set correctly after the file data has been written + bw.Write(0xffffffff); + bw.Write(0xffffffff); + bw.Write(0xffffffff); + + ushort fileNameLength = (ushort)bFileName.Length; + bw.Write(fileNameLength); + + ushort extraFieldLength = (ushort)(Zip64 ? 20 : 0); + bw.Write(extraFieldLength); + + bw.Write(bFileName, 0, fileNameLength); + + _extraLocation = (ulong)zipFs.Position; + if (Zip64) + bw.Write(new byte[20], 0, extraFieldLength); + } + } + + public void LocalFileHeaderFake(ulong filePosition, ulong uncompressedSize, ulong compressedSize, byte[] crc32, MemoryStream ms) + { + using (BinaryWriter bw = new BinaryWriter(ms, Encoding.UTF8, true)) + { + RelativeOffsetOfLocalHeader = filePosition; + TrrntZip = true; + UncompressedSize = uncompressedSize; + _compressedSize = compressedSize; + CRC = crc32; + + Zip64 = UncompressedSize >= 0xffffffff || _compressedSize >= 0xffffffff; + + byte[] bFileName; + if (ZipUtils.IsCodePage437(FileName)) + { + bFileName = ZipUtils.GetBytes(FileName); + } + else + { + GeneralPurposeBitFlag |= 1 << 11; + bFileName = Encoding.UTF8.GetBytes(FileName); + } + + ushort versionNeededToExtract = (ushort)(Zip64 ? 45 : 20); + + const uint header = 0x4034B50; + bw.Write(header); + bw.Write(versionNeededToExtract); + bw.Write(GeneralPurposeBitFlag); + bw.Write(_compressionMethod); + + ZipUtils.SetDateTime(_lastModFileTimeDate, out ushort lastModFileDate, out ushort lastModFileTime); + bw.Write(lastModFileTime); + bw.Write(lastModFileDate); + + uint tCompressedSize; + uint tUncompressedSize; + if (Zip64) + { + tCompressedSize = 0xffffffff; + tUncompressedSize = 0xffffffff; + } + else + { + tCompressedSize = (uint)_compressedSize; + tUncompressedSize = (uint)UncompressedSize; + } + + bw.Write(CRC[3]); + bw.Write(CRC[2]); + bw.Write(CRC[1]); + bw.Write(CRC[0]); + bw.Write(tCompressedSize); + bw.Write(tUncompressedSize); + + ushort fileNameLength = (ushort)bFileName.Length; + bw.Write(fileNameLength); + + ushort extraFieldLength = (ushort)(Zip64 ? 20 : 0); + bw.Write(extraFieldLength); + + bw.Write(bFileName, 0, fileNameLength); + + if (Zip64) + { + bw.Write((ushort)0x0001); // id + bw.Write((ushort)16); // data length + bw.Write(UncompressedSize); + bw.Write(_compressedSize); + } + } + } + public ZipReturn LocalFileOpenReadStream(Stream zipFs, bool raw, out Stream readStream, out ulong streamSize, out ushort compressionMethod) + { + streamSize = 0; + compressionMethod = _compressionMethod; + + readStream = null; + zipFs.Seek((long)_dataLocation, SeekOrigin.Begin); + + switch (_compressionMethod) + { + case 8: + if (raw) + { + readStream = zipFs; + streamSize = _compressedSize; + } + else + { + readStream=new System.IO.Compression.DeflateStream(zipFs,System.IO.Compression.CompressionMode.Decompress,true); + //readStream = new ZlibBaseStream(zipFs, CompressionMode.Decompress, CompressionLevel.Default, ZlibStreamFlavor.DEFLATE, true); + streamSize = UncompressedSize; + } + break; + case 0: + readStream = zipFs; + streamSize = _compressedSize; // same as UncompressedSize + break; + } + + return readStream == null ? ZipReturn.ZipErrorGettingDataStream : ZipReturn.ZipGood; + } + + public ZipReturn LocalFileOpenWriteStream(Stream zipFs, bool raw, bool trrntZip, ulong uncompressedSize, ushort compressionMethod, out Stream writeStream) + { + UncompressedSize = uncompressedSize; + _compressionMethod = compressionMethod; + + LocalFileHeaderWrite(zipFs); + _dataLocation = (ulong)zipFs.Position; + + if (raw) + { + writeStream = zipFs; + TrrntZip = trrntZip; + } + else + { + if (compressionMethod == 0) + { + writeStream = zipFs; + TrrntZip = false; + } + else + { + writeStream = new ZlibBaseStream(zipFs, CompressionMode.Compress, CompressionLevel.BestCompression, ZlibStreamFlavor.DEFLATE, true); + TrrntZip = true; + } + } + + return writeStream == null ? ZipReturn.ZipErrorGettingDataStream : ZipReturn.ZipGood; + } + + public ZipReturn LocalFileCloseWriteStream(Stream zipFs, byte[] crc32) + { + + _compressedSize = (ulong)zipFs.Position - _dataLocation; + + if (_compressedSize == 0 && UncompressedSize == 0) + { + LocalFileAddZeroLengthFile(zipFs); + _compressedSize = (ulong)zipFs.Position - _dataLocation; + } + else if (_compressedSize == 0 && UncompressedSize != 0) + { + return ZipReturn.ZipErrorWritingToOutputStream; + } + + CRC = crc32; + WriteCompressedSize(zipFs); + + return ZipReturn.ZipGood; + } + + private void FixFileForZip64(Stream zipFs) + { + long posNow = zipFs.Position; + using (BinaryWriter bw = new BinaryWriter(zipFs, Encoding.UTF8, true)) + { + // _crc32Location - 10 needs set to 45 + zipFs.Seek((long)_crc32Location - 10, SeekOrigin.Begin); + ushort versionNeededToExtract = 45; + bw.Write(versionNeededToExtract); + + zipFs.Seek((long)_crc32Location + 14, SeekOrigin.Begin); + ushort extraFieldLength = 20; + bw.Write(extraFieldLength); + } + ExpandFile(zipFs, (long)_extraLocation, posNow, 20); + zipFs.Position = posNow + 20; + } + + private static void ExpandFile(Stream stream, long offset, long length, int extraBytes) + { + const int bufferSize = 40960; + byte[] buffer = new byte[bufferSize]; + // Expand file + long pos = length; + while (pos > offset) + { + int toRead = pos - bufferSize >= offset ? bufferSize : (int)(pos - offset); + pos -= toRead; + stream.Position = pos; + stream.Read(buffer, 0, toRead); + stream.Position = pos + extraBytes; + stream.Write(buffer, 0, toRead); + } + } + + private void WriteCompressedSize(Stream zipFs) + { + if (_compressedSize >= 0xffffffff && !Zip64) + { + Zip64 = true; + FixFileForZip64(zipFs); + } + + + long posNow = zipFs.Position; + zipFs.Seek((long)_crc32Location, SeekOrigin.Begin); + using (BinaryWriter bw = new BinaryWriter(zipFs, Encoding.UTF8, true)) + { + uint tCompressedSize; + uint tUncompressedSize; + if (Zip64) + { + tCompressedSize = 0xffffffff; + tUncompressedSize = 0xffffffff; + } + else + { + tCompressedSize = (uint)_compressedSize; + tUncompressedSize = (uint)UncompressedSize; + } + + bw.Write(CRC[3]); + bw.Write(CRC[2]); + bw.Write(CRC[1]); + bw.Write(CRC[0]); + bw.Write(tCompressedSize); + bw.Write(tUncompressedSize); + + + // also need to write extradata + if (Zip64) + { + zipFs.Seek((long)_extraLocation, SeekOrigin.Begin); + bw.Write((ushort)0x0001); // id + bw.Write((ushort)16); // data length + bw.Write(UncompressedSize); + bw.Write(_compressedSize); + } + } + + zipFs.Seek(posNow, SeekOrigin.Begin); + } + + public static void LocalFileAddZeroLengthFile(Stream zipFs) + { + zipFs.WriteByte(03); + zipFs.WriteByte(00); + } + + private static byte[] ReadCRC(BinaryReader br) + { + byte[] tCRC = new byte[4]; + tCRC[3] = br.ReadByte(); + tCRC[2] = br.ReadByte(); + tCRC[1] = br.ReadByte(); + tCRC[0] = br.ReadByte(); + return tCRC; + } + } + +} diff --git a/SabreTools.FileTypes/Compress/ZipFile/ZipRead.cs b/SabreTools.FileTypes/Compress/ZipFile/ZipRead.cs new file mode 100644 index 00000000..5a07820a --- /dev/null +++ b/SabreTools.FileTypes/Compress/ZipFile/ZipRead.cs @@ -0,0 +1,251 @@ +using System; +using System.IO; +using Compress.Utils; +using FileInfo = RVIO.FileInfo; +using FileStream = RVIO.FileStream; + +namespace Compress.ZipFile +{ + public partial class Zip + { + + public ZipReturn ZipFileOpen(string newFilename, long timestamp, bool readHeaders) + { + ZipFileClose(); + ZipStatus = ZipStatus.None; + _zip64 = false; + _centralDirStart = 0; + _centralDirSize = 0; + _zipFileInfo = null; + + try + { + if (!RVIO.File.Exists(newFilename)) + { + ZipFileClose(); + return ZipReturn.ZipErrorFileNotFound; + } + _zipFileInfo = new FileInfo(newFilename); + if (timestamp != -1 && _zipFileInfo.LastWriteTime != timestamp) + { + ZipFileClose(); + return ZipReturn.ZipErrorTimeStamp; + } + int errorCode = FileStream.OpenFileRead(newFilename, out _zipFs); + if (errorCode != 0) + { + ZipFileClose(); + if (errorCode == 32) + { + return ZipReturn.ZipFileLocked; + } + return ZipReturn.ZipErrorOpeningFile; + } + } + catch (PathTooLongException) + { + ZipFileClose(); + return ZipReturn.ZipFileNameToLong; + } + catch (IOException) + { + ZipFileClose(); + return ZipReturn.ZipErrorOpeningFile; + } + ZipOpen = ZipOpenType.OpenRead; + + if (!readHeaders) + { + return ZipReturn.ZipGood; + } + + + return ZipFileReadHeaders(); + } + + + public ZipReturn ZipFileOpen(Stream inStream) + { + ZipFileClose(); + ZipStatus = ZipStatus.None; + _zip64 = false; + _centralDirStart = 0; + _centralDirSize = 0; + _zipFileInfo = null; + _zipFs = inStream; + + ZipOpen = ZipOpenType.OpenRead; + return ZipFileReadHeaders(); + } + + + private void zipFileCloseRead() + { + if (_zipFs != null) + { + _zipFs.Close(); + _zipFs.Dispose(); + } + ZipOpen = ZipOpenType.Closed; + } + + + private ZipReturn ZipFileReadHeaders() + { + try + { + ZipReturn zRet = FindEndOfCentralDirSignature(); + if (zRet != ZipReturn.ZipGood) + { + ZipFileClose(); + return zRet; + } + + ulong endOfCentralDir = (ulong)_zipFs.Position; + zRet = EndOfCentralDirRead(); + if (zRet != ZipReturn.ZipGood) + { + ZipFileClose(); + return zRet; + } + + + // check if ZIP64 header is required + bool zip64Required = (_centralDirStart == 0xffffffff || _centralDirSize == 0xffffffff || _localFilesCount == 0xffff); + + // check for a ZIP64 header + _zipFs.Position = (long)endOfCentralDir - 20; + zRet = Zip64EndOfCentralDirectoryLocatorRead(); + if (zRet == ZipReturn.ZipGood) + { + _zipFs.Position = (long)_endOfCenterDir64; + zRet = Zip64EndOfCentralDirRead(); + if (zRet == ZipReturn.ZipGood) + { + _zip64 = true; + endOfCentralDir = _endOfCenterDir64; + } + } + + if (zip64Required && !_zip64) + { + return ZipReturn.Zip64EndOfCentralDirError; + } + + bool trrntzip = false; + + // check if the ZIP has a valid TorrentZip file comment + if (_fileComment.Length == 22) + { + if (ZipUtils.GetString(_fileComment).Substring(0, 14) == "TORRENTZIPPED-") + { + CrcCalculatorStream crcCs = new CrcCalculatorStream(_zipFs, true); + byte[] buffer = new byte[_centralDirSize]; + _zipFs.Position = (long)_centralDirStart; + crcCs.Read(buffer, 0, (int)_centralDirSize); + crcCs.Flush(); + crcCs.Close(); + + uint r = (uint)crcCs.Crc; + crcCs.Dispose(); + + string tcrc = ZipUtils.GetString(_fileComment).Substring(14, 8); + string zcrc = r.ToString("X8"); + if (string.Compare(tcrc, zcrc, StringComparison.Ordinal) == 0) + { + trrntzip = true; + } + } + } + + if (zip64Required != _zip64) + trrntzip = false; + + // now read the central directory + _zipFs.Position = (long)_centralDirStart; + + _localFiles.Clear(); + _localFiles.Capacity = (int)_localFilesCount; + for (int i = 0; i < _localFilesCount; i++) + { + LocalFile lc = new LocalFile(); + zRet = lc.CenteralDirectoryRead(_zipFs); + if (zRet != ZipReturn.ZipGood) + { + ZipFileClose(); + return zRet; + } + _zip64 |= lc.Zip64; + _localFiles.Add(lc); + } + + for (int i = 0; i < _localFilesCount; i++) + { + zRet = _localFiles[i].LocalFileHeaderRead(_zipFs); + if (zRet != ZipReturn.ZipGood) + { + ZipFileClose(); + return zRet; + } + trrntzip &= _localFiles[i].TrrntZip; + } + + // check trrntzip file order + if (trrntzip) + { + for (int i = 0; i < _localFilesCount - 1; i++) + { + if (ZipUtils.TrrntZipStringCompare(_localFiles[i].FileName, _localFiles[i + 1].FileName) < 0) + { + continue; + } + trrntzip = false; + break; + } + } + + // check trrntzip directories + if (trrntzip) + { + for (int i = 0; i < _localFilesCount - 1; i++) + { + // see if we found a directory + string filename0 = _localFiles[i].FileName; + if (filename0.Substring(filename0.Length - 1, 1) != "/") + { + continue; + } + + // see if the next file is in that directory + string filename1 = _localFiles[i + 1].FileName; + if (filename1.Length <= filename0.Length) + { + continue; + } + if (ZipUtils.TrrntZipStringCompare(filename0, filename1.Substring(0, filename0.Length)) != 0) + { + continue; + } + + // if we found a file in the directory then we do not need the directory entry + trrntzip = false; + break; + } + } + + if (trrntzip) + { + ZipStatus |= ZipStatus.TrrntZip; + } + + return ZipReturn.ZipGood; + } + catch + { + ZipFileClose(); + return ZipReturn.ZipErrorReadingFile; + } + } + + } +} diff --git a/SabreTools.FileTypes/Compress/ZipFile/ZipReadStream.cs b/SabreTools.FileTypes/Compress/ZipFile/ZipReadStream.cs new file mode 100644 index 00000000..4e80eacd --- /dev/null +++ b/SabreTools.FileTypes/Compress/ZipFile/ZipReadStream.cs @@ -0,0 +1,80 @@ +using System.IO; +using Compress.ZipFile.ZLib; + +namespace Compress.ZipFile +{ + public partial class Zip + { + public ZipReturn ZipFileOpenReadStream(int index, out Stream stream, out ulong streamSize) + { + return ZipFileOpenReadStream(index, false, out stream, out streamSize, out ushort _); + } + + public ZipReturn ZipFileOpenReadStream(int index, bool raw, out Stream stream, out ulong streamSize, out ushort compressionMethod) + { + ZipFileCloseReadStream(); + + streamSize = 0; + compressionMethod = 0; + stream = null; + if (ZipOpen != ZipOpenType.OpenRead) + { + return ZipReturn.ZipReadingFromOutputFile; + } + + ZipReturn zRet = _localFiles[index].LocalFileHeaderRead(_zipFs); + if (zRet != ZipReturn.ZipGood) + { + ZipFileClose(); + return zRet; + } + + zRet = _localFiles[index].LocalFileOpenReadStream(_zipFs, raw, out stream, out streamSize, out compressionMethod); + _compressionStream = stream; + return zRet; + } + + public ZipReturn ZipFileOpenReadStreamQuick(ulong pos, bool raw, out Stream stream, out ulong streamSize, out ushort compressionMethod) + { + ZipFileCloseReadStream(); + + LocalFile tmpFile = new LocalFile { LocalFilePos = pos }; + _localFiles.Clear(); + _localFiles.Add(tmpFile); + ZipReturn zRet = tmpFile.LocalFileHeaderReadQuick(_zipFs); + if (zRet != ZipReturn.ZipGood) + { + stream = null; + streamSize = 0; + compressionMethod = 0; + return zRet; + } + + zRet = tmpFile.LocalFileOpenReadStream(_zipFs, raw, out stream, out streamSize, out compressionMethod); + _compressionStream = stream; + return zRet; + } + + + public ZipReturn ZipFileCloseReadStream() + { + if (_compressionStream == null) + return ZipReturn.ZipGood; + if (_compressionStream is ZlibBaseStream dfStream) + { + dfStream.Close(); + dfStream.Dispose(); + } + else if (_compressionStream is System.IO.Compression.DeflateStream dfIOStream) + { + dfIOStream.Close(); + dfIOStream.Dispose(); + } + _compressionStream = null; + + return ZipReturn.ZipGood; + } + + + } +} diff --git a/SabreTools.FileTypes/Compress/ZipFile/ZipUtils.cs b/SabreTools.FileTypes/Compress/ZipFile/ZipUtils.cs new file mode 100644 index 00000000..e4078639 --- /dev/null +++ b/SabreTools.FileTypes/Compress/ZipFile/ZipUtils.cs @@ -0,0 +1,242 @@ +using System; +using System.Text; + +namespace Compress.ZipFile +{ + public static class ZipUtils + { + // according to the zip documents, zip filesname are stored as MS-DOS Code Page 437. + // (Unless the uncode flag is set, in which case they are stored as UTF-8. + private static Encoding enc = Encoding.GetEncoding(437); + + public static string GetString(byte[] byteArr) + { + return enc.GetString(byteArr); + } + + // to test if a filename can be stored as codepage 437 we take the filename string + // convert it to bytes using the 437 code page, and then convert it back to a string + // and we see if we lost characters as a result of the conversion there and back. + internal static bool IsCodePage437(string s) + { + byte[] bOut = enc.GetBytes(s); + string sOut = enc.GetString(bOut); + + return CompareString(s, sOut); + } + + internal static byte[] GetBytes(string s) + { + return enc.GetBytes(s); + } + + internal static bool CompareString(string s1, string s2) + { + char[] c1 = s1.ToCharArray(); + char[] c2 = s2.ToCharArray(); + + if (c1.Length != c2.Length) + { + return false; + } + + for (int i = 0; i < c1.Length; i++) + { + if (c1[i] != c2[i]) + { + return false; + } + } + return true; + } + + internal static bool CompareStringSlash(string s1, string s2) + { + char[] c1 = s1.ToCharArray(); + char[] c2 = s2.ToCharArray(); + + if (c1.Length != c2.Length) + { + return false; + } + + for (int i = 0; i < c1.Length; i++) + { + if (c1[i] == '/') c1[i] = '\\'; + if (c2[i] == '/') c2[i] = '\\'; + if (c1[i] != c2[i]) + { + return false; + } + } + return true; + } + + + internal static bool ByteArrCompare(byte[] b0, byte[] b1) + { + if ((b0 == null) || (b1 == null)) + { + return false; + } + if (b0.Length != b1.Length) + { + return false; + } + + for (int i = 0; i < b0.Length; i++) + { + if (b0[i] != b1[i]) + { + return false; + } + } + return true; + } + + + internal static int TrrntZipStringCompare(string string1, string string2) + { + char[] bytes1 = string1.ToCharArray(); + char[] bytes2 = string2.ToCharArray(); + + int pos1 = 0; + int pos2 = 0; + + for (; ; ) + { + if (pos1 == bytes1.Length) + { + return pos2 == bytes2.Length ? 0 : -1; + } + if (pos2 == bytes2.Length) + { + return 1; + } + + int byte1 = bytes1[pos1++]; + int byte2 = bytes2[pos2++]; + + if (byte1 >= 65 && byte1 <= 90) + { + byte1 += 0x20; + } + if (byte2 >= 65 && byte2 <= 90) + { + byte2 += 0x20; + } + + if (byte1 < byte2) + { + return -1; + } + if (byte1 > byte2) + { + return 1; + } + } + } + + public static string ZipErrorMessageText(ZipReturn zS) + { + string ret = "Unknown"; + switch (zS) + { + case ZipReturn.ZipGood: + ret = ""; + break; + case ZipReturn.ZipFileCountError: + ret = "The number of file in the Zip does not mach the number of files in the Zips Centeral Directory"; + break; + case ZipReturn.ZipSignatureError: + ret = "An unknown Signature Block was found in the Zip"; + break; + case ZipReturn.ZipExtraDataOnEndOfZip: + ret = "Extra Data was found on the end of the Zip"; + break; + case ZipReturn.ZipUnsupportedCompression: + ret = "An unsupported Compression method was found in the Zip, if you recompress this zip it will be usable"; + break; + case ZipReturn.ZipLocalFileHeaderError: + ret = "Error reading a zipped file header information"; + break; + case ZipReturn.ZipCentralDirError: + ret = "There is an error in the Zip Centeral Directory"; + break; + case ZipReturn.ZipReadingFromOutputFile: + ret = "Trying to write to a Zip file open for output only"; + break; + case ZipReturn.ZipWritingToInputFile: + ret = "Tring to read from a Zip file open for input only"; + break; + case ZipReturn.ZipErrorGettingDataStream: + ret = "Error creating Data Stream"; + break; + case ZipReturn.ZipCRCDecodeError: + ret = "CRC error"; + break; + case ZipReturn.ZipDecodeError: + ret = "Error unzipping a file"; + break; + } + + return ret; + } + public const long fileTimeToUTCTime = 504911232000000000; + public const long epochTimeToUTCTime = 621355968000000000; + public const long trrntzipDateTime = 629870671200000000; + + private const long TicksPerMillisecond = 10000; + private const long TicksPerSecond = TicksPerMillisecond * 1000; + + public static void SetDateTime(long ticks, out ushort DosFileDate, out ushort DosFileTime) + { + DateTime DateTime = new DateTime(ticks, DateTimeKind.Unspecified); + DosFileDate = (ushort)((DateTime.Day & 0x1f) | ((DateTime.Month & 0x0f) << 5) | (((DateTime.Year - 1980) & 0x7f) << 9)); + DosFileTime = (ushort)(((DateTime.Second >> 1) & 0x1f) | ((DateTime.Minute & 0x3f) << 5) | ((DateTime.Hour & 0x1f) << 11)); + } + + public static long SetDateTime(ushort DosFileDate, ushort DosFileTime) + { + if (DosFileDate == 0) + return 0; + + int second = (DosFileTime & 0x1f) << 1; + int minute = (DosFileTime >> 5) & 0x3f; + int hour = (DosFileTime >> 11) & 0x1f; + + int day = DosFileDate & 0x1f; + int month = (DosFileDate >> 5) & 0x0f; + int year = ((DosFileDate >> 9) & 0x7f) + 1980; + + // valid hours 0 to 23 + // valid minutes 0 to 59 + // valid seconds 0 to 59 + // valid month 1 to 12 + // valid day 1 to 31 + + if (hour > 23 || minute > 59 || second > 59 || month < 1 || month > 12 || day < 1 || day > 31) + return 0; + + try + { + return new DateTime(year, month, day, hour, minute, second, DateTimeKind.Unspecified).Ticks; + } + catch + { + return 0; + } + } + + public static long FileTimeToUTCTime(long ticks) + { + return ticks + fileTimeToUTCTime; + } + + public static long SetDateTimeFromUnixSeconds(int seconds) + { + return seconds * TicksPerSecond + epochTimeToUTCTime; + } + + } +} diff --git a/SabreTools.FileTypes/Compress/ZipFile/ZipWrite.cs b/SabreTools.FileTypes/Compress/ZipFile/ZipWrite.cs new file mode 100644 index 00000000..fbc67e2f --- /dev/null +++ b/SabreTools.FileTypes/Compress/ZipFile/ZipWrite.cs @@ -0,0 +1,109 @@ +using Compress.Utils; +using FileInfo = RVIO.FileInfo; +using FileStream = RVIO.FileStream; + +// UInt16 = ushort +// UInt32 = uint +// ULong = ulong + +namespace Compress.ZipFile +{ + public partial class Zip + { + private ulong _centralDirStart; + private ulong _centralDirSize; + private ulong _endOfCenterDir64; + + public ZipReturn ZipFileCreate(string newFilename) + { + if (ZipOpen != ZipOpenType.Closed) + { + return ZipReturn.ZipFileAlreadyOpen; + } + + DirUtil.CreateDirForFile(newFilename); + _zipFileInfo = new FileInfo(newFilename); + + int errorCode = FileStream.OpenFileWrite(newFilename, out _zipFs); + if (errorCode != 0) + { + ZipFileClose(); + return ZipReturn.ZipErrorOpeningFile; + } + ZipOpen = ZipOpenType.OpenWrite; + return ZipReturn.ZipGood; + } + + private void zipFileCloseWrite() + { + bool lTrrntzip = true; + + _centralDirStart = (ulong)_zipFs.Position; + + using (CrcCalculatorStream crcCs = new CrcCalculatorStream(_zipFs, true)) + { + foreach (LocalFile t in _localFiles) + { + t.CenteralDirectoryWrite(crcCs); + lTrrntzip &= t.TrrntZip; + } + + crcCs.Flush(); + crcCs.Close(); + + _centralDirSize = (ulong)_zipFs.Position - _centralDirStart; + + _fileComment = lTrrntzip ? ZipUtils.GetBytes("TORRENTZIPPED-" + crcCs.Crc.ToString("X8")) : new byte[0]; + ZipStatus = lTrrntzip ? ZipStatus.TrrntZip : ZipStatus.None; + } + + _zip64 = false; + _zip64 |= _centralDirStart >= 0xffffffff; + _zip64 |= _centralDirSize >= 0xffffffff; + _zip64 |= _localFiles.Count >= 0xffff; + + if (_zip64) + { + _endOfCenterDir64 = (ulong)_zipFs.Position; + Zip64EndOfCentralDirWrite(); + Zip64EndOfCentralDirectoryLocatorWrite(); + } + EndOfCentralDirWrite(); + + _zipFs.SetLength(_zipFs.Position); + _zipFs.Flush(); + _zipFs.Close(); + _zipFs.Dispose(); + _zipFileInfo = new FileInfo(_zipFileInfo.FullName); + ZipOpen = ZipOpenType.Closed; + } + + + public void ZipFileCloseFailed() + { + switch (ZipOpen) + { + case ZipOpenType.Closed: + return; + case ZipOpenType.OpenRead: + if (_zipFs != null) + { + _zipFs.Close(); + _zipFs.Dispose(); + } + break; + case ZipOpenType.OpenWrite: + _zipFs.Flush(); + _zipFs.Close(); + _zipFs.Dispose(); + if (_zipFileInfo != null) + RVIO.File.Delete(_zipFileInfo.FullName); + _zipFileInfo = null; + break; + } + + ZipOpen = ZipOpenType.Closed; + } + + } +} diff --git a/SabreTools.FileTypes/Compress/ZipFile/ZipWriteStream.cs b/SabreTools.FileTypes/Compress/ZipFile/ZipWriteStream.cs new file mode 100644 index 00000000..7d2e911c --- /dev/null +++ b/SabreTools.FileTypes/Compress/ZipFile/ZipWriteStream.cs @@ -0,0 +1,73 @@ +using System.IO; +using Compress.Utils; +using Compress.ZipFile.ZLib; + +// UInt16 = ushort +// UInt32 = uint +// ULong = ulong + +namespace Compress.ZipFile +{ + public partial class Zip + { + private Stream _compressionStream; + + public ZipReturn ZipFileOpenWriteStream(bool raw, bool trrntzip, string filename, ulong uncompressedSize, ushort compressionMethod, out Stream stream, TimeStamps timeStamp = null) + { + stream = null; + if (ZipOpen != ZipOpenType.OpenWrite) + { + return ZipReturn.ZipWritingToInputFile; + } + + LocalFile lf = new LocalFile(filename, timeStamp); + + ZipReturn retVal = lf.LocalFileOpenWriteStream(_zipFs, raw, trrntzip, uncompressedSize, compressionMethod, out stream); + + _compressionStream = stream; + _localFiles.Add(lf); + + return retVal; + } + + public void ZipFileAddZeroLengthFile() + { + LocalFile.LocalFileAddZeroLengthFile(_zipFs); + } + + + public ZipReturn ZipFileCloseWriteStream(byte[] crc32) + { + if (_compressionStream is ZlibBaseStream dfStream) + { + dfStream.Flush(); + dfStream.Close(); + dfStream.Dispose(); + } + _compressionStream = null; + + return _localFiles[_localFiles.Count - 1].LocalFileCloseWriteStream(_zipFs, crc32); + } + + public ZipReturn ZipFileRollBack() + { + if (ZipOpen != ZipOpenType.OpenWrite) + { + return ZipReturn.ZipWritingToInputFile; + } + + int fileCount = _localFiles.Count; + if (fileCount == 0) + { + return ZipReturn.ZipErrorRollBackFile; + } + + LocalFile lf = _localFiles[fileCount - 1]; + + _localFiles.RemoveAt(fileCount - 1); + _zipFs.Position = (long)lf.LocalFilePos; + return ZipReturn.ZipGood; + } + + } +} diff --git a/SabreTools.FileTypes/Compress/ZipFile/zipFile.cs b/SabreTools.FileTypes/Compress/ZipFile/zipFile.cs deleted file mode 100644 index 32eb1a86..00000000 --- a/SabreTools.FileTypes/Compress/ZipFile/zipFile.cs +++ /dev/null @@ -1,1957 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using Compress.Utils; -using Compress.ZipFile.ZLib; -using Directory = RVIO.Directory; -using FileInfo = RVIO.FileInfo; -using FileStream = RVIO.FileStream; -using Path = RVIO.Path; - -// UInt16 = ushort -// UInt32 = uint -// ULong = ulong - -namespace Compress.ZipFile -{ - public class ZipFile : ICompress - { - private const uint LocalFileHeaderSignature = 0x04034b50; - private const uint CentralDirectoryHeaderSigniature = 0x02014b50; - private const uint EndOfCentralDirSignature = 0x06054b50; - private const uint Zip64EndOfCentralDirSignatue = 0x06064b50; - private const uint Zip64EndOfCentralDirectoryLocator = 0x07064b50; - private readonly List _localFiles = new List(); - - - private FileInfo _zipFileInfo; - - private ulong _centerDirStart; - private ulong _centerDirSize; - private ulong _endOfCenterDir64; - - private byte[] _fileComment; - private Stream _zipFs; - private Stream _compressionStream; - - private uint _localFilesCount; - - private bool _zip64; - - public string ZipFilename => _zipFileInfo != null ? _zipFileInfo.FullName : string.Empty; - - public long TimeStamp => _zipFileInfo?.LastWriteTime ?? 0; - - public ZipOpenType ZipOpen { get; private set; } - - - public ZipStatus ZipStatus { get; set; } - - public int LocalFilesCount() - { - return _localFiles.Count; - } - - public string Filename(int i) - { - return _localFiles[i].FileName; - } - - public ulong UncompressedSize(int i) - { - return _localFiles[i].UncompressedSize; - } - - public ulong? LocalHeader(int i) - { - return (_localFiles[i].GeneralPurposeBitFlag & 8) == 0 ? (ulong?)_localFiles[i].RelativeOffsetOfLocalHeader : null; - } - - public byte[] CRC32(int i) - { - return _localFiles[i].CRC; - } - - public bool IsDirectory(int i) - { - try - { - if (_localFiles[i].UncompressedSize != 0) - return false; - string filename = _localFiles[i].FileName; - char lastChar = filename[filename.Length - 1]; - return lastChar == '/' || lastChar == '\\'; - } - catch (Exception ex) - { - ArgumentException argEx = new ArgumentException("Error in file " + _zipFileInfo?.FullName + " : " + ex.Message, ex.InnerException); - throw argEx; - } - - } - - public DateTime LastModified(int i) - { - return _localFiles[i].DateTime; - } - - public ZipReturn ZipFileCreate(string newFilename) - { - if (ZipOpen != ZipOpenType.Closed) - { - return ZipReturn.ZipFileAlreadyOpen; - } - - CreateDirForFile(newFilename); - _zipFileInfo = new FileInfo(newFilename); - - int errorCode = FileStream.OpenFileWrite(newFilename, out _zipFs); - if (errorCode != 0) - { - ZipFileClose(); - return ZipReturn.ZipErrorOpeningFile; - } - ZipOpen = ZipOpenType.OpenWrite; - return ZipReturn.ZipGood; - } - - public void ZipFileClose() - { - if (ZipOpen == ZipOpenType.Closed) - { - return; - } - - if (ZipOpen == ZipOpenType.OpenRead) - { - if (_zipFs != null) - { - _zipFs.Close(); - _zipFs.Dispose(); - } - ZipOpen = ZipOpenType.Closed; - return; - } - - _zip64 = false; - bool lTrrntzip = true; - - _centerDirStart = (ulong)_zipFs.Position; - - using (CrcCalculatorStream crcCs = new CrcCalculatorStream(_zipFs, true)) - { - foreach (LocalFile t in _localFiles) - { - t.CenteralDirectoryWrite(crcCs); - _zip64 |= t.Zip64; - lTrrntzip &= t.TrrntZip; - } - - crcCs.Flush(); - crcCs.Close(); - - _centerDirSize = (ulong)_zipFs.Position - _centerDirStart; - - _fileComment = lTrrntzip ? GetBytes("TORRENTZIPPED-" + crcCs.Crc.ToString("X8")) : new byte[0]; - ZipStatus = lTrrntzip ? ZipStatus.TrrntZip : ZipStatus.None; - } - _zip64 |= _centerDirStart >= 0xffffffff; - _zip64 |= _centerDirSize >= 0xffffffff; - _zip64 |= _localFiles.Count >= 0xffff; - - if (_zip64) - { - _endOfCenterDir64 = (ulong)_zipFs.Position; - Zip64EndOfCentralDirWrite(); - Zip64EndOfCentralDirectoryLocatorWrite(); - } - EndOfCentralDirWrite(); - - _zipFs.SetLength(_zipFs.Position); - _zipFs.Flush(); - _zipFs.Close(); - _zipFs.Dispose(); - _zipFileInfo = new FileInfo(_zipFileInfo.FullName); - ZipOpen = ZipOpenType.Closed; - } - - - public void ZipFileCloseFailed() - { - switch (ZipOpen) - { - case ZipOpenType.Closed: - return; - case ZipOpenType.OpenRead: - if (_zipFs != null) - { - _zipFs.Close(); - _zipFs.Dispose(); - } - break; - case ZipOpenType.OpenWrite: - _zipFs.Flush(); - _zipFs.Close(); - _zipFs.Dispose(); - if (_zipFileInfo != null) - RVIO.File.Delete(_zipFileInfo.FullName); - _zipFileInfo = null; - break; - } - - ZipOpen = ZipOpenType.Closed; - } - - public ZipReturn ZipFileCloseReadStream() - { - if (_compressionStream == null) - return ZipReturn.ZipGood; - if (_compressionStream is ZlibBaseStream dfStream) - { - dfStream.Close(); - dfStream.Dispose(); - } - _compressionStream = null; - - return ZipReturn.ZipGood; - } - - public ZipReturn ZipFileOpenWriteStream(bool raw, bool trrntzip, string filename, ulong uncompressedSize, ushort compressionMethod, uint? datetime, out Stream stream) - { - stream = null; - if (ZipOpen != ZipOpenType.OpenWrite) - { - return ZipReturn.ZipWritingToInputFile; - } - - LocalFile lf = new LocalFile(filename, datetime); - - ZipReturn retVal = lf.LocalFileOpenWriteStream(_zipFs, raw, trrntzip, uncompressedSize, compressionMethod, out stream); - - _compressionStream = stream; - _localFiles.Add(lf); - - return retVal; - } - - - public ZipReturn ZipFileCloseWriteStream(byte[] crc32) - { - if (_compressionStream is ZlibBaseStream dfStream) - { - dfStream.Flush(); - dfStream.Close(); - dfStream.Dispose(); - } - _compressionStream = null; - - return _localFiles[_localFiles.Count - 1].LocalFileCloseWriteStream(_zipFs, crc32); - } - - public ZipReturn ZipFileRollBack() - { - if (ZipOpen != ZipOpenType.OpenWrite) - { - return ZipReturn.ZipWritingToInputFile; - } - - int fileCount = _localFiles.Count; - if (fileCount == 0) - { - return ZipReturn.ZipErrorRollBackFile; - } - - LocalFile lf = _localFiles[fileCount - 1]; - - _localFiles.RemoveAt(fileCount - 1); - _zipFs.Position = (long)lf.LocalFilePos; - return ZipReturn.ZipGood; - } - - public void ZipFileAddZeroLengthFile() - { - LocalFile.LocalFileAddZeroLengthFile(_zipFs); - } - - /* - public void BreakTrrntZip(string filename) - { - _zipFs = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite); - using (BinaryReader zipBr = new BinaryReader(_zipFs,Encoding.UTF8,true)) - { - _zipFs.Position = _zipFs.Length - 22; - byte[] fileComment = zipBr.ReadBytes(22); - if (GetString(fileComment).Substring(0, 14) == "TORRENTZIPPED-") - { - _zipFs.Position = _zipFs.Length - 8; - _zipFs.WriteByte(48); _zipFs.WriteByte(48); _zipFs.WriteByte(48); _zipFs.WriteByte(48); - _zipFs.WriteByte(48); _zipFs.WriteByte(48); _zipFs.WriteByte(48); _zipFs.WriteByte(48); - } - } - _zipFs.Flush(); - _zipFs.Close(); - } - */ - - ~ZipFile() - { - if (_zipFs != null) - { - _zipFs.Close(); - _zipFs.Dispose(); - } - } - - - private ZipReturn FindEndOfCentralDirSignature() - { - long fileSize = _zipFs.Length; - long maxBackSearch = 0xffff; - - if (_zipFs.Length < maxBackSearch) - { - maxBackSearch = fileSize; - } - - const long buffSize = 0x400; - - byte[] buffer = new byte[buffSize + 4]; - - long backPosition = 4; - while (backPosition < maxBackSearch) - { - backPosition += buffSize; - if (backPosition > maxBackSearch) - { - backPosition = maxBackSearch; - } - - long readSize = backPosition > buffSize + 4 ? buffSize + 4 : backPosition; - - _zipFs.Position = fileSize - backPosition; - - _zipFs.Read(buffer, 0, (int)readSize); - - - for (long i = readSize - 4; i >= 0; i--) - { - if (buffer[i] != 0x50 || buffer[i + 1] != 0x4b || buffer[i + 2] != 0x05 || buffer[i + 3] != 0x06) - { - continue; - } - - _zipFs.Position = fileSize - backPosition + i; - return ZipReturn.ZipGood; - } - } - return ZipReturn.ZipCentralDirError; - } - - - private ZipReturn EndOfCentralDirRead() - { - using (BinaryReader zipBr = new BinaryReader(_zipFs, Encoding.UTF8, true)) - { - uint thisSignature = zipBr.ReadUInt32(); - if (thisSignature != EndOfCentralDirSignature) - { - return ZipReturn.ZipEndOfCentralDirectoryError; - } - - ushort tushort = zipBr.ReadUInt16(); // NumberOfThisDisk - if (tushort != 0) - { - return ZipReturn.ZipEndOfCentralDirectoryError; - } - - tushort = zipBr.ReadUInt16(); // NumberOfThisDiskCenterDir - if (tushort != 0) - { - return ZipReturn.ZipEndOfCentralDirectoryError; - } - - _localFilesCount = zipBr.ReadUInt16(); // TotalNumberOfEnteriesDisk - - tushort = zipBr.ReadUInt16(); // TotalNumber of enteries in the central directory - if (tushort != _localFilesCount) - { - return ZipReturn.ZipEndOfCentralDirectoryError; - } - - _centerDirSize = zipBr.ReadUInt32(); // SizeOfCenteralDir - _centerDirStart = zipBr.ReadUInt32(); // Offset - - ushort zipFileCommentLength = zipBr.ReadUInt16(); - - _fileComment = zipBr.ReadBytes(zipFileCommentLength); - - if (_zipFs.Position != _zipFs.Length) - { - ZipStatus |= ZipStatus.ExtraData; - } - - return ZipReturn.ZipGood; - } - } - - private void EndOfCentralDirWrite() - { - using (BinaryWriter bw = new BinaryWriter(_zipFs, Encoding.UTF8, true)) - { - bw.Write(EndOfCentralDirSignature); - bw.Write((ushort)0); // NumberOfThisDisk - bw.Write((ushort)0); // NumberOfThisDiskCenterDir - bw.Write((ushort)(_localFiles.Count >= 0xffff ? 0xffff : _localFiles.Count)); // TotalNumberOfEnteriesDisk - bw.Write((ushort)(_localFiles.Count >= 0xffff ? 0xffff : _localFiles.Count)); // TotalNumber of enteries in the central directory - bw.Write((uint)(_centerDirSize >= 0xffffffff ? 0xffffffff : _centerDirSize)); - bw.Write((uint)(_centerDirStart >= 0xffffffff ? 0xffffffff : _centerDirStart)); - bw.Write((ushort)_fileComment.Length); - bw.Write(_fileComment, 0, _fileComment.Length); - } - } - - private ZipReturn Zip64EndOfCentralDirRead() - { - using (BinaryReader zipBr = new BinaryReader(_zipFs, Encoding.UTF8, true)) - { - _zip64 = true; - uint thisSignature = zipBr.ReadUInt32(); - if (thisSignature != Zip64EndOfCentralDirSignatue) - { - return ZipReturn.ZipEndOfCentralDirectoryError; - } - - ulong tulong = zipBr.ReadUInt64(); // Size of zip64 end of central directory record - if (tulong != 44) - { - return ZipReturn.Zip64EndOfCentralDirError; - } - - zipBr.ReadUInt16(); // version made by - - ushort tushort = zipBr.ReadUInt16(); // version needed to extract - if (tushort != 45) - { - return ZipReturn.Zip64EndOfCentralDirError; - } - - uint tuint = zipBr.ReadUInt32(); // number of this disk - if (tuint != 0) - { - return ZipReturn.Zip64EndOfCentralDirError; - } - - tuint = zipBr.ReadUInt32(); // number of the disk with the start of the central directory - if (tuint != 0) - { - return ZipReturn.Zip64EndOfCentralDirError; - } - - _localFilesCount = - (uint)zipBr.ReadUInt64(); // total number of entries in the central directory on this disk - - tulong = zipBr.ReadUInt64(); // total number of entries in the central directory - if (tulong != _localFilesCount) - { - return ZipReturn.Zip64EndOfCentralDirError; - } - - _centerDirSize = zipBr.ReadUInt64(); // size of central directory - - _centerDirStart = - zipBr.ReadUInt64(); // offset of start of central directory with respect to the starting disk number - - return ZipReturn.ZipGood; - } - } - - private void Zip64EndOfCentralDirWrite() - { - using (BinaryWriter bw = new BinaryWriter(_zipFs, Encoding.UTF8, true)) - { - bw.Write(Zip64EndOfCentralDirSignatue); - bw.Write((ulong)44); // Size of zip64 end of central directory record - bw.Write((ushort)45); // version made by - bw.Write((ushort)45); // version needed to extract - bw.Write((uint)0); // number of this disk - bw.Write((uint)0); // number of the disk with the start of the central directroy - bw.Write((ulong)_localFiles.Count); // total number of entries in the central directory on this disk - bw.Write((ulong)_localFiles.Count); // total number of entries in the central directory - bw.Write(_centerDirSize); // size of central directory - bw.Write(_centerDirStart); // offset of start of central directory with respect to the starting disk number - } - } - - private ZipReturn Zip64EndOfCentralDirectoryLocatorRead() - { - using (BinaryReader zipBr = new BinaryReader(_zipFs, Encoding.UTF8, true)) - { - _zip64 = true; - uint thisSignature = zipBr.ReadUInt32(); - if (thisSignature != Zip64EndOfCentralDirectoryLocator) - { - return ZipReturn.ZipEndOfCentralDirectoryError; - } - - uint tuint = - zipBr.ReadUInt32(); // number of the disk with the start of the zip64 end of centeral directory - if (tuint != 0) - { - return ZipReturn.Zip64EndOfCentralDirectoryLocatorError; - } - - _endOfCenterDir64 = zipBr.ReadUInt64(); // relative offset of the zip64 end of central directroy record - - tuint = zipBr.ReadUInt32(); // total number of disks - if (tuint != 1) - { - return ZipReturn.Zip64EndOfCentralDirectoryLocatorError; - } - - return ZipReturn.ZipGood; - } - } - - private void Zip64EndOfCentralDirectoryLocatorWrite() - { - using (BinaryWriter bw = new BinaryWriter(_zipFs, Encoding.UTF8, true)) - { - bw.Write(Zip64EndOfCentralDirectoryLocator); - bw.Write((uint)0); // number of the disk with the start of the zip64 end of centeral directory - bw.Write(_endOfCenterDir64); // relative offset of the zip64 end of central directroy record - bw.Write((uint)1); // total number of disks - } - } - - - - - public ZipReturn ZipFileOpen(string newFilename, long timestamp, bool readHeaders) - { - ZipFileClose(); - ZipStatus = ZipStatus.None; - _zip64 = false; - _centerDirStart = 0; - _centerDirSize = 0; - _zipFileInfo = null; - - try - { - if (!RVIO.File.Exists(newFilename)) - { - ZipFileClose(); - return ZipReturn.ZipErrorFileNotFound; - } - _zipFileInfo = new FileInfo(newFilename); - if (timestamp != -1 && _zipFileInfo.LastWriteTime != timestamp) - { - ZipFileClose(); - return ZipReturn.ZipErrorTimeStamp; - } - int errorCode = FileStream.OpenFileRead(newFilename, out _zipFs); - if (errorCode != 0) - { - ZipFileClose(); - if (errorCode == 32) - { - return ZipReturn.ZipFileLocked; - } - return ZipReturn.ZipErrorOpeningFile; - } - } - catch (PathTooLongException) - { - ZipFileClose(); - return ZipReturn.ZipFileNameToLong; - } - catch (IOException) - { - ZipFileClose(); - return ZipReturn.ZipErrorOpeningFile; - } - ZipOpen = ZipOpenType.OpenRead; - - if (!readHeaders) - { - return ZipReturn.ZipGood; - } - - - return ZipFileReadHeaders(); - } - - - public ZipReturn ZipFileOpen(Stream inStream) - { - ZipFileClose(); - ZipStatus = ZipStatus.None; - _zip64 = false; - _centerDirStart = 0; - _centerDirSize = 0; - _zipFileInfo = null; - _zipFs = inStream; - - ZipOpen = ZipOpenType.OpenRead; - return ZipFileReadHeaders(); - } - - - private ZipReturn ZipFileReadHeaders() - { - try - { - ZipReturn zRet = FindEndOfCentralDirSignature(); - if (zRet != ZipReturn.ZipGood) - { - ZipFileClose(); - return zRet; - } - - long endOfCentralDir = _zipFs.Position; - zRet = EndOfCentralDirRead(); - if (zRet != ZipReturn.ZipGood) - { - ZipFileClose(); - return zRet; - } - - // check if this is a ZIP64 zip and if it is read the Zip64 End Of Central Dir Info - if (_centerDirStart == 0xffffffff || _centerDirSize == 0xffffffff || _localFilesCount == 0xffff) - { - _zip64 = true; - _zipFs.Position = endOfCentralDir - 20; - zRet = Zip64EndOfCentralDirectoryLocatorRead(); - if (zRet != ZipReturn.ZipGood) - { - ZipFileClose(); - return zRet; - } - _zipFs.Position = (long)_endOfCenterDir64; - zRet = Zip64EndOfCentralDirRead(); - if (zRet != ZipReturn.ZipGood) - { - ZipFileClose(); - return zRet; - } - } - - bool trrntzip = false; - - // check if the ZIP has a valid TorrentZip file comment - if (_fileComment.Length == 22) - { - if (GetString(_fileComment).Substring(0, 14) == "TORRENTZIPPED-") - { - CrcCalculatorStream crcCs = new CrcCalculatorStream(_zipFs, true); - byte[] buffer = new byte[_centerDirSize]; - _zipFs.Position = (long)_centerDirStart; - crcCs.Read(buffer, 0, (int)_centerDirSize); - crcCs.Flush(); - crcCs.Close(); - - uint r = (uint)crcCs.Crc; - crcCs.Dispose(); - - string tcrc = GetString(_fileComment).Substring(14, 8); - string zcrc = r.ToString("X8"); - if (string.Compare(tcrc, zcrc, StringComparison.Ordinal) == 0) - { - trrntzip = true; - } - } - } - - - // now read the central directory - _zipFs.Position = (long)_centerDirStart; - - _localFiles.Clear(); - _localFiles.Capacity = (int)_localFilesCount; - for (int i = 0; i < _localFilesCount; i++) - { - LocalFile lc = new LocalFile(); - zRet = lc.CenteralDirectoryRead(_zipFs); - if (zRet != ZipReturn.ZipGood) - { - ZipFileClose(); - return zRet; - } - _zip64 |= lc.Zip64; - _localFiles.Add(lc); - } - - for (int i = 0; i < _localFilesCount; i++) - { - zRet = _localFiles[i].LocalFileHeaderRead(_zipFs); - if (zRet != ZipReturn.ZipGood) - { - ZipFileClose(); - return zRet; - } - trrntzip &= _localFiles[i].TrrntZip; - } - - // check trrntzip file order - if (trrntzip) - { - for (int i = 0; i < _localFilesCount - 1; i++) - { - if (TrrntZipStringCompare(_localFiles[i].FileName, _localFiles[i + 1].FileName) < 0) - { - continue; - } - trrntzip = false; - break; - } - } - - // check trrntzip directories - if (trrntzip) - { - for (int i = 0; i < _localFilesCount - 1; i++) - { - // see if we found a directory - string filename0 = _localFiles[i].FileName; - if (filename0.Substring(filename0.Length - 1, 1) != "/") - { - continue; - } - - // see if the next file is in that directory - string filename1 = _localFiles[i + 1].FileName; - if (filename1.Length <= filename0.Length) - { - continue; - } - if (TrrntZipStringCompare(filename0, filename1.Substring(0, filename0.Length)) != 0) - { - continue; - } - - // if we found a file in the directory then we do not need the directory entry - trrntzip = false; - break; - } - } - - if (trrntzip) - { - ZipStatus |= ZipStatus.TrrntZip; - } - - return ZipReturn.ZipGood; - } - catch - { - ZipFileClose(); - return ZipReturn.ZipErrorReadingFile; - } - } - - public void ZipCreateFake() - { - if (ZipOpen != ZipOpenType.Closed) - { - return; - } - - ZipOpen = ZipOpenType.OpenFakeWrite; - } - - public void ZipFileCloseFake(ulong fileOffset, out byte[] centeralDir) - { - centeralDir = null; - if (ZipOpen != ZipOpenType.OpenFakeWrite) - { - return; - } - - _zip64 = false; - bool lTrrntzip = true; - - _zipFs = new MemoryStream(); - - _centerDirStart = fileOffset; - if (_centerDirStart >= 0xffffffff) - { - _zip64 = true; - } - - CrcCalculatorStream crcCs = new CrcCalculatorStream(_zipFs, true); - - foreach (LocalFile t in _localFiles) - { - t.CenteralDirectoryWrite(crcCs); - _zip64 |= t.Zip64; - lTrrntzip &= t.TrrntZip; - } - - crcCs.Flush(); - crcCs.Close(); - - _centerDirSize = (ulong)_zipFs.Position; - - _fileComment = lTrrntzip ? GetBytes("TORRENTZIPPED-" + crcCs.Crc.ToString("X8")) : new byte[0]; - ZipStatus = lTrrntzip ? ZipStatus.TrrntZip : ZipStatus.None; - - crcCs.Dispose(); - - if (_zip64) - { - _endOfCenterDir64 = fileOffset + (ulong)_zipFs.Position; - Zip64EndOfCentralDirWrite(); - Zip64EndOfCentralDirectoryLocatorWrite(); - } - EndOfCentralDirWrite(); - - centeralDir = ((MemoryStream)_zipFs).ToArray(); - _zipFs.Close(); - _zipFs.Dispose(); - ZipOpen = ZipOpenType.Closed; - } - - - - public ZipReturn ZipFileOpenReadStream(int index, out Stream stream, out ulong streamSize) - { - return ZipFileOpenReadStream(index, false, out stream, out streamSize, out ushort _); - } - - public ZipReturn ZipFileOpenReadStream(int index, bool raw, out Stream stream, out ulong streamSize, out ushort compressionMethod) - { - ZipFileCloseReadStream(); - - streamSize = 0; - compressionMethod = 0; - stream = null; - if (ZipOpen != ZipOpenType.OpenRead) - { - return ZipReturn.ZipReadingFromOutputFile; - } - - ZipReturn zRet = _localFiles[index].LocalFileHeaderRead(_zipFs); - if (zRet != ZipReturn.ZipGood) - { - ZipFileClose(); - return zRet; - } - - zRet = _localFiles[index].LocalFileOpenReadStream(_zipFs, raw, out stream, out streamSize, out compressionMethod); - _compressionStream = stream; - return zRet; - } - - public ZipReturn ZipFileOpenReadStreamQuick(ulong pos, bool raw, out Stream stream, out ulong streamSize, out ushort compressionMethod) - { - ZipFileCloseReadStream(); - - LocalFile tmpFile = new LocalFile { LocalFilePos = pos }; - _localFiles.Clear(); - _localFiles.Add(tmpFile); - ZipReturn zRet = tmpFile.LocalFileHeaderReadQuick(_zipFs); - if (zRet != ZipReturn.ZipGood) - { - stream = null; - streamSize = 0; - compressionMethod = 0; - return zRet; - } - - zRet = tmpFile.LocalFileOpenReadStream(_zipFs, raw, out stream, out streamSize, out compressionMethod); - _compressionStream = stream; - return zRet; - } - - public ZipReturn ZipFileAddFake(string filename, ulong fileOffset, ulong uncompressedSize, ulong compressedSize, byte[] crc32, uint? datetime, out byte[] localHeader) - { - localHeader = null; - - if (ZipOpen != ZipOpenType.OpenFakeWrite) - { - return ZipReturn.ZipWritingToInputFile; - } - - LocalFile lf = new LocalFile(filename, datetime); - _localFiles.Add(lf); - - MemoryStream ms = new MemoryStream(); - lf.LocalFileHeaderFake(fileOffset, uncompressedSize, compressedSize, crc32, ms); - - localHeader = ms.ToArray(); - ms.Close(); - - return ZipReturn.ZipGood; - } - - public static void CreateDirForFile(string sFilename) - { - string strTemp = Path.GetDirectoryName(sFilename); - - if (string.IsNullOrEmpty(strTemp)) - { - return; - } - - if (Directory.Exists(strTemp)) - { - return; - } - - - while (strTemp.Length > 0 && !Directory.Exists(strTemp)) - { - int pos = strTemp.LastIndexOf(Path.DirectorySeparatorChar); - if (pos < 0) - { - pos = 0; - } - strTemp = strTemp.Substring(0, pos); - } - - while (sFilename.IndexOf(Path.DirectorySeparatorChar, strTemp.Length + 1) > 0) - { - strTemp = sFilename.Substring(0, sFilename.IndexOf(Path.DirectorySeparatorChar, strTemp.Length + 1)); - Directory.CreateDirectory(strTemp); - } - } - - - public static string ZipErrorMessageText(ZipReturn zS) - { - string ret = "Unknown"; - switch (zS) - { - case ZipReturn.ZipGood: - ret = string.Empty; - break; - case ZipReturn.ZipFileCountError: - ret = "The number of file in the Zip does not mach the number of files in the Zips Centeral Directory"; - break; - case ZipReturn.ZipSignatureError: - ret = "An unknown Signature Block was found in the Zip"; - break; - case ZipReturn.ZipExtraDataOnEndOfZip: - ret = "Extra Data was found on the end of the Zip"; - break; - case ZipReturn.ZipUnsupportedCompression: - ret = "An unsupported Compression method was found in the Zip, if you recompress this zip it will be usable"; - break; - case ZipReturn.ZipLocalFileHeaderError: - ret = "Error reading a zipped file header information"; - break; - case ZipReturn.ZipCentralDirError: - ret = "There is an error in the Zip Centeral Directory"; - break; - case ZipReturn.ZipReadingFromOutputFile: - ret = "Trying to write to a Zip file open for output only"; - break; - case ZipReturn.ZipWritingToInputFile: - ret = "Tring to read from a Zip file open for input only"; - break; - case ZipReturn.ZipErrorGettingDataStream: - ret = "Error creating Data Stream"; - break; - case ZipReturn.ZipCRCDecodeError: - ret = "CRC error"; - break; - case ZipReturn.ZipDecodeError: - ret = "Error unzipping a file"; - break; - } - - return ret; - } - - private static byte[] GetBytes(string s) - { - char[] c = s.ToCharArray(); - byte[] b = new byte[c.Length]; - for (int i = 0; i < c.Length; i++) - { - char t = c[i]; - b[i] = t > 255 ? (byte)'?' : (byte)c[i]; - } - return b; - } - - private static bool IsUnicode(string s) - { - char[] charArr = s.ToCharArray(); - foreach (char ch in charArr) - { - if (ch > 127) - { - return true; - } - } - return false; - } - - private static string GetString(byte[] byteArr) - { - string s = string.Empty; - foreach (byte by in byteArr) - { - s += (char)by; - } - return s; - } - - private static bool CompareString(string s1, string s2) - { - char[] c1 = s1.ToCharArray(); - char[] c2 = s2.ToCharArray(); - - if (c1.Length != c2.Length) - { - return false; - } - - for (int i = 0; i < c1.Length; i++) - { - if (c1[i] != c2[i]) - { - return false; - } - } - return true; - } - - - private static bool ByteArrCompare(byte[] b0, byte[] b1) - { - if ((b0 == null) || (b1 == null)) - { - return false; - } - if (b0.Length != b1.Length) - { - return false; - } - - for (int i = 0; i < b0.Length; i++) - { - if (b0[i] != b1[i]) - { - return false; - } - } - return true; - } - - public static int TrrntZipStringCompare(string string1, string string2) - { - char[] bytes1 = string1.ToCharArray(); - char[] bytes2 = string2.ToCharArray(); - - int pos1 = 0; - int pos2 = 0; - - for (; ; ) - { - if (pos1 == bytes1.Length) - { - return pos2 == bytes2.Length ? 0 : -1; - } - if (pos2 == bytes2.Length) - { - return 1; - } - - int byte1 = bytes1[pos1++]; - int byte2 = bytes2[pos2++]; - - if (byte1 >= 65 && byte1 <= 90) - { - byte1 += 0x20; - } - if (byte2 >= 65 && byte2 <= 90) - { - byte2 += 0x20; - } - - if (byte1 < byte2) - { - return -1; - } - if (byte1 > byte2) - { - return 1; - } - } - } - - private class LocalFile - { - private ushort _compressionMethod; - private ushort _lastModFileTime; - private ushort _lastModFileDate; - private uint? _lastModFileDateTime; - private ulong _compressedSize; - public ulong RelativeOffsetOfLocalHeader; // only in centeral directory - - private ulong _crc32Location; - private ulong _extraLocation; - private ulong _dataLocation; - - public LocalFile() - { - } - - public LocalFile(string filename, uint? datetime) - { - Zip64 = false; - GeneralPurposeBitFlag = 2; // Maximum Compression Deflating - _compressionMethod = 8; // Compression Method Deflate - if (datetime == null) - { - _lastModFileTime = 48128; - _lastModFileDate = 8600; - } - else - { - _lastModFileDateTime = datetime; - } - - FileName = filename; - } - - public string FileName { get; private set; } - public ushort GeneralPurposeBitFlag { get; private set; } - public byte[] CRC { get; private set; } - public ulong UncompressedSize { get; private set; } - - public bool Zip64 { get; private set; } - public bool TrrntZip { get; private set; } - - public DateTime DateTime - { - get - { - try - { - if (_lastModFileDateTime == null) - { - int second = (_lastModFileTime & 0x1f) * 2; - int minute = (_lastModFileTime >> 5) & 0x3f; - int hour = (_lastModFileTime >> 11) & 0x1f; - - int day = _lastModFileDate & 0x1f; - int month = (_lastModFileDate >> 5) & 0x0f; - int year = ((_lastModFileDate >> 9) & 0x7f) + 1980; - - return new DateTime(year, month, day, hour, minute, second); - } - else - { - return SabreTools.Core.Tools.Utilities.ConvertMsDosTimeFormatToDateTime(_lastModFileDateTime.Value); - } - } - catch - { - return DateTime.MinValue; - } - } - } - - public ulong LocalFilePos - { - get => RelativeOffsetOfLocalHeader; - set => RelativeOffsetOfLocalHeader = value; - } - - - public ZipReturn CenteralDirectoryRead(Stream zipFs) - { - try - { - using (BinaryReader br = new BinaryReader(zipFs, Encoding.UTF8, true)) - { - uint thisSignature = br.ReadUInt32(); - if (thisSignature != CentralDirectoryHeaderSigniature) - { - return ZipReturn.ZipCentralDirError; - } - - br.ReadUInt16(); // Version Made By - - br.ReadUInt16(); // Version Needed To Extract - - - GeneralPurposeBitFlag = br.ReadUInt16(); - _compressionMethod = br.ReadUInt16(); - if (_compressionMethod != 8 && _compressionMethod != 0) - { - return ZipReturn.ZipUnsupportedCompression; - } - - _lastModFileTime = br.ReadUInt16(); - _lastModFileDate = br.ReadUInt16(); - CRC = ReadCRC(br); - - _compressedSize = br.ReadUInt32(); - UncompressedSize = br.ReadUInt32(); - - ushort fileNameLength = br.ReadUInt16(); - ushort extraFieldLength = br.ReadUInt16(); - ushort fileCommentLength = br.ReadUInt16(); - - br.ReadUInt16(); // diskNumberStart - br.ReadUInt16(); // internalFileAttributes - br.ReadUInt32(); // externalFileAttributes - - RelativeOffsetOfLocalHeader = br.ReadUInt32(); - - byte[] bFileName = br.ReadBytes(fileNameLength); - FileName = (GeneralPurposeBitFlag & (1 << 11)) == 0 - ? GetString(bFileName) - : Encoding.UTF8.GetString(bFileName, 0, fileNameLength); - - byte[] extraField = br.ReadBytes(extraFieldLength); - br.ReadBytes(fileCommentLength); // File Comments - - int pos = 0; - while (extraFieldLength > pos) - { - ushort type = BitConverter.ToUInt16(extraField, pos); - pos += 2; - ushort blockLength = BitConverter.ToUInt16(extraField, pos); - pos += 2; - switch (type) - { - case 0x0001: - Zip64 = true; - if (UncompressedSize == 0xffffffff) - { - UncompressedSize = BitConverter.ToUInt64(extraField, pos); - pos += 8; - } - - if (_compressedSize == 0xffffffff) - { - _compressedSize = BitConverter.ToUInt64(extraField, pos); - pos += 8; - } - - if (RelativeOffsetOfLocalHeader == 0xffffffff) - { - RelativeOffsetOfLocalHeader = BitConverter.ToUInt64(extraField, pos); - pos += 8; - } - - break; - case 0x7075: - //byte version = extraField[pos]; - pos += 1; - uint nameCRC32 = BitConverter.ToUInt32(extraField, pos); - pos += 4; - - CRC crcTest = new CRC(); - crcTest.SlurpBlock(bFileName, 0, fileNameLength); - uint fCRC = crcTest.Crc32ResultU; - - if (nameCRC32 != fCRC) - { - return ZipReturn.ZipCentralDirError; - } - - int charLen = blockLength - 5; - - FileName = Encoding.UTF8.GetString(extraField, pos, charLen); - pos += charLen; - - break; - default: - pos += blockLength; - break; - } - } - - return ZipReturn.ZipGood; - } - } - catch - { - return ZipReturn.ZipCentralDirError; - } - } - - public void CenteralDirectoryWrite(Stream crcStream) - { - using (BinaryWriter bw = new BinaryWriter(crcStream, Encoding.UTF8, true)) - { - const uint header = 0x2014B50; - - List extraField = new List(); - - uint cdUncompressedSize; - if (UncompressedSize >= 0xffffffff) - { - Zip64 = true; - cdUncompressedSize = 0xffffffff; - extraField.AddRange(BitConverter.GetBytes(UncompressedSize)); - } - else - { - cdUncompressedSize = (uint)UncompressedSize; - } - - uint cdCompressedSize; - if (_compressedSize >= 0xffffffff) - { - Zip64 = true; - cdCompressedSize = 0xffffffff; - extraField.AddRange(BitConverter.GetBytes(_compressedSize)); - } - else - { - cdCompressedSize = (uint)_compressedSize; - } - - uint cdRelativeOffsetOfLocalHeader; - if (RelativeOffsetOfLocalHeader >= 0xffffffff) - { - Zip64 = true; - cdRelativeOffsetOfLocalHeader = 0xffffffff; - extraField.AddRange(BitConverter.GetBytes(RelativeOffsetOfLocalHeader)); - } - else - { - cdRelativeOffsetOfLocalHeader = (uint)RelativeOffsetOfLocalHeader; - } - - - if (extraField.Count > 0) - { - ushort exfl = (ushort)extraField.Count; - extraField.InsertRange(0, BitConverter.GetBytes((ushort)0x0001)); - extraField.InsertRange(2, BitConverter.GetBytes(exfl)); - } - - ushort extraFieldLength = (ushort)extraField.Count; - - byte[] bFileName; - if (IsUnicode(FileName)) - { - GeneralPurposeBitFlag |= 1 << 11; - bFileName = Encoding.UTF8.GetBytes(FileName); - } - else - { - bFileName = GetBytes(FileName); - } - - ushort fileNameLength = (ushort)bFileName.Length; - - ushort versionNeededToExtract = (ushort)(Zip64 ? 45 : 20); - - bw.Write(header); - bw.Write((ushort)0); - bw.Write(versionNeededToExtract); - bw.Write(GeneralPurposeBitFlag); - bw.Write(_compressionMethod); - if (_lastModFileDateTime == null) - { - bw.Write(_lastModFileTime); - bw.Write(_lastModFileDate); - } - else - { - bw.Write(_lastModFileDateTime.Value); - } - bw.Write(CRC[3]); - bw.Write(CRC[2]); - bw.Write(CRC[1]); - bw.Write(CRC[0]); - bw.Write(cdCompressedSize); - bw.Write(cdUncompressedSize); - bw.Write(fileNameLength); - bw.Write(extraFieldLength); - bw.Write((ushort)0); // file comment length - bw.Write((ushort)0); // disk number start - bw.Write((ushort)0); // internal file attributes - bw.Write((uint)0); // external file attributes - bw.Write(cdRelativeOffsetOfLocalHeader); - - bw.Write(bFileName, 0, fileNameLength); - bw.Write(extraField.ToArray(), 0, extraFieldLength); - // No File Comment - } - } - public ZipReturn LocalFileHeaderRead(Stream zipFs) - { - try - { - using (BinaryReader br = new BinaryReader(zipFs, Encoding.UTF8, true)) - { - - TrrntZip = true; - - zipFs.Position = (long)RelativeOffsetOfLocalHeader; - uint thisSignature = br.ReadUInt32(); - if (thisSignature != LocalFileHeaderSignature) - { - return ZipReturn.ZipLocalFileHeaderError; - } - - br.ReadUInt16(); // version needed to extract - ushort generalPurposeBitFlagLocal = br.ReadUInt16(); - if (generalPurposeBitFlagLocal != GeneralPurposeBitFlag) - { - TrrntZip = false; - } - - ushort tshort = br.ReadUInt16(); - if (tshort != _compressionMethod) - { - return ZipReturn.ZipLocalFileHeaderError; - } - - tshort = br.ReadUInt16(); - if (tshort != _lastModFileTime) - { - return ZipReturn.ZipLocalFileHeaderError; - } - - tshort = br.ReadUInt16(); - if (tshort != _lastModFileDate) - { - return ZipReturn.ZipLocalFileHeaderError; - } - - byte[] tCRC = ReadCRC(br); - ulong tCompressedSize = br.ReadUInt32(); - ulong tUnCompressedSize = br.ReadUInt32(); - - ushort fileNameLength = br.ReadUInt16(); - ushort extraFieldLength = br.ReadUInt16(); - - - byte[] bFileName = br.ReadBytes(fileNameLength); - string tFileName = (generalPurposeBitFlagLocal & (1 << 11)) == 0 - ? GetString(bFileName) - : Encoding.UTF8.GetString(bFileName, 0, fileNameLength); - - byte[] extraField = br.ReadBytes(extraFieldLength); - - - Zip64 = false; - int pos = 0; - while (extraFieldLength > pos) - { - ushort type = BitConverter.ToUInt16(extraField, pos); - pos += 2; - ushort blockLength = BitConverter.ToUInt16(extraField, pos); - pos += 2; - switch (type) - { - case 0x0001: - Zip64 = true; - if (tUnCompressedSize == 0xffffffff) - { - tUnCompressedSize = BitConverter.ToUInt64(extraField, pos); - pos += 8; - } - - if (tCompressedSize == 0xffffffff) - { - tCompressedSize = BitConverter.ToUInt64(extraField, pos); - pos += 8; - } - - break; - case 0x7075: - //byte version = extraField[pos]; - pos += 1; - uint nameCRC32 = BitConverter.ToUInt32(extraField, pos); - pos += 4; - - CRC crcTest = new CRC(); - crcTest.SlurpBlock(bFileName, 0, fileNameLength); - uint fCRC = crcTest.Crc32ResultU; - - if (nameCRC32 != fCRC) - { - return ZipReturn.ZipLocalFileHeaderError; - } - - int charLen = blockLength - 5; - - tFileName = Encoding.UTF8.GetString(extraField, pos, charLen); - pos += charLen; - - break; - default: - pos += blockLength; - break; - } - } - - if (!CompareString(FileName, tFileName)) - { - return ZipReturn.ZipLocalFileHeaderError; - } - - _dataLocation = (ulong)zipFs.Position; - - if ((GeneralPurposeBitFlag & 8) == 8) - { - zipFs.Position += (long)_compressedSize; - - tCRC = ReadCRC(br); - if (!ByteArrCompare(tCRC, new byte[] { 0x50, 0x4b, 0x07, 0x08 })) - { - tCRC = ReadCRC(br); - } - - tCompressedSize = br.ReadUInt32(); - tUnCompressedSize = br.ReadUInt32(); - } - - - - if (!ByteArrCompare(tCRC, CRC)) - { - return ZipReturn.ZipLocalFileHeaderError; - } - - if (tCompressedSize != _compressedSize) - { - return ZipReturn.ZipLocalFileHeaderError; - } - - if (tUnCompressedSize != UncompressedSize) - { - return ZipReturn.ZipLocalFileHeaderError; - } - - return ZipReturn.ZipGood; - } - } - catch - { - return ZipReturn.ZipLocalFileHeaderError; - } - } - - public ZipReturn LocalFileHeaderReadQuick(Stream zipFs) - { - try - { - - using (BinaryReader br = new BinaryReader(zipFs, Encoding.UTF8, true)) - { - TrrntZip = true; - - - zipFs.Position = (long)RelativeOffsetOfLocalHeader; - uint thisSignature = br.ReadUInt32(); - if (thisSignature != LocalFileHeaderSignature) - { - return ZipReturn.ZipLocalFileHeaderError; - } - - br.ReadUInt16(); // version needed to extract - GeneralPurposeBitFlag = br.ReadUInt16(); - if ((GeneralPurposeBitFlag & 8) == 8) - { - return ZipReturn.ZipCannotFastOpen; - } - - _compressionMethod = br.ReadUInt16(); - _lastModFileTime = br.ReadUInt16(); - _lastModFileDate = br.ReadUInt16(); - CRC = ReadCRC(br); - _compressedSize = br.ReadUInt32(); - UncompressedSize = br.ReadUInt32(); - - ushort fileNameLength = br.ReadUInt16(); - ushort extraFieldLength = br.ReadUInt16(); - - byte[] bFileName = br.ReadBytes(fileNameLength); - - FileName = (GeneralPurposeBitFlag & (1 << 11)) == 0 - ? GetString(bFileName) - : Encoding.UTF8.GetString(bFileName, 0, fileNameLength); - - byte[] extraField = br.ReadBytes(extraFieldLength); - - Zip64 = false; - int pos = 0; - while (extraFieldLength > pos) - { - ushort type = BitConverter.ToUInt16(extraField, pos); - pos += 2; - ushort blockLength = BitConverter.ToUInt16(extraField, pos); - pos += 2; - switch (type) - { - case 0x0001: - Zip64 = true; - if (UncompressedSize == 0xffffffff) - { - UncompressedSize = BitConverter.ToUInt64(extraField, pos); - pos += 8; - } - - if (_compressedSize == 0xffffffff) - { - _compressedSize = BitConverter.ToUInt64(extraField, pos); - pos += 8; - } - - break; - case 0x7075: - pos += 1; - uint nameCRC32 = BitConverter.ToUInt32(extraField, pos); - pos += 4; - - CRC crcTest = new CRC(); - crcTest.SlurpBlock(bFileName, 0, fileNameLength); - uint fCRC = crcTest.Crc32ResultU; - - if (nameCRC32 != fCRC) - { - return ZipReturn.ZipLocalFileHeaderError; - } - - int charLen = blockLength - 5; - - FileName = Encoding.UTF8.GetString(extraField, pos, charLen); - - pos += charLen; - - break; - default: - pos += blockLength; - break; - } - } - - _dataLocation = (ulong)zipFs.Position; - return ZipReturn.ZipGood; - } - } - catch - { - return ZipReturn.ZipLocalFileHeaderError; - } - } - - - private void LocalFileHeaderWrite(Stream zipFs) - { - using (BinaryWriter bw = new BinaryWriter(zipFs, Encoding.UTF8, true)) - { - Zip64 = UncompressedSize >= 0xffffffff; - - byte[] bFileName; - if (IsUnicode(FileName)) - { - GeneralPurposeBitFlag |= 1 << 11; - bFileName = Encoding.UTF8.GetBytes(FileName); - } - else - { - bFileName = GetBytes(FileName); - } - - ushort versionNeededToExtract = (ushort)(Zip64 ? 45 : 20); - - RelativeOffsetOfLocalHeader = (ulong)zipFs.Position; - const uint header = 0x4034B50; - bw.Write(header); - bw.Write(versionNeededToExtract); - bw.Write(GeneralPurposeBitFlag); - bw.Write(_compressionMethod); - if (_lastModFileDateTime == null) - { - bw.Write(_lastModFileTime); - bw.Write(_lastModFileDate); - } - else - { - bw.Write(_lastModFileDateTime.Value); - } - - _crc32Location = (ulong)zipFs.Position; - - // these 3 values will be set correctly after the file data has been written - bw.Write(0xffffffff); - bw.Write(0xffffffff); - bw.Write(0xffffffff); - - ushort fileNameLength = (ushort)bFileName.Length; - bw.Write(fileNameLength); - - ushort extraFieldLength = (ushort)(Zip64 ? 20 : 0); - bw.Write(extraFieldLength); - - bw.Write(bFileName, 0, fileNameLength); - - _extraLocation = (ulong)zipFs.Position; - if (Zip64) - bw.Write(new byte[20], 0, extraFieldLength); - } - } - - public void LocalFileHeaderFake(ulong filePosition, ulong uncompressedSize, ulong compressedSize, byte[] crc32, MemoryStream ms) - { - using (BinaryWriter bw = new BinaryWriter(ms, Encoding.UTF8, true)) - { - RelativeOffsetOfLocalHeader = filePosition; - TrrntZip = true; - UncompressedSize = uncompressedSize; - _compressedSize = compressedSize; - CRC = crc32; - - Zip64 = UncompressedSize >= 0xffffffff || _compressedSize >= 0xffffffff; - - byte[] bFileName; - if (IsUnicode(FileName)) - { - GeneralPurposeBitFlag |= 1 << 11; - bFileName = Encoding.UTF8.GetBytes(FileName); - } - else - { - bFileName = GetBytes(FileName); - } - - ushort versionNeededToExtract = (ushort)(Zip64 ? 45 : 20); - - const uint header = 0x4034B50; - bw.Write(header); - bw.Write(versionNeededToExtract); - bw.Write(GeneralPurposeBitFlag); - bw.Write(_compressionMethod); - if (_lastModFileDateTime == null) - { - bw.Write(_lastModFileTime); - bw.Write(_lastModFileDate); - } - else - { - bw.Write(_lastModFileDateTime.Value); - } - - uint tCompressedSize; - uint tUncompressedSize; - if (Zip64) - { - tCompressedSize = 0xffffffff; - tUncompressedSize = 0xffffffff; - } - else - { - tCompressedSize = (uint)_compressedSize; - tUncompressedSize = (uint)UncompressedSize; - } - - bw.Write(CRC[3]); - bw.Write(CRC[2]); - bw.Write(CRC[1]); - bw.Write(CRC[0]); - bw.Write(tCompressedSize); - bw.Write(tUncompressedSize); - - ushort fileNameLength = (ushort)bFileName.Length; - bw.Write(fileNameLength); - - ushort extraFieldLength = (ushort)(Zip64 ? 20 : 0); - bw.Write(extraFieldLength); - - bw.Write(bFileName, 0, fileNameLength); - - if (Zip64) - { - bw.Write((ushort)0x0001); // id - bw.Write((ushort)16); // data length - bw.Write(UncompressedSize); - bw.Write(_compressedSize); - } - } - } - public ZipReturn LocalFileOpenReadStream(Stream zipFs, bool raw, out Stream readStream, out ulong streamSize, out ushort compressionMethod) - { - streamSize = 0; - compressionMethod = _compressionMethod; - - readStream = null; - zipFs.Seek((long)_dataLocation, SeekOrigin.Begin); - - switch (_compressionMethod) - { - case 8: - if (raw) - { - readStream = zipFs; - streamSize = _compressedSize; - } - else - { - readStream = new ZlibBaseStream(zipFs, CompressionMode.Decompress, CompressionLevel.Default, ZlibStreamFlavor.DEFLATE, true); - streamSize = UncompressedSize; - } - break; - case 0: - readStream = zipFs; - streamSize = _compressedSize; // same as UncompressedSize - break; - } - - return readStream == null ? ZipReturn.ZipErrorGettingDataStream : ZipReturn.ZipGood; - } - - public ZipReturn LocalFileOpenWriteStream(Stream zipFs, bool raw, bool trrntZip, ulong uncompressedSize, ushort compressionMethod, out Stream writeStream) - { - UncompressedSize = uncompressedSize; - _compressionMethod = compressionMethod; - - LocalFileHeaderWrite(zipFs); - _dataLocation = (ulong)zipFs.Position; - - if (raw) - { - writeStream = zipFs; - TrrntZip = trrntZip; - } - else - { - if (compressionMethod == 0) - { - writeStream = zipFs; - TrrntZip = false; - } - else - { - writeStream = new ZlibBaseStream(zipFs, CompressionMode.Compress, CompressionLevel.BestCompression, ZlibStreamFlavor.DEFLATE, true); - TrrntZip = true; - } - } - - return writeStream == null ? ZipReturn.ZipErrorGettingDataStream : ZipReturn.ZipGood; - } - - public ZipReturn LocalFileCloseWriteStream(Stream zipFs, byte[] crc32) - { - _compressedSize = (ulong)zipFs.Position - _dataLocation; - - if (_compressedSize == 0 && UncompressedSize == 0) - { - LocalFileAddZeroLengthFile(zipFs); - _compressedSize = (ulong)zipFs.Position - _dataLocation; - } - else if (_compressedSize == 0 && UncompressedSize != 0) - { - return ZipReturn.ZipErrorWritingToOutputStream; - } - - CRC = crc32; - WriteCompressedSize(zipFs); - - return ZipReturn.ZipGood; - } - - private void FixFileForZip64(Stream zipFs) - { - long posNow = zipFs.Position; - using (BinaryWriter bw = new BinaryWriter(zipFs, Encoding.UTF8, true)) - { - // _crc32Loction - 10 needs set to 45 - zipFs.Seek((long)_crc32Location - 10, SeekOrigin.Begin); - ushort versionNeededToExtract = 45; - bw.Write(versionNeededToExtract); - - zipFs.Seek((long)_crc32Location + 14, SeekOrigin.Begin); - ushort extraFieldLength = 20; - bw.Write(extraFieldLength); - } - ExpandFile(zipFs, (long)_extraLocation, posNow, 20); - zipFs.Position = posNow + 20; - } - - private static void ExpandFile(Stream stream, long offset, long length, int extraBytes) - { - const int bufferSize = 40960; - byte[] buffer = new byte[bufferSize]; - // Expand file - long pos = length; - while (pos > offset) - { - int toRead = pos - bufferSize >= offset ? bufferSize : (int)(pos - offset); - pos -= toRead; - stream.Position = pos; - stream.Read(buffer, 0, toRead); - stream.Position = pos + extraBytes; - stream.Write(buffer, 0, toRead); - } - } - - private void WriteCompressedSize(Stream zipFs) - { - if (_compressedSize >= 0xffffffff && !Zip64) - { - Zip64 = true; - FixFileForZip64(zipFs); - } - - - long posNow = zipFs.Position; - zipFs.Seek((long)_crc32Location, SeekOrigin.Begin); - using (BinaryWriter bw = new BinaryWriter(zipFs, Encoding.UTF8, true)) - { - uint tCompressedSize; - uint tUncompressedSize; - if (Zip64) - { - tCompressedSize = 0xffffffff; - tUncompressedSize = 0xffffffff; - } - else - { - tCompressedSize = (uint)_compressedSize; - tUncompressedSize = (uint)UncompressedSize; - } - - bw.Write(CRC[3]); - bw.Write(CRC[2]); - bw.Write(CRC[1]); - bw.Write(CRC[0]); - bw.Write(tCompressedSize); - bw.Write(tUncompressedSize); - - - // also need to write extradata - if (Zip64) - { - zipFs.Seek((long)_extraLocation, SeekOrigin.Begin); - bw.Write((ushort)0x0001); // id - bw.Write((ushort)16); // data length - bw.Write(UncompressedSize); - bw.Write(_compressedSize); - } - } - - zipFs.Seek(posNow, SeekOrigin.Begin); - } - - public static void LocalFileAddZeroLengthFile(Stream zipFs) - { - zipFs.WriteByte(03); - zipFs.WriteByte(00); - } - - private static byte[] ReadCRC(BinaryReader br) - { - byte[] tCRC = new byte[4]; - tCRC[3] = br.ReadByte(); - tCRC[2] = br.ReadByte(); - tCRC[1] = br.ReadByte(); - tCRC[0] = br.ReadByte(); - return tCRC; - } - } - } -} \ No newline at end of file diff --git a/SabreTools.FileTypes/Compress/gZip/gZip.cs b/SabreTools.FileTypes/Compress/gZip/gZip.cs index dfa99d85..4c8049c0 100644 --- a/SabreTools.FileTypes/Compress/gZip/gZip.cs +++ b/SabreTools.FileTypes/Compress/gZip/gZip.cs @@ -1,8 +1,8 @@ using System; using System.IO; using System.Text; +using Compress.Utils; using Compress.ZipFile.ZLib; -using Directory = RVIO.Directory; using FileInfo = RVIO.FileInfo; using FileStream = RVIO.FileStream; using Path = RVIO.Path; @@ -52,6 +52,19 @@ namespace Compress.gZip { return false; } + public long LastModified(int i) + { + return 0; // need to test if this is the same as Zip Date (Probably is) + } + public long? Created(int i) + { + return null; + } + public long? Accessed(int i) + { + return null; + } + public ZipOpenType ZipOpen { get; private set; } @@ -137,7 +150,6 @@ namespace Compress.gZip byte FLG = zipBr.ReadByte(); - uint MTime = zipBr.ReadUInt32(); byte XFL = zipBr.ReadByte(); byte OS = zipBr.ReadByte(); @@ -152,19 +164,47 @@ namespace Compress.gZip switch (XLen) { case 12: + // 0-3: byte[4] CRC CRC = new byte[4]; Array.Copy(ExtraData, 0, CRC, 0, 4); + // 4-11: ulong uncompressed UnCompressedSize = BitConverter.ToUInt64(ExtraData, 4); break; case 28: + // 0-15: byte[16] md5 + // byte[] md5Hash = new byte[16]; + // Array.Copy(ExtraData, 0, md5Hash, 0, 16); + // 16-19: byte[4] CRC CRC = new byte[4]; Array.Copy(ExtraData, 16, CRC, 0, 4); + // 20-27: ulong uncompressed UnCompressedSize = BitConverter.ToUInt64(ExtraData, 20); break; case 77: + // 0-15: byte[16] md5 + // md5Hash = new byte[16]; + // Array.Copy(ExtraData, 0, md5Hash, 0, 16); + // 16-19: byte[4] CRC CRC = new byte[4]; Array.Copy(ExtraData, 16, CRC, 0, 4); + // 20-27: ulong uncompressed UnCompressedSize = BitConverter.ToUInt64(ExtraData, 20); + + // 28: altFileType + // byte altType = ExtraData[28]; + + // 29-44: byte[16] altmd5 + // byte[] altmd5Hash = new byte[16]; + // Array.Copy(ExtraData, 29, altmd5Hash, 0, 16); + // 45-64: byte[20] altsha1 + // byte[] altsha1Hash = new byte[20]; + // Array.Copy(ExtraData, 45, altsha1Hash, 0, 20); + // 65-68: byte[4] altcrc + // byte[] altcrc = new byte[4]; + // Array.Copy(ExtraData, 65, altcrc, 0, 4); + // 69-76: ulong altuncompressed + // ulong uncompressedAltSize = BitConverter.ToUInt64(ExtraData, 69); + break; } } @@ -230,43 +270,71 @@ namespace Compress.gZip public void ZipFileClose() { - if (ZipOpen == ZipOpenType.Closed) + switch (ZipOpen) { - return; - } + case ZipOpenType.Closed: + return; - if (ZipOpen == ZipOpenType.OpenRead) - { - if (_zipFs != null) - { - _zipFs.Close(); - _zipFs.Dispose(); - } - ZipOpen = ZipOpenType.Closed; - return; - } + case ZipOpenType.OpenRead: + { + if (_zipFs != null) + { + _zipFs.Close(); + _zipFs.Dispose(); + } + ZipOpen = ZipOpenType.Closed; + return; + } + case ZipOpenType.OpenWrite: + { + if (_zipFs != null) + { + _zipFs.Close(); + _zipFs.Dispose(); + } + ZipOpen = ZipOpenType.Closed; + return; + } + } } public ZipReturn ZipFileOpenReadStream(int index, out Stream stream, out ulong streamSize) + { + return ZipFileOpenReadStream(index, false, out stream, out streamSize); + } + + public ZipReturn ZipFileOpenReadStream(int index, bool raw, out Stream stream, out ulong streamSize) { ZipFileCloseReadStream(); + stream = null; + streamSize = 0; + + if (ZipOpen != ZipOpenType.OpenRead) + { + return ZipReturn.ZipReadingFromOutputFile; + } _zipFs.Position = dataStartPos; - - _compressionStream = new ZlibBaseStream(_zipFs, CompressionMode.Decompress, CompressionLevel.Default, ZlibStreamFlavor.DEFLATE, true); - stream = _compressionStream; - streamSize = UnCompressedSize; + if (raw) + { + stream = _zipFs; + streamSize = CompressedSize; + } + else + { + //_compressionStream = new ZlibBaseStream(_zipFs, CompressionMode.Decompress, CompressionLevel.Default, ZlibStreamFlavor.DEFLATE, true); + _compressionStream = new System.IO.Compression.DeflateStream(_zipFs, System.IO.Compression.CompressionMode.Decompress, true); + stream = _compressionStream; + streamSize = UnCompressedSize; + } return ZipReturn.ZipGood; } - public bool hasAltFileHeader; - - public byte[] ExtraData; - public ZipReturn ZipFileOpenWriteStream(bool raw, bool trrntzip, string filename, ulong unCompressedSize, ushort compressionMethod, uint? datetime, out Stream stream) + public ZipReturn ZipFileOpenWriteStream(bool raw, bool trrntzip, string filename, ulong unCompressedSize, ushort compressionMethod, out Stream stream, TimeStamps dateTime) { using (BinaryWriter zipBw = new BinaryWriter(_zipFs, Encoding.UTF8, true)) { @@ -295,13 +363,17 @@ namespace Compress.gZip dataStartPos = zipBw.BaseStream.Position; - stream = raw - ? _zipFs - : new ZlibBaseStream(_zipFs, CompressionMode.Compress, CompressionLevel.BestCompression, ZlibStreamFlavor.DEFLATE, true); + + + _compressionStream = raw + ? _zipFs + : new ZlibBaseStream(_zipFs, CompressionMode.Compress, CompressionLevel.BestCompression, ZlibStreamFlavor.DEFLATE, true); zipBw.Flush(); zipBw.Close(); } + + stream = _compressionStream; return ZipReturn.ZipGood; } @@ -315,6 +387,11 @@ namespace Compress.gZip dfStream.Close(); dfStream.Dispose(); } + else if (_compressionStream is System.IO.Compression.DeflateStream dfioStream) + { + dfioStream.Close(); + dfioStream.Dispose(); + } _compressionStream = null; return ZipReturn.ZipGood; @@ -322,7 +399,7 @@ namespace Compress.gZip public ZipStatus ZipStatus { get; private set; } - public string ZipFilename => _zipFileInfo != null ? _zipFileInfo.FullName : string.Empty; + public string ZipFilename => _zipFileInfo != null ? _zipFileInfo.FullName : ""; public long TimeStamp => _zipFileInfo?.LastWriteTime ?? 0; @@ -338,7 +415,7 @@ namespace Compress.gZip return ZipReturn.ZipFileAlreadyOpen; } - CreateDirForFile(newFilename); + DirUtil.CreateDirForFile(newFilename); _zipFileInfo = new FileInfo(newFilename); int errorCode = FileStream.OpenFileWrite(newFilename, out _zipFs); @@ -354,14 +431,24 @@ namespace Compress.gZip public ZipReturn ZipFileCloseWriteStream(byte[] crc32) { + if (_compressionStream is ZlibBaseStream dfStream) + { + dfStream.Flush(); + dfStream.Close(); + dfStream.Dispose(); + } + + _compressionStream = null; + + CompressedSize = (ulong)(_zipFs.Position - dataStartPos); + using (BinaryWriter zipBw = new BinaryWriter(_zipFs, Encoding.UTF8, true)) { - CompressedSize = (ulong)(zipBw.BaseStream.Position - dataStartPos); - zipBw.Write(CRC[3]); - zipBw.Write(CRC[2]); - zipBw.Write(CRC[1]); - zipBw.Write(CRC[0]); + zipBw.Write(crc32[3]); + zipBw.Write(crc32[2]); + zipBw.Write(crc32[1]); + zipBw.Write(crc32[0]); zipBw.Write((uint)UnCompressedSize); long endpos = _zipFs.Position; @@ -384,8 +471,6 @@ namespace Compress.gZip zipBw.Close(); } - _zipFs.Close(); - return ZipReturn.ZipGood; } @@ -420,39 +505,27 @@ namespace Compress.gZip _zipFileInfo = null; ZipOpen = ZipOpenType.Closed; } - - - private static void CreateDirForFile(string sFilename) + public ZipReturn GetRawStream(out Stream st) { - string strTemp = Path.GetDirectoryName(sFilename); - - if (string.IsNullOrEmpty(strTemp)) + st = null; + if (!RVIO.File.Exists(_zipFileInfo.FullName)) { - return; + return ZipReturn.ZipErrorFileNotFound; } - if (Directory.Exists(strTemp)) + int errorCode = FileStream.OpenFileRead(_zipFileInfo.FullName, out st); + if (errorCode != 0) { - return; - } - - - while (strTemp.Length > 0 && !Directory.Exists(strTemp)) - { - int pos = strTemp.LastIndexOf(Path.DirectorySeparatorChar); - if (pos < 0) + if (errorCode == 32) { - pos = 0; + return ZipReturn.ZipFileLocked; } - strTemp = strTemp.Substring(0, pos); + return ZipReturn.ZipErrorOpeningFile; } - while (sFilename.IndexOf(Path.DirectorySeparatorChar, strTemp.Length + 1) > 0) - { - strTemp = sFilename.Substring(0, sFilename.IndexOf(Path.DirectorySeparatorChar, strTemp.Length + 1)); - Directory.CreateDirectory(strTemp); - } + st.Position = dataStartPos; + + return ZipReturn.ZipGood; } - } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/RVIO/RVIO.cs b/SabreTools.FileTypes/RVIO/RVIO.cs index 1f8ff3d5..1896b26f 100644 --- a/SabreTools.FileTypes/RVIO/RVIO.cs +++ b/SabreTools.FileTypes/RVIO/RVIO.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.IO; using System.Runtime.InteropServices; using System.Text; -using Microsoft.Win32.SafeHandles; namespace RVIO { @@ -49,7 +48,6 @@ namespace RVIO public class FileInfo { - public string Name; public string FullName; public long LastWriteTime; @@ -63,28 +61,13 @@ namespace RVIO FullName = path; Name = Path.GetFileName(path); - if (unix.IsUnix) - { - System.IO.FileInfo fi = new System.IO.FileInfo(path); + System.IO.FileInfo fi = new System.IO.FileInfo(NameFix.AddLongPathPrefix(path)); - if (!fi.Exists) return; + if (!fi.Exists) return; - Length = fi.Length; - LastWriteTime = fi.LastWriteTimeUtc.Ticks; - return; - } - - string fileName = NameFix.AddLongPathPrefix(path); - Win32Native.WIN32_FILE_ATTRIBUTE_DATA wIn32FileAttributeData = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); - - bool b = Win32Native.GetFileAttributesEx(fileName, 0, ref wIn32FileAttributeData); - - if (!b || (wIn32FileAttributeData.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) != 0) return; - - Length = Convert.Length(wIn32FileAttributeData.fileSizeHigh, wIn32FileAttributeData.fileSizeLow); - LastWriteTime = Convert.Time(wIn32FileAttributeData.ftLastWriteTimeHigh, wIn32FileAttributeData.ftLastWriteTimeLow); + Length = fi.Length; + LastWriteTime = fi.LastWriteTimeUtc.Ticks; } - } public class DirectoryInfo @@ -100,39 +83,24 @@ namespace RVIO FullName = path; Name = Path.GetFileName(path); - if (unix.IsUnix) - { - System.IO.DirectoryInfo fi = new System.IO.DirectoryInfo(path); + System.IO.DirectoryInfo fi = new System.IO.DirectoryInfo(NameFix.AddLongPathPrefix(path)); - if (!fi.Exists) return; + if (!fi.Exists) return; - LastWriteTime = fi.LastWriteTimeUtc.Ticks; - return; - } - - string fileName = NameFix.AddLongPathPrefix(path); - Win32Native.WIN32_FILE_ATTRIBUTE_DATA wIn32FileAttributeData = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); - - bool b = Win32Native.GetFileAttributesEx(fileName, 0, ref wIn32FileAttributeData); - - if (!b || (wIn32FileAttributeData.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) == 0) return; - LastWriteTime = Convert.Time(wIn32FileAttributeData.ftLastWriteTimeHigh, wIn32FileAttributeData.ftLastWriteTimeLow); + LastWriteTime = fi.LastWriteTimeUtc.Ticks; } - - - public DirectoryInfo[] GetDirectories(bool includeHidden = true) - { - return GetDirectories("*", includeHidden); - } - public DirectoryInfo[] GetDirectories(string SearchPattern, bool includeHidden = true) + public DirectoryInfo[] GetDirectories() { List dirs = new List(); - if (unix.IsUnix) + try { - System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(FullName); - System.IO.DirectoryInfo[] arrDi = di.GetDirectories(SearchPattern); + System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(NameFix.AddLongPathPrefix(FullName)); + if (!di.Exists) + return dirs.ToArray(); + + System.IO.DirectoryInfo[] arrDi = di.GetDirectories(); foreach (System.IO.DirectoryInfo tDi in arrDi) { DirectoryInfo lDi = new DirectoryInfo @@ -143,55 +111,24 @@ namespace RVIO }; dirs.Add(lDi); } - return dirs.ToArray(); } - - - - string dirName = NameFix.AddLongPathPrefix(FullName); - - Win32Native.WIN32_FIND_DATA findData = new Win32Native.WIN32_FIND_DATA(); - SafeFindHandle findHandle = Win32Native.FindFirstFile(dirName + @"\" + SearchPattern, findData); - - if (!findHandle.IsInvalid) + catch (Exception e) { - do - { - string currentFileName = findData.cFileName; - // if this is a directory, find its contents - if ((findData.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) == 0) continue; - if (currentFileName == "." || currentFileName == "..") continue; - if (!includeHidden && (findData.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_HIDDEN) != 0) continue; - - DirectoryInfo di = new DirectoryInfo - { - Name = currentFileName, - FullName = Path.Combine(FullName, currentFileName), - LastWriteTime = Convert.Time(findData.ftLastWriteTimeHigh, findData.ftLastWriteTimeLow) - }; - dirs.Add(di); - } - while (Win32Native.FindNextFile(findHandle, findData)); } - - // close the find handle - findHandle.Dispose(); - return dirs.ToArray(); } - public FileInfo[] GetFiles() - { - return GetFiles("*"); - } - public FileInfo[] GetFiles(string SearchPattern, bool includeHidden = true) + public FileInfo[] GetFiles(string SearchPattern = "*") { List files = new List(); - if (unix.IsUnix) + try { - System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(FullName); + System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(NameFix.AddLongPathPrefix(FullName)); + if (!di.Exists) + return files.ToArray(); + System.IO.FileInfo[] arrDi = di.GetFiles(SearchPattern); foreach (System.IO.FileInfo tDi in arrDi) { @@ -204,124 +141,36 @@ namespace RVIO }; files.Add(lDi); } - return files.ToArray(); } - - string dirName = NameFix.AddLongPathPrefix(FullName); - - Win32Native.WIN32_FIND_DATA findData = new Win32Native.WIN32_FIND_DATA(); - SafeFindHandle findHandle = Win32Native.FindFirstFile(dirName + @"\" + SearchPattern, findData); - - if (!findHandle.IsInvalid) + catch (Exception e) { - do - { - string currentFileName = findData.cFileName; - - // if this is a directory, find its contents - if ((findData.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) != 0) continue; - if (!includeHidden && (findData.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_HIDDEN) != 0) continue; - - FileInfo fi = new FileInfo - { - Name = currentFileName, - FullName = Path.Combine(FullName, currentFileName), - Length = Convert.Length(findData.nFileSizeHigh, findData.nFileSizeLow), - LastWriteTime = Convert.Time(findData.ftLastWriteTimeHigh, findData.ftLastWriteTimeLow) - }; - files.Add(fi); - } - while (Win32Native.FindNextFile(findHandle, findData)); } - // close the find handle - findHandle.Dispose(); - return files.ToArray(); } } + public static class Directory { public static bool Exists(string path) { - if (unix.IsUnix) - return System.IO.Directory.Exists(path); - - - string fixPath = NameFix.AddLongPathPrefix(path); - - Win32Native.WIN32_FILE_ATTRIBUTE_DATA wIn32FileAttributeData = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); - - bool b = Win32Native.GetFileAttributesEx(fixPath, 0, ref wIn32FileAttributeData); - return b && (wIn32FileAttributeData.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) != 0; + return System.IO.Directory.Exists(NameFix.AddLongPathPrefix(path)); } + public static void Move(string sourceDirName, string destDirName) { - if (unix.IsUnix) - { - System.IO.Directory.Move(sourceDirName, destDirName); - return; - } - - - if (sourceDirName == null) - throw new ArgumentNullException("sourceDirName"); - if (sourceDirName.Length == 0) - throw new ArgumentException("Argument_EmptyFileName", "sourceDirName"); - - if (destDirName == null) - throw new ArgumentNullException("destDirName"); - if (destDirName.Length == 0) - throw new ArgumentException("Argument_EmptyFileName", "destDirName"); - - string fullsourceDirName = NameFix.AddLongPathPrefix(sourceDirName); - - string fulldestDirName = NameFix.AddLongPathPrefix(destDirName); - - if (!Win32Native.MoveFile(fullsourceDirName, fulldestDirName)) - { - int hr = Marshal.GetLastWin32Error(); - if (hr == Win32Native.ERROR_FILE_NOT_FOUND) // Source dir not found - { - throw new Exception("ERROR_PATH_NOT_FOUND " + fullsourceDirName); - } - if (hr == Win32Native.ERROR_ACCESS_DENIED) // WinNT throws IOException. This check is for Win9x. We can't change it for backcomp. - { - throw new Exception("UnauthorizedAccess_IODenied_Path" + sourceDirName); - } - } + System.IO.Directory.Move(NameFix.AddLongPathPrefix(sourceDirName), NameFix.AddLongPathPrefix(destDirName)); } + public static void Delete(string path) { - if (unix.IsUnix) - { - System.IO.Directory.Delete(path); - return; - } - - string fullPath = NameFix.AddLongPathPrefix(path); - - Win32Native.RemoveDirectory(fullPath); + System.IO.Directory.Delete(NameFix.AddLongPathPrefix(path)); } public static void CreateDirectory(string path) { - if (unix.IsUnix) - { - System.IO.Directory.CreateDirectory(path); - return; - } - - - if (path == null) - throw new ArgumentNullException("path"); - if (path.Length == 0) - throw new ArgumentException("Argument_PathEmpty"); - - string fullPath = NameFix.AddLongPathPrefix(path); - - Win32Native.CreateDirectory(fullPath, IntPtr.Zero); + System.IO.Directory.CreateDirectory(NameFix.AddLongPathPrefix(path)); } } @@ -329,16 +178,7 @@ namespace RVIO { public static bool Exists(string path) { - if (unix.IsUnix) - return System.IO.File.Exists(path); - - - string fixPath = NameFix.AddLongPathPrefix(path); - - Win32Native.WIN32_FILE_ATTRIBUTE_DATA wIn32FileAttributeData = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); - - bool b = Win32Native.GetFileAttributesEx(fixPath, 0, ref wIn32FileAttributeData); - return b && (wIn32FileAttributeData.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) == 0; + return System.IO.File.Exists(NameFix.AddLongPathPrefix(path)); } public static void Copy(string sourceFileName, string destfileName) { @@ -346,130 +186,34 @@ namespace RVIO } public static void Copy(string sourceFileName, string destFileName, bool overwrite) { - if (unix.IsUnix) - { - System.IO.File.Copy(sourceFileName, destFileName, overwrite); - return; - } - - if (sourceFileName == null || destFileName == null) - throw new ArgumentNullException((sourceFileName == null ? "sourceFileName" : "destFileName"), "ArgumentNull_FileName"); - if (sourceFileName.Length == 0 || destFileName.Length == 0) - throw new ArgumentException("Argument_EmptyFileName", (sourceFileName.Length == 0 ? "sourceFileName" : "destFileName")); - - string fullSourceFileName = NameFix.AddLongPathPrefix(sourceFileName); - string fullDestFileName = NameFix.AddLongPathPrefix(destFileName); - - bool r = Win32Native.CopyFile(fullSourceFileName, fullDestFileName, !overwrite); - if (!r) - { - // Save Win32 error because subsequent checks will overwrite this HRESULT. - int errorCode = Marshal.GetLastWin32Error(); - string fileName = destFileName; - - /* - if (errorCode != Win32Native.ERROR_FILE_EXISTS) - { - // For a number of error codes (sharing violation, path - // not found, etc) we don't know if the problem was with - // the source or dest file. Try reading the source file. - using (SafeFileHandle handle = Win32Native.UnsafeCreateFile(fullSourceFileName, FileStream.GENERIC_READ, FileShare.Read, null, FileMode.Open, 0, IntPtr.Zero)) - { - if (handle.IsInvalid) - fileName = sourceFileName; - } - - if (errorCode == Win32Native.ERROR_ACCESS_DENIED) - { - if (Directory.InternalExists(fullDestFileName)) - throw new IOException(string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Arg_FileIsDirectory_Name"), destFileName), Win32Native.ERROR_ACCESS_DENIED, fullDestFileName); - } - } - - __Error.WinIOError(errorCode, fileName); - - */ - } + System.IO.File.Copy(NameFix.AddLongPathPrefix(sourceFileName), NameFix.AddLongPathPrefix(destFileName), overwrite); } + public static void Move(string sourceFileName, string destFileName) { - if (unix.IsUnix) - { - System.IO.File.Move(sourceFileName, destFileName); - return; - } + System.IO.File.Move(NameFix.AddLongPathPrefix(sourceFileName), NameFix.AddLongPathPrefix(destFileName)); - if (sourceFileName == null || destFileName == null) - throw new ArgumentNullException((sourceFileName == null ? "sourceFileName" : "destFileName"), "ArgumentNull_FileName"); - if (sourceFileName.Length == 0 || destFileName.Length == 0) - throw new ArgumentException("Argument_EmptyFileName", (sourceFileName.Length == 0 ? "sourceFileName" : "destFileName")); - - string fullSourceFileName = NameFix.AddLongPathPrefix(sourceFileName); - string fullDestFileName = NameFix.AddLongPathPrefix(destFileName); - - if (!Exists(fullSourceFileName)) - throw new Exception("ERROR_FILE_NOT_FOUND" + fullSourceFileName); - - if (!Win32Native.MoveFile(fullSourceFileName, fullDestFileName)) - { - int hr = Marshal.GetLastWin32Error(); - throw new Exception(GetErrorCode(hr), new Exception("ERROR_MOVING_FILE. (" + fullSourceFileName + " to " + fullDestFileName + ")")); - } } public static void Delete(string path) { - if (unix.IsUnix) - { - System.IO.File.Delete(path); - return; - } + System.IO.File.Delete(NameFix.AddLongPathPrefix(path)); - - string fixPath = NameFix.AddLongPathPrefix(path); - - if (!Win32Native.DeleteFile(fixPath)) - { - int hr = Marshal.GetLastWin32Error(); - if (hr != Win32Native.ERROR_FILE_NOT_FOUND) - throw new Exception(GetErrorCode(hr), new Exception("ERROR_DELETING_FILE. (" + path + ")")); - } - } - - - private static string GetErrorCode(int hr) - { - switch (hr) - { - case 5: return "ERROR_ACCESS_DENIED: Access is denied."; - case 32: return "ERROR_FILE_IN_USE: The file is in use by another process."; - case 39: return "ERROR_HANDLE_DISK_FULL: The disk is full."; - case 112: return "ERROR_DISK_FULL: There is not enough space on the disk."; - case 123: return "ERROR_INVALID_NAME: The filename, directory name, or volume label syntax is incorrect."; - case 183: return "ERROR_ALREADY_EXISTS: Cannot create a file when that file already exists."; - } - - return hr.ToString(); } public static bool SetAttributes(string path, FileAttributes fileAttributes) { - if (unix.IsUnix) + try { - try - { - System.IO.File.SetAttributes(path, (System.IO.FileAttributes)fileAttributes); - return true; - } - catch (Exception) - { - return false; - } + System.IO.File.SetAttributes(NameFix.AddLongPathPrefix(path), (System.IO.FileAttributes)fileAttributes); + return true; + } + catch (Exception) + { + return false; } - - string fullPath = NameFix.AddLongPathPrefix(path); - return Win32Native.SetFileAttributes(fullPath, (int)fileAttributes); } + public static StreamWriter CreateText(string filename) { int errorCode = FileStream.OpenFileWrite(filename, out Stream fStream); @@ -480,16 +224,18 @@ namespace RVIO int errorCode = FileStream.OpenFileRead(filename, out Stream fStream); return errorCode != 0 ? null : new StreamReader(fStream, Enc); } - - private const int ERROR_INVALID_PARAMETER = 87; - private const int ERROR_ACCESS_DENIED = 0x5; } public static class Path { - public static readonly char DirectorySeparatorChar = '\\'; - public static readonly char AltDirectorySeparatorChar = '/'; - public static readonly char VolumeSeparatorChar = ':'; + private const char DirectorySeparatorChar = '\\'; + private const char AltDirectorySeparatorChar = '/'; + private const char VolumeSeparatorChar = ':'; + + public static char DirSeparatorChar + { + get { return unix.IsUnix ? AltDirectorySeparatorChar : DirectorySeparatorChar; } + } public static string GetExtension(string path) { @@ -527,36 +273,12 @@ namespace RVIO int length = path.Length; if ( - (length >= 1 && (path[0] == DirectorySeparatorChar || - path[0] == AltDirectorySeparatorChar)) || + (length >= 1 && (path[0] == DirectorySeparatorChar || path[0] == AltDirectorySeparatorChar)) || (length >= 2 && path[1] == VolumeSeparatorChar) - ) return true; + ) return true; } return false; } - /* - private static void CheckInvalidPathChars(string path) - { - for (int index = 0; index < path.Length; ++index) - { - int num = path[index]; - switch (num) - { - case 34: - case 60: - case 62: - case 124: - ReportError.SendErrorMessage("Invalid Character " + num + " in filename " + path); - continue; - default: - if (num >= 32) - continue; - - goto case 34; - } - } - } - */ public static string GetFileNameWithoutExtension(string path) { @@ -569,66 +291,14 @@ namespace RVIO } public static string GetDirectoryName(string path) { - if (unix.IsUnix) - return System.IO.Path.GetDirectoryName(path); + return System.IO.Path.GetDirectoryName(path); - - if (path != null) - { - int root = GetRootLength(path); - int i = path.Length; - if (i > root) - { - i = path.Length; - if (i == root) return null; - while (i > root && path[--i] != DirectorySeparatorChar && path[i] != AltDirectorySeparatorChar) ; - return path.Substring(0, i); - } - } - return null; } - - private static int GetRootLength(string path) - { - int i = 0; - int length = path.Length; - - if (length >= 1 && (IsDirectorySeparator(path[0]))) - { - // handles UNC names and directories off current drive's root. - i = 1; - if (length >= 2 && (IsDirectorySeparator(path[1]))) - { - i = 2; - int n = 2; - while (i < length && ((path[i] != DirectorySeparatorChar && path[i] != AltDirectorySeparatorChar) || --n > 0)) i++; - } - } - else if (length >= 2 && path[1] == VolumeSeparatorChar) - { - // handles A:\foo. - i = 2; - if (length >= 3 && (IsDirectorySeparator(path[2]))) i++; - } - return i; - } - private static bool IsDirectorySeparator(char c) - { - return (c == DirectorySeparatorChar || c == AltDirectorySeparatorChar); - } - } public static class FileStream { - private const uint GENERIC_READ = 0x80000000; - private const uint GENERIC_WRITE = 0x40000000; - - private const uint FILE_ATTRIBUTE_NORMAL = 0x80; - - // errorMessage = new Win32Exception(errorCode).Message; - public static Stream OpenFileRead(string path, out int result) { result = OpenFileRead(path, out Stream stream); @@ -637,76 +307,31 @@ namespace RVIO public static int OpenFileRead(string path, out Stream stream) { - if (unix.IsUnix) + try { - try - { - stream = new System.IO.FileStream(path, FileMode.Open, FileAccess.Read); - return 0; - } - catch (Exception) - { - stream = null; - return Marshal.GetLastWin32Error(); - } + stream = new System.IO.FileStream(NameFix.AddLongPathPrefix(path), FileMode.Open, FileAccess.Read); + return 0; } - - string filename = NameFix.AddLongPathPrefix(path); - SafeFileHandle hFile = Win32Native.CreateFile(filename, - GENERIC_READ, - System.IO.FileShare.Read, - IntPtr.Zero, - FileMode.Open, - FILE_ATTRIBUTE_NORMAL, - IntPtr.Zero); - - if (hFile.IsInvalid) + catch (Exception) { stream = null; return Marshal.GetLastWin32Error(); } - stream = new System.IO.FileStream(hFile, FileAccess.Read); - - return 0; } public static int OpenFileWrite(string path, out Stream stream) { - if (unix.IsUnix) + try { - try - { - stream = new System.IO.FileStream(path, FileMode.Create, FileAccess.ReadWrite); - return 0; - } - catch (Exception) - { - stream = null; - return Marshal.GetLastWin32Error(); - } + stream = new System.IO.FileStream(NameFix.AddLongPathPrefix(path), FileMode.Create, FileAccess.ReadWrite); + return 0; } - - - string filename = NameFix.AddLongPathPrefix(path); - SafeFileHandle hFile = Win32Native.CreateFile(filename, - GENERIC_READ | GENERIC_WRITE, - System.IO.FileShare.None, - IntPtr.Zero, - FileMode.Create, - FILE_ATTRIBUTE_NORMAL, - IntPtr.Zero); - - if (hFile.IsInvalid) + catch (Exception) { stream = null; return Marshal.GetLastWin32Error(); } - - stream = new System.IO.FileStream(hFile, FileAccess.ReadWrite); - return 0; } - - } public static class NameFix @@ -734,7 +359,6 @@ namespace RVIO remove = 4; } - const int MAX_PATH = 300; StringBuilder shortPath = new StringBuilder(MAX_PATH); Win32Native.GetShortPathName(retPath, shortPath, MAX_PATH); @@ -750,6 +374,9 @@ namespace RVIO internal static string AddLongPathPrefix(string path) { + if (unix.IsUnix) + return path; + if (string.IsNullOrEmpty(path) || path.StartsWith(@"\\?\")) return path; @@ -763,7 +390,6 @@ namespace RVIO retPath = cleandots(retPath); return @"\\?\" + retPath; - } private static string cleandots(string path) @@ -783,4 +409,4 @@ namespace RVIO } } -} \ No newline at end of file +} diff --git a/SabreTools.FileTypes/RVIO/Win32Native.cs b/SabreTools.FileTypes/RVIO/Win32Native.cs index 749e7bf0..acbcfa63 100644 --- a/SabreTools.FileTypes/RVIO/Win32Native.cs +++ b/SabreTools.FileTypes/RVIO/Win32Native.cs @@ -1,7 +1,7 @@ /****************************************************** * ROMVault3 is written by Gordon J. * * Contact gordon@romvault.com * - * Copyright 2019 * + * Copyright 2020 * ******************************************************/ using System; @@ -19,63 +19,6 @@ namespace RVIO { private const string KERNEL32 = "kernel32.dll"; - public const int FILE_ATTRIBUTE_DIRECTORY = 0x00000010; - public const int FILE_ATTRIBUTE_HIDDEN = 0x00000002; - - - internal const int ERROR_FILE_NOT_FOUND = 0x2; - internal const int ERROR_ACCESS_DENIED = 0x5; - internal const int ERROR_FILE_EXISTS = 0x50; - - [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] - [ResourceExposure(ResourceScope.None)] - internal static extern bool GetFileAttributesEx(string fileName, int fileInfoLevel, ref WIN32_FILE_ATTRIBUTE_DATA lpFileInformation); - - [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] - [ResourceExposure(ResourceScope.None)] - internal static extern SafeFindHandle FindFirstFile(string fileName, [In] [Out] WIN32_FIND_DATA data); - - [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] - [ResourceExposure(ResourceScope.None)] - internal static extern bool FindNextFile(SafeFindHandle hndFindFile, [In] [Out] [MarshalAs(UnmanagedType.LPStruct)] WIN32_FIND_DATA lpFindFileData); - - [DllImport(KERNEL32)] - [ResourceExposure(ResourceScope.None)] - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - internal static extern bool FindClose(IntPtr handle); - - [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] - [ResourceExposure(ResourceScope.Machine)] - internal static extern SafeFileHandle CreateFile(string lpFileName, - uint dwDesiredAccess, FileShare dwShareMode, - IntPtr securityAttrs, FileMode dwCreationDisposition, - uint dwFlagsAndAttributes, IntPtr hTemplateFile); - - [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] - [ResourceExposure(ResourceScope.Machine)] - internal static extern bool CreateDirectory(string path, IntPtr lpSecurityAttributes); - - [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] - [ResourceExposure(ResourceScope.Machine)] - internal static extern bool RemoveDirectory(string path); - - - [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] - [ResourceExposure(ResourceScope.Machine)] - internal static extern bool CopyFile(string src, string dst, bool failIfExists); - - [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] - [ResourceExposure(ResourceScope.Machine)] - internal static extern bool MoveFile(string src, string dst); - - [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] - [ResourceExposure(ResourceScope.Machine)] - internal static extern bool DeleteFile(string path); - - [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] - [ResourceExposure(ResourceScope.None)] - internal static extern bool SetFileAttributes(string name, int attr); - [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] [ResourceExposure(ResourceScope.Machine)] @@ -85,59 +28,9 @@ namespace RVIO int shortPathLength ); - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] - [BestFitMapping(false)] - internal class WIN32_FIND_DATA - { - internal int dwFileAttributes = 0; - internal uint ftCreationTimeLow; - internal uint ftCreationTimeHigh; - internal uint ftLastAccessTimeLow; - internal uint ftLastAccessTimeHigh; - internal uint ftLastWriteTimeLow; - internal uint ftLastWriteTimeHigh; - internal int nFileSizeHigh = 0; - internal int nFileSizeLow = 0; - internal int dwReserved0 = 0; - internal int dwReserved1 = 0; - - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] internal string cFileName = null; - - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)] internal string cAlternateFileName = null; - } - - [StructLayout(LayoutKind.Sequential)] - [Serializable] - internal struct WIN32_FILE_ATTRIBUTE_DATA - { - internal int fileAttributes; - internal uint ftCreationTimeLow; - internal uint ftCreationTimeHigh; - internal uint ftLastAccessTimeLow; - internal uint ftLastAccessTimeHigh; - internal uint ftLastWriteTimeLow; - internal uint ftLastWriteTimeHigh; - internal int fileSizeHigh; - internal int fileSizeLow; - } } - - internal sealed class SafeFindHandle : SafeHandleZeroOrMinusOneIsInvalid - { - [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] - internal SafeFindHandle() : base(true) - { - } - - protected override bool ReleaseHandle() - { - return Win32Native.FindClose(handle); - } - } - - - internal static class Convert + + public static class FileParamConvert { private const long TicksPerMillisecond = 10000; private const long TicksPerSecond = TicksPerMillisecond * 1000; @@ -145,34 +38,17 @@ namespace RVIO private const long TicksPerHour = TicksPerMinute * 60; private const long TicksPerDay = TicksPerHour * 24; - // Number of days in a non-leap year + // Number of days in a non-leap year private const int DaysPerYear = 365; - // Number of days in 4 years + // Number of days in 4 years private const int DaysPer4Years = DaysPerYear * 4 + 1; // Number of days in 100 years private const int DaysPer100Years = DaysPer4Years * 25 - 1; // Number of days in 400 years private const int DaysPer400Years = DaysPer100Years * 4 + 1; - // Number of days from 1/1/0001 to 12/31/1600 + // Number of days from 1/1/0001 to 12/31/1600 private const int DaysTo1601 = DaysPer400Years * 4; public const long FileTimeOffset = DaysTo1601 * TicksPerDay; - - - // Number of days from 1/1/0001 to 12/31/9999 - private const int DaysTo10000 = DaysPer400Years * 25 - 366; - private const long MinTicks = 0; - private const long MaxTicks = DaysTo10000 * TicksPerDay - 1; - - - public static long Length(int high, int low) - { - return ((long)high << 32) | (low & 0xFFFFFFFFL); - } - - public static long Time(uint high, uint low) - { - return ((long)high << 32) | low; - } } } \ No newline at end of file