Update Compress library from RVWorld latest

This commit is contained in:
Matt Nadareski
2021-01-29 17:18:28 -08:00
parent a26833b8a8
commit 6e8792c361
84 changed files with 4348 additions and 3509 deletions

View File

@@ -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;

View File

@@ -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];

View File

@@ -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)

View File

@@ -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];

View File

@@ -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;
}
}
}

View File

@@ -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();

View File

@@ -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)
{

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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
{

View File

@@ -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);

View File

@@ -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++);
}
}
}

View File

@@ -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;

View File

@@ -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>

View File

@@ -2,7 +2,7 @@
using System.IO;
using System.Runtime.InteropServices;
namespace Zstandard.Net
namespace Compress.SevenZip.Compress.ZSTD
{
internal static class ZstandardInterop
{

View File

@@ -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.

View File

@@ -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++)

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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)

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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
{

View File

@@ -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:

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,9 @@
namespace Compress.Utils
{
public class TimeStamps
{
public long? ModTime;
public long? CreateTime;
public long? AccessTime;
}
}

View 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

View File

@@ -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

View File

@@ -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);
}
}
}
}

View File

@@ -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;

View File

@@ -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)));
}
}

View File

@@ -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)
{

View File

@@ -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)
{

View File

@@ -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)
{

View File

@@ -123,3 +123,4 @@ namespace Compress.ZipFile.ZLib
}
}

View 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();
}
}
}

View 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
}
}
}
}

View 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;
}
}
}
}

View 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;
}
}
}

View 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;
}
}
}

View 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;
}
}
}
}

View 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;
}
}
}

View 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;
}
}
}

View 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;
}
}
}

View 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

View File

@@ -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;
}
}
}

View File

@@ -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)

View File

@@ -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;
}
}
}