mirror of
https://github.com/claunia/SabreTools.git
synced 2025-12-16 19:14:27 +00:00
Update Compress library from RVWorld latest
This commit is contained in:
@@ -107,7 +107,7 @@ namespace SabreTools.Core.Tools
|
||||
/// <remarks>
|
||||
/// Adapted from 7-zip Source Code: CPP/Windows/TimeUtils.cpp:FileTimeToDosTime
|
||||
/// </remarks>
|
||||
public static uint ConvertDateTimeToMsDosTimeFormat(DateTime dateTime)
|
||||
public static long ConvertDateTimeToMsDosTimeFormat(DateTime dateTime)
|
||||
{
|
||||
uint year = (uint)((dateTime.Year - 1980) % 128);
|
||||
uint mon = (uint)dateTime.Month;
|
||||
|
||||
@@ -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<string> 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<string> 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<string> 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];
|
||||
|
||||
@@ -330,7 +330,7 @@ namespace SabreTools.FileTypes.Archives
|
||||
|
||||
// Get the order for the entries with the new file
|
||||
List<string> 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<string> 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<string> 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)
|
||||
|
||||
@@ -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
|
||||
/// <inheritdoc/>
|
||||
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<string> 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<string> 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<string> 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];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -48,13 +48,13 @@ namespace Compress.SevenZip.Compress.PPmd.I1
|
||||
/// </summary>
|
||||
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
|
||||
/// </summary>
|
||||
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
|
||||
/// </summary>
|
||||
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
|
||||
/// <returns></returns>
|
||||
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
|
||||
/// <returns></returns>
|
||||
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);
|
||||
|
||||
@@ -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
|
||||
/// <returns></returns>
|
||||
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
|
||||
/// <returns></returns>
|
||||
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
|
||||
/// <returns></returns>
|
||||
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
|
||||
/// <returns></returns>
|
||||
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
|
||||
/// <returns></returns>
|
||||
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
|
||||
/// <returns></returns>
|
||||
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
|
||||
/// <returns>The number of bytes between the two pointers.</returns>
|
||||
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
|
||||
/// <returns></returns>
|
||||
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
|
||||
/// <returns></returns>
|
||||
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
|
||||
/// <returns></returns>
|
||||
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
|
||||
/// <returns></returns>
|
||||
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);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -58,13 +58,13 @@ namespace Compress.SevenZip.Compress.PPmd.I1
|
||||
/// </summary>
|
||||
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
|
||||
/// <returns></returns>
|
||||
public PpmState this[int offset]
|
||||
{
|
||||
get { return new PpmState((uint)(Address + offset * Size), Memory); }
|
||||
get { return new PpmState((uint) (Address + offset * Size), Memory); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -97,7 +97,7 @@ namespace Compress.SevenZip.Compress.PPmd.I1
|
||||
/// <returns></returns>
|
||||
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
|
||||
/// <returns></returns>
|
||||
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);
|
||||
|
||||
@@ -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,7 +48,7 @@ namespace Compress.SevenZip.Compress.PPmd.I1
|
||||
if (Shift < PeriodBitCount && --Count == 0)
|
||||
{
|
||||
Summary += Summary;
|
||||
Count = (byte)(3 << Shift++);
|
||||
Count = (byte) (3 << Shift++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// A Zstandard dictionary improves the compression ratio and speed on small data dramatically.
|
||||
@@ -38,7 +38,7 @@ namespace Zstandard.Net
|
||||
/// <param name="dictionaryPath">The dictionary path.</param>
|
||||
public ZstandardDictionary(string dictionaryPath)
|
||||
{
|
||||
this.dictionary = File.ReadAllBytes(dictionaryPath);
|
||||
this.dictionary = System.IO.File.ReadAllBytes(dictionaryPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Zstandard.Net
|
||||
namespace Compress.SevenZip.Compress.ZSTD
|
||||
{
|
||||
internal static class ZstandardInterop
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides methods and properties for compressing and decompressing streams by using the Zstandard algorithm.
|
||||
|
||||
@@ -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++)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,6 +162,11 @@ namespace Compress.SevenZip
|
||||
}
|
||||
}
|
||||
|
||||
if (_header.FileInfo.TimeLastWrite != null)
|
||||
{
|
||||
lf.LastModified = DateTime.FromFileTimeUtc((long)_header.FileInfo.TimeLastWrite[i]).Ticks;
|
||||
}
|
||||
|
||||
localFiles.Add(lf);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
9
SabreTools.FileTypes/Compress/Utils/TimeStamps.cs
Normal file
9
SabreTools.FileTypes/Compress/Utils/TimeStamps.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Compress.Utils
|
||||
{
|
||||
public class TimeStamps
|
||||
{
|
||||
public long? ModTime;
|
||||
public long? CreateTime;
|
||||
public long? AccessTime;
|
||||
}
|
||||
}
|
||||
613
SabreTools.FileTypes/Compress/ZipFile/Explode/Original.c
Normal file
613
SabreTools.FileTypes/Compress/ZipFile/Explode/Original.c
Normal file
@@ -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)<<k;k+=8;}}
|
||||
#define DUMPBITS(n) {b>>=(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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -65,372 +65,372 @@ using System;
|
||||
namespace Compress.ZipFile.ZLib
|
||||
{
|
||||
|
||||
sealed class InfTree
|
||||
{
|
||||
sealed class InfTree
|
||||
{
|
||||
|
||||
private const int MANY = 1440;
|
||||
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;
|
||||
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;
|
||||
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,
|
||||
//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 };
|
||||
//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 };
|
||||
// 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 };
|
||||
// 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 '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 };
|
||||
//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
|
||||
// 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
|
||||
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)
|
||||
{
|
||||
// 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 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;
|
||||
// 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.
|
||||
|
||||
// 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++;
|
||||
}
|
||||
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
|
||||
|
||||
// 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 counts for each bit length
|
||||
|
||||
// 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)
|
||||
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;
|
||||
c[i] += y;
|
||||
|
||||
// connect to last table, if there is one
|
||||
if (h != 0)
|
||||
// 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<BMAX; i++){u[i]=0;}
|
||||
//Array.Copy(c, 0, u, 0, BMAX);
|
||||
Array.Clear(u,0,BMAX);
|
||||
// for(int i=0; i<BMAX+1; i++){x[i]=0;}
|
||||
//Array.Copy(c, 0, x, 0, BMAX + 1);
|
||||
Array.Clear(x,0,BMAX+1);
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
{
|
||||
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<BMAX; i++){u[i]=0;}
|
||||
//Array.Copy(c, 0, u, 0, BMAX);
|
||||
Array.Clear(u, 0, BMAX);
|
||||
// for(int i=0; i<BMAX+1; i++){x[i]=0;}
|
||||
//Array.Copy(c, 0, x, 0, BMAX + 1);
|
||||
Array.Clear(x, 0, BMAX + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,16 +76,16 @@ namespace Compress.ZipFile.ZLib
|
||||
|
||||
private enum InflateBlockMode
|
||||
{
|
||||
TYPE = 0, // get type bits (3, including end bit)
|
||||
LENS = 1, // get lengths for stored
|
||||
TYPE = 0, // get type bits (3, including end bit)
|
||||
LENS = 1, // get lengths for stored
|
||||
STORED = 2, // processing stored block
|
||||
TABLE = 3, // get table lengths
|
||||
BTREE = 4, // get bit lengths tree for a dynamic block
|
||||
DTREE = 5, // get length, distance trees for a dynamic block
|
||||
CODES = 6, // processing fixed or dynamic block
|
||||
DRY = 7, // output remaining window bytes
|
||||
DONE = 8, // finished last block, done
|
||||
BAD = 9, // ot a data error--stuck here
|
||||
TABLE = 3, // get table lengths
|
||||
BTREE = 4, // get bit lengths tree for a dynamic block
|
||||
DTREE = 5, // get length, distance trees for a dynamic block
|
||||
CODES = 6, // processing fixed or dynamic block
|
||||
DRY = 7, // output remaining window bytes
|
||||
DONE = 8, // finished last block, done
|
||||
BAD = 9, // ot a data error--stuck here
|
||||
}
|
||||
|
||||
private InflateBlockMode mode; // current inflate_block mode
|
||||
@@ -104,7 +104,7 @@ namespace Compress.ZipFile.ZLib
|
||||
|
||||
internal ZlibCodec _codec; // pointer back to this zlib stream
|
||||
|
||||
// mode independent information
|
||||
// mode independent information
|
||||
internal int bitk; // bits in bit buffer
|
||||
internal int bitb; // bit buffer
|
||||
internal int[] hufts; // single malloc for tree space
|
||||
@@ -255,7 +255,7 @@ namespace Compress.ZipFile.ZLib
|
||||
k += 8;
|
||||
}
|
||||
|
||||
if ((((~b) >> 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;
|
||||
|
||||
@@ -82,9 +82,9 @@ namespace Compress.ZipFile.ZLib
|
||||
};
|
||||
|
||||
// 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 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 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
|
||||
@@ -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;
|
||||
@@ -221,7 +221,7 @@ 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)
|
||||
@@ -237,7 +237,7 @@ 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:
|
||||
@@ -247,7 +247,7 @@ namespace Compress.ZipFile.ZLib
|
||||
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]
|
||||
@@ -265,8 +265,8 @@ 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--;
|
||||
}
|
||||
@@ -279,13 +279,13 @@ namespace Compress.ZipFile.ZLib
|
||||
// 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
|
||||
@@ -313,7 +313,7 @@ namespace Compress.ZipFile.ZLib
|
||||
// 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--;
|
||||
@@ -345,9 +345,9 @@ namespace Compress.ZipFile.ZLib
|
||||
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++;
|
||||
@@ -372,7 +372,7 @@ namespace Compress.ZipFile.ZLib
|
||||
// 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
|
||||
@@ -382,9 +382,8 @@ namespace Compress.ZipFile.ZLib
|
||||
// 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
|
||||
@@ -399,7 +398,7 @@ namespace Compress.ZipFile.ZLib
|
||||
if (len == 0)
|
||||
continue;
|
||||
// Now reverse the bits
|
||||
tree[n * 2] = unchecked((short)(bi_reverse(next_code[len]++, len)));
|
||||
tree[n * 2] = unchecked((short) (bi_reverse(next_code[len]++, len)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
/// </summary>
|
||||
None = 0,
|
||||
None= 0,
|
||||
/// <summary>
|
||||
/// Same as None.
|
||||
/// </summary>
|
||||
@@ -249,7 +249,7 @@ namespace Compress.ZipFile.ZLib
|
||||
/// <summary>
|
||||
/// Used to specify that the stream should compress the data.
|
||||
/// </summary>
|
||||
Compress = 0,
|
||||
Compress= 0,
|
||||
/// <summary>
|
||||
/// Used to specify that the stream should decompress the data.
|
||||
/// </summary>
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Interop = System.Runtime.InteropServices;
|
||||
using Interop=System.Runtime.InteropServices;
|
||||
|
||||
namespace Compress.ZipFile.ZLib
|
||||
{
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -123,3 +123,4 @@ namespace Compress.ZipFile.ZLib
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
140
SabreTools.FileTypes/Compress/ZipFile/Zip.cs
Normal file
140
SabreTools.FileTypes/Compress/ZipFile/Zip.cs
Normal file
@@ -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<LocalFile> _localFiles = new List<LocalFile>();
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
239
SabreTools.FileTypes/Compress/ZipFile/ZipCentralDir.cs
Normal file
239
SabreTools.FileTypes/Compress/ZipFile/ZipCentralDir.cs
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
605
SabreTools.FileTypes/Compress/ZipFile/ZipExtraField.cs
Normal file
605
SabreTools.FileTypes/Compress/ZipFile/ZipExtraField.cs
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
91
SabreTools.FileTypes/Compress/ZipFile/ZipFake.cs
Normal file
91
SabreTools.FileTypes/Compress/ZipFile/ZipFake.cs
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
741
SabreTools.FileTypes/Compress/ZipFile/ZipLocalFile.cs
Normal file
741
SabreTools.FileTypes/Compress/ZipFile/ZipLocalFile.cs
Normal file
@@ -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<byte> extraField = new List<byte>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
251
SabreTools.FileTypes/Compress/ZipFile/ZipRead.cs
Normal file
251
SabreTools.FileTypes/Compress/ZipFile/ZipRead.cs
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
80
SabreTools.FileTypes/Compress/ZipFile/ZipReadStream.cs
Normal file
80
SabreTools.FileTypes/Compress/ZipFile/ZipReadStream.cs
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
242
SabreTools.FileTypes/Compress/ZipFile/ZipUtils.cs
Normal file
242
SabreTools.FileTypes/Compress/ZipFile/ZipUtils.cs
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
109
SabreTools.FileTypes/Compress/ZipFile/ZipWrite.cs
Normal file
109
SabreTools.FileTypes/Compress/ZipFile/ZipWrite.cs
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
73
SabreTools.FileTypes/Compress/ZipFile/ZipWriteStream.cs
Normal file
73
SabreTools.FileTypes/Compress/ZipFile/ZipWriteStream.cs
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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<DirectoryInfo> dirs = new List<DirectoryInfo>();
|
||||
|
||||
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<FileInfo> files = new List<FileInfo>();
|
||||
|
||||
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)
|
||||
|
||||
@@ -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;
|
||||
@@ -157,22 +50,5 @@ namespace RVIO
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user