remove our outdated 7z shenanigans with sharpcompress
This commit is contained in:
parent
19dd590f2c
commit
b862a464ee
|
@ -1,101 +0,0 @@
|
|||
using System.IO;
|
||||
using System;
|
||||
|
||||
namespace SevenZip
|
||||
{
|
||||
/// <summary>
|
||||
/// The Stream extension class to emulate the archive part of a stream.
|
||||
/// </summary>
|
||||
internal class ArchiveEmulationStreamProxy : Stream, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the file offset.
|
||||
/// </summary>
|
||||
public int Offset { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The source wrapped stream.
|
||||
/// </summary>
|
||||
public Stream Source { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ArchiveEmulationStream class.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream to wrap.</param>
|
||||
/// <param name="offset">The stream offset.</param>
|
||||
public ArchiveEmulationStreamProxy(Stream stream, int offset)
|
||||
{
|
||||
Source = stream;
|
||||
Offset = offset;
|
||||
Source.Position = offset;
|
||||
}
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get { return Source.CanRead; }
|
||||
}
|
||||
|
||||
public override bool CanSeek
|
||||
{
|
||||
get { return Source.CanSeek; }
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return Source.CanWrite; }
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
Source.Flush();
|
||||
}
|
||||
|
||||
public override long Length
|
||||
{
|
||||
get { return Source.Length - Offset; }
|
||||
}
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get
|
||||
{
|
||||
return Source.Position - Offset;
|
||||
}
|
||||
set
|
||||
{
|
||||
Source.Position = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
return Source.Read(buffer, offset, count);
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
return Source.Seek(origin == SeekOrigin.Begin ? offset + Offset : offset,
|
||||
origin) - Offset;
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
Source.SetLength(value);
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
Source.Write(buffer, offset, count);
|
||||
}
|
||||
|
||||
public new void Dispose()
|
||||
{
|
||||
Source.Dispose();
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
Source.Close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,602 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
#if MONO
|
||||
using SevenZip.Mono.COM;
|
||||
using System.Runtime.InteropServices;
|
||||
#endif
|
||||
|
||||
namespace SevenZip
|
||||
{
|
||||
#if UNMANAGED
|
||||
/// <summary>
|
||||
/// Archive extraction callback to handle the process of unpacking files
|
||||
/// </summary>
|
||||
internal sealed class ArchiveExtractCallback : CallbackBase, IArchiveExtractCallback, ICryptoGetTextPassword,
|
||||
IDisposable
|
||||
{
|
||||
private List<uint> _actualIndexes;
|
||||
private IInArchive _archive;
|
||||
|
||||
/// <summary>
|
||||
/// For Compressing event.
|
||||
/// </summary>
|
||||
private long _bytesCount;
|
||||
|
||||
private long _bytesWritten;
|
||||
private long _bytesWrittenOld;
|
||||
private string _directory;
|
||||
|
||||
/// <summary>
|
||||
/// Rate of the done work from [0, 1].
|
||||
/// </summary>
|
||||
private float _doneRate;
|
||||
|
||||
private SevenZipExtractor _extractor;
|
||||
private FakeOutStreamWrapper _fakeStream;
|
||||
private uint? _fileIndex;
|
||||
private int _filesCount;
|
||||
private OutStreamWrapper _fileStream;
|
||||
private bool _directoryStructure;
|
||||
private int _currentIndex;
|
||||
#if !WINCE
|
||||
const int MEMORY_PRESSURE = 64 * 1024 * 1024; //64mb seems to be the maximum value
|
||||
#endif
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ArchiveExtractCallback class
|
||||
/// </summary>
|
||||
/// <param name="archive">IInArchive interface for the archive</param>
|
||||
/// <param name="directory">Directory where files are to be unpacked to</param>
|
||||
/// <param name="filesCount">The archive files count</param>'
|
||||
/// <param name="extractor">The owner of the callback</param>
|
||||
/// <param name="actualIndexes">The list of actual indexes (solid archives support)</param>
|
||||
/// <param name="directoryStructure">The value indicating whether to preserve directory structure of extracted files.</param>
|
||||
public ArchiveExtractCallback(IInArchive archive, string directory, int filesCount, bool directoryStructure,
|
||||
List<uint> actualIndexes, SevenZipExtractor extractor)
|
||||
{
|
||||
Init(archive, directory, filesCount, directoryStructure, actualIndexes, extractor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ArchiveExtractCallback class
|
||||
/// </summary>
|
||||
/// <param name="archive">IInArchive interface for the archive</param>
|
||||
/// <param name="directory">Directory where files are to be unpacked to</param>
|
||||
/// <param name="filesCount">The archive files count</param>
|
||||
/// <param name="password">Password for the archive</param>
|
||||
/// <param name="extractor">The owner of the callback</param>
|
||||
/// <param name="actualIndexes">The list of actual indexes (solid archives support)</param>
|
||||
/// <param name="directoryStructure">The value indicating whether to preserve directory structure of extracted files.</param>
|
||||
public ArchiveExtractCallback(IInArchive archive, string directory, int filesCount, bool directoryStructure,
|
||||
List<uint> actualIndexes, string password, SevenZipExtractor extractor)
|
||||
: base(password)
|
||||
{
|
||||
Init(archive, directory, filesCount, directoryStructure, actualIndexes, extractor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ArchiveExtractCallback class
|
||||
/// </summary>
|
||||
/// <param name="archive">IInArchive interface for the archive</param>
|
||||
/// <param name="stream">The stream where files are to be unpacked to</param>
|
||||
/// <param name="filesCount">The archive files count</param>
|
||||
/// <param name="fileIndex">The file index for the stream</param>
|
||||
/// <param name="extractor">The owner of the callback</param>
|
||||
public ArchiveExtractCallback(IInArchive archive, Stream stream, int filesCount, uint fileIndex,
|
||||
SevenZipExtractor extractor)
|
||||
{
|
||||
Init(archive, stream, filesCount, fileIndex, extractor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ArchiveExtractCallback class
|
||||
/// </summary>
|
||||
/// <param name="archive">IInArchive interface for the archive</param>
|
||||
/// <param name="stream">The stream where files are to be unpacked to</param>
|
||||
/// <param name="filesCount">The archive files count</param>
|
||||
/// <param name="fileIndex">The file index for the stream</param>
|
||||
/// <param name="password">Password for the archive</param>
|
||||
/// <param name="extractor">The owner of the callback</param>
|
||||
public ArchiveExtractCallback(IInArchive archive, Stream stream, int filesCount, uint fileIndex, string password,
|
||||
SevenZipExtractor extractor)
|
||||
: base(password)
|
||||
{
|
||||
Init(archive, stream, filesCount, fileIndex, extractor);
|
||||
}
|
||||
|
||||
private void Init(IInArchive archive, string directory, int filesCount, bool directoryStructure,
|
||||
List<uint> actualIndexes, SevenZipExtractor extractor)
|
||||
{
|
||||
CommonInit(archive, filesCount, extractor);
|
||||
_directory = directory;
|
||||
_actualIndexes = actualIndexes;
|
||||
_directoryStructure = directoryStructure;
|
||||
if (!directory.EndsWith("" + Path.DirectorySeparatorChar, StringComparison.CurrentCulture))
|
||||
{
|
||||
_directory += Path.DirectorySeparatorChar;
|
||||
}
|
||||
}
|
||||
|
||||
private void Init(IInArchive archive, Stream stream, int filesCount, uint fileIndex, SevenZipExtractor extractor)
|
||||
{
|
||||
CommonInit(archive, filesCount, extractor);
|
||||
_fileStream = new OutStreamWrapper(stream, false);
|
||||
_fileStream.BytesWritten += IntEventArgsHandler;
|
||||
_fileIndex = fileIndex;
|
||||
}
|
||||
|
||||
private void CommonInit(IInArchive archive, int filesCount, SevenZipExtractor extractor)
|
||||
{
|
||||
_archive = archive;
|
||||
_filesCount = filesCount;
|
||||
_fakeStream = new FakeOutStreamWrapper();
|
||||
_fakeStream.BytesWritten += IntEventArgsHandler;
|
||||
_extractor = extractor;
|
||||
#if !WINCE
|
||||
GC.AddMemoryPressure(MEMORY_PRESSURE);
|
||||
#endif
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a new file is going to be unpacked
|
||||
/// </summary>
|
||||
/// <remarks>Occurs when 7-zip engine requests for an output stream for a new file to unpack in</remarks>
|
||||
public event EventHandler<FileInfoEventArgs> FileExtractionStarted;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a file has been successfully unpacked
|
||||
/// </summary>
|
||||
public event EventHandler<FileInfoEventArgs> FileExtractionFinished;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the archive is opened and 7-zip sends the size of unpacked data
|
||||
/// </summary>
|
||||
public event EventHandler<OpenEventArgs> Open;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the extraction is performed
|
||||
/// </summary>
|
||||
public event EventHandler<ProgressEventArgs> Extracting;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs during the extraction when a file already exists
|
||||
/// </summary>
|
||||
public event EventHandler<FileOverwriteEventArgs> FileExists;
|
||||
|
||||
private void OnFileExists(FileOverwriteEventArgs e)
|
||||
{
|
||||
if (FileExists != null)
|
||||
{
|
||||
FileExists(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnOpen(OpenEventArgs e)
|
||||
{
|
||||
if (Open != null)
|
||||
{
|
||||
Open(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnFileExtractionStarted(FileInfoEventArgs e)
|
||||
{
|
||||
if (FileExtractionStarted != null)
|
||||
{
|
||||
FileExtractionStarted(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnFileExtractionFinished(FileInfoEventArgs e)
|
||||
{
|
||||
if (FileExtractionFinished != null)
|
||||
{
|
||||
FileExtractionFinished(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnExtracting(ProgressEventArgs e)
|
||||
{
|
||||
if (Extracting != null)
|
||||
{
|
||||
Extracting(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void IntEventArgsHandler(object sender, IntEventArgs e)
|
||||
{
|
||||
var pold = (int)((_bytesWrittenOld * 100) / _bytesCount);
|
||||
_bytesWritten += e.Value;
|
||||
var pnow = (int)((_bytesWritten * 100) / _bytesCount);
|
||||
if (pnow > pold)
|
||||
{
|
||||
if (pnow > 100)
|
||||
{
|
||||
pold = pnow = 0;
|
||||
}
|
||||
_bytesWrittenOld = _bytesWritten;
|
||||
OnExtracting(new ProgressEventArgs((byte)pnow, (byte)(pnow - pold)));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IArchiveExtractCallback Members
|
||||
|
||||
/// <summary>
|
||||
/// Gives the size of the unpacked archive files
|
||||
/// </summary>
|
||||
/// <param name="total">Size of the unpacked archive files (in bytes)</param>
|
||||
public void SetTotal(ulong total)
|
||||
{
|
||||
_bytesCount = (long)total;
|
||||
OnOpen(new OpenEventArgs(total));
|
||||
}
|
||||
|
||||
public void SetCompleted(ref ulong completeValue) { }
|
||||
|
||||
/// <summary>
|
||||
/// Sets output stream for writing unpacked data
|
||||
/// </summary>
|
||||
/// <param name="index">Current file index</param>
|
||||
/// <param name="outStream">Output stream pointer</param>
|
||||
/// <param name="askExtractMode">Extraction mode</param>
|
||||
/// <returns>0 if OK</returns>
|
||||
public int GetStream(uint index, out
|
||||
#if !MONO
|
||||
ISequentialOutStream
|
||||
#else
|
||||
HandleRef
|
||||
#endif
|
||||
outStream, AskMode askExtractMode)
|
||||
{
|
||||
#if !MONO
|
||||
outStream = null;
|
||||
#else
|
||||
outStream = new System.Runtime.InteropServices.HandleRef(null, IntPtr.Zero);
|
||||
#endif
|
||||
if (Canceled)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
_currentIndex = (int)index;
|
||||
if (askExtractMode == AskMode.Extract)
|
||||
{
|
||||
var fileName = _directory;
|
||||
if (!_fileIndex.HasValue)
|
||||
{
|
||||
#region Extraction to a file
|
||||
|
||||
if (_actualIndexes == null || _actualIndexes.Contains(index))
|
||||
{
|
||||
var data = new PropVariant();
|
||||
_archive.GetProperty(index, ItemPropId.Path, ref data);
|
||||
string entryName = NativeMethods.SafeCast(data, "");
|
||||
|
||||
#region Get entryName
|
||||
|
||||
if (String.IsNullOrEmpty(entryName))
|
||||
{
|
||||
if (_filesCount == 1)
|
||||
{
|
||||
var archName = Path.GetFileName(_extractor.FileName);
|
||||
archName = archName.Substring(0, archName.LastIndexOf('.'));
|
||||
if (!archName.EndsWith(".tar", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
archName += ".tar";
|
||||
}
|
||||
entryName = archName;
|
||||
}
|
||||
else
|
||||
{
|
||||
entryName = "[no name] " + index.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
fileName = Path.Combine(_directory, _directoryStructure? entryName : Path.GetFileName(entryName));
|
||||
_archive.GetProperty(index, ItemPropId.IsDirectory, ref data);
|
||||
try
|
||||
{
|
||||
fileName = ValidateFileName(fileName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
AddException(e);
|
||||
goto FileExtractionStartedLabel;
|
||||
}
|
||||
if (!NativeMethods.SafeCast(data, false))
|
||||
{
|
||||
#region Branch
|
||||
|
||||
_archive.GetProperty(index, ItemPropId.LastWriteTime, ref data);
|
||||
var time = NativeMethods.SafeCast(data, DateTime.MinValue);
|
||||
if (File.Exists(fileName))
|
||||
{
|
||||
var fnea = new FileOverwriteEventArgs(fileName);
|
||||
OnFileExists(fnea);
|
||||
if (fnea.Cancel)
|
||||
{
|
||||
Canceled = true;
|
||||
return -1;
|
||||
}
|
||||
if (String.IsNullOrEmpty(fnea.FileName))
|
||||
{
|
||||
#if !MONO
|
||||
outStream = _fakeStream;
|
||||
#else
|
||||
outStream = _fakeStream.Handle;
|
||||
#endif
|
||||
goto FileExtractionStartedLabel;
|
||||
}
|
||||
fileName = fnea.FileName;
|
||||
}
|
||||
try
|
||||
{
|
||||
_fileStream = new OutStreamWrapper(File.Create(fileName), fileName, time, true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e is FileNotFoundException)
|
||||
{
|
||||
AddException(
|
||||
new IOException("The file \"" + fileName +
|
||||
"\" was not extracted due to the File.Create fail."));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddException(e);
|
||||
}
|
||||
outStream = _fakeStream;
|
||||
goto FileExtractionStartedLabel;
|
||||
}
|
||||
_fileStream.BytesWritten += IntEventArgsHandler;
|
||||
outStream = _fileStream;
|
||||
|
||||
#endregion
|
||||
}
|
||||
else
|
||||
{
|
||||
#region Branch
|
||||
|
||||
if (!Directory.Exists(fileName))
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(fileName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
AddException(e);
|
||||
}
|
||||
outStream = _fakeStream;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
outStream = _fakeStream;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
else
|
||||
{
|
||||
#region Extraction to a stream
|
||||
|
||||
if (index == _fileIndex)
|
||||
{
|
||||
outStream = _fileStream;
|
||||
_fileIndex = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
outStream = _fakeStream;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
FileExtractionStartedLabel:
|
||||
_doneRate += 1.0f / _filesCount;
|
||||
var iea = new FileInfoEventArgs(
|
||||
_extractor.ArchiveFileData[(int)index], PercentDoneEventArgs.ProducePercentDone(_doneRate));
|
||||
OnFileExtractionStarted(iea);
|
||||
if (iea.Cancel)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(fileName))
|
||||
{
|
||||
_fileStream.Dispose();
|
||||
if (File.Exists(fileName))
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(fileName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
AddException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Canceled = true;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void PrepareOperation(AskMode askExtractMode) { }
|
||||
|
||||
/// <summary>
|
||||
/// Called when the archive was extracted
|
||||
/// </summary>
|
||||
/// <param name="operationResult"></param>
|
||||
public void SetOperationResult(OperationResult operationResult)
|
||||
{
|
||||
if (operationResult != OperationResult.Ok && ReportErrors)
|
||||
{
|
||||
switch (operationResult)
|
||||
{
|
||||
case OperationResult.CrcError:
|
||||
AddException(new ExtractionFailedException("File is corrupted. Crc check has failed."));
|
||||
break;
|
||||
case OperationResult.DataError:
|
||||
AddException(new ExtractionFailedException("File is corrupted. Data error has occured."));
|
||||
break;
|
||||
case OperationResult.UnsupportedMethod:
|
||||
AddException(new ExtractionFailedException("Unsupported method error has occured."));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_fileStream != null && !_fileIndex.HasValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
_fileStream.BytesWritten -= IntEventArgsHandler;
|
||||
_fileStream.Dispose();
|
||||
}
|
||||
catch (ObjectDisposedException) { }
|
||||
_fileStream = null;
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
}
|
||||
var iea = new FileInfoEventArgs(
|
||||
_extractor.ArchiveFileData[_currentIndex], PercentDoneEventArgs.ProducePercentDone(_doneRate));
|
||||
OnFileExtractionFinished(iea);
|
||||
if (iea.Cancel)
|
||||
{
|
||||
Canceled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ICryptoGetTextPassword Members
|
||||
|
||||
/// <summary>
|
||||
/// Sets password for the archive
|
||||
/// </summary>
|
||||
/// <param name="password">Password for the archive</param>
|
||||
/// <returns>Zero if everything is OK</returns>
|
||||
public int CryptoGetTextPassword(out string password)
|
||||
{
|
||||
password = Password;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
#if !WINCE
|
||||
GC.RemoveMemoryPressure(MEMORY_PRESSURE);
|
||||
#endif
|
||||
if (_fileStream != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
_fileStream.Dispose();
|
||||
}
|
||||
catch (ObjectDisposedException) { }
|
||||
_fileStream = null;
|
||||
}
|
||||
if (_fakeStream != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
_fakeStream.Dispose();
|
||||
}
|
||||
catch (ObjectDisposedException) { }
|
||||
_fakeStream = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Validates the file name and ensures that the directory to the file name is valid and creates intermediate directories if necessary
|
||||
/// </summary>
|
||||
/// <param name="fileName">File name</param>
|
||||
/// <returns>The valid file name</returns>
|
||||
private static string ValidateFileName(string fileName)
|
||||
{
|
||||
if (String.IsNullOrEmpty(fileName))
|
||||
{
|
||||
throw new SevenZipArchiveException("some archive name is null or empty.");
|
||||
}
|
||||
var splittedFileName = new List<string>(fileName.Split(Path.DirectorySeparatorChar));
|
||||
#if !WINCE
|
||||
foreach (char chr in Path.GetInvalidFileNameChars())
|
||||
{
|
||||
for (int i = 0; i < splittedFileName.Count; i++)
|
||||
{
|
||||
if (chr == ':' && i == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (String.IsNullOrEmpty(splittedFileName[i]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
while (splittedFileName[i].IndexOf(chr) > -1)
|
||||
{
|
||||
splittedFileName[i] = splittedFileName[i].Replace(chr, '_');
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (fileName.StartsWith(new string(Path.DirectorySeparatorChar, 2),
|
||||
StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
splittedFileName.RemoveAt(0);
|
||||
splittedFileName.RemoveAt(0);
|
||||
splittedFileName[0] = new string(Path.DirectorySeparatorChar, 2) + splittedFileName[0];
|
||||
}
|
||||
if (splittedFileName.Count > 2)
|
||||
{
|
||||
string tfn = splittedFileName[0];
|
||||
for (int i = 1; i < splittedFileName.Count - 1; i++)
|
||||
{
|
||||
tfn += Path.DirectorySeparatorChar + splittedFileName[i];
|
||||
if (!Directory.Exists(tfn))
|
||||
{
|
||||
Directory.CreateDirectory(tfn);
|
||||
}
|
||||
}
|
||||
}
|
||||
return String.Join(new string(Path.DirectorySeparatorChar, 1), splittedFileName.ToArray());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -1,217 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
#if MONO
|
||||
using SevenZip.Mono;
|
||||
using SevenZip.Mono.COM;
|
||||
#endif
|
||||
|
||||
namespace SevenZip
|
||||
{
|
||||
#if UNMANAGED
|
||||
/// <summary>
|
||||
/// Callback to handle the archive opening
|
||||
/// </summary>
|
||||
internal sealed class ArchiveOpenCallback : CallbackBase, IArchiveOpenCallback, IArchiveOpenVolumeCallback,
|
||||
ICryptoGetTextPassword, IDisposable
|
||||
{
|
||||
private FileInfo _fileInfo;
|
||||
private Dictionary<string, InStreamWrapper> _wrappers =
|
||||
new Dictionary<string, InStreamWrapper>();
|
||||
private readonly List<string> _volumeFileNames = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of volume file names.
|
||||
/// </summary>
|
||||
public IList<string> VolumeFileNames
|
||||
{
|
||||
get
|
||||
{
|
||||
return _volumeFileNames;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs the common initialization.
|
||||
/// </summary>
|
||||
/// <param name="fileName">Volume file name.</param>
|
||||
private void Init(string fileName)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(fileName))
|
||||
{
|
||||
_fileInfo = new FileInfo(fileName);
|
||||
_volumeFileNames.Add(fileName);
|
||||
if (fileName.EndsWith("001"))
|
||||
{
|
||||
int index = 2;
|
||||
var baseName = fileName.Substring(0, fileName.Length - 3);
|
||||
var volName = baseName + (index > 99 ? index.ToString() :
|
||||
index > 9 ? "0" + index : "00" + index);
|
||||
while (File.Exists(volName))
|
||||
{
|
||||
_volumeFileNames.Add(volName);
|
||||
index++;
|
||||
volName = baseName + (index > 99 ? index.ToString() :
|
||||
index > 9 ? "0" + index : "00" + index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ArchiveOpenCallback class.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The archive file name.</param>
|
||||
public ArchiveOpenCallback(string fileName)
|
||||
{
|
||||
Init(fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ArchiveOpenCallback class.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The archive file name.</param>
|
||||
/// <param name="password">Password for the archive.</param>
|
||||
public ArchiveOpenCallback(string fileName, string password) : base(password)
|
||||
{
|
||||
Init(fileName);
|
||||
}
|
||||
|
||||
#region IArchiveOpenCallback Members
|
||||
|
||||
public void SetTotal(IntPtr files, IntPtr bytes) {}
|
||||
|
||||
public void SetCompleted(IntPtr files, IntPtr bytes) {}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IArchiveOpenVolumeCallback Members
|
||||
|
||||
public int GetProperty(ItemPropId propId, ref PropVariant value)
|
||||
{
|
||||
switch (propId)
|
||||
{
|
||||
case ItemPropId.Name:
|
||||
value.VarType = VarEnum.VT_BSTR;
|
||||
value.Value = Marshal.StringToBSTR(_fileInfo.FullName);
|
||||
break;
|
||||
case ItemPropId.IsDirectory:
|
||||
value.VarType = VarEnum.VT_BOOL;
|
||||
value.UInt64Value = (byte) (_fileInfo.Attributes & FileAttributes.Directory);
|
||||
break;
|
||||
case ItemPropId.Size:
|
||||
value.VarType = VarEnum.VT_UI8;
|
||||
value.UInt64Value = (UInt64) _fileInfo.Length;
|
||||
break;
|
||||
case ItemPropId.Attributes:
|
||||
value.VarType = VarEnum.VT_UI4;
|
||||
value.UInt32Value = (uint) _fileInfo.Attributes;
|
||||
break;
|
||||
case ItemPropId.CreationTime:
|
||||
value.VarType = VarEnum.VT_FILETIME;
|
||||
value.Int64Value = _fileInfo.CreationTime.ToFileTime();
|
||||
break;
|
||||
case ItemPropId.LastAccessTime:
|
||||
value.VarType = VarEnum.VT_FILETIME;
|
||||
value.Int64Value = _fileInfo.LastAccessTime.ToFileTime();
|
||||
break;
|
||||
case ItemPropId.LastWriteTime:
|
||||
value.VarType = VarEnum.VT_FILETIME;
|
||||
value.Int64Value = _fileInfo.LastWriteTime.ToFileTime();
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int GetStream(string name, out IInStream inStream)
|
||||
{
|
||||
if (!File.Exists(name))
|
||||
{
|
||||
name = Path.Combine(Path.GetDirectoryName(_fileInfo.FullName), name);
|
||||
if (!File.Exists(name))
|
||||
{
|
||||
inStream = null;
|
||||
AddException(new FileNotFoundException("The volume \"" + name + "\" was not found. Extraction can be impossible."));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
_volumeFileNames.Add(name);
|
||||
if (_wrappers.ContainsKey(name))
|
||||
{
|
||||
inStream = _wrappers[name];
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
var wrapper = new InStreamWrapper(
|
||||
new FileStream(name, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), true);
|
||||
_wrappers.Add(name, wrapper);
|
||||
inStream = wrapper;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
AddException(new FileNotFoundException("Failed to open the volume \"" + name + "\". Extraction is impossible."));
|
||||
inStream = null;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ICryptoGetTextPassword Members
|
||||
|
||||
/// <summary>
|
||||
/// Sets password for the archive
|
||||
/// </summary>
|
||||
/// <param name="password">Password for the archive</param>
|
||||
/// <returns>Zero if everything is OK</returns>
|
||||
public int CryptoGetTextPassword(out string password)
|
||||
{
|
||||
password = Password;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_wrappers != null)
|
||||
{
|
||||
foreach (InStreamWrapper wrap in _wrappers.Values)
|
||||
{
|
||||
wrap.Dispose();
|
||||
}
|
||||
_wrappers = null;
|
||||
}
|
||||
#if MONO
|
||||
libp7zInvokerRaw.FreeObject(Handle);
|
||||
#endif
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -1,817 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
#pragma warning disable
|
||||
|
||||
#if MONO
|
||||
using SevenZip.Mono.COM;
|
||||
#endif
|
||||
|
||||
namespace SevenZip
|
||||
{
|
||||
#if UNMANAGED
|
||||
#if COMPRESS
|
||||
/// <summary>
|
||||
/// Archive update callback to handle the process of packing files
|
||||
/// </summary>
|
||||
internal sealed class ArchiveUpdateCallback : CallbackBase, IArchiveUpdateCallback, ICryptoGetTextPassword2,
|
||||
IDisposable
|
||||
{
|
||||
#region Fields
|
||||
/// <summary>
|
||||
/// _files.Count if do not count directories
|
||||
/// </summary>
|
||||
private int _actualFilesCount;
|
||||
|
||||
/// <summary>
|
||||
/// For Compressing event.
|
||||
/// </summary>
|
||||
private long _bytesCount;
|
||||
|
||||
private long _bytesWritten;
|
||||
private long _bytesWrittenOld;
|
||||
private SevenZipCompressor _compressor;
|
||||
|
||||
/// <summary>
|
||||
/// No directories.
|
||||
/// </summary>
|
||||
private bool _directoryStructure;
|
||||
|
||||
/// <summary>
|
||||
/// Rate of the done work from [0, 1]
|
||||
/// </summary>
|
||||
private float _doneRate;
|
||||
|
||||
/// <summary>
|
||||
/// The names of the archive entries
|
||||
/// </summary>
|
||||
private string[] _entries;
|
||||
|
||||
/// <summary>
|
||||
/// Array of files to pack
|
||||
/// </summary>
|
||||
private FileInfo[] _files;
|
||||
|
||||
private InStreamWrapper _fileStream;
|
||||
|
||||
private uint _indexInArchive;
|
||||
private uint _indexOffset;
|
||||
|
||||
/// <summary>
|
||||
/// Common root of file names length.
|
||||
/// </summary>
|
||||
private int _rootLength;
|
||||
|
||||
/// <summary>
|
||||
/// Input streams to be compressed.
|
||||
/// </summary>
|
||||
private Stream[] _streams;
|
||||
|
||||
private UpdateData _updateData;
|
||||
private List<InStreamWrapper> _wrappersToDispose;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the default item name used in MemoryStream compression.
|
||||
/// </summary>
|
||||
public string DefaultItemName { private get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value indicating whether to compress as fast as possible, without calling events.
|
||||
/// </summary>
|
||||
public bool FastCompression { private get; set; }
|
||||
#if !WINCE
|
||||
private int _memoryPressure;
|
||||
#endif
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ArchiveUpdateCallback class
|
||||
/// </summary>
|
||||
/// <param name="files">Array of files to pack</param>
|
||||
/// <param name="rootLength">Common file names root length</param>
|
||||
/// <param name="compressor">The owner of the callback</param>
|
||||
/// <param name="updateData">The compression parameters.</param>
|
||||
/// <param name="directoryStructure">Preserve directory structure.</param>
|
||||
public ArchiveUpdateCallback(
|
||||
FileInfo[] files, int rootLength,
|
||||
SevenZipCompressor compressor, UpdateData updateData, bool directoryStructure)
|
||||
{
|
||||
Init(files, rootLength, compressor, updateData, directoryStructure);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ArchiveUpdateCallback class
|
||||
/// </summary>
|
||||
/// <param name="files">Array of files to pack</param>
|
||||
/// <param name="rootLength">Common file names root length</param>
|
||||
/// <param name="password">The archive password</param>
|
||||
/// <param name="compressor">The owner of the callback</param>
|
||||
/// <param name="updateData">The compression parameters.</param>
|
||||
/// <param name="directoryStructure">Preserve directory structure.</param>
|
||||
public ArchiveUpdateCallback(
|
||||
FileInfo[] files, int rootLength, string password,
|
||||
SevenZipCompressor compressor, UpdateData updateData, bool directoryStructure)
|
||||
: base(password)
|
||||
{
|
||||
Init(files, rootLength, compressor, updateData, directoryStructure);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ArchiveUpdateCallback class
|
||||
/// </summary>
|
||||
/// <param name="stream">The input stream</param>
|
||||
/// <param name="compressor">The owner of the callback</param>
|
||||
/// <param name="updateData">The compression parameters.</param>
|
||||
/// <param name="directoryStructure">Preserve directory structure.</param>
|
||||
public ArchiveUpdateCallback(
|
||||
Stream stream, SevenZipCompressor compressor, UpdateData updateData, bool directoryStructure)
|
||||
{
|
||||
Init(stream, compressor, updateData, directoryStructure);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ArchiveUpdateCallback class
|
||||
/// </summary>
|
||||
/// <param name="stream">The input stream</param>
|
||||
/// <param name="password">The archive password</param>
|
||||
/// <param name="compressor">The owner of the callback</param>
|
||||
/// <param name="updateData">The compression parameters.</param>
|
||||
/// <param name="directoryStructure">Preserve directory structure.</param>
|
||||
public ArchiveUpdateCallback(
|
||||
Stream stream, string password, SevenZipCompressor compressor, UpdateData updateData,
|
||||
bool directoryStructure)
|
||||
: base(password)
|
||||
{
|
||||
Init(stream, compressor, updateData, directoryStructure);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ArchiveUpdateCallback class
|
||||
/// </summary>
|
||||
/// <param name="streamDict">Dictionary<file stream, name of the archive entry></param>
|
||||
/// <param name="compressor">The owner of the callback</param>
|
||||
/// <param name="updateData">The compression parameters.</param>
|
||||
/// <param name="directoryStructure">Preserve directory structure.</param>
|
||||
public ArchiveUpdateCallback(
|
||||
Dictionary<string, Stream> streamDict,
|
||||
SevenZipCompressor compressor, UpdateData updateData, bool directoryStructure)
|
||||
{
|
||||
Init(streamDict, compressor, updateData, directoryStructure);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ArchiveUpdateCallback class
|
||||
/// </summary>
|
||||
/// <param name="streamDict">Dictionary<file stream, name of the archive entry></param>
|
||||
/// <param name="password">The archive password</param>
|
||||
/// <param name="compressor">The owner of the callback</param>
|
||||
/// <param name="updateData">The compression parameters.</param>
|
||||
/// <param name="directoryStructure">Preserve directory structure.</param>
|
||||
public ArchiveUpdateCallback(
|
||||
Dictionary<string, Stream> streamDict, string password,
|
||||
SevenZipCompressor compressor, UpdateData updateData, bool directoryStructure)
|
||||
: base(password)
|
||||
{
|
||||
Init(streamDict, compressor, updateData, directoryStructure);
|
||||
}
|
||||
|
||||
private void CommonInit(SevenZipCompressor compressor, UpdateData updateData, bool directoryStructure)
|
||||
{
|
||||
_compressor = compressor;
|
||||
_indexInArchive = updateData.FilesCount;
|
||||
_indexOffset = updateData.Mode != InternalCompressionMode.Append ? 0 : _indexInArchive;
|
||||
if (_compressor.ArchiveFormat == OutArchiveFormat.Zip)
|
||||
{
|
||||
_wrappersToDispose = new List<InStreamWrapper>();
|
||||
}
|
||||
_updateData = updateData;
|
||||
_directoryStructure = directoryStructure;
|
||||
DefaultItemName = "default";
|
||||
}
|
||||
|
||||
private void Init(
|
||||
FileInfo[] files, int rootLength, SevenZipCompressor compressor,
|
||||
UpdateData updateData, bool directoryStructure)
|
||||
{
|
||||
_files = files;
|
||||
_rootLength = rootLength;
|
||||
if (files != null)
|
||||
{
|
||||
foreach (var fi in files)
|
||||
{
|
||||
if (fi.Exists)
|
||||
{
|
||||
_bytesCount += fi.Length;
|
||||
if ((fi.Attributes & FileAttributes.Directory) == 0)
|
||||
{
|
||||
_actualFilesCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CommonInit(compressor, updateData, directoryStructure);
|
||||
}
|
||||
|
||||
private void Init(
|
||||
Stream stream, SevenZipCompressor compressor, UpdateData updateData, bool directoryStructure)
|
||||
{
|
||||
_fileStream = new InStreamWrapper(stream, false);
|
||||
_fileStream.BytesRead += IntEventArgsHandler;
|
||||
_actualFilesCount = 1;
|
||||
try
|
||||
{
|
||||
_bytesCount = stream.Length;
|
||||
}
|
||||
catch (NotSupportedException)
|
||||
{
|
||||
_bytesCount = -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
catch (NotSupportedException)
|
||||
{
|
||||
_bytesCount = -1;
|
||||
}
|
||||
CommonInit(compressor, updateData, directoryStructure);
|
||||
}
|
||||
|
||||
private void Init(
|
||||
Dictionary<string, Stream> streamDict,
|
||||
SevenZipCompressor compressor, UpdateData updateData, bool directoryStructure)
|
||||
{
|
||||
_streams = new Stream[streamDict.Count];
|
||||
streamDict.Values.CopyTo(_streams, 0);
|
||||
_entries = new string[streamDict.Count];
|
||||
streamDict.Keys.CopyTo(_entries, 0);
|
||||
_actualFilesCount = streamDict.Count;
|
||||
//zero 11-oct-2014 - we want sequential streams only. length is unknown.
|
||||
//foreach (Stream str in _streams)
|
||||
//{
|
||||
// if (str != null)
|
||||
// {
|
||||
// _bytesCount += str.Length;
|
||||
// }
|
||||
//}
|
||||
CommonInit(compressor, updateData, directoryStructure);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the dictionary size.
|
||||
/// </summary>
|
||||
public float DictionarySize
|
||||
{
|
||||
set
|
||||
{
|
||||
#if !WINCE
|
||||
_memoryPressure = (int)(value * 1024 * 1024);
|
||||
GC.AddMemoryPressure(_memoryPressure);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raises events for the GetStream method.
|
||||
/// </summary>
|
||||
/// <param name="index">The current item index.</param>
|
||||
/// <returns>True if not cancelled; otherwise, false.</returns>
|
||||
private bool EventsForGetStream(uint index)
|
||||
{
|
||||
if (!FastCompression)
|
||||
{
|
||||
if (_fileStream != null)
|
||||
{
|
||||
_fileStream.BytesRead += IntEventArgsHandler;
|
||||
}
|
||||
_doneRate += 1.0f / _actualFilesCount;
|
||||
var fiea = new FileNameEventArgs(_files != null? _files[index].Name : _entries[index],
|
||||
PercentDoneEventArgs.ProducePercentDone(_doneRate));
|
||||
OnFileCompression(fiea);
|
||||
if (fiea.Cancel)
|
||||
{
|
||||
Canceled = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#region Events
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the next file is going to be packed.
|
||||
/// </summary>
|
||||
/// <remarks>Occurs when 7-zip engine requests for an input stream for the next file to pack it</remarks>
|
||||
public event EventHandler<FileNameEventArgs> FileCompressionStarted;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when data are being compressed.
|
||||
/// </summary>
|
||||
public event EventHandler<ProgressEventArgs> Compressing;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the current file was compressed.
|
||||
/// </summary>
|
||||
public event EventHandler FileCompressionFinished;
|
||||
|
||||
private void OnFileCompression(FileNameEventArgs e)
|
||||
{
|
||||
if (FileCompressionStarted != null)
|
||||
{
|
||||
FileCompressionStarted(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCompressing(ProgressEventArgs e)
|
||||
{
|
||||
if (Compressing != null)
|
||||
{
|
||||
Compressing(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnFileCompressionFinished(EventArgs e)
|
||||
{
|
||||
if (FileCompressionFinished != null)
|
||||
{
|
||||
FileCompressionFinished(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IArchiveUpdateCallback Members
|
||||
|
||||
public void SetTotal(ulong total) {}
|
||||
|
||||
public void SetCompleted(ref ulong completeValue) {}
|
||||
|
||||
public int GetUpdateItemInfo(uint index, ref int newData, ref int newProperties, ref uint indexInArchive)
|
||||
{
|
||||
switch (_updateData.Mode)
|
||||
{
|
||||
case InternalCompressionMode.Create:
|
||||
newData = 1;
|
||||
newProperties = 1;
|
||||
indexInArchive = UInt32.MaxValue;
|
||||
break;
|
||||
case InternalCompressionMode.Append:
|
||||
if (index < _indexInArchive)
|
||||
{
|
||||
newData = 0;
|
||||
newProperties = 0;
|
||||
indexInArchive = index;
|
||||
}
|
||||
else
|
||||
{
|
||||
newData = 1;
|
||||
newProperties = 1;
|
||||
indexInArchive = UInt32.MaxValue;
|
||||
}
|
||||
break;
|
||||
case InternalCompressionMode.Modify:
|
||||
newData = 0;
|
||||
newProperties = Convert.ToInt32(_updateData.FileNamesToModify.ContainsKey((int)index)
|
||||
&& _updateData.FileNamesToModify[(int)index] != null);
|
||||
if (_updateData.FileNamesToModify.ContainsKey((int)index)
|
||||
&& _updateData.FileNamesToModify[(int)index] == null)
|
||||
{
|
||||
indexInArchive = (UInt32)_updateData.ArchiveFileData.Count;
|
||||
foreach (KeyValuePair<Int32, string> pairModification in _updateData.FileNamesToModify)
|
||||
if ((pairModification.Key <= index) && (pairModification.Value == null))
|
||||
{
|
||||
do
|
||||
{
|
||||
indexInArchive--;
|
||||
}
|
||||
while ((indexInArchive > 0) && _updateData.FileNamesToModify.ContainsKey((Int32)indexInArchive)
|
||||
&& (_updateData.FileNamesToModify[(Int32)indexInArchive] == null));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
indexInArchive = index;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int GetProperty(uint index, ItemPropId propID, ref PropVariant value)
|
||||
{
|
||||
index -= _indexOffset;
|
||||
try
|
||||
{
|
||||
switch (propID)
|
||||
{
|
||||
case ItemPropId.IsAnti:
|
||||
value.VarType = VarEnum.VT_BOOL;
|
||||
value.UInt64Value = 0;
|
||||
break;
|
||||
case ItemPropId.Path:
|
||||
#region Path
|
||||
|
||||
value.VarType = VarEnum.VT_BSTR;
|
||||
string val = DefaultItemName;
|
||||
if (_updateData.Mode != InternalCompressionMode.Modify)
|
||||
{
|
||||
if (_files == null)
|
||||
{
|
||||
if (_entries != null)
|
||||
{
|
||||
val = _entries[index];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_directoryStructure)
|
||||
{
|
||||
if (_rootLength > 0)
|
||||
{
|
||||
val = _files[index].FullName.Substring(_rootLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
val = _files[index].FullName[0] + _files[index].FullName.Substring(2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
val = _files[index].Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
val = _updateData.FileNamesToModify[(int) index];
|
||||
}
|
||||
value.Value = Marshal.StringToBSTR(val);
|
||||
#endregion
|
||||
break;
|
||||
case ItemPropId.IsDirectory:
|
||||
value.VarType = VarEnum.VT_BOOL;
|
||||
if (_updateData.Mode != InternalCompressionMode.Modify)
|
||||
{
|
||||
if (_files == null)
|
||||
{
|
||||
if (_streams == null)
|
||||
{
|
||||
value.UInt64Value = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
value.UInt64Value = (ulong)(_streams[index] == null ? 1 : 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value.UInt64Value = (byte)(_files[index].Attributes & FileAttributes.Directory);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value.UInt64Value = Convert.ToUInt64(_updateData.ArchiveFileData[(int) index].IsDirectory);
|
||||
}
|
||||
break;
|
||||
case ItemPropId.Size:
|
||||
#region Size
|
||||
|
||||
//zero 11-oct-2014 - this doesnt matter, we think it's only used for updating the progress indicator
|
||||
value.VarType = VarEnum.VT_UI8;
|
||||
//value.UInt64Value = unchecked((ulong)-1);
|
||||
break;
|
||||
|
||||
value.VarType = VarEnum.VT_UI8;
|
||||
UInt64 size;
|
||||
if (_updateData.Mode != InternalCompressionMode.Modify)
|
||||
{
|
||||
if (_files == null)
|
||||
{
|
||||
if (_streams == null)
|
||||
{
|
||||
size = _bytesCount > 0 ? (ulong) _bytesCount : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
size = (ulong) (_streams[index] == null? 0 : _streams[index].Length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size = (_files[index].Attributes & FileAttributes.Directory) == 0
|
||||
? (ulong) _files[index].Length
|
||||
: 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size = _updateData.ArchiveFileData[(int) index].Size;
|
||||
}
|
||||
value.UInt64Value = size;
|
||||
|
||||
#endregion
|
||||
break;
|
||||
case ItemPropId.Attributes:
|
||||
value.VarType = VarEnum.VT_UI4;
|
||||
if (_updateData.Mode != InternalCompressionMode.Modify)
|
||||
{
|
||||
if (_files == null)
|
||||
{
|
||||
if (_streams == null)
|
||||
{
|
||||
value.UInt32Value = (uint)FileAttributes.Normal;
|
||||
}
|
||||
else
|
||||
{
|
||||
value.UInt32Value = (uint)(_streams[index] == null ? FileAttributes.Directory : FileAttributes.Normal);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value.UInt32Value = (uint) _files[index].Attributes;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value.UInt32Value = _updateData.ArchiveFileData[(int) index].Attributes;
|
||||
}
|
||||
break;
|
||||
#region Times
|
||||
case ItemPropId.CreationTime:
|
||||
value.VarType = VarEnum.VT_FILETIME;
|
||||
if (_updateData.Mode != InternalCompressionMode.Modify)
|
||||
{
|
||||
value.Int64Value = _files == null
|
||||
? DateTime.Now.ToFileTime()
|
||||
: _files[index].CreationTime.ToFileTime();
|
||||
}
|
||||
else
|
||||
{
|
||||
value.Int64Value = _updateData.ArchiveFileData[(int) index].CreationTime.ToFileTime();
|
||||
}
|
||||
break;
|
||||
case ItemPropId.LastAccessTime:
|
||||
value.VarType = VarEnum.VT_FILETIME;
|
||||
if (_updateData.Mode != InternalCompressionMode.Modify)
|
||||
{
|
||||
value.Int64Value = _files == null
|
||||
? DateTime.Now.ToFileTime()
|
||||
: _files[index].LastAccessTime.ToFileTime();
|
||||
}
|
||||
else
|
||||
{
|
||||
value.Int64Value = _updateData.ArchiveFileData[(int) index].LastAccessTime.ToFileTime();
|
||||
}
|
||||
break;
|
||||
case ItemPropId.LastWriteTime:
|
||||
value.VarType = VarEnum.VT_FILETIME;
|
||||
if (_updateData.Mode != InternalCompressionMode.Modify)
|
||||
{
|
||||
value.Int64Value = _files == null
|
||||
? DateTime.Now.ToFileTime()
|
||||
: _files[index].LastWriteTime.ToFileTime();
|
||||
}
|
||||
else
|
||||
{
|
||||
value.Int64Value = _updateData.ArchiveFileData[(int) index].LastWriteTime.ToFileTime();
|
||||
}
|
||||
break;
|
||||
#endregion
|
||||
case ItemPropId.Extension:
|
||||
#region Extension
|
||||
|
||||
value.VarType = VarEnum.VT_BSTR;
|
||||
if (_updateData.Mode != InternalCompressionMode.Modify)
|
||||
{
|
||||
try
|
||||
{
|
||||
val = _files != null
|
||||
? _files[index].Extension.Substring(1)
|
||||
: _entries == null
|
||||
? ""
|
||||
: Path.GetExtension(_entries[index]);
|
||||
value.Value = Marshal.StringToBSTR(val);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
value.Value = Marshal.StringToBSTR("");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
val = Path.GetExtension(_updateData.ArchiveFileData[(int) index].FileName);
|
||||
value.Value = Marshal.StringToBSTR(val);
|
||||
}
|
||||
|
||||
#endregion
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
AddException(e);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the stream for 7-zip library.
|
||||
/// </summary>
|
||||
/// <param name="index">File index</param>
|
||||
/// <param name="inStream">Input file stream</param>
|
||||
/// <returns>Zero if Ok</returns>
|
||||
public int GetStream(uint index, out
|
||||
#if !MONO
|
||||
ISequentialInStream
|
||||
#else
|
||||
HandleRef
|
||||
#endif
|
||||
inStream)
|
||||
{
|
||||
index -= _indexOffset;
|
||||
if (_files != null)
|
||||
{
|
||||
_fileStream = null;
|
||||
try
|
||||
{
|
||||
if (File.Exists(_files[index].FullName))
|
||||
{
|
||||
_fileStream = new InStreamWrapper(
|
||||
new FileStream(_files[index].FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite),
|
||||
true);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
AddException(e);
|
||||
inStream = null;
|
||||
return -1;
|
||||
}
|
||||
inStream = _fileStream;
|
||||
if (!EventsForGetStream(index))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_streams == null)
|
||||
{
|
||||
inStream = _fileStream;
|
||||
}
|
||||
else
|
||||
{
|
||||
_fileStream = new InStreamWrapper(_streams[index], true);
|
||||
inStream = _fileStream;
|
||||
if (!EventsForGetStream(index))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long EnumProperties(IntPtr enumerator)
|
||||
{
|
||||
//Not implemented HRESULT
|
||||
return 0x80004001L;
|
||||
}
|
||||
|
||||
public void SetOperationResult(OperationResult operationResult)
|
||||
{
|
||||
if (operationResult != OperationResult.Ok && ReportErrors)
|
||||
{
|
||||
switch (operationResult)
|
||||
{
|
||||
case OperationResult.CrcError:
|
||||
AddException(new ExtractionFailedException("File is corrupted. Crc check has failed."));
|
||||
break;
|
||||
case OperationResult.DataError:
|
||||
AddException(new ExtractionFailedException("File is corrupted. Data error has occured."));
|
||||
break;
|
||||
case OperationResult.UnsupportedMethod:
|
||||
AddException(new ExtractionFailedException("Unsupported method error has occured."));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_fileStream != null)
|
||||
{
|
||||
|
||||
_fileStream.BytesRead -= IntEventArgsHandler;
|
||||
//Specific Zip implementation - can not Dispose files for Zip.
|
||||
if (_compressor.ArchiveFormat != OutArchiveFormat.Zip)
|
||||
{
|
||||
try
|
||||
{
|
||||
_fileStream.Dispose();
|
||||
}
|
||||
catch (ObjectDisposedException) {}
|
||||
}
|
||||
else
|
||||
{
|
||||
_wrappersToDispose.Add(_fileStream);
|
||||
}
|
||||
_fileStream = null;
|
||||
GC.Collect();
|
||||
// Issue #6987
|
||||
//GC.WaitForPendingFinalizers();
|
||||
}
|
||||
OnFileCompressionFinished(EventArgs.Empty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ICryptoGetTextPassword2 Members
|
||||
|
||||
public int CryptoGetTextPassword2(ref int passwordIsDefined, out string password)
|
||||
{
|
||||
passwordIsDefined = String.IsNullOrEmpty(Password) ? 0 : 1;
|
||||
password = Password;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
#if !WINCE
|
||||
GC.RemoveMemoryPressure(_memoryPressure);
|
||||
#endif
|
||||
if (_fileStream != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
_fileStream.Dispose();
|
||||
}
|
||||
catch (ObjectDisposedException) {}
|
||||
}
|
||||
if (_wrappersToDispose != null)
|
||||
{
|
||||
foreach (var wrapper in _wrappersToDispose)
|
||||
{
|
||||
try
|
||||
{
|
||||
wrapper.Dispose();
|
||||
}
|
||||
catch (ObjectDisposedException) {}
|
||||
}
|
||||
}
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void IntEventArgsHandler(object sender, IntEventArgs e)
|
||||
{
|
||||
//zero 11-oct-2014 - first of all, its possible for _files to be null (if we're compressing streams)
|
||||
//second of all, if we're compressing streams, we cant possibly have _bytesCount anyway. so.. goodbye
|
||||
//lock (_files)
|
||||
//{
|
||||
// var pold = (byte) ((_bytesWrittenOld*100)/_bytesCount);
|
||||
// _bytesWritten += e.Value;
|
||||
// byte pnow;
|
||||
// if (_bytesCount < _bytesWritten) //Holy shit, this check for ZIP is golden
|
||||
// {
|
||||
// pnow = 100;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// pnow = (byte)((_bytesWritten * 100) / _bytesCount);
|
||||
// }
|
||||
// if (pnow > pold)
|
||||
// {
|
||||
// _bytesWrittenOld = _bytesWritten;
|
||||
// OnCompressing(new ProgressEventArgs(pnow, (byte) (pnow - pold)));
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,842 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
#if !WINCE
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
#endif
|
||||
#if DOTNET20
|
||||
using System.Threading;
|
||||
#else
|
||||
using System.Windows.Threading;
|
||||
#endif
|
||||
#if MONO
|
||||
using SevenZip.Mono.COM;
|
||||
#endif
|
||||
|
||||
namespace SevenZip
|
||||
{
|
||||
#if UNMANAGED
|
||||
|
||||
/// <summary>
|
||||
/// The way of the event synchronization.
|
||||
/// </summary>
|
||||
public enum EventSynchronizationStrategy
|
||||
{
|
||||
/// <summary>
|
||||
/// Events are called synchronously if user can do some action; that is, cancel the execution process for example.
|
||||
/// </summary>
|
||||
Default,
|
||||
/// <summary>
|
||||
/// Always call events asynchronously.
|
||||
/// </summary>
|
||||
AlwaysAsynchronous,
|
||||
/// <summary>
|
||||
/// Always call events synchronously.
|
||||
/// </summary>
|
||||
AlwaysSynchronous
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SevenZip Extractor/Compressor base class. Implements Password string, ReportErrors flag.
|
||||
/// </summary>
|
||||
public abstract class SevenZipBase : MarshalByRefObject
|
||||
{
|
||||
private readonly string _password;
|
||||
private readonly bool _reportErrors;
|
||||
private readonly int _uniqueID;
|
||||
private static readonly List<int> Identificators = new List<int>();
|
||||
#if !WINCE
|
||||
internal static readonly AsyncCallback AsyncCallbackImplementation = AsyncCallbackMethod;
|
||||
|
||||
/// <summary>
|
||||
/// True if the instance of the class needs to be recreated in new thread context; otherwise, false.
|
||||
/// </summary>
|
||||
protected internal bool NeedsToBeRecreated;
|
||||
|
||||
/// <summary>
|
||||
/// AsyncCallback implementation used in asynchronous invocations.
|
||||
/// </summary>
|
||||
/// <param name="ar">IAsyncResult instance.</param>
|
||||
internal static void AsyncCallbackMethod(IAsyncResult ar)
|
||||
{
|
||||
var result = (AsyncResult)ar;
|
||||
result.AsyncDelegate.GetType().GetMethod("EndInvoke").Invoke(result.AsyncDelegate, new[] { ar });
|
||||
((SevenZipBase)ar.AsyncState).ReleaseContext();
|
||||
}
|
||||
|
||||
virtual internal void SaveContext(
|
||||
#if !DOTNET20
|
||||
DispatcherPriority priority = DispatcherPriority.Normal
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#if !DOTNET20
|
||||
Dispatcher = Dispatcher.CurrentDispatcher;
|
||||
Priority = priority;
|
||||
#else
|
||||
Context = SynchronizationContext.Current;
|
||||
#endif
|
||||
NeedsToBeRecreated = true;
|
||||
}
|
||||
|
||||
virtual internal void ReleaseContext()
|
||||
{
|
||||
#if !DOTNET20
|
||||
Dispatcher = null;
|
||||
#else
|
||||
Context = null;
|
||||
#endif
|
||||
NeedsToBeRecreated = true;
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private delegate void EventHandlerDelegate<T>(EventHandler<T> handler, T e) where T : EventArgs;
|
||||
|
||||
internal void OnEvent<T>(EventHandler<T> handler, T e, bool synchronous) where T : EventArgs
|
||||
{
|
||||
try
|
||||
{
|
||||
if (handler != null)
|
||||
{
|
||||
switch (EventSynchronization)
|
||||
{
|
||||
case EventSynchronizationStrategy.AlwaysAsynchronous:
|
||||
synchronous = false;
|
||||
break;
|
||||
case EventSynchronizationStrategy.AlwaysSynchronous:
|
||||
synchronous = true;
|
||||
break;
|
||||
}
|
||||
if (
|
||||
#if !DOTNET20
|
||||
Dispatcher == null
|
||||
#else
|
||||
Context == null
|
||||
#endif
|
||||
)
|
||||
{
|
||||
// Usual synchronous call
|
||||
handler(this, e);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if !DOTNET20
|
||||
var eventHandlerDelegate = new EventHandlerDelegate<T>((h, ee) => h(this, ee));
|
||||
if (synchronous)
|
||||
{
|
||||
// Could be just handler(this, e);
|
||||
Dispatcher.Invoke(eventHandlerDelegate, Priority, handler, e);
|
||||
}
|
||||
else
|
||||
{
|
||||
Dispatcher.BeginInvoke(eventHandlerDelegate, Priority, handler, e);
|
||||
}
|
||||
#else
|
||||
var callback = new SendOrPostCallback((obj) =>
|
||||
{
|
||||
var array = (object[])obj;
|
||||
((EventHandler<T>)array[0])(array[1], (T)array[2]);
|
||||
});
|
||||
if (synchronous)
|
||||
{
|
||||
// Could be just handler(this, e);
|
||||
this.Context.Send(callback, new object[] { handler, this, e });
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Context.Post(callback, new object[] { handler, this, e });
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AddException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Gets or sets the Dispatcher object for this instance.
|
||||
/// It will be used to fire events in the user context.
|
||||
/// </summary>
|
||||
internal Dispatcher Dispatcher { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Dispatcher priority of calling user events.
|
||||
/// </summary>
|
||||
internal DispatcherPriority Priority { get; set; }
|
||||
#else
|
||||
internal SynchronizationContext Context { get; set; }
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Gets or sets the event synchronization strategy.
|
||||
/// </summary>
|
||||
public EventSynchronizationStrategy EventSynchronization { get; set; }
|
||||
#else // WINCE
|
||||
internal void OnEvent<T>(EventHandler<T> handler, T e, bool synchronous) where T : System.EventArgs
|
||||
{
|
||||
try
|
||||
{
|
||||
handler(this, e);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AddException(ex);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Gets the unique identificator of this SevenZipBase instance.
|
||||
/// </summary>
|
||||
public int UniqueID
|
||||
{
|
||||
get
|
||||
{
|
||||
return _uniqueID;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// User exceptions thrown during the requested operations, for example, in events.
|
||||
/// </summary>
|
||||
private readonly List<Exception> _exceptions = new List<Exception>();
|
||||
|
||||
private static int GetUniqueID()
|
||||
{
|
||||
lock(Identificators)
|
||||
{
|
||||
|
||||
int id;
|
||||
var rnd = new Random(DateTime.Now.Millisecond);
|
||||
do
|
||||
{
|
||||
id = rnd.Next(Int32.MaxValue);
|
||||
}
|
||||
while (Identificators.Contains(id));
|
||||
Identificators.Add(id);
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
#region Constructors
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipBase class.
|
||||
/// </summary>
|
||||
protected SevenZipBase()
|
||||
{
|
||||
_password = "";
|
||||
_reportErrors = true;
|
||||
_uniqueID = GetUniqueID();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipBase class
|
||||
/// </summary>
|
||||
/// <param name="password">The archive password.</param>
|
||||
protected SevenZipBase(string password)
|
||||
{
|
||||
if (String.IsNullOrEmpty(password))
|
||||
{
|
||||
throw new SevenZipException("Empty password was specified.");
|
||||
}
|
||||
_password = password;
|
||||
_reportErrors = true;
|
||||
_uniqueID = GetUniqueID();
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Removes the UniqueID from the list.
|
||||
/// </summary>
|
||||
~SevenZipBase()
|
||||
{
|
||||
// This lock probably isn't necessary but just in case...
|
||||
lock (Identificators)
|
||||
{
|
||||
Identificators.Remove(_uniqueID);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the archive password
|
||||
/// </summary>
|
||||
public string Password
|
||||
{
|
||||
get
|
||||
{
|
||||
return _password;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets throw exceptions on archive errors flag
|
||||
/// </summary>
|
||||
internal bool ReportErrors
|
||||
{
|
||||
get
|
||||
{
|
||||
return _reportErrors;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user exceptions thrown during the requested operations, for example, in events.
|
||||
/// </summary>
|
||||
internal ReadOnlyCollection<Exception> Exceptions
|
||||
{
|
||||
get
|
||||
{
|
||||
return new ReadOnlyCollection<Exception>(_exceptions);
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddException(Exception e)
|
||||
{
|
||||
_exceptions.Add(e);
|
||||
}
|
||||
|
||||
internal void ClearExceptions()
|
||||
{
|
||||
_exceptions.Clear();
|
||||
}
|
||||
|
||||
internal bool HasExceptions
|
||||
{
|
||||
get
|
||||
{
|
||||
return _exceptions.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws the specified exception when is able to.
|
||||
/// </summary>
|
||||
/// <param name="e">The exception to throw.</param>
|
||||
/// <param name="handler">The handler responsible for the exception.</param>
|
||||
internal bool ThrowException(CallbackBase handler, params Exception[] e)
|
||||
{
|
||||
if (_reportErrors && (handler == null || !handler.Canceled))
|
||||
{
|
||||
throw e[0];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal void ThrowUserException()
|
||||
{
|
||||
if (HasExceptions)
|
||||
{
|
||||
throw new SevenZipException(SevenZipException.USER_EXCEPTION_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws exception if HRESULT != 0.
|
||||
/// </summary>
|
||||
/// <param name="hresult">Result code to check.</param>
|
||||
/// <param name="message">Exception message.</param>
|
||||
/// <param name="handler">The class responsible for the callback.</param>
|
||||
internal void CheckedExecute(int hresult, string message, CallbackBase handler)
|
||||
{
|
||||
if (hresult != (int)OperationResult.Ok || handler.HasExceptions)
|
||||
{
|
||||
if (!handler.HasExceptions)
|
||||
{
|
||||
if (hresult < -2000000000)
|
||||
{
|
||||
ThrowException(handler,
|
||||
new SevenZipException(
|
||||
"The execution has failed due to the bug in the SevenZipSharp.\n" +
|
||||
"Please report about it to http://sevenzipsharp.codeplex.com/WorkItem/List.aspx, post the release number and attach the archive."));
|
||||
}
|
||||
else
|
||||
{
|
||||
ThrowException(handler,
|
||||
new SevenZipException(message + hresult.ToString(CultureInfo.InvariantCulture) +
|
||||
'.'));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ThrowException(handler, handler.Exceptions[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !WINCE && !MONO
|
||||
/// <summary>
|
||||
/// Changes the path to the 7-zip native library.
|
||||
/// </summary>
|
||||
/// <param name="libraryPath">The path to the 7-zip native library.</param>
|
||||
public static void SetLibraryPath(string libraryPath)
|
||||
{
|
||||
SevenZipLibraryManager.SetLibraryPath(libraryPath);
|
||||
}
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Gets the current library features.
|
||||
/// </summary>
|
||||
public static LibraryFeature CurrentLibraryFeatures
|
||||
{
|
||||
get
|
||||
{
|
||||
return SevenZipLibraryManager.CurrentLibraryFeatures;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified System.Object is equal to the current SevenZipBase.
|
||||
/// </summary>
|
||||
/// <param name="obj">The System.Object to compare with the current SevenZipBase.</param>
|
||||
/// <returns>true if the specified System.Object is equal to the current SevenZipBase; otherwise, false.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var inst = obj as SevenZipBase;
|
||||
if (inst == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return _uniqueID == inst._uniqueID;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serves as a hash function for a particular type.
|
||||
/// </summary>
|
||||
/// <returns> A hash code for the current SevenZipBase.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _uniqueID;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a System.String that represents the current SevenZipBase.
|
||||
/// </summary>
|
||||
/// <returns>A System.String that represents the current SevenZipBase.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
var type = "SevenZipBase";
|
||||
if (this is SevenZipExtractor)
|
||||
{
|
||||
type = "SevenZipExtractor";
|
||||
}
|
||||
if (this is SevenZipCompressor)
|
||||
{
|
||||
type = "SevenZipCompressor";
|
||||
}
|
||||
return string.Format("{0} [{1}]", type, _uniqueID);
|
||||
}
|
||||
}
|
||||
|
||||
internal class CallbackBase : MarshalByRefObject
|
||||
{
|
||||
private readonly string _password;
|
||||
private readonly bool _reportErrors;
|
||||
/// <summary>
|
||||
/// User exceptions thrown during the requested operations, for example, in events.
|
||||
/// </summary>
|
||||
private readonly List<Exception> _exceptions = new List<Exception>();
|
||||
|
||||
#region Constructors
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CallbackBase class.
|
||||
/// </summary>
|
||||
protected CallbackBase()
|
||||
{
|
||||
_password = "";
|
||||
_reportErrors = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CallbackBase class.
|
||||
/// </summary>
|
||||
/// <param name="password">The archive password.</param>
|
||||
protected CallbackBase(string password)
|
||||
{
|
||||
if (String.IsNullOrEmpty(password))
|
||||
{
|
||||
throw new SevenZipException("Empty password was specified.");
|
||||
}
|
||||
_password = password;
|
||||
_reportErrors = true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the archive password
|
||||
/// </summary>
|
||||
public string Password
|
||||
{
|
||||
get
|
||||
{
|
||||
return _password;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value indicating whether the current procedure was cancelled.
|
||||
/// </summary>
|
||||
public bool Canceled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets throw exceptions on archive errors flag
|
||||
/// </summary>
|
||||
public bool ReportErrors
|
||||
{
|
||||
get
|
||||
{
|
||||
return _reportErrors;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user exceptions thrown during the requested operations, for example, in events.
|
||||
/// </summary>
|
||||
public ReadOnlyCollection<Exception> Exceptions
|
||||
{
|
||||
get
|
||||
{
|
||||
return new ReadOnlyCollection<Exception>(_exceptions);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddException(Exception e)
|
||||
{
|
||||
_exceptions.Add(e);
|
||||
}
|
||||
|
||||
public void ClearExceptions()
|
||||
{
|
||||
_exceptions.Clear();
|
||||
}
|
||||
|
||||
public bool HasExceptions
|
||||
{
|
||||
get
|
||||
{
|
||||
return _exceptions.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws the specified exception when is able to.
|
||||
/// </summary>
|
||||
/// <param name="e">The exception to throw.</param>
|
||||
/// <param name="handler">The handler responsible for the exception.</param>
|
||||
public bool ThrowException(CallbackBase handler, params Exception[] e)
|
||||
{
|
||||
if (_reportErrors && (handler == null || !handler.Canceled))
|
||||
{
|
||||
throw e[0];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws the first exception in the list if any exists.
|
||||
/// </summary>
|
||||
/// <returns>True means no exceptions.</returns>
|
||||
public bool ThrowException()
|
||||
{
|
||||
if (HasExceptions && _reportErrors)
|
||||
{
|
||||
throw _exceptions[0];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ThrowUserException()
|
||||
{
|
||||
if (HasExceptions)
|
||||
{
|
||||
throw new SevenZipException(SevenZipException.USER_EXCEPTION_MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Struct for storing information about files in the 7-zip archive.
|
||||
/// </summary>
|
||||
public struct ArchiveFileInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets index of the file in the archive file table.
|
||||
/// </summary>
|
||||
public int Index { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets file name
|
||||
/// </summary>
|
||||
public string FileName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the file last write time.
|
||||
/// </summary>
|
||||
public DateTime LastWriteTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the file creation time.
|
||||
/// </summary>
|
||||
public DateTime CreationTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the file creation time.
|
||||
/// </summary>
|
||||
public DateTime LastAccessTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets size of the file (unpacked).
|
||||
/// </summary>
|
||||
public ulong Size { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets CRC checksum of the file.
|
||||
/// </summary>
|
||||
public uint Crc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets file attributes.
|
||||
/// </summary>
|
||||
public uint Attributes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets being a directory.
|
||||
/// </summary>
|
||||
public bool IsDirectory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets being encrypted.
|
||||
/// </summary>
|
||||
public bool Encrypted { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets comment for the file.
|
||||
/// </summary>
|
||||
public string Comment { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified System.Object is equal to the current ArchiveFileInfo.
|
||||
/// </summary>
|
||||
/// <param name="obj">The System.Object to compare with the current ArchiveFileInfo.</param>
|
||||
/// <returns>true if the specified System.Object is equal to the current ArchiveFileInfo; otherwise, false.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return (obj is ArchiveFileInfo) ? Equals((ArchiveFileInfo)obj) : false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified ArchiveFileInfo is equal to the current ArchiveFileInfo.
|
||||
/// </summary>
|
||||
/// <param name="afi">The ArchiveFileInfo to compare with the current ArchiveFileInfo.</param>
|
||||
/// <returns>true if the specified ArchiveFileInfo is equal to the current ArchiveFileInfo; otherwise, false.</returns>
|
||||
public bool Equals(ArchiveFileInfo afi)
|
||||
{
|
||||
return afi.Index == Index && afi.FileName == FileName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serves as a hash function for a particular type.
|
||||
/// </summary>
|
||||
/// <returns> A hash code for the current ArchiveFileInfo.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return FileName.GetHashCode() ^ Index;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a System.String that represents the current ArchiveFileInfo.
|
||||
/// </summary>
|
||||
/// <returns>A System.String that represents the current ArchiveFileInfo.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return "[" + Index.ToString(CultureInfo.CurrentCulture) + "] " + FileName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified ArchiveFileInfo instances are considered equal.
|
||||
/// </summary>
|
||||
/// <param name="afi1">The first ArchiveFileInfo to compare.</param>
|
||||
/// <param name="afi2">The second ArchiveFileInfo to compare.</param>
|
||||
/// <returns>true if the specified ArchiveFileInfo instances are considered equal; otherwise, false.</returns>
|
||||
public static bool operator ==(ArchiveFileInfo afi1, ArchiveFileInfo afi2)
|
||||
{
|
||||
return afi1.Equals(afi2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified ArchiveFileInfo instances are not considered equal.
|
||||
/// </summary>
|
||||
/// <param name="afi1">The first ArchiveFileInfo to compare.</param>
|
||||
/// <param name="afi2">The second ArchiveFileInfo to compare.</param>
|
||||
/// <returns>true if the specified ArchiveFileInfo instances are not considered equal; otherwise, false.</returns>
|
||||
public static bool operator !=(ArchiveFileInfo afi1, ArchiveFileInfo afi2)
|
||||
{
|
||||
return !afi1.Equals(afi2);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Archive property struct.
|
||||
/// </summary>
|
||||
public struct ArchiveProperty
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name of the archive property.
|
||||
/// </summary>
|
||||
public string Name { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the archive property.
|
||||
/// </summary>
|
||||
public object Value { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified System.Object is equal to the current ArchiveProperty.
|
||||
/// </summary>
|
||||
/// <param name="obj">The System.Object to compare with the current ArchiveProperty.</param>
|
||||
/// <returns>true if the specified System.Object is equal to the current ArchiveProperty; otherwise, false.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return (obj is ArchiveProperty) ? Equals((ArchiveProperty)obj) : false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified ArchiveProperty is equal to the current ArchiveProperty.
|
||||
/// </summary>
|
||||
/// <param name="afi">The ArchiveProperty to compare with the current ArchiveProperty.</param>
|
||||
/// <returns>true if the specified ArchiveProperty is equal to the current ArchiveProperty; otherwise, false.</returns>
|
||||
public bool Equals(ArchiveProperty afi)
|
||||
{
|
||||
return afi.Name == Name && afi.Value == Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serves as a hash function for a particular type.
|
||||
/// </summary>
|
||||
/// <returns> A hash code for the current ArchiveProperty.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Name.GetHashCode() ^ Value.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a System.String that represents the current ArchiveProperty.
|
||||
/// </summary>
|
||||
/// <returns>A System.String that represents the current ArchiveProperty.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return Name + " = " + Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified ArchiveProperty instances are considered equal.
|
||||
/// </summary>
|
||||
/// <param name="afi1">The first ArchiveProperty to compare.</param>
|
||||
/// <param name="afi2">The second ArchiveProperty to compare.</param>
|
||||
/// <returns>true if the specified ArchiveProperty instances are considered equal; otherwise, false.</returns>
|
||||
public static bool operator ==(ArchiveProperty afi1, ArchiveProperty afi2)
|
||||
{
|
||||
return afi1.Equals(afi2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified ArchiveProperty instances are not considered equal.
|
||||
/// </summary>
|
||||
/// <param name="afi1">The first ArchiveProperty to compare.</param>
|
||||
/// <param name="afi2">The second ArchiveProperty to compare.</param>
|
||||
/// <returns>true if the specified ArchiveProperty instances are not considered equal; otherwise, false.</returns>
|
||||
public static bool operator !=(ArchiveProperty afi1, ArchiveProperty afi2)
|
||||
{
|
||||
return !afi1.Equals(afi2);
|
||||
}
|
||||
}
|
||||
|
||||
#if COMPRESS
|
||||
|
||||
/// <summary>
|
||||
/// Archive compression mode.
|
||||
/// </summary>
|
||||
public enum CompressionMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a new archive; overwrite the existing one.
|
||||
/// </summary>
|
||||
Create,
|
||||
/// <summary>
|
||||
/// Add data to the archive.
|
||||
/// </summary>
|
||||
Append,
|
||||
}
|
||||
|
||||
internal enum InternalCompressionMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a new archive; overwrite the existing one.
|
||||
/// </summary>
|
||||
Create,
|
||||
/// <summary>
|
||||
/// Add data to the archive.
|
||||
/// </summary>
|
||||
Append,
|
||||
/// <summary>
|
||||
/// Modify archive data.
|
||||
/// </summary>
|
||||
Modify
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Zip encryption method enum.
|
||||
/// </summary>
|
||||
public enum ZipEncryptionMethod
|
||||
{
|
||||
/// <summary>
|
||||
/// ZipCrypto encryption method.
|
||||
/// </summary>
|
||||
ZipCrypto,
|
||||
/// <summary>
|
||||
/// AES 128 bit encryption method.
|
||||
/// </summary>
|
||||
Aes128,
|
||||
/// <summary>
|
||||
/// AES 192 bit encryption method.
|
||||
/// </summary>
|
||||
Aes192,
|
||||
/// <summary>
|
||||
/// AES 256 bit encryption method.
|
||||
/// </summary>
|
||||
Aes256
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Archive update data for UpdateCallback.
|
||||
/// </summary>
|
||||
internal struct UpdateData
|
||||
{
|
||||
public uint FilesCount;
|
||||
public InternalCompressionMode Mode;
|
||||
|
||||
public Dictionary<int, string> FileNamesToModify { get; set; }
|
||||
|
||||
public List<ArchiveFileInfo> ArchiveFileData { get; set; }
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
|
@ -1,399 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace SevenZip
|
||||
{
|
||||
/// <summary>
|
||||
/// The definition of the interface which supports the cancellation of a process.
|
||||
/// </summary>
|
||||
public interface ICancellable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets whether to stop the current archive operation.
|
||||
/// </summary>
|
||||
bool Cancel { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EventArgs for storing PercentDone property.
|
||||
/// </summary>
|
||||
public class PercentDoneEventArgs : EventArgs
|
||||
{
|
||||
private readonly byte _percentDone;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the PercentDoneEventArgs class.
|
||||
/// </summary>
|
||||
/// <param name="percentDone">The percent of finished work.</param>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException"/>
|
||||
public PercentDoneEventArgs(byte percentDone)
|
||||
{
|
||||
if (percentDone > 100 || percentDone < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("percentDone",
|
||||
"The percent of finished work must be between 0 and 100.");
|
||||
}
|
||||
_percentDone = percentDone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the percent of finished work.
|
||||
/// </summary>
|
||||
public byte PercentDone
|
||||
{
|
||||
get
|
||||
{
|
||||
return _percentDone;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a [0, 1] rate to its percent equivalent.
|
||||
/// </summary>
|
||||
/// <param name="doneRate">The rate of the done work.</param>
|
||||
/// <returns>Percent integer equivalent.</returns>
|
||||
/// <exception cref="System.ArgumentException"/>
|
||||
internal static byte ProducePercentDone(float doneRate)
|
||||
{
|
||||
#if !WINCE
|
||||
return (byte) Math.Round(Math.Min(100*doneRate, 100), MidpointRounding.AwayFromZero);
|
||||
#else
|
||||
return (byte) Math.Round(Math.Min(100*doneRate, 100));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The EventArgs class for accurate progress handling.
|
||||
/// </summary>
|
||||
public sealed class ProgressEventArgs : PercentDoneEventArgs
|
||||
{
|
||||
private readonly byte _delta;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ProgressEventArgs class.
|
||||
/// </summary>
|
||||
/// <param name="percentDone">The percent of finished work.</param>
|
||||
/// <param name="percentDelta">The percent of work done after the previous event.</param>
|
||||
public ProgressEventArgs(byte percentDone, byte percentDelta)
|
||||
: base(percentDone)
|
||||
{
|
||||
_delta = percentDelta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the change in done work percentage.
|
||||
/// </summary>
|
||||
public byte PercentDelta
|
||||
{
|
||||
get
|
||||
{
|
||||
return _delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if UNMANAGED
|
||||
/// <summary>
|
||||
/// EventArgs used to report the file information which is going to be packed.
|
||||
/// </summary>
|
||||
public sealed class FileInfoEventArgs : PercentDoneEventArgs, ICancellable
|
||||
{
|
||||
private readonly ArchiveFileInfo _fileInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the FileInfoEventArgs class.
|
||||
/// </summary>
|
||||
/// <param name="fileInfo">The current ArchiveFileInfo.</param>
|
||||
/// <param name="percentDone">The percent of finished work.</param>
|
||||
public FileInfoEventArgs(ArchiveFileInfo fileInfo, byte percentDone)
|
||||
: base(percentDone)
|
||||
{
|
||||
_fileInfo = fileInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether to stop the current archive operation.
|
||||
/// </summary>
|
||||
public bool Cancel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the corresponding FileInfo to the event.
|
||||
/// </summary>
|
||||
public ArchiveFileInfo FileInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
return _fileInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EventArgs used to report the size of unpacked archive data
|
||||
/// </summary>
|
||||
public sealed class OpenEventArgs : EventArgs
|
||||
{
|
||||
private readonly ulong _totalSize;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the OpenEventArgs class
|
||||
/// </summary>
|
||||
/// <param name="totalSize">Size of unpacked archive data</param>
|
||||
public OpenEventArgs(ulong totalSize)
|
||||
{
|
||||
_totalSize = totalSize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of unpacked archive data
|
||||
/// </summary>
|
||||
public ulong TotalSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return _totalSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores an int number
|
||||
/// </summary>
|
||||
public sealed class IntEventArgs : EventArgs
|
||||
{
|
||||
private readonly int _value;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the IntEventArgs class
|
||||
/// </summary>
|
||||
/// <param name="value">Useful data carried by the IntEventArgs class</param>
|
||||
public IntEventArgs(int value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the IntEventArgs class
|
||||
/// </summary>
|
||||
public int Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EventArgs class which stores the file name.
|
||||
/// </summary>
|
||||
public sealed class FileNameEventArgs : PercentDoneEventArgs, ICancellable
|
||||
{
|
||||
private readonly string _fileName;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the FileNameEventArgs class.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The file name.</param>
|
||||
/// <param name="percentDone">The percent of finished work</param>
|
||||
public FileNameEventArgs(string fileName, byte percentDone) :
|
||||
base(percentDone)
|
||||
{
|
||||
_fileName = fileName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether to stop the current archive operation.
|
||||
/// </summary>
|
||||
public bool Cancel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file name.
|
||||
/// </summary>
|
||||
public string FileName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _fileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EventArgs for FileExists event, stores the file name and asks whether to overwrite it in case it already exists.
|
||||
/// </summary>
|
||||
public sealed class FileOverwriteEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the FileOverwriteEventArgs class
|
||||
/// </summary>
|
||||
/// <param name="fileName">The file name.</param>
|
||||
public FileOverwriteEventArgs(string fileName)
|
||||
{
|
||||
FileName = fileName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value indicating whether to cancel the extraction.
|
||||
/// </summary>
|
||||
public bool Cancel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the file name to extract to. Null means skip.
|
||||
/// </summary>
|
||||
public string FileName { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The reason for calling <see cref="ExtractFileCallback"/>.
|
||||
/// </summary>
|
||||
public enum ExtractFileCallbackReason
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="ExtractFileCallback"/> is called the first time for a file.
|
||||
/// </summary>
|
||||
Start,
|
||||
|
||||
/// <summary>
|
||||
/// All data has been written to the target without any exceptions.
|
||||
/// </summary>
|
||||
Done,
|
||||
|
||||
/// <summary>
|
||||
/// An exception occured during extraction of the file.
|
||||
/// </summary>
|
||||
Failure
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The arguments passed to <see cref="ExtractFileCallback"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For each file, <see cref="ExtractFileCallback"/> is first called with <see cref="Reason"/>
|
||||
/// set to <see cref="ExtractFileCallbackReason.Start"/>. If the callback chooses to extract the
|
||||
/// file data by setting <see cref="ExtractToFile"/> or <see cref="ExtractToStream"/>, the callback
|
||||
/// will be called a second time with <see cref="Reason"/> set to
|
||||
/// <see cref="ExtractFileCallbackReason.Done"/> or <see cref="ExtractFileCallbackReason.Failure"/>
|
||||
/// to allow for any cleanup task like closing the stream.
|
||||
/// </remarks>
|
||||
public class ExtractFileCallbackArgs : EventArgs
|
||||
{
|
||||
private readonly ArchiveFileInfo _archiveFileInfo;
|
||||
private Stream _extractToStream;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ExtractFileCallbackArgs"/> class.
|
||||
/// </summary>
|
||||
/// <param name="archiveFileInfo">The information about file in the archive.</param>
|
||||
public ExtractFileCallbackArgs(ArchiveFileInfo archiveFileInfo)
|
||||
{
|
||||
Reason = ExtractFileCallbackReason.Start;
|
||||
_archiveFileInfo = archiveFileInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Information about file in the archive.
|
||||
/// </summary>
|
||||
/// <value>Information about file in the archive.</value>
|
||||
public ArchiveFileInfo ArchiveFileInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
return _archiveFileInfo;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The reason for calling <see cref="ExtractFileCallback"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If neither <see cref="ExtractToFile"/> nor <see cref="ExtractToStream"/> is set,
|
||||
/// <see cref="ExtractFileCallback"/> will not be called after <see cref="ExtractFileCallbackReason.Start"/>.
|
||||
/// </remarks>
|
||||
/// <value>The reason.</value>
|
||||
public ExtractFileCallbackReason Reason { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The exception that occurred during extraction.
|
||||
/// </summary>
|
||||
/// <value>The _Exception.</value>
|
||||
/// <remarks>
|
||||
/// If the callback is called with <see cref="Reason"/> set to <see cref="ExtractFileCallbackReason.Failure"/>,
|
||||
/// this member contains the _Exception that occurred.
|
||||
/// The default behavior is to rethrow the _Exception after return of the callback.
|
||||
/// However the callback can set <see cref="Exception"/> to <c>null</c> to swallow the _Exception
|
||||
/// and continue extraction with the next file.
|
||||
/// </remarks>
|
||||
public Exception Exception { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to cancel the extraction.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> to cancel the extraction; <c>false</c> to continue. The default is <c>false</c>.</value>
|
||||
public bool CancelExtraction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether and where to extract the file.
|
||||
/// </summary>
|
||||
/// <value>The path where to extract the file to.</value>
|
||||
/// <remarks>
|
||||
/// If <see cref="ExtractToStream"/> is set, this mmember will be ignored.
|
||||
/// </remarks>
|
||||
public string ExtractToFile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether and where to extract the file.
|
||||
/// </summary>
|
||||
/// <value>The the extracted data is written to.</value>
|
||||
/// <remarks>
|
||||
/// If both this member and <see cref="ExtractToFile"/> are <c>null</c> (the defualt), the file
|
||||
/// will not be extracted and the callback will be be executed a second time with the <see cref="Reason"/>
|
||||
/// set to <see cref="ExtractFileCallbackReason.Done"/> or <see cref="ExtractFileCallbackReason.Failure"/>.
|
||||
/// </remarks>
|
||||
public Stream ExtractToStream
|
||||
{
|
||||
get
|
||||
{
|
||||
return _extractToStream;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_extractToStream != null && !_extractToStream.CanWrite)
|
||||
{
|
||||
throw new ExtractionFailedException("The specified stream is not writable!");
|
||||
}
|
||||
_extractToStream = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets any data that will be preserved between the <see cref="ExtractFileCallbackReason.Start"/> callback call
|
||||
/// and the <see cref="ExtractFileCallbackReason.Done"/> or <see cref="ExtractFileCallbackReason.Failure"/> calls.
|
||||
/// </summary>
|
||||
/// <value>The data.</value>
|
||||
public object ObjectData { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback delegate for <see cref="SevenZipExtractor.ExtractFiles(SevenZip.ExtractFileCallback)"/>.
|
||||
/// </summary>
|
||||
public delegate void ExtractFileCallback(ExtractFileCallbackArgs extractFileCallbackArgs);
|
||||
#endif
|
||||
}
|
|
@ -1,464 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
#if !WINCE
|
||||
using System.Runtime.Serialization;
|
||||
#endif
|
||||
|
||||
namespace SevenZip
|
||||
{
|
||||
/// <summary>
|
||||
/// Base SevenZip exception class.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class SevenZipException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// The message for thrown user exceptions.
|
||||
/// </summary>
|
||||
internal const string USER_EXCEPTION_MESSAGE = "The extraction was successful but" +
|
||||
"some exceptions were thrown in your events. Check UserExceptions for details.";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipException class
|
||||
/// </summary>
|
||||
public SevenZipException() : base("SevenZip unknown exception.") {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipException class
|
||||
/// </summary>
|
||||
/// <param name="defaultMessage">Default exception message</param>
|
||||
public SevenZipException(string defaultMessage)
|
||||
: base(defaultMessage) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipException class
|
||||
/// </summary>
|
||||
/// <param name="defaultMessage">Default exception message</param>
|
||||
/// <param name="message">Additional detailed message</param>
|
||||
public SevenZipException(string defaultMessage, string message)
|
||||
: base(defaultMessage + " Message: " + message) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipException class
|
||||
/// </summary>
|
||||
/// <param name="defaultMessage">Default exception message</param>
|
||||
/// <param name="message">Additional detailed message</param>
|
||||
/// <param name="inner">Inner exception occured</param>
|
||||
public SevenZipException(string defaultMessage, string message, Exception inner)
|
||||
: base(
|
||||
defaultMessage + (defaultMessage.EndsWith(" ", StringComparison.CurrentCulture) ? "" : " Message: ") +
|
||||
message, inner) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipException class
|
||||
/// </summary>
|
||||
/// <param name="defaultMessage">Default exception message</param>
|
||||
/// <param name="inner">Inner exception occured</param>
|
||||
public SevenZipException(string defaultMessage, Exception inner)
|
||||
: base(defaultMessage, inner) {}
|
||||
#if !WINCE
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipException class
|
||||
/// </summary>
|
||||
/// <param name="info">All data needed for serialization or deserialization</param>
|
||||
/// <param name="context">Serialized stream descriptor</param>
|
||||
protected SevenZipException(
|
||||
SerializationInfo info, StreamingContext context)
|
||||
: base(info, context) {}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if UNMANAGED
|
||||
|
||||
/// <summary>
|
||||
/// Exception class for ArchiveExtractCallback.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ExtractionFailedException : SevenZipException
|
||||
{
|
||||
/// <summary>
|
||||
/// Exception dafault message which is displayed if no extra information is specified
|
||||
/// </summary>
|
||||
public const string DEFAULT_MESSAGE = "Could not extract files!";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ExtractionFailedException class
|
||||
/// </summary>
|
||||
public ExtractionFailedException() : base(DEFAULT_MESSAGE) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ExtractionFailedException class
|
||||
/// </summary>
|
||||
/// <param name="message">Additional detailed message</param>
|
||||
public ExtractionFailedException(string message) : base(DEFAULT_MESSAGE, message) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ExtractionFailedException class
|
||||
/// </summary>
|
||||
/// <param name="message">Additional detailed message</param>
|
||||
/// <param name="inner">Inner exception occured</param>
|
||||
public ExtractionFailedException(string message, Exception inner) : base(DEFAULT_MESSAGE, message, inner) {}
|
||||
#if !WINCE
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ExtractionFailedException class
|
||||
/// </summary>
|
||||
/// <param name="info">All data needed for serialization or deserialization</param>
|
||||
/// <param name="context">Serialized stream descriptor</param>
|
||||
protected ExtractionFailedException(
|
||||
SerializationInfo info, StreamingContext context)
|
||||
: base(info, context) {}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if COMPRESS
|
||||
|
||||
/// <summary>
|
||||
/// Exception class for ArchiveUpdateCallback.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class CompressionFailedException : SevenZipException
|
||||
{
|
||||
/// <summary>
|
||||
/// Exception dafault message which is displayed if no extra information is specified
|
||||
/// </summary>
|
||||
public const string DEFAULT_MESSAGE = "Could not pack files!";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CompressionFailedException class
|
||||
/// </summary>
|
||||
public CompressionFailedException() : base(DEFAULT_MESSAGE) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CompressionFailedException class
|
||||
/// </summary>
|
||||
/// <param name="message">Additional detailed message</param>
|
||||
public CompressionFailedException(string message) : base(DEFAULT_MESSAGE, message) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CompressionFailedException class
|
||||
/// </summary>
|
||||
/// <param name="message">Additional detailed message</param>
|
||||
/// <param name="inner">Inner exception occured</param>
|
||||
public CompressionFailedException(string message, Exception inner) : base(DEFAULT_MESSAGE, message, inner) {}
|
||||
#if !WINCE
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CompressionFailedException class
|
||||
/// </summary>
|
||||
/// <param name="info">All data needed for serialization or deserialization</param>
|
||||
/// <param name="context">Serialized stream descriptor</param>
|
||||
protected CompressionFailedException(
|
||||
SerializationInfo info, StreamingContext context)
|
||||
: base(info, context) {}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Exception class for LZMA operations.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class LzmaException : SevenZipException
|
||||
{
|
||||
/// <summary>
|
||||
/// Exception dafault message which is displayed if no extra information is specified
|
||||
/// </summary>
|
||||
public const string DEFAULT_MESSAGE = "Specified stream is not a valid LZMA compressed stream!";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the LzmaException class
|
||||
/// </summary>
|
||||
public LzmaException() : base(DEFAULT_MESSAGE) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the LzmaException class
|
||||
/// </summary>
|
||||
/// <param name="message">Additional detailed message</param>
|
||||
public LzmaException(string message) : base(DEFAULT_MESSAGE, message) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the LzmaException class
|
||||
/// </summary>
|
||||
/// <param name="message">Additional detailed message</param>
|
||||
/// <param name="inner">Inner exception occured</param>
|
||||
public LzmaException(string message, Exception inner) : base(DEFAULT_MESSAGE, message, inner) {}
|
||||
#if !WINCE
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the LzmaException class
|
||||
/// </summary>
|
||||
/// <param name="info">All data needed for serialization or deserialization</param>
|
||||
/// <param name="context">Serialized stream descriptor</param>
|
||||
protected LzmaException(
|
||||
SerializationInfo info, StreamingContext context)
|
||||
: base(info, context) {}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if UNMANAGED
|
||||
|
||||
/// <summary>
|
||||
/// Exception class for 7-zip archive open or read operations.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class SevenZipArchiveException : SevenZipException
|
||||
{
|
||||
/// <summary>
|
||||
/// Exception dafault message which is displayed if no extra information is specified
|
||||
/// </summary>
|
||||
public const string DEFAULT_MESSAGE =
|
||||
"Invalid archive: open/read error! Is it encrypted and a wrong password was provided?\n" +
|
||||
"If your archive is an exotic one, it is possible that SevenZipSharp has no signature for "+
|
||||
"its format and thus decided it is TAR by mistake.";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipArchiveException class
|
||||
/// </summary>
|
||||
public SevenZipArchiveException() : base(DEFAULT_MESSAGE) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipArchiveException class
|
||||
/// </summary>
|
||||
/// <param name="message">Additional detailed message</param>
|
||||
public SevenZipArchiveException(string message) : base(DEFAULT_MESSAGE, message) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipArchiveException class
|
||||
/// </summary>
|
||||
/// <param name="message">Additional detailed message</param>
|
||||
/// <param name="inner">Inner exception occured</param>
|
||||
public SevenZipArchiveException(string message, Exception inner) : base(DEFAULT_MESSAGE, message, inner) {}
|
||||
#if !WINCE
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipArchiveException class
|
||||
/// </summary>
|
||||
/// <param name="info">All data needed for serialization or deserialization</param>
|
||||
/// <param name="context">Serialized stream descriptor</param>
|
||||
protected SevenZipArchiveException(
|
||||
SerializationInfo info, StreamingContext context)
|
||||
: base(info, context) {}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exception class for empty common root if file name array in SevenZipCompressor.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class SevenZipInvalidFileNamesException : SevenZipException
|
||||
{
|
||||
/// <summary>
|
||||
/// Exception dafault message which is displayed if no extra information is specified
|
||||
/// </summary>
|
||||
public const string DEFAULT_MESSAGE = "Invalid file names have been specified: ";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipInvalidFileNamesException class
|
||||
/// </summary>
|
||||
public SevenZipInvalidFileNamesException() : base(DEFAULT_MESSAGE) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipInvalidFileNamesException class
|
||||
/// </summary>
|
||||
/// <param name="message">Additional detailed message</param>
|
||||
public SevenZipInvalidFileNamesException(string message) : base(DEFAULT_MESSAGE, message) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipInvalidFileNamesException class
|
||||
/// </summary>
|
||||
/// <param name="message">Additional detailed message</param>
|
||||
/// <param name="inner">Inner exception occured</param>
|
||||
public SevenZipInvalidFileNamesException(string message, Exception inner) : base(DEFAULT_MESSAGE, message, inner) {}
|
||||
#if !WINCE
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipInvalidFileNamesException class
|
||||
/// </summary>
|
||||
/// <param name="info">All data needed for serialization or deserialization</param>
|
||||
/// <param name="context">Serialized stream descriptor</param>
|
||||
protected SevenZipInvalidFileNamesException(
|
||||
SerializationInfo info, StreamingContext context)
|
||||
: base(info, context) {}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if COMPRESS
|
||||
|
||||
/// <summary>
|
||||
/// Exception class for fail to create an archive in SevenZipCompressor.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class SevenZipCompressionFailedException : SevenZipException
|
||||
{
|
||||
/// <summary>
|
||||
/// Exception dafault message which is displayed if no extra information is specified
|
||||
/// </summary>
|
||||
public const string DEFAULT_MESSAGE = "The compression has failed for an unknown reason with code ";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipCompressionFailedException class
|
||||
/// </summary>
|
||||
public SevenZipCompressionFailedException() : base(DEFAULT_MESSAGE) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipCompressionFailedException class
|
||||
/// </summary>
|
||||
/// <param name="message">Additional detailed message</param>
|
||||
public SevenZipCompressionFailedException(string message) : base(DEFAULT_MESSAGE, message) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipCompressionFailedException class
|
||||
/// </summary>
|
||||
/// <param name="message">Additional detailed message</param>
|
||||
/// <param name="inner">Inner exception occured</param>
|
||||
public SevenZipCompressionFailedException(string message, Exception inner)
|
||||
: base(DEFAULT_MESSAGE, message, inner) {}
|
||||
#if !WINCE
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipCompressionFailedException class
|
||||
/// </summary>
|
||||
/// <param name="info">All data needed for serialization or deserialization</param>
|
||||
/// <param name="context">Serialized stream descriptor</param>
|
||||
protected SevenZipCompressionFailedException(
|
||||
SerializationInfo info, StreamingContext context)
|
||||
: base(info, context) {}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Exception class for fail to extract an archive in SevenZipExtractor.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class SevenZipExtractionFailedException : SevenZipException
|
||||
{
|
||||
/// <summary>
|
||||
/// Exception dafault message which is displayed if no extra information is specified
|
||||
/// </summary>
|
||||
public const string DEFAULT_MESSAGE = "The extraction has failed for an unknown reason with code ";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipExtractionFailedException class
|
||||
/// </summary>
|
||||
public SevenZipExtractionFailedException() : base(DEFAULT_MESSAGE) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipExtractionFailedException class
|
||||
/// </summary>
|
||||
/// <param name="message">Additional detailed message</param>
|
||||
public SevenZipExtractionFailedException(string message) : base(DEFAULT_MESSAGE, message) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipExtractionFailedException class
|
||||
/// </summary>
|
||||
/// <param name="message">Additional detailed message</param>
|
||||
/// <param name="inner">Inner exception occured</param>
|
||||
public SevenZipExtractionFailedException(string message, Exception inner) : base(DEFAULT_MESSAGE, message, inner) {}
|
||||
#if !WINCE
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipExtractionFailedException class
|
||||
/// </summary>
|
||||
/// <param name="info">All data needed for serialization or deserialization</param>
|
||||
/// <param name="context">Serialized stream descriptor</param>
|
||||
protected SevenZipExtractionFailedException(
|
||||
SerializationInfo info, StreamingContext context)
|
||||
: base(info, context) {}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exception class for 7-zip library operations.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class SevenZipLibraryException : SevenZipException
|
||||
{
|
||||
/// <summary>
|
||||
/// Exception dafault message which is displayed if no extra information is specified
|
||||
/// </summary>
|
||||
public const string DEFAULT_MESSAGE = "Can not load 7-zip library or internal COM error!";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipLibraryException class
|
||||
/// </summary>
|
||||
public SevenZipLibraryException() : base(DEFAULT_MESSAGE) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipLibraryException class
|
||||
/// </summary>
|
||||
/// <param name="message">Additional detailed message</param>
|
||||
public SevenZipLibraryException(string message) : base(DEFAULT_MESSAGE, message) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipLibraryException class
|
||||
/// </summary>
|
||||
/// <param name="message">Additional detailed message</param>
|
||||
/// <param name="inner">Inner exception occured</param>
|
||||
public SevenZipLibraryException(string message, Exception inner) : base(DEFAULT_MESSAGE, message, inner) {}
|
||||
#if !WINCE
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipLibraryException class
|
||||
/// </summary>
|
||||
/// <param name="info">All data needed for serialization or deserialization</param>
|
||||
/// <param name="context">Serialized stream descriptor</param>
|
||||
protected SevenZipLibraryException(
|
||||
SerializationInfo info, StreamingContext context)
|
||||
: base(info, context) {}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SFX
|
||||
|
||||
/// <summary>
|
||||
/// Exception class for 7-zip sfx settings validation.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class SevenZipSfxValidationException : SevenZipException
|
||||
{
|
||||
/// <summary>
|
||||
/// Exception dafault message which is displayed if no extra information is specified
|
||||
/// </summary>
|
||||
public static readonly string DefaultMessage = "Sfx settings validation failed.";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipSfxValidationException class
|
||||
/// </summary>
|
||||
public SevenZipSfxValidationException() : base(DefaultMessage) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipSfxValidationException class
|
||||
/// </summary>
|
||||
/// <param name="message">Additional detailed message</param>
|
||||
public SevenZipSfxValidationException(string message) : base(DefaultMessage, message) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipSfxValidationException class
|
||||
/// </summary>
|
||||
/// <param name="message">Additional detailed message</param>
|
||||
/// <param name="inner">Inner exception occured</param>
|
||||
public SevenZipSfxValidationException(string message, Exception inner) : base(DefaultMessage, message, inner) {}
|
||||
#if !WINCE
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipSfxValidationException class
|
||||
/// </summary>
|
||||
/// <param name="info">All data needed for serialization or deserialization</param>
|
||||
/// <param name="context">Serialized stream descriptor</param>
|
||||
protected SevenZipSfxValidationException(
|
||||
SerializationInfo info, StreamingContext context)
|
||||
: base(info, context) {}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -1,252 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace SevenZip
|
||||
{
|
||||
#if UNMANAGED
|
||||
/// <summary>
|
||||
/// The signature checker class. Original code by Siddharth Uppal, adapted by Markhor.
|
||||
/// </summary>
|
||||
/// <remarks>Based on the code at http://blog.somecreativity.com/2008/04/08/how-to-check-if-a-file-is-compressed-in-c/#</remarks>
|
||||
public static class FileChecker
|
||||
{
|
||||
public static bool ThrowExceptions = true;
|
||||
|
||||
private const int SIGNATURE_SIZE = 16;
|
||||
private const int SFX_SCAN_LENGTH = 256 * 1024;
|
||||
|
||||
private static bool SpecialDetect(Stream stream, int offset, InArchiveFormat expectedFormat)
|
||||
{
|
||||
if (stream.Length > offset + SIGNATURE_SIZE)
|
||||
{
|
||||
var signature = new byte[SIGNATURE_SIZE];
|
||||
int bytesRequired = SIGNATURE_SIZE;
|
||||
int index = 0;
|
||||
stream.Seek(offset, SeekOrigin.Begin);
|
||||
while (bytesRequired > 0)
|
||||
{
|
||||
int bytesRead = stream.Read(signature, index, bytesRequired);
|
||||
bytesRequired -= bytesRead;
|
||||
index += bytesRead;
|
||||
}
|
||||
string actualSignature = BitConverter.ToString(signature);
|
||||
foreach (string expectedSignature in Formats.InSignatureFormats.Keys)
|
||||
{
|
||||
if (Formats.InSignatureFormats[expectedSignature] != expectedFormat)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (actualSignature.StartsWith(expectedSignature, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the InArchiveFormat for a specific extension.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream to identify.</param>
|
||||
/// <param name="offset">The archive beginning offset.</param>
|
||||
/// <param name="isExecutable">True if the original format of the stream is PE; otherwise, false.</param>
|
||||
/// <returns>Corresponding InArchiveFormat.</returns>
|
||||
public static InArchiveFormat CheckSignature(Stream stream, out int offset, out bool isExecutable)
|
||||
{
|
||||
offset = 0;
|
||||
isExecutable = false;
|
||||
|
||||
if (!stream.CanRead)
|
||||
{
|
||||
if (ThrowExceptions)
|
||||
throw new ArgumentException("The stream must be readable.");
|
||||
else return InArchiveFormat.None;
|
||||
}
|
||||
if (stream.Length < SIGNATURE_SIZE)
|
||||
{
|
||||
if (ThrowExceptions)
|
||||
throw new ArgumentException("The stream is invalid.");
|
||||
else return InArchiveFormat.None;
|
||||
}
|
||||
|
||||
#region Get file signature
|
||||
|
||||
var signature = new byte[SIGNATURE_SIZE];
|
||||
int bytesRequired = SIGNATURE_SIZE;
|
||||
int index = 0;
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
while (bytesRequired > 0)
|
||||
{
|
||||
int bytesRead = stream.Read(signature, index, bytesRequired);
|
||||
bytesRequired -= bytesRead;
|
||||
index += bytesRead;
|
||||
}
|
||||
string actualSignature = BitConverter.ToString(signature);
|
||||
|
||||
#endregion
|
||||
|
||||
InArchiveFormat suspectedFormat = InArchiveFormat.XZ; // any except PE and Cab
|
||||
isExecutable = false;
|
||||
|
||||
foreach (string expectedSignature in Formats.InSignatureFormats.Keys)
|
||||
{
|
||||
if (actualSignature.StartsWith(expectedSignature, StringComparison.OrdinalIgnoreCase) ||
|
||||
actualSignature.Substring(6).StartsWith(expectedSignature, StringComparison.OrdinalIgnoreCase) &&
|
||||
Formats.InSignatureFormats[expectedSignature] == InArchiveFormat.Lzh)
|
||||
{
|
||||
if (Formats.InSignatureFormats[expectedSignature] == InArchiveFormat.PE)
|
||||
{
|
||||
suspectedFormat = InArchiveFormat.PE;
|
||||
isExecutable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Formats.InSignatureFormats[expectedSignature];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Many Microsoft formats
|
||||
if (actualSignature.StartsWith("D0-CF-11-E0-A1-B1-1A-E1", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
suspectedFormat = InArchiveFormat.Cab; // != InArchiveFormat.XZ
|
||||
}
|
||||
|
||||
#region SpecialDetect
|
||||
try
|
||||
{
|
||||
SpecialDetect(stream, 257, InArchiveFormat.Tar);
|
||||
}
|
||||
catch (ArgumentException) {}
|
||||
if (SpecialDetect(stream, 0x8001, InArchiveFormat.Iso))
|
||||
{
|
||||
return InArchiveFormat.Iso;
|
||||
}
|
||||
if (SpecialDetect(stream, 0x8801, InArchiveFormat.Iso))
|
||||
{
|
||||
return InArchiveFormat.Iso;
|
||||
}
|
||||
if (SpecialDetect(stream, 0x9001, InArchiveFormat.Iso))
|
||||
{
|
||||
return InArchiveFormat.Iso;
|
||||
}
|
||||
if (SpecialDetect(stream, 0x9001, InArchiveFormat.Iso))
|
||||
{
|
||||
return InArchiveFormat.Iso;
|
||||
}
|
||||
if (SpecialDetect(stream, 0x400, InArchiveFormat.Hfs))
|
||||
{
|
||||
return InArchiveFormat.Hfs;
|
||||
}
|
||||
#region Last resort for tar - can mistake
|
||||
if (stream.Length >= 1024)
|
||||
{
|
||||
stream.Seek(-1024, SeekOrigin.End);
|
||||
byte[] buf = new byte[1024];
|
||||
stream.Read(buf, 0, 1024);
|
||||
bool istar = true;
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
istar = istar && buf[i] == 0;
|
||||
}
|
||||
if (istar)
|
||||
{
|
||||
return InArchiveFormat.Tar;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Check if it is an SFX archive or a file with an embedded archive.
|
||||
if (suspectedFormat != InArchiveFormat.XZ)
|
||||
{
|
||||
#region Get first Min(stream.Length, SFX_SCAN_LENGTH) bytes
|
||||
var scanLength = Math.Min(stream.Length, SFX_SCAN_LENGTH);
|
||||
signature = new byte[scanLength];
|
||||
bytesRequired = (int)scanLength;
|
||||
index = 0;
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
while (bytesRequired > 0)
|
||||
{
|
||||
int bytesRead = stream.Read(signature, index, bytesRequired);
|
||||
bytesRequired -= bytesRead;
|
||||
index += bytesRead;
|
||||
}
|
||||
actualSignature = BitConverter.ToString(signature);
|
||||
#endregion
|
||||
|
||||
foreach (var format in new InArchiveFormat[]
|
||||
{
|
||||
InArchiveFormat.Zip,
|
||||
InArchiveFormat.SevenZip,
|
||||
InArchiveFormat.Rar,
|
||||
InArchiveFormat.Cab,
|
||||
InArchiveFormat.Arj
|
||||
})
|
||||
{
|
||||
int pos = actualSignature.IndexOf(Formats.InSignatureFormatsReversed[format]);
|
||||
if (pos > -1)
|
||||
{
|
||||
offset = pos / 3;
|
||||
return format;
|
||||
}
|
||||
}
|
||||
// Nothing
|
||||
if (suspectedFormat == InArchiveFormat.PE)
|
||||
{
|
||||
return InArchiveFormat.PE;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
if (ThrowExceptions)
|
||||
throw new ArgumentException("The stream is invalid or no corresponding signature was found.");
|
||||
else return InArchiveFormat.None;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the InArchiveFormat for a specific file name.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The archive file name.</param>
|
||||
/// <param name="offset">The archive beginning offset.</param>
|
||||
/// <param name="isExecutable">True if the original format of the file is PE; otherwise, false.</param>
|
||||
/// <returns>Corresponding InArchiveFormat.</returns>
|
||||
/// <exception cref="System.ArgumentException"/>
|
||||
public static InArchiveFormat CheckSignature(string fileName, out int offset, out bool isExecutable)
|
||||
{
|
||||
using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
try
|
||||
{
|
||||
InArchiveFormat format = CheckSignature(fs, out offset, out isExecutable);
|
||||
if (format != InArchiveFormat.None) return format;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
isExecutable = false;
|
||||
return Formats.FormatByFileName(fileName, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -1,540 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace SevenZip
|
||||
{
|
||||
#if UNMANAGED
|
||||
/// <summary>
|
||||
/// Readable archive format enumeration.
|
||||
/// </summary>
|
||||
public enum InArchiveFormat
|
||||
{
|
||||
/// <summary>
|
||||
/// Open 7-zip archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/7-zip">Wikipedia information</a></remarks>
|
||||
SevenZip,
|
||||
/// <summary>
|
||||
/// Proprietary Arj archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/ARJ">Wikipedia information</a></remarks>
|
||||
Arj,
|
||||
/// <summary>
|
||||
/// Open Bzip2 archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Bzip2">Wikipedia information</a></remarks>
|
||||
BZip2,
|
||||
/// <summary>
|
||||
/// Microsoft cabinet archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Cabinet_(file_format)">Wikipedia information</a></remarks>
|
||||
Cab,
|
||||
/// <summary>
|
||||
/// Microsoft Compiled HTML Help file format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Microsoft_Compiled_HTML_Help">Wikipedia information</a></remarks>
|
||||
Chm,
|
||||
/// <summary>
|
||||
/// Microsoft Compound file format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Compound_File_Binary_Format">Wikipedia information</a></remarks>
|
||||
Compound,
|
||||
/// <summary>
|
||||
/// Open Cpio archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Cpio">Wikipedia information</a></remarks>
|
||||
Cpio,
|
||||
/// <summary>
|
||||
/// Open Debian software package format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Deb_(file_format)">Wikipedia information</a></remarks>
|
||||
Deb,
|
||||
/// <summary>
|
||||
/// Open Gzip archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Gzip">Wikipedia information</a></remarks>
|
||||
GZip,
|
||||
/// <summary>
|
||||
/// Open ISO disk image format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/ISO_image">Wikipedia information</a></remarks>
|
||||
Iso,
|
||||
/// <summary>
|
||||
/// Open Lzh archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Lzh">Wikipedia information</a></remarks>
|
||||
Lzh,
|
||||
/// <summary>
|
||||
/// Open core 7-zip Lzma raw archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Lzma">Wikipedia information</a></remarks>
|
||||
Lzma,
|
||||
/// <summary>
|
||||
/// Nullsoft installation package format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/NSIS">Wikipedia information</a></remarks>
|
||||
Nsis,
|
||||
/// <summary>
|
||||
/// RarLab Rar archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Rar">Wikipedia information</a></remarks>
|
||||
Rar,
|
||||
/// <summary>
|
||||
/// Open Rpm software package format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/RPM_Package_Manager">Wikipedia information</a></remarks>
|
||||
Rpm,
|
||||
/// <summary>
|
||||
/// Open split file format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="?">Wikipedia information</a></remarks>
|
||||
Split,
|
||||
/// <summary>
|
||||
/// Open Tar archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Tar_(file_format)">Wikipedia information</a></remarks>
|
||||
Tar,
|
||||
/// <summary>
|
||||
/// Microsoft Windows Imaging disk image format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Windows_Imaging_Format">Wikipedia information</a></remarks>
|
||||
Wim,
|
||||
/// <summary>
|
||||
/// Open LZW archive format; implemented in "compress" program; also known as "Z" archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Compress">Wikipedia information</a></remarks>
|
||||
Lzw,
|
||||
/// <summary>
|
||||
/// Open Zip archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/ZIP_(file_format)">Wikipedia information</a></remarks>
|
||||
Zip,
|
||||
/// <summary>
|
||||
/// Open Udf disk image format.
|
||||
/// </summary>
|
||||
Udf,
|
||||
/// <summary>
|
||||
/// Xar open source archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Xar_(archiver)">Wikipedia information</a></remarks>
|
||||
Xar,
|
||||
/// <summary>
|
||||
/// Mub
|
||||
/// </summary>
|
||||
Mub,
|
||||
/// <summary>
|
||||
/// Macintosh Disk Image on CD.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/HFS_Plus">Wikipedia information</a></remarks>
|
||||
Hfs,
|
||||
/// <summary>
|
||||
/// Apple Mac OS X Disk Copy Disk Image format.
|
||||
/// </summary>
|
||||
Dmg,
|
||||
/// <summary>
|
||||
/// Open Xz archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Xz">Wikipedia information</a></remarks>
|
||||
XZ,
|
||||
/// <summary>
|
||||
/// MSLZ archive format.
|
||||
/// </summary>
|
||||
Mslz,
|
||||
/// <summary>
|
||||
/// Flash video format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Flv">Wikipedia information</a></remarks>
|
||||
Flv,
|
||||
/// <summary>
|
||||
/// Shockwave Flash format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Swf">Wikipedia information</a></remarks>
|
||||
Swf,
|
||||
/// <summary>
|
||||
/// Windows PE executable format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Portable_Executable">Wikipedia information</a></remarks>
|
||||
PE,
|
||||
/// <summary>
|
||||
/// Linux executable Elf format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Executable_and_Linkable_Format">Wikipedia information</a></remarks>
|
||||
Elf,
|
||||
/// <summary>
|
||||
/// Windows Installer Database.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Windows_Installer">Wikipedia information</a></remarks>
|
||||
Msi,
|
||||
/// <summary>
|
||||
/// Microsoft virtual hard disk file format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/VHD_%28file_format%29">Wikipedia information</a></remarks>
|
||||
Vhd,
|
||||
/// <summary>
|
||||
/// Not an archive
|
||||
/// </summary>
|
||||
None
|
||||
}
|
||||
|
||||
#if COMPRESS
|
||||
/// <summary>
|
||||
/// Writable archive format enumeration.
|
||||
/// </summary>
|
||||
public enum OutArchiveFormat
|
||||
{
|
||||
/// <summary>
|
||||
/// Open 7-zip archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/7-zip">Wikipedia information</a></remarks>
|
||||
SevenZip,
|
||||
/// <summary>
|
||||
/// Open Zip archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/ZIP_(file_format)">Wikipedia information</a></remarks>
|
||||
Zip,
|
||||
/// <summary>
|
||||
/// Open Gzip archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Gzip">Wikipedia information</a></remarks>
|
||||
GZip,
|
||||
/// <summary>
|
||||
/// Open Bzip2 archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Bzip2">Wikipedia information</a></remarks>
|
||||
BZip2,
|
||||
/// <summary>
|
||||
/// Open Tar archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Tar_(file_format)">Wikipedia information</a></remarks>
|
||||
Tar,
|
||||
/// <summary>
|
||||
/// Open Xz archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Xz">Wikipedia information</a></remarks>
|
||||
XZ
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compression level enumeration
|
||||
/// </summary>
|
||||
public enum CompressionLevel
|
||||
{
|
||||
/// <summary>
|
||||
/// No compression
|
||||
/// </summary>
|
||||
None,
|
||||
/// <summary>
|
||||
/// Very low compression level
|
||||
/// </summary>
|
||||
Fast,
|
||||
/// <summary>
|
||||
/// Low compression level
|
||||
/// </summary>
|
||||
Low,
|
||||
/// <summary>
|
||||
/// Normal compression level (default)
|
||||
/// </summary>
|
||||
Normal,
|
||||
/// <summary>
|
||||
/// High compression level
|
||||
/// </summary>
|
||||
High,
|
||||
/// <summary>
|
||||
/// The best compression level (slow)
|
||||
/// </summary>
|
||||
Ultra
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compression method enumeration.
|
||||
/// </summary>
|
||||
/// <remarks>Some methods are applicable only to Zip format, some - only to 7-zip.</remarks>
|
||||
public enum CompressionMethod
|
||||
{
|
||||
/// <summary>
|
||||
/// Zip or 7-zip|no compression method.
|
||||
/// </summary>
|
||||
Copy,
|
||||
/// <summary>
|
||||
/// Zip|Deflate method.
|
||||
/// </summary>
|
||||
Deflate,
|
||||
/// <summary>
|
||||
/// Zip|Deflate64 method.
|
||||
/// </summary>
|
||||
Deflate64,
|
||||
/// <summary>
|
||||
/// Zip or 7-zip|Bzip2 method.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Cabinet_(file_format)">Wikipedia information</a></remarks>
|
||||
BZip2,
|
||||
/// <summary>
|
||||
/// Zip or 7-zip|LZMA method based on Lempel-Ziv algorithm, it is default for 7-zip.
|
||||
/// </summary>
|
||||
Lzma,
|
||||
/// <summary>
|
||||
/// 7-zip|LZMA version 2, LZMA with improved multithreading and usually slight archive size decrease.
|
||||
/// </summary>
|
||||
Lzma2,
|
||||
/// <summary>
|
||||
/// Zip or 7-zip|PPMd method based on Dmitry Shkarin's PPMdH source code, very efficient for compressing texts.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Prediction_by_Partial_Matching">Wikipedia information</a></remarks>
|
||||
Ppmd,
|
||||
/// <summary>
|
||||
/// No method change.
|
||||
/// </summary>
|
||||
Default
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Archive format routines
|
||||
/// </summary>
|
||||
public static class Formats
|
||||
{
|
||||
/*/// <summary>
|
||||
/// Gets the max value of the specified enum type.
|
||||
/// </summary>
|
||||
/// <param name="type">Type of the enum</param>
|
||||
/// <returns>Max value</returns>
|
||||
internal static int GetMaxValue(Type type)
|
||||
{
|
||||
List<int> enumList = new List<int>((IEnumerable<int>)Enum.GetValues(type));
|
||||
enumList.Sort();
|
||||
return enumList[enumList.Count - 1];
|
||||
}*/
|
||||
|
||||
/// <summary>
|
||||
/// List of readable archive format interface guids for 7-zip COM interop.
|
||||
/// </summary>
|
||||
internal static readonly Dictionary<InArchiveFormat, Guid> InFormatGuids =
|
||||
new Dictionary<InArchiveFormat, Guid>(20)
|
||||
#region InFormatGuids initialization
|
||||
|
||||
{
|
||||
{InArchiveFormat.SevenZip, new Guid("23170f69-40c1-278a-1000-000110070000")},
|
||||
{InArchiveFormat.Arj, new Guid("23170f69-40c1-278a-1000-000110040000")},
|
||||
{InArchiveFormat.BZip2, new Guid("23170f69-40c1-278a-1000-000110020000")},
|
||||
{InArchiveFormat.Cab, new Guid("23170f69-40c1-278a-1000-000110080000")},
|
||||
{InArchiveFormat.Chm, new Guid("23170f69-40c1-278a-1000-000110e90000")},
|
||||
{InArchiveFormat.Compound, new Guid("23170f69-40c1-278a-1000-000110e50000")},
|
||||
{InArchiveFormat.Cpio, new Guid("23170f69-40c1-278a-1000-000110ed0000")},
|
||||
{InArchiveFormat.Deb, new Guid("23170f69-40c1-278a-1000-000110ec0000")},
|
||||
{InArchiveFormat.GZip, new Guid("23170f69-40c1-278a-1000-000110ef0000")},
|
||||
{InArchiveFormat.Iso, new Guid("23170f69-40c1-278a-1000-000110e70000")},
|
||||
{InArchiveFormat.Lzh, new Guid("23170f69-40c1-278a-1000-000110060000")},
|
||||
{InArchiveFormat.Lzma, new Guid("23170f69-40c1-278a-1000-0001100a0000")},
|
||||
{InArchiveFormat.Nsis, new Guid("23170f69-40c1-278a-1000-000110090000")},
|
||||
{InArchiveFormat.Rar, new Guid("23170f69-40c1-278a-1000-000110030000")},
|
||||
{InArchiveFormat.Rpm, new Guid("23170f69-40c1-278a-1000-000110eb0000")},
|
||||
{InArchiveFormat.Split, new Guid("23170f69-40c1-278a-1000-000110ea0000")},
|
||||
{InArchiveFormat.Tar, new Guid("23170f69-40c1-278a-1000-000110ee0000")},
|
||||
{InArchiveFormat.Wim, new Guid("23170f69-40c1-278a-1000-000110e60000")},
|
||||
{InArchiveFormat.Lzw, new Guid("23170f69-40c1-278a-1000-000110050000")},
|
||||
{InArchiveFormat.Zip, new Guid("23170f69-40c1-278a-1000-000110010000")},
|
||||
{InArchiveFormat.Udf, new Guid("23170f69-40c1-278a-1000-000110E00000")},
|
||||
{InArchiveFormat.Xar, new Guid("23170f69-40c1-278a-1000-000110E10000")},
|
||||
{InArchiveFormat.Mub, new Guid("23170f69-40c1-278a-1000-000110E20000")},
|
||||
{InArchiveFormat.Hfs, new Guid("23170f69-40c1-278a-1000-000110E30000")},
|
||||
{InArchiveFormat.Dmg, new Guid("23170f69-40c1-278a-1000-000110E40000")},
|
||||
{InArchiveFormat.XZ, new Guid("23170f69-40c1-278a-1000-0001100C0000")},
|
||||
{InArchiveFormat.Mslz, new Guid("23170f69-40c1-278a-1000-000110D50000")},
|
||||
{InArchiveFormat.PE, new Guid("23170f69-40c1-278a-1000-000110DD0000")},
|
||||
{InArchiveFormat.Elf, new Guid("23170f69-40c1-278a-1000-000110DE0000")},
|
||||
{InArchiveFormat.Swf, new Guid("23170f69-40c1-278a-1000-000110D70000")},
|
||||
{InArchiveFormat.Vhd, new Guid("23170f69-40c1-278a-1000-000110DC0000")}
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#if COMPRESS
|
||||
/// <summary>
|
||||
/// List of writable archive format interface guids for 7-zip COM interop.
|
||||
/// </summary>
|
||||
internal static readonly Dictionary<OutArchiveFormat, Guid> OutFormatGuids =
|
||||
new Dictionary<OutArchiveFormat, Guid>(2)
|
||||
#region OutFormatGuids initialization
|
||||
|
||||
{
|
||||
{OutArchiveFormat.SevenZip, new Guid("23170f69-40c1-278a-1000-000110070000")},
|
||||
{OutArchiveFormat.Zip, new Guid("23170f69-40c1-278a-1000-000110010000")},
|
||||
{OutArchiveFormat.BZip2, new Guid("23170f69-40c1-278a-1000-000110020000")},
|
||||
{OutArchiveFormat.GZip, new Guid("23170f69-40c1-278a-1000-000110ef0000")},
|
||||
{OutArchiveFormat.Tar, new Guid("23170f69-40c1-278a-1000-000110ee0000")},
|
||||
{OutArchiveFormat.XZ, new Guid("23170f69-40c1-278a-1000-0001100C0000")},
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
internal static readonly Dictionary<CompressionMethod, string> MethodNames =
|
||||
new Dictionary<CompressionMethod, string>(6)
|
||||
#region MethodNames initialization
|
||||
|
||||
{
|
||||
{CompressionMethod.Copy, "Copy"},
|
||||
{CompressionMethod.Deflate, "Deflate"},
|
||||
{CompressionMethod.Deflate64, "Deflate64"},
|
||||
{CompressionMethod.Lzma, "LZMA"},
|
||||
{CompressionMethod.Lzma2, "LZMA2"},
|
||||
{CompressionMethod.Ppmd, "PPMd"},
|
||||
{CompressionMethod.BZip2, "BZip2"}
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
internal static readonly Dictionary<OutArchiveFormat, InArchiveFormat> InForOutFormats =
|
||||
new Dictionary<OutArchiveFormat, InArchiveFormat>(6)
|
||||
#region InForOutFormats initialization
|
||||
|
||||
{
|
||||
{OutArchiveFormat.SevenZip, InArchiveFormat.SevenZip},
|
||||
{OutArchiveFormat.GZip, InArchiveFormat.GZip},
|
||||
{OutArchiveFormat.BZip2, InArchiveFormat.BZip2},
|
||||
{OutArchiveFormat.Tar, InArchiveFormat.Tar},
|
||||
{OutArchiveFormat.XZ, InArchiveFormat.XZ},
|
||||
{OutArchiveFormat.Zip, InArchiveFormat.Zip}
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// List of archive formats corresponding to specific extensions
|
||||
/// </summary>
|
||||
private static readonly Dictionary<string, InArchiveFormat> InExtensionFormats =
|
||||
new Dictionary<string, InArchiveFormat>
|
||||
#region InExtensionFormats initialization
|
||||
|
||||
{{"7z", InArchiveFormat.SevenZip},
|
||||
{"gz", InArchiveFormat.GZip},
|
||||
{"tar", InArchiveFormat.Tar},
|
||||
{"rar", InArchiveFormat.Rar},
|
||||
{"zip", InArchiveFormat.Zip},
|
||||
{"lzma", InArchiveFormat.Lzma},
|
||||
{"lzh", InArchiveFormat.Lzh},
|
||||
{"arj", InArchiveFormat.Arj},
|
||||
{"bz2", InArchiveFormat.BZip2},
|
||||
{"cab", InArchiveFormat.Cab},
|
||||
{"chm", InArchiveFormat.Chm},
|
||||
{"deb", InArchiveFormat.Deb},
|
||||
{"iso", InArchiveFormat.Iso},
|
||||
{"rpm", InArchiveFormat.Rpm},
|
||||
{"wim", InArchiveFormat.Wim},
|
||||
{"udf", InArchiveFormat.Udf},
|
||||
{"mub", InArchiveFormat.Mub},
|
||||
{"xar", InArchiveFormat.Xar},
|
||||
{"hfs", InArchiveFormat.Hfs},
|
||||
{"dmg", InArchiveFormat.Dmg},
|
||||
{"Z", InArchiveFormat.Lzw},
|
||||
{"xz", InArchiveFormat.XZ},
|
||||
{"flv", InArchiveFormat.Flv},
|
||||
{"swf", InArchiveFormat.Swf},
|
||||
{"exe", InArchiveFormat.PE},
|
||||
{"dll", InArchiveFormat.PE},
|
||||
{"vhd", InArchiveFormat.Vhd}
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// List of archive formats corresponding to specific signatures
|
||||
/// </summary>
|
||||
/// <remarks>Based on the information at <a href="http://www.garykessler.net/library/file_sigs.html">this site.</a></remarks>
|
||||
internal static readonly Dictionary<string, InArchiveFormat> InSignatureFormats =
|
||||
new Dictionary<string, InArchiveFormat>
|
||||
#region InSignatureFormats initialization
|
||||
|
||||
{{"37-7A-BC-AF-27-1C", InArchiveFormat.SevenZip},
|
||||
{"1F-8B-08", InArchiveFormat.GZip},
|
||||
{"75-73-74-61-72", InArchiveFormat.Tar},
|
||||
//257 byte offset
|
||||
{"52-61-72-21-1A-07-00", InArchiveFormat.Rar},
|
||||
{"50-4B-03-04", InArchiveFormat.Zip},
|
||||
{"5D-00-00-40-00", InArchiveFormat.Lzma},
|
||||
{"2D-6C-68", InArchiveFormat.Lzh},
|
||||
//^ 2 byte offset
|
||||
{"1F-9D-90", InArchiveFormat.Lzw},
|
||||
{"60-EA", InArchiveFormat.Arj},
|
||||
{"42-5A-68", InArchiveFormat.BZip2},
|
||||
//{"4D-53-43-46", InArchiveFormat.Cab},
|
||||
//{"49-54-53-46", InArchiveFormat.Chm},
|
||||
//{"21-3C-61-72-63-68-3E-0A-64-65-62-69-61-6E-2D-62-69-6E-61-72-79", InArchiveFormat.Deb},
|
||||
//{"43-44-30-30-31", InArchiveFormat.Iso},
|
||||
//^ 0x8001, 0x8801 or 0x9001 byte offset
|
||||
//{"ED-AB-EE-DB", InArchiveFormat.Rpm},
|
||||
//{"4D-53-57-49-4D-00-00-00", InArchiveFormat.Wim},
|
||||
//{"udf", InArchiveFormat.Udf},
|
||||
//{"mub", InArchiveFormat.Mub},
|
||||
//{"78-61-72-21", InArchiveFormat.Xar},
|
||||
//0x400 byte offset
|
||||
//{"48-2B", InArchiveFormat.Hfs},
|
||||
{"FD-37-7A-58-5A", InArchiveFormat.XZ},
|
||||
//{"46-4C-56", InArchiveFormat.Flv},
|
||||
//{"46-57-53", InArchiveFormat.Swf},
|
||||
//{"4D-5A", InArchiveFormat.PE},
|
||||
//{"7F-45-4C-46", InArchiveFormat.Elf},
|
||||
//{"78", InArchiveFormat.Dmg},
|
||||
//{"63-6F-6E-65-63-74-69-78", InArchiveFormat.Vhd},
|
||||
{"4E-45-53", InArchiveFormat.None}
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
internal static Dictionary<InArchiveFormat, string> InSignatureFormatsReversed;
|
||||
|
||||
static Formats()
|
||||
{
|
||||
InSignatureFormatsReversed = new Dictionary<InArchiveFormat, string>(InSignatureFormats.Count);
|
||||
foreach (var pair in InSignatureFormats)
|
||||
{
|
||||
InSignatureFormatsReversed.Add(pair.Value, pair.Key);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets InArchiveFormat for specified archive file name
|
||||
/// </summary>
|
||||
/// <param name="fileName">Archive file name</param>
|
||||
/// <param name="reportErrors">Indicates whether to throw exceptions</param>
|
||||
/// <returns>InArchiveFormat recognized by the file name extension</returns>
|
||||
/// <exception cref="System.ArgumentException"/>
|
||||
public static InArchiveFormat FormatByFileName(string fileName, bool reportErrors)
|
||||
{
|
||||
if (String.IsNullOrEmpty(fileName) && reportErrors)
|
||||
{
|
||||
throw new ArgumentException("File name is null or empty string!");
|
||||
}
|
||||
string extension = Path.GetExtension(fileName);
|
||||
if (extension.StartsWith("."))
|
||||
extension = extension.Substring(1);
|
||||
if (!InExtensionFormats.ContainsKey(extension) && reportErrors)
|
||||
{
|
||||
if (FileChecker.ThrowExceptions)
|
||||
throw new ArgumentException("Extension \"" + extension + "\" is not a supported archive file name extension.");
|
||||
else return InArchiveFormat.None;
|
||||
|
||||
}
|
||||
return InExtensionFormats[extension];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace SevenZip
|
||||
{
|
||||
/// <summary>
|
||||
/// The set of features supported by the library.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum LibraryFeature : uint
|
||||
{
|
||||
/// <summary>
|
||||
/// Default feature.
|
||||
/// </summary>
|
||||
None = 0,
|
||||
/// <summary>
|
||||
/// The library can extract 7zip archives compressed with LZMA method.
|
||||
/// </summary>
|
||||
Extract7z = 0x1,
|
||||
/// <summary>
|
||||
/// The library can extract 7zip archives compressed with LZMA2 method.
|
||||
/// </summary>
|
||||
Extract7zLZMA2 = 0x2,
|
||||
/// <summary>
|
||||
/// The library can extract 7z archives compressed with all known methods.
|
||||
/// </summary>
|
||||
Extract7zAll = Extract7z|Extract7zLZMA2|0x4,
|
||||
/// <summary>
|
||||
/// The library can extract zip archives.
|
||||
/// </summary>
|
||||
ExtractZip = 0x8,
|
||||
/// <summary>
|
||||
/// The library can extract rar archives.
|
||||
/// </summary>
|
||||
ExtractRar = 0x10,
|
||||
/// <summary>
|
||||
/// The library can extract gzip archives.
|
||||
/// </summary>
|
||||
ExtractGzip = 0x20,
|
||||
/// <summary>
|
||||
/// The library can extract bzip2 archives.
|
||||
/// </summary>
|
||||
ExtractBzip2 = 0x40,
|
||||
/// <summary>
|
||||
/// The library can extract tar archives.
|
||||
/// </summary>
|
||||
ExtractTar = 0x80,
|
||||
/// <summary>
|
||||
/// The library can extract xz archives.
|
||||
/// </summary>
|
||||
ExtractXz = 0x100,
|
||||
/// <summary>
|
||||
/// The library can extract all types of archives supported.
|
||||
/// </summary>
|
||||
ExtractAll = Extract7zAll|ExtractZip|ExtractRar|ExtractGzip|ExtractBzip2|ExtractTar|ExtractXz,
|
||||
/// <summary>
|
||||
/// The library can compress data to 7zip archives with LZMA method.
|
||||
/// </summary>
|
||||
Compress7z = 0x200,
|
||||
/// <summary>
|
||||
/// The library can compress data to 7zip archives with LZMA2 method.
|
||||
/// </summary>
|
||||
Compress7zLZMA2 = 0x400,
|
||||
/// <summary>
|
||||
/// The library can compress data to 7zip archives with all methods known.
|
||||
/// </summary>
|
||||
Compress7zAll = Compress7z|Compress7zLZMA2|0x800,
|
||||
/// <summary>
|
||||
/// The library can compress data to tar archives.
|
||||
/// </summary>
|
||||
CompressTar = 0x1000,
|
||||
/// <summary>
|
||||
/// The library can compress data to gzip archives.
|
||||
/// </summary>
|
||||
CompressGzip = 0x2000,
|
||||
/// <summary>
|
||||
/// The library can compress data to bzip2 archives.
|
||||
/// </summary>
|
||||
CompressBzip2 = 0x4000,
|
||||
/// <summary>
|
||||
/// The library can compress data to xz archives.
|
||||
/// </summary>
|
||||
CompressXz = 0x8000,
|
||||
/// <summary>
|
||||
/// The library can compress data to zip archives.
|
||||
/// </summary>
|
||||
CompressZip = 0x10000,
|
||||
/// <summary>
|
||||
/// The library can compress data to all types of archives supported.
|
||||
/// </summary>
|
||||
CompressAll = Compress7zAll|CompressTar|CompressGzip|CompressBzip2|CompressXz|CompressZip,
|
||||
/// <summary>
|
||||
/// The library can modify archives.
|
||||
/// </summary>
|
||||
Modify = 0x20000
|
||||
}
|
||||
}
|
|
@ -1,591 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using BizHawk.Common;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
#if !WINCE && !MONO
|
||||
using System.Configuration;
|
||||
using System.Diagnostics;
|
||||
using System.Security.Permissions;
|
||||
#endif
|
||||
#if WINCE
|
||||
using OpenNETCF.Diagnostics;
|
||||
#endif
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
#if MONO
|
||||
using SevenZip.Mono.COM;
|
||||
#endif
|
||||
|
||||
namespace SevenZip
|
||||
{
|
||||
#if UNMANAGED
|
||||
/// <summary>
|
||||
/// 7-zip library low-level wrapper.
|
||||
/// </summary>
|
||||
internal static class SevenZipLibraryManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Synchronization root for all locking.
|
||||
/// </summary>
|
||||
private static readonly object _syncRoot = new object();
|
||||
|
||||
#if !WINCE && !MONO
|
||||
|
||||
//zero 07-jul-2014 - no sense for this industrial strength enterprise bullshit. lets just hack it to our needs.
|
||||
//NOTE - I think we hacked this originally.. it was this way from the initial commit, perhaps it had already been modified for our use
|
||||
|
||||
/// <summary>
|
||||
/// Path to the 7-zip dll.
|
||||
/// </summary>
|
||||
/// <remarks>7zxa.dll supports only decoding from .7z archives.
|
||||
/// Features of 7za.dll:
|
||||
/// - Supporting 7z format;
|
||||
/// - Built encoders: LZMA, PPMD, BCJ, BCJ2, COPY, AES-256 Encryption.
|
||||
/// - Built decoders: LZMA, PPMD, BCJ, BCJ2, COPY, AES-256 Encryption, BZip2, Deflate.
|
||||
/// 7z.dll (from the 7-zip distribution) supports every InArchiveFormat for encoding and decoding.
|
||||
/// </remarks>
|
||||
//private static string _libraryFileName = ConfigurationManager.AppSettings["7zLocation"] ?? Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "7z.dll");
|
||||
private static string _libraryFileName = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "dll\\7z.dll");
|
||||
|
||||
#endif
|
||||
#if WINCE
|
||||
private static string _libraryFileName =
|
||||
Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase), "7z.dll");
|
||||
#endif
|
||||
/// <summary>
|
||||
/// 7-zip library handle.
|
||||
/// </summary>
|
||||
private static IntPtr _modulePtr;
|
||||
|
||||
/// <summary>
|
||||
/// 7-zip library features.
|
||||
/// </summary>
|
||||
private static LibraryFeature? _features;
|
||||
|
||||
private static Dictionary<object, Dictionary<InArchiveFormat, IInArchive>> _inArchives;
|
||||
#if COMPRESS
|
||||
private static Dictionary<object, Dictionary<OutArchiveFormat, IOutArchive>> _outArchives;
|
||||
#endif
|
||||
private static int _totalUsers;
|
||||
|
||||
// private static string _LibraryVersion;
|
||||
private static bool? _modifyCapabale;
|
||||
|
||||
private static readonly OSTailoredCode.ILinkedLibManager libLoader = OSTailoredCode.LinkedLibManager;
|
||||
|
||||
private static void InitUserInFormat(object user, InArchiveFormat format)
|
||||
{
|
||||
if (!_inArchives.ContainsKey(user))
|
||||
{
|
||||
_inArchives.Add(user, new Dictionary<InArchiveFormat, IInArchive>());
|
||||
}
|
||||
if (!_inArchives[user].ContainsKey(format))
|
||||
{
|
||||
_inArchives[user].Add(format, null);
|
||||
_totalUsers++;
|
||||
}
|
||||
}
|
||||
|
||||
#if COMPRESS
|
||||
private static void InitUserOutFormat(object user, OutArchiveFormat format)
|
||||
{
|
||||
if (!_outArchives.ContainsKey(user))
|
||||
{
|
||||
_outArchives.Add(user, new Dictionary<OutArchiveFormat, IOutArchive>());
|
||||
}
|
||||
if (!_outArchives[user].ContainsKey(format))
|
||||
{
|
||||
_outArchives[user].Add(format, null);
|
||||
_totalUsers++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private static void Init()
|
||||
{
|
||||
_inArchives = new Dictionary<object, Dictionary<InArchiveFormat, IInArchive>>();
|
||||
#if COMPRESS
|
||||
_outArchives = new Dictionary<object, Dictionary<OutArchiveFormat, IOutArchive>>();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the 7-zip library if necessary and adds user to the reference list
|
||||
/// </summary>
|
||||
/// <param name="user">Caller of the function</param>
|
||||
/// <param name="format">Archive format</param>
|
||||
public static void LoadLibrary(object user, Enum format)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_inArchives == null
|
||||
#if COMPRESS
|
||||
|| _outArchives == null
|
||||
#endif
|
||||
)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
#if !WINCE && !MONO
|
||||
if (_modulePtr == IntPtr.Zero)
|
||||
{
|
||||
//zero 29-oct-2012 - this check isnt useful since LoadOrNull can pretty much check for the same thing. and it wrecks our dll relocation scheme
|
||||
//if (!File.Exists(_libraryFileName))
|
||||
//{
|
||||
// throw new SevenZipLibraryException("DLL file does not exist.");
|
||||
//}
|
||||
var newPtr = libLoader.LoadOrNull(_libraryFileName);
|
||||
if (!newPtr.HasValue)
|
||||
{
|
||||
//try a different directory
|
||||
newPtr = libLoader.LoadOrNull(Path.Combine(Path.Combine(Path.GetDirectoryName(_libraryFileName), "dll"), "7z.dll"));
|
||||
if (!newPtr.HasValue) throw new SevenZipLibraryException("failed to load library.");
|
||||
}
|
||||
_modulePtr = newPtr.Value;
|
||||
|
||||
if (libLoader.GetProcAddr(_modulePtr, "GetHandlerProperty") == IntPtr.Zero)
|
||||
{
|
||||
libLoader.FreeByPtr(_modulePtr);
|
||||
throw new SevenZipLibraryException("library is invalid.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (format is InArchiveFormat)
|
||||
{
|
||||
InitUserInFormat(user, (InArchiveFormat) format);
|
||||
return;
|
||||
}
|
||||
#if COMPRESS
|
||||
if (format is OutArchiveFormat)
|
||||
{
|
||||
InitUserOutFormat(user, (OutArchiveFormat) format);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
throw new ArgumentException("Enum " + format + " is not a valid archive format attribute!");
|
||||
}
|
||||
}
|
||||
|
||||
/*/// <summary>
|
||||
/// Gets the native 7zip library version string.
|
||||
/// </summary>
|
||||
public static string LibraryVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
if (String.IsNullOrEmpty(_LibraryVersion))
|
||||
{
|
||||
FileVersionInfo dllVersionInfo = FileVersionInfo.GetVersionInfo(_libraryFileName);
|
||||
_LibraryVersion = String.Format(
|
||||
System.Globalization.CultureInfo.CurrentCulture,
|
||||
"{0}.{1}",
|
||||
dllVersionInfo.FileMajorPart, dllVersionInfo.FileMinorPart);
|
||||
}
|
||||
return _LibraryVersion;
|
||||
}
|
||||
}*/
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value indicating whether the library supports modifying archives.
|
||||
/// </summary>
|
||||
public static bool ModifyCapable
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (!_modifyCapabale.HasValue)
|
||||
{
|
||||
#if !WINCE && !MONO
|
||||
FileVersionInfo dllVersionInfo = FileVersionInfo.GetVersionInfo(_libraryFileName);
|
||||
_modifyCapabale = dllVersionInfo.FileMajorPart >= 9;
|
||||
#else
|
||||
_modifyCapabale = true;
|
||||
#endif
|
||||
}
|
||||
return _modifyCapabale.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
//static readonly string Namespace = Assembly.GetExecutingAssembly().GetManifestResourceNames()[0].Split('.')[0];
|
||||
static readonly string Namespace = "BizHawk"; //Remove dirty hack above
|
||||
|
||||
private static string GetResourceString(string str)
|
||||
{
|
||||
return Namespace + ".arch." + str;
|
||||
}
|
||||
|
||||
private static bool ExtractionBenchmark(string archiveFileName, Stream outStream,
|
||||
ref LibraryFeature? features, LibraryFeature testedFeature)
|
||||
{
|
||||
var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(
|
||||
GetResourceString(archiveFileName));
|
||||
try
|
||||
{
|
||||
using (var extr = new SevenZipExtractor(stream))
|
||||
{
|
||||
extr.ExtractFile(0, outStream);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
features |= testedFeature;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool CompressionBenchmark(Stream inStream, Stream outStream,
|
||||
OutArchiveFormat format, CompressionMethod method,
|
||||
ref LibraryFeature? features, LibraryFeature testedFeature)
|
||||
{
|
||||
try
|
||||
{
|
||||
var compr = new SevenZipCompressor { ArchiveFormat = format, CompressionMethod = method };
|
||||
compr.CompressStream(inStream, outStream);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
features |= testedFeature;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static LibraryFeature CurrentLibraryFeatures
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_features != null && _features.HasValue)
|
||||
{
|
||||
return _features.Value;
|
||||
}
|
||||
_features = LibraryFeature.None;
|
||||
#region Benchmark
|
||||
#region Extraction features
|
||||
using (var outStream = new MemoryStream())
|
||||
{
|
||||
ExtractionBenchmark("Test.lzma.7z", outStream, ref _features, LibraryFeature.Extract7z);
|
||||
ExtractionBenchmark("Test.lzma2.7z", outStream, ref _features, LibraryFeature.Extract7zLZMA2);
|
||||
int i = 0;
|
||||
if (ExtractionBenchmark("Test.bzip2.7z", outStream, ref _features, _features.Value))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
if (ExtractionBenchmark("Test.ppmd.7z", outStream, ref _features, _features.Value))
|
||||
{
|
||||
i++;
|
||||
if (i == 2 && (_features & LibraryFeature.Extract7z) != 0 &&
|
||||
(_features & LibraryFeature.Extract7zLZMA2) != 0)
|
||||
{
|
||||
_features |= LibraryFeature.Extract7zAll;
|
||||
}
|
||||
}
|
||||
ExtractionBenchmark("Test.rar", outStream, ref _features, LibraryFeature.ExtractRar);
|
||||
ExtractionBenchmark("Test.tar", outStream, ref _features, LibraryFeature.ExtractTar);
|
||||
ExtractionBenchmark("Test.txt.bz2", outStream, ref _features, LibraryFeature.ExtractBzip2);
|
||||
ExtractionBenchmark("Test.txt.gz", outStream, ref _features, LibraryFeature.ExtractGzip);
|
||||
ExtractionBenchmark("Test.txt.xz", outStream, ref _features, LibraryFeature.ExtractXz);
|
||||
ExtractionBenchmark("Test.zip", outStream, ref _features, LibraryFeature.ExtractZip);
|
||||
}
|
||||
#endregion
|
||||
#region Compression features
|
||||
using (var inStream = new MemoryStream())
|
||||
{
|
||||
inStream.Write(Encoding.UTF8.GetBytes("Test"), 0, 4);
|
||||
using (var outStream = new MemoryStream())
|
||||
{
|
||||
CompressionBenchmark(inStream, outStream,
|
||||
OutArchiveFormat.SevenZip, CompressionMethod.Lzma,
|
||||
ref _features, LibraryFeature.Compress7z);
|
||||
CompressionBenchmark(inStream, outStream,
|
||||
OutArchiveFormat.SevenZip, CompressionMethod.Lzma2,
|
||||
ref _features, LibraryFeature.Compress7zLZMA2);
|
||||
int i = 0;
|
||||
if (CompressionBenchmark(inStream, outStream,
|
||||
OutArchiveFormat.SevenZip, CompressionMethod.BZip2,
|
||||
ref _features, _features.Value))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
if (CompressionBenchmark(inStream, outStream,
|
||||
OutArchiveFormat.SevenZip, CompressionMethod.Ppmd,
|
||||
ref _features, _features.Value))
|
||||
{
|
||||
i++;
|
||||
if (i == 2 && (_features & LibraryFeature.Compress7z) != 0 &&
|
||||
(_features & LibraryFeature.Compress7zLZMA2) != 0)
|
||||
{
|
||||
_features |= LibraryFeature.Compress7zAll;
|
||||
}
|
||||
}
|
||||
CompressionBenchmark(inStream, outStream,
|
||||
OutArchiveFormat.Zip, CompressionMethod.Default,
|
||||
ref _features, LibraryFeature.CompressZip);
|
||||
CompressionBenchmark(inStream, outStream,
|
||||
OutArchiveFormat.BZip2, CompressionMethod.Default,
|
||||
ref _features, LibraryFeature.CompressBzip2);
|
||||
CompressionBenchmark(inStream, outStream,
|
||||
OutArchiveFormat.GZip, CompressionMethod.Default,
|
||||
ref _features, LibraryFeature.CompressGzip);
|
||||
CompressionBenchmark(inStream, outStream,
|
||||
OutArchiveFormat.Tar, CompressionMethod.Default,
|
||||
ref _features, LibraryFeature.CompressTar);
|
||||
CompressionBenchmark(inStream, outStream,
|
||||
OutArchiveFormat.XZ, CompressionMethod.Default,
|
||||
ref _features, LibraryFeature.CompressXz);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
if (ModifyCapable && (_features.Value & LibraryFeature.Compress7z) != 0)
|
||||
{
|
||||
_features |= LibraryFeature.Modify;
|
||||
}
|
||||
return _features.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes user from reference list and frees the 7-zip library if it becomes empty
|
||||
/// </summary>
|
||||
/// <param name="user">Caller of the function</param>
|
||||
/// <param name="format">Archive format</param>
|
||||
public static void FreeLibrary(object user, Enum format)
|
||||
{
|
||||
#if !WINCE && !MONO
|
||||
var sp = new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);
|
||||
sp.Demand();
|
||||
#endif
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_modulePtr != IntPtr.Zero)
|
||||
{
|
||||
if (format is InArchiveFormat)
|
||||
{
|
||||
if (_inArchives != null && _inArchives.ContainsKey(user) &&
|
||||
_inArchives[user].ContainsKey((InArchiveFormat) format) &&
|
||||
_inArchives[user][(InArchiveFormat) format] != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Marshal.ReleaseComObject(_inArchives[user][(InArchiveFormat) format]);
|
||||
}
|
||||
catch (InvalidComObjectException) {}
|
||||
_inArchives[user].Remove((InArchiveFormat) format);
|
||||
_totalUsers--;
|
||||
if (_inArchives[user].Count == 0)
|
||||
{
|
||||
_inArchives.Remove(user);
|
||||
}
|
||||
}
|
||||
}
|
||||
#if COMPRESS
|
||||
if (format is OutArchiveFormat)
|
||||
{
|
||||
if (_outArchives != null && _outArchives.ContainsKey(user) &&
|
||||
_outArchives[user].ContainsKey((OutArchiveFormat) format) &&
|
||||
_outArchives[user][(OutArchiveFormat) format] != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Marshal.ReleaseComObject(_outArchives[user][(OutArchiveFormat) format]);
|
||||
}
|
||||
catch (InvalidComObjectException) {}
|
||||
_outArchives[user].Remove((OutArchiveFormat) format);
|
||||
_totalUsers--;
|
||||
if (_outArchives[user].Count == 0)
|
||||
{
|
||||
_outArchives.Remove(user);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if ((_inArchives == null || _inArchives.Count == 0)
|
||||
#if COMPRESS
|
||||
&& (_outArchives == null || _outArchives.Count == 0)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
_inArchives = null;
|
||||
#if COMPRESS
|
||||
_outArchives = null;
|
||||
#endif
|
||||
if (_totalUsers == 0)
|
||||
{
|
||||
#if !WINCE && !MONO
|
||||
libLoader.FreeByPtr(_modulePtr);
|
||||
|
||||
#endif
|
||||
_modulePtr = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets IInArchive interface to extract 7-zip archives.
|
||||
/// </summary>
|
||||
/// <param name="format">Archive format.</param>
|
||||
/// <param name="user">Archive format user.</param>
|
||||
public static IInArchive InArchive(InArchiveFormat format, object user)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_inArchives[user][format] == null)
|
||||
{
|
||||
#if !WINCE && !MONO
|
||||
var sp = new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);
|
||||
sp.Demand();
|
||||
|
||||
if (_modulePtr == IntPtr.Zero)
|
||||
{
|
||||
LoadLibrary(user, format);
|
||||
if (_modulePtr == IntPtr.Zero)
|
||||
{
|
||||
throw new SevenZipLibraryException();
|
||||
}
|
||||
}
|
||||
var createObject = (NativeMethods.CreateObjectDelegate)
|
||||
Marshal.GetDelegateForFunctionPointer(
|
||||
libLoader.GetProcAddr(_modulePtr, "CreateObject"),
|
||||
typeof(NativeMethods.CreateObjectDelegate));
|
||||
if (createObject == null)
|
||||
{
|
||||
throw new SevenZipLibraryException();
|
||||
}
|
||||
#endif
|
||||
object result;
|
||||
Guid interfaceId =
|
||||
#if !WINCE && !MONO
|
||||
typeof(IInArchive).GUID;
|
||||
#else
|
||||
new Guid(((GuidAttribute)typeof(IInArchive).GetCustomAttributes(typeof(GuidAttribute), false)[0]).Value);
|
||||
#endif
|
||||
Guid classID = Formats.InFormatGuids[format];
|
||||
try
|
||||
{
|
||||
#if !WINCE && !MONO
|
||||
createObject(ref classID, ref interfaceId, out result);
|
||||
#elif !MONO
|
||||
NativeMethods.CreateCOMObject(ref classID, ref interfaceId, out result);
|
||||
#else
|
||||
result = SevenZip.Mono.Factory.CreateInterface<IInArchive>(user, classID, interfaceId);
|
||||
#endif
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new SevenZipLibraryException("Your 7-zip library does not support this archive type.");
|
||||
}
|
||||
InitUserInFormat(user, format);
|
||||
_inArchives[user][format] = result as IInArchive;
|
||||
}
|
||||
return _inArchives[user][format];
|
||||
#if !WINCE && !MONO
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if COMPRESS
|
||||
/// <summary>
|
||||
/// Gets IOutArchive interface to pack 7-zip archives.
|
||||
/// </summary>
|
||||
/// <param name="format">Archive format.</param>
|
||||
/// <param name="user">Archive format user.</param>
|
||||
public static IOutArchive OutArchive(OutArchiveFormat format, object user)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_outArchives[user][format] == null)
|
||||
{
|
||||
#if !WINCE && !MONO
|
||||
var sp = new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);
|
||||
sp.Demand();
|
||||
if (_modulePtr == IntPtr.Zero)
|
||||
{
|
||||
throw new SevenZipLibraryException();
|
||||
}
|
||||
var createObject = (NativeMethods.CreateObjectDelegate)
|
||||
Marshal.GetDelegateForFunctionPointer(
|
||||
libLoader.GetProcAddr(_modulePtr, "CreateObject"),
|
||||
typeof(NativeMethods.CreateObjectDelegate));
|
||||
if (createObject == null)
|
||||
{
|
||||
throw new SevenZipLibraryException();
|
||||
}
|
||||
#endif
|
||||
object result;
|
||||
Guid interfaceId =
|
||||
#if !WINCE && !MONO
|
||||
typeof(IOutArchive).GUID;
|
||||
#else
|
||||
new Guid(((GuidAttribute)typeof(IOutArchive).GetCustomAttributes(typeof(GuidAttribute), false)[0]).Value);
|
||||
#endif
|
||||
Guid classID = Formats.OutFormatGuids[format];
|
||||
try
|
||||
{
|
||||
#if !WINCE && !MONO
|
||||
createObject(ref classID, ref interfaceId, out result);
|
||||
#elif !MONO
|
||||
NativeMethods.CreateCOMObject(ref classID, ref interfaceId, out result);
|
||||
#else
|
||||
result = SevenZip.Mono.Factory.CreateInterface<IOutArchive>(classID, interfaceId, user);
|
||||
#endif
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new SevenZipLibraryException("Your 7-zip library does not support this archive type.");
|
||||
}
|
||||
InitUserOutFormat(user, format);
|
||||
_outArchives[user][format] = result as IOutArchive;
|
||||
}
|
||||
return _outArchives[user][format];
|
||||
#if !WINCE && !MONO
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif
|
||||
#if !WINCE && !MONO
|
||||
public static void SetLibraryPath(string libraryPath)
|
||||
{
|
||||
if (_modulePtr != IntPtr.Zero && !Path.GetFullPath(libraryPath).Equals(
|
||||
Path.GetFullPath(_libraryFileName), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new SevenZipLibraryException(
|
||||
"can not change the library path while the library \"" + _libraryFileName + "\" is being used.");
|
||||
}
|
||||
if (!File.Exists(libraryPath))
|
||||
{
|
||||
throw new SevenZipLibraryException(
|
||||
"can not change the library path because the file \"" + libraryPath + "\" does not exist.");
|
||||
}
|
||||
_libraryFileName = libraryPath;
|
||||
_features = null;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -1,240 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using SevenZip.Sdk.Compression.Lzma;
|
||||
|
||||
namespace SevenZip
|
||||
{
|
||||
#if LZMA_STREAM
|
||||
/// <summary>
|
||||
/// The stream which decompresses data with LZMA on the fly.
|
||||
/// </summary>
|
||||
public class LzmaDecodeStream : Stream
|
||||
{
|
||||
private readonly MemoryStream _buffer = new MemoryStream();
|
||||
private readonly Decoder _decoder = new Decoder();
|
||||
private readonly Stream _input;
|
||||
private byte[] _commonProperties;
|
||||
private bool _error;
|
||||
private bool _firstChunkRead;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the LzmaDecodeStream class.
|
||||
/// </summary>
|
||||
/// <param name="encodedStream">A compressed stream.</param>
|
||||
public LzmaDecodeStream(Stream encodedStream)
|
||||
{
|
||||
if (!encodedStream.CanRead)
|
||||
{
|
||||
throw new ArgumentException("The specified stream can not read.", "encodedStream");
|
||||
}
|
||||
_input = encodedStream;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the chunk size.
|
||||
/// </summary>
|
||||
public int ChunkSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return (int) _buffer.Length;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the current stream supports reading.
|
||||
/// </summary>
|
||||
public override bool CanRead
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the current stream supports seeking.
|
||||
/// </summary>
|
||||
public override bool CanSeek
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the current stream supports writing.
|
||||
/// </summary>
|
||||
public override bool CanWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length in bytes of the output stream.
|
||||
/// </summary>
|
||||
public override long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_input.CanSeek)
|
||||
{
|
||||
return _input.Length;
|
||||
}
|
||||
return _buffer.Length;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the position within the output stream.
|
||||
/// </summary>
|
||||
public override long Position
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_input.CanSeek)
|
||||
{
|
||||
return _input.Position;
|
||||
}
|
||||
return _buffer.Position;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadChunk()
|
||||
{
|
||||
long size;
|
||||
byte[] properties;
|
||||
try
|
||||
{
|
||||
properties = SevenZipExtractor.GetLzmaProperties(_input, out size);
|
||||
}
|
||||
catch (LzmaException)
|
||||
{
|
||||
_error = true;
|
||||
return;
|
||||
}
|
||||
if (!_firstChunkRead)
|
||||
{
|
||||
_commonProperties = properties;
|
||||
}
|
||||
if (_commonProperties[0] != properties[0] ||
|
||||
_commonProperties[1] != properties[1] ||
|
||||
_commonProperties[2] != properties[2] ||
|
||||
_commonProperties[3] != properties[3] ||
|
||||
_commonProperties[4] != properties[4])
|
||||
{
|
||||
_error = true;
|
||||
return;
|
||||
}
|
||||
if (_buffer.Capacity < (int) size)
|
||||
{
|
||||
_buffer.Capacity = (int) size;
|
||||
}
|
||||
_buffer.SetLength(size);
|
||||
_decoder.SetDecoderProperties(properties);
|
||||
_buffer.Position = 0;
|
||||
_decoder.Code(
|
||||
_input, _buffer, 0, size, null);
|
||||
_buffer.Position = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does nothing.
|
||||
/// </summary>
|
||||
public override void Flush() {}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a sequence of bytes from the current stream and decompresses data if necessary.
|
||||
/// </summary>
|
||||
/// <param name="buffer">An array of bytes.</param>
|
||||
/// <param name="offset">The zero-based byte offset in buffer at which to begin storing the data read from the current stream.</param>
|
||||
/// <param name="count">The maximum number of bytes to be read from the current stream.</param>
|
||||
/// <returns>The total number of bytes read into the buffer.</returns>
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (_error)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_firstChunkRead)
|
||||
{
|
||||
ReadChunk();
|
||||
_firstChunkRead = true;
|
||||
}
|
||||
int readCount = 0;
|
||||
while (count > _buffer.Length - _buffer.Position && !_error)
|
||||
{
|
||||
var buf = new byte[_buffer.Length - _buffer.Position];
|
||||
_buffer.Read(buf, 0, buf.Length);
|
||||
buf.CopyTo(buffer, offset);
|
||||
offset += buf.Length;
|
||||
count -= buf.Length;
|
||||
readCount += buf.Length;
|
||||
ReadChunk();
|
||||
}
|
||||
if (!_error)
|
||||
{
|
||||
_buffer.Read(buffer, offset, count);
|
||||
readCount += count;
|
||||
}
|
||||
return readCount;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the position within the current stream.
|
||||
/// </summary>
|
||||
/// <param name="offset">A byte offset relative to the origin parameter.</param>
|
||||
/// <param name="origin">A value of type System.IO.SeekOrigin indicating the reference point used to obtain the new position.</param>
|
||||
/// <returns>The new position within the current stream.</returns>
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the length of the current stream.
|
||||
/// </summary>
|
||||
/// <param name="value">The desired length of the current stream in bytes.</param>
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a sequence of bytes to the current stream.
|
||||
/// </summary>
|
||||
/// <param name="buffer">An array of bytes.</param>
|
||||
/// <param name="offset">The zero-based byte offset in buffer at which to begin storing the data read from the current stream.</param>
|
||||
/// <param name="count">The maximum number of bytes to be read from the current stream.</param>
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -1,304 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using SevenZip.Sdk.Compression.Lzma;
|
||||
|
||||
namespace SevenZip
|
||||
{
|
||||
#if LZMA_STREAM
|
||||
#if COMPRESS
|
||||
/// <summary>
|
||||
/// The stream which compresses data with LZMA on the fly.
|
||||
/// </summary>
|
||||
public class LzmaEncodeStream : Stream
|
||||
{
|
||||
private const int MAX_BUFFER_CAPACITY = 1 << 30; //1 Gb
|
||||
private readonly MemoryStream _buffer = new MemoryStream();
|
||||
private readonly int _bufferCapacity = 1 << 18; //256 kb
|
||||
private readonly bool _ownOutput;
|
||||
private bool _disposed;
|
||||
private Encoder _lzmaEncoder;
|
||||
private Stream _output;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the LzmaEncodeStream class.
|
||||
/// </summary>
|
||||
public LzmaEncodeStream()
|
||||
{
|
||||
_output = new MemoryStream();
|
||||
_ownOutput = true;
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the LzmaEncodeStream class.
|
||||
/// </summary>
|
||||
/// <param name="bufferCapacity">The buffer size. The bigger size, the better compression.</param>
|
||||
public LzmaEncodeStream(int bufferCapacity)
|
||||
{
|
||||
_output = new MemoryStream();
|
||||
_ownOutput = true;
|
||||
if (bufferCapacity > MAX_BUFFER_CAPACITY)
|
||||
{
|
||||
throw new ArgumentException("Too large capacity.", "bufferCapacity");
|
||||
}
|
||||
_bufferCapacity = bufferCapacity;
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the LzmaEncodeStream class.
|
||||
/// </summary>
|
||||
/// <param name="outputStream">An output stream which supports writing.</param>
|
||||
public LzmaEncodeStream(Stream outputStream)
|
||||
{
|
||||
if (!outputStream.CanWrite)
|
||||
{
|
||||
throw new ArgumentException("The specified stream can not write.", "outputStream");
|
||||
}
|
||||
_output = outputStream;
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the LzmaEncodeStream class.
|
||||
/// </summary>
|
||||
/// <param name="outputStream">An output stream which supports writing.</param>
|
||||
/// <param name="bufferCapacity">A buffer size. The bigger size, the better compression.</param>
|
||||
public LzmaEncodeStream(Stream outputStream, int bufferCapacity)
|
||||
{
|
||||
if (!outputStream.CanWrite)
|
||||
{
|
||||
throw new ArgumentException("The specified stream can not write.", "outputStream");
|
||||
}
|
||||
_output = outputStream;
|
||||
if (bufferCapacity > 1 << 30)
|
||||
{
|
||||
throw new ArgumentException("Too large capacity.", "bufferCapacity");
|
||||
}
|
||||
_bufferCapacity = bufferCapacity;
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the current stream supports reading.
|
||||
/// </summary>
|
||||
public override bool CanRead
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the current stream supports seeking.
|
||||
/// </summary>
|
||||
public override bool CanSeek
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the current stream supports writing.
|
||||
/// </summary>
|
||||
public override bool CanWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
DisposedCheck();
|
||||
return _buffer.CanWrite;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length in bytes of the output stream.
|
||||
/// </summary>
|
||||
public override long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
DisposedCheck();
|
||||
if (_output.CanSeek)
|
||||
{
|
||||
return _output.Length;
|
||||
}
|
||||
return _buffer.Position;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the position within the output stream.
|
||||
/// </summary>
|
||||
public override long Position
|
||||
{
|
||||
get
|
||||
{
|
||||
DisposedCheck();
|
||||
if (_output.CanSeek)
|
||||
{
|
||||
return _output.Position;
|
||||
}
|
||||
return _buffer.Position;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
_buffer.Capacity = _bufferCapacity;
|
||||
SevenZipCompressor.LzmaDictionarySize = _bufferCapacity;
|
||||
_lzmaEncoder = new Encoder();
|
||||
SevenZipCompressor.WriteLzmaProperties(_lzmaEncoder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checked whether the class was disposed.
|
||||
/// </summary>
|
||||
/// <exception cref="System.ObjectDisposedException" />
|
||||
private void DisposedCheck()
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
throw new ObjectDisposedException("SevenZipExtractor");
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteChunk()
|
||||
{
|
||||
_lzmaEncoder.WriteCoderProperties(_output);
|
||||
long streamSize = _buffer.Position;
|
||||
if (_buffer.Length != _buffer.Position)
|
||||
{
|
||||
_buffer.SetLength(_buffer.Position);
|
||||
}
|
||||
_buffer.Position = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
_output.WriteByte((byte) (streamSize >> (8*i)));
|
||||
}
|
||||
_lzmaEncoder.Code(_buffer, _output, -1, -1, null);
|
||||
_buffer.Position = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the LzmaEncodeStream to the LzmaDecodeStream to read data.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public LzmaDecodeStream ToDecodeStream()
|
||||
{
|
||||
DisposedCheck();
|
||||
Flush();
|
||||
return new LzmaDecodeStream(_output);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all buffers for this stream and causes any buffered data to be compressed and written.
|
||||
/// </summary>
|
||||
public override void Flush()
|
||||
{
|
||||
DisposedCheck();
|
||||
WriteChunk();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases all unmanaged resources used by LzmaEncodeStream.
|
||||
/// </summary>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
Flush();
|
||||
_buffer.Close();
|
||||
if (_ownOutput)
|
||||
{
|
||||
_output.Dispose();
|
||||
}
|
||||
_output = null;
|
||||
}
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read.
|
||||
/// </summary>
|
||||
/// <param name="buffer">An array of bytes.</param>
|
||||
/// <param name="offset">The zero-based byte offset in buffer at which to begin storing the data read from the current stream.</param>
|
||||
/// <param name="count">The maximum number of bytes to be read from the current stream.</param>
|
||||
/// <returns>The total number of bytes read into the buffer.</returns>
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
DisposedCheck();
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the position within the current stream.
|
||||
/// </summary>
|
||||
/// <param name="offset">A byte offset relative to the origin parameter.</param>
|
||||
/// <param name="origin">A value of type System.IO.SeekOrigin indicating the reference point used to obtain the new position.</param>
|
||||
/// <returns>The new position within the current stream.</returns>
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
DisposedCheck();
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the length of the current stream.
|
||||
/// </summary>
|
||||
/// <param name="value">The desired length of the current stream in bytes.</param>
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
DisposedCheck();
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a sequence of bytes to the current stream and compresses it if necessary.
|
||||
/// </summary>
|
||||
/// <param name="buffer">An array of bytes.</param>
|
||||
/// <param name="offset">The zero-based byte offset in buffer at which to begin storing the data read from the current stream.</param>
|
||||
/// <param name="count">The maximum number of bytes to be read from the current stream.</param>
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
DisposedCheck();
|
||||
int dataLength = Math.Min(buffer.Length - offset, count);
|
||||
while (_buffer.Position + dataLength >= _bufferCapacity)
|
||||
{
|
||||
int length = _bufferCapacity - (int) _buffer.Position;
|
||||
_buffer.Write(buffer, offset, length);
|
||||
offset = length + offset;
|
||||
dataLength -= length;
|
||||
WriteChunk();
|
||||
}
|
||||
_buffer.Write(buffer, offset, dataLength);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using SevenZip.Sdk;
|
||||
|
||||
namespace SevenZip
|
||||
{
|
||||
/// <summary>
|
||||
/// Callback to implement the ICodeProgress interface
|
||||
/// </summary>
|
||||
internal sealed class LzmaProgressCallback : ICodeProgress
|
||||
{
|
||||
private readonly long _inSize;
|
||||
private float _oldPercentDone;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the LzmaProgressCallback class
|
||||
/// </summary>
|
||||
/// <param name="inSize">The input size</param>
|
||||
/// <param name="working">Progress event handler</param>
|
||||
public LzmaProgressCallback(long inSize, EventHandler<ProgressEventArgs> working)
|
||||
{
|
||||
_inSize = inSize;
|
||||
Working += working;
|
||||
}
|
||||
|
||||
#region ICodeProgress Members
|
||||
|
||||
/// <summary>
|
||||
/// Sets the progress
|
||||
/// </summary>
|
||||
/// <param name="inSize">The processed input size</param>
|
||||
/// <param name="outSize">The processed output size</param>
|
||||
public void SetProgress(long inSize, long outSize)
|
||||
{
|
||||
if (Working != null)
|
||||
{
|
||||
float newPercentDone = (inSize + 0.0f) / _inSize;
|
||||
float delta = newPercentDone - _oldPercentDone;
|
||||
if (delta * 100 < 1.0)
|
||||
{
|
||||
delta = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_oldPercentDone = newPercentDone;
|
||||
}
|
||||
Working(this, new ProgressEventArgs(
|
||||
PercentDoneEventArgs.ProducePercentDone(newPercentDone),
|
||||
delta > 0 ? PercentDoneEventArgs.ProducePercentDone(delta) : (byte)0));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public event EventHandler<ProgressEventArgs> Working;
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
#if MONO
|
||||
using SevenZip.Mono.COM;
|
||||
#endif
|
||||
|
||||
namespace SevenZip
|
||||
{
|
||||
#if UNMANAGED
|
||||
internal static class NativeMethods
|
||||
{
|
||||
#if !WINCE && !MONO
|
||||
#region Delegates
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||
public delegate int CreateObjectDelegate(
|
||||
[In] ref Guid classID,
|
||||
[In] ref Guid interfaceID,
|
||||
[MarshalAs(UnmanagedType.Interface)] out object outObject);
|
||||
|
||||
#endregion
|
||||
#endif
|
||||
|
||||
#if WINCE
|
||||
[DllImport("7z.dll", EntryPoint="CreateObject")]
|
||||
public static extern int CreateCOMObject(
|
||||
[In] ref Guid classID,
|
||||
[In] ref Guid interfaceID,
|
||||
[MarshalAs(UnmanagedType.Interface)] out object outObject);
|
||||
#endif
|
||||
|
||||
public static T SafeCast<T>(PropVariant var, T def)
|
||||
{
|
||||
object obj;
|
||||
try
|
||||
{
|
||||
obj = var.Object;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
if (obj != null && obj is T)
|
||||
{
|
||||
return (T) obj;
|
||||
}
|
||||
return def;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,705 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace SevenZip
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
#if DOTNET20
|
||||
using System.Threading;
|
||||
#else
|
||||
using System.Windows.Threading;
|
||||
#endif
|
||||
|
||||
partial class SevenZipCompressor
|
||||
{
|
||||
#region Delegates
|
||||
private delegate void CompressFiles1Delegate(string archiveName, string[] fileFullNames);
|
||||
private delegate void CompressFiles2Delegate(Stream archiveStream, string[] fileFullNames);
|
||||
private delegate void CompressFiles3Delegate(string archiveName, int commonRootLength, string[] fileFullNames);
|
||||
private delegate void CompressFiles4Delegate(Stream archiveStream, int commonRootLength, string[] fileFullNames);
|
||||
|
||||
private delegate void CompressFilesEncrypted1Delegate(string archiveName, string password, string[] fileFullNames);
|
||||
private delegate void CompressFilesEncrypted2Delegate(Stream archiveStream, string password, string[] fileFullNames);
|
||||
private delegate void CompressFilesEncrypted3Delegate(string archiveName, int commonRootLength, string password, string[] fileFullNames);
|
||||
private delegate void CompressFilesEncrypted4Delegate(Stream archiveStream, int commonRootLength, string password, string[] fileFullNames);
|
||||
|
||||
private delegate void CompressDirectory1Delegate(string directory, string archiveName);
|
||||
private delegate void CompressDirectory2Delegate(string directory, Stream archiveStream);
|
||||
private delegate void CompressDirectory3Delegate(string directory, string archiveName, string password);
|
||||
private delegate void CompressDirectory4Delegate(string directory, Stream archiveStream, string password);
|
||||
private delegate void CompressDirectory5Delegate(string directory, string archiveName,
|
||||
string password, string searchPattern, bool recursion);
|
||||
private delegate void CompressDirectory6Delegate(string directory, Stream archiveStream,
|
||||
string password, string searchPattern, bool recursion);
|
||||
|
||||
private delegate void CompressStream1Delegate(Stream inStream, Stream outStream);
|
||||
private delegate void CompressStream2Delegate(Stream inStream, Stream outStream, string password);
|
||||
|
||||
private delegate void ModifyArchive1Delegate(string archiveName, Dictionary<int, string> newFileNames);
|
||||
private delegate void ModifyArchive2Delegate(string archiveName, Dictionary<int, string> newFileNames,
|
||||
string password);
|
||||
#endregion
|
||||
|
||||
#region CompressFiles overloads
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Packs files into the archive asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="fileFullNames">Array of file names to pack.</param>
|
||||
/// <param name="archiveName">The archive file name.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Packs files into the archive asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="fileFullNames">Array of file names to pack.</param>
|
||||
/// <param name="archiveName">The archive file name.</param>
|
||||
#endif
|
||||
public void BeginCompressFiles(
|
||||
string archiveName
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#endif
|
||||
, params string[] fileFullNames
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new CompressFiles1Delegate(CompressFiles)).BeginInvoke(archiveName, fileFullNames,
|
||||
AsyncCallbackImplementation, this);
|
||||
}
|
||||
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Packs files into the archive asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="fileFullNames">Array of file names to pack.</param>
|
||||
/// <param name="archiveStream">The archive output stream.
|
||||
/// Use CompressFiles(string archiveName ... ) overloads for archiving to disk.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Packs files into the archive asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="fileFullNames">Array of file names to pack.</param>
|
||||
/// <param name="archiveStream">The archive output stream.
|
||||
/// Use CompressFiles(string archiveName ... ) overloads for archiving to disk.</param>
|
||||
#endif
|
||||
public void BeginCompressFiles(
|
||||
Stream archiveStream
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#endif
|
||||
, params string[] fileFullNames
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new CompressFiles2Delegate(CompressFiles)).BeginInvoke(archiveStream, fileFullNames,
|
||||
AsyncCallbackImplementation, this);
|
||||
}
|
||||
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Packs files into the archive asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="fileFullNames">Array of file names to pack.</param>
|
||||
/// <param name="commonRootLength">The length of the common root of the file names.</param>
|
||||
/// <param name="archiveName">The archive file name.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Packs files into the archive asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="fileFullNames">Array of file names to pack.</param>
|
||||
/// <param name="commonRootLength">The length of the common root of the file names.</param>
|
||||
/// <param name="archiveName">The archive file name.</param>
|
||||
#endif
|
||||
public void BeginCompressFiles(
|
||||
string archiveName, int commonRootLength
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#endif
|
||||
, params string[] fileFullNames
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new CompressFiles3Delegate(CompressFiles)).BeginInvoke(archiveName, commonRootLength, fileFullNames,
|
||||
AsyncCallbackImplementation, this);
|
||||
}
|
||||
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Packs files into the archive asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="fileFullNames">Array of file names to pack.</param>
|
||||
/// <param name="commonRootLength">The length of the common root of the file names.</param>
|
||||
/// <param name="archiveStream">The archive output stream.
|
||||
/// Use CompressFiles(string archiveName, ... ) overloads for archiving to disk.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Packs files into the archive asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="fileFullNames">Array of file names to pack.</param>
|
||||
/// <param name="commonRootLength">The length of the common root of the file names.</param>
|
||||
/// <param name="archiveStream">The archive output stream.
|
||||
/// Use CompressFiles(string archiveName, ... ) overloads for archiving to disk.</param>
|
||||
#endif
|
||||
public void BeginCompressFiles(
|
||||
Stream archiveStream, int commonRootLength
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#endif
|
||||
, params string[] fileFullNames
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new CompressFiles4Delegate(CompressFiles)).BeginInvoke(archiveStream, commonRootLength, fileFullNames,
|
||||
AsyncCallbackImplementation, this);
|
||||
}
|
||||
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Packs files into the archive asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="fileFullNames">Array of file names to pack.</param>
|
||||
/// <param name="archiveName">The archive file name</param>
|
||||
/// <param name="password">The archive password.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Packs files into the archive asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="fileFullNames">Array of file names to pack.</param>
|
||||
/// <param name="archiveName">The archive file name</param>
|
||||
/// <param name="password">The archive password.</param>
|
||||
#endif
|
||||
public void BeginCompressFilesEncrypted(
|
||||
string archiveName, string password
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#endif
|
||||
, params string[] fileFullNames
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new CompressFilesEncrypted1Delegate(CompressFilesEncrypted)).BeginInvoke(archiveName, password, fileFullNames,
|
||||
AsyncCallbackImplementation, this);
|
||||
}
|
||||
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Packs files into the archive asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="fileFullNames">Array of file names to pack.</param>
|
||||
/// <param name="archiveStream">The archive output stream.
|
||||
/// Use CompressFiles( ... string archiveName ... ) overloads for archiving to disk.</param>
|
||||
/// <param name="password">The archive password.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Packs files into the archive asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="fileFullNames">Array of file names to pack.</param>
|
||||
/// <param name="archiveStream">The archive output stream.
|
||||
/// Use CompressFiles( ... string archiveName ... ) overloads for archiving to disk.</param>
|
||||
/// <param name="password">The archive password.</param>
|
||||
#endif
|
||||
public void BeginCompressFilesEncrypted(
|
||||
Stream archiveStream, string password
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#endif
|
||||
, params string[] fileFullNames
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new CompressFilesEncrypted2Delegate(CompressFilesEncrypted)).BeginInvoke(archiveStream, password, fileFullNames,
|
||||
AsyncCallbackImplementation, this);
|
||||
}
|
||||
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Packs files into the archive asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="fileFullNames">Array of file names to pack.</param>
|
||||
/// <param name="archiveName">The archive file name</param>
|
||||
/// <param name="password">The archive password.</param>
|
||||
/// <param name="commonRootLength">The length of the common root of the file names.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Packs files into the archive asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="fileFullNames">Array of file names to pack.</param>
|
||||
/// <param name="archiveName">The archive file name</param>
|
||||
/// <param name="password">The archive password.</param>
|
||||
/// <param name="commonRootLength">The length of the common root of the file names.</param>
|
||||
#endif
|
||||
public void BeginCompressFilesEncrypted(
|
||||
string archiveName, int commonRootLength, string password
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#endif
|
||||
, params string[] fileFullNames
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new CompressFilesEncrypted3Delegate(CompressFilesEncrypted)).BeginInvoke(archiveName, commonRootLength, password,
|
||||
fileFullNames, AsyncCallbackImplementation, this);
|
||||
}
|
||||
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Packs files into the archive asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="fileFullNames">Array of file names to pack.</param>
|
||||
/// <param name="archiveStream">The archive output stream.
|
||||
/// Use CompressFiles( ... string archiveName ... ) overloads for archiving to disk.</param>
|
||||
/// <param name="password">The archive password.</param>
|
||||
/// <param name="commonRootLength">The length of the common root of the file names.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Packs files into the archive asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="fileFullNames">Array of file names to pack.</param>
|
||||
/// <param name="archiveStream">The archive output stream.
|
||||
/// Use CompressFiles( ... string archiveName ... ) overloads for archiving to disk.</param>
|
||||
/// <param name="password">The archive password.</param>
|
||||
/// <param name="commonRootLength">The length of the common root of the file names.</param>
|
||||
#endif
|
||||
public void BeginCompressFilesEncrypted(
|
||||
Stream archiveStream, int commonRootLength, string password
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#endif
|
||||
, params string[] fileFullNames
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new CompressFilesEncrypted4Delegate(CompressFilesEncrypted)).BeginInvoke(archiveStream, commonRootLength, password,
|
||||
fileFullNames, AsyncCallbackImplementation, this);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region BeginCompressDirectory overloads
|
||||
|
||||
#if !CS4
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Recursively packs all files in the specified directory.
|
||||
/// </summary>
|
||||
/// <param name="directory">The directory to compress.</param>
|
||||
/// <param name="archiveName">The archive file name.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Recursively packs all files in the specified directory.
|
||||
/// </summary>
|
||||
/// <param name="directory">The directory to compress.</param>
|
||||
/// <param name="archiveName">The archive file name.</param>
|
||||
#endif
|
||||
public void BeginCompressDirectory(
|
||||
string directory, string archiveName
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#endif
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new CompressDirectory1Delegate(CompressDirectory)).BeginInvoke(directory, archiveName,
|
||||
AsyncCallbackImplementation, this);
|
||||
}
|
||||
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Recursively packs all files in the specified directory.
|
||||
/// </summary>
|
||||
/// <param name="directory">The directory to compress.</param>
|
||||
/// <param name="archiveStream">The archive output stream.
|
||||
/// Use CompressDirectory( ... string archiveName ... ) overloads for archiving to disk.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Recursively packs all files in the specified directory.
|
||||
/// </summary>
|
||||
/// <param name="directory">The directory to compress.</param>
|
||||
/// <param name="archiveStream">The archive output stream.
|
||||
/// Use CompressDirectory( ... string archiveName ... ) overloads for archiving to disk.</param>
|
||||
#endif
|
||||
public void BeginCompressDirectory(
|
||||
string directory, Stream archiveStream
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#endif
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new CompressDirectory2Delegate(CompressDirectory)).BeginInvoke(directory, archiveStream,
|
||||
AsyncCallbackImplementation, this);
|
||||
}
|
||||
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Recursively packs all files in the specified directory.
|
||||
/// </summary>
|
||||
/// <param name="directory">The directory to compress.</param>
|
||||
/// <param name="archiveName">The archive file name.</param>
|
||||
/// <param name="password">The archive password.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Recursively packs all files in the specified directory.
|
||||
/// </summary>
|
||||
/// <param name="directory">The directory to compress.</param>
|
||||
/// <param name="archiveName">The archive file name.</param>
|
||||
/// <param name="password">The archive password.</param>
|
||||
#endif
|
||||
public void BeginCompressDirectory(
|
||||
string directory, string archiveName, string password
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#endif
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new CompressDirectory3Delegate(CompressDirectory)).BeginInvoke(directory, archiveName,
|
||||
password, AsyncCallbackImplementation, this);
|
||||
}
|
||||
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Recursively packs all files in the specified directory.
|
||||
/// </summary>
|
||||
/// <param name="directory">The directory to compress.</param>
|
||||
/// <param name="archiveStream">The archive output stream.
|
||||
/// Use CompressDirectory( ... string archiveName ... ) overloads for archiving to disk.</param>
|
||||
/// <param name="password">The archive password.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Recursively packs all files in the specified directory.
|
||||
/// </summary>
|
||||
/// <param name="directory">The directory to compress.</param>
|
||||
/// <param name="archiveStream">The archive output stream.
|
||||
/// Use CompressDirectory( ... string archiveName ... ) overloads for archiving to disk.</param>
|
||||
/// <param name="password">The archive password.</param>
|
||||
#endif
|
||||
public void BeginCompressDirectory(
|
||||
string directory, Stream archiveStream, string password
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#endif
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new CompressDirectory4Delegate(CompressDirectory)).BeginInvoke(directory, archiveStream,
|
||||
password, AsyncCallbackImplementation, this);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Packs all files in the specified directory asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="directory">The directory to compress.</param>
|
||||
/// <param name="archiveName">The archive file name.</param>
|
||||
/// <param name="password">The archive password.</param>
|
||||
/// <param name="searchPattern">Search string, such as "*.txt".</param>
|
||||
/// <param name="recursion">If true, files will be searched for recursively; otherwise, not.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Packs all files in the specified directory asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="directory">The directory to compress.</param>
|
||||
/// <param name="archiveName">The archive file name.</param>
|
||||
/// <param name="password">The archive password.</param>
|
||||
/// <param name="searchPattern">Search string, such as "*.txt".</param>
|
||||
/// <param name="recursion">If true, files will be searched for recursively; otherwise, not.</param>
|
||||
#endif
|
||||
public void BeginCompressDirectory(string directory, string archiveName,
|
||||
string password
|
||||
#if CS4
|
||||
= ""
|
||||
#endif
|
||||
, string searchPattern
|
||||
#if CS4
|
||||
= "*"
|
||||
#endif
|
||||
, bool recursion
|
||||
#if CS4
|
||||
= true
|
||||
#endif
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#if CS4
|
||||
= DispatcherPriority.Normal
|
||||
#endif
|
||||
#endif
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new CompressDirectory5Delegate(CompressDirectory)).BeginInvoke(directory, archiveName,
|
||||
password, searchPattern, recursion, AsyncCallbackImplementation, this);
|
||||
}
|
||||
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Packs all files in the specified directory asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="directory">The directory to compress.</param>
|
||||
/// <param name="archiveStream">The archive output stream.
|
||||
/// Use CompressDirectory( ... string archiveName ... ) overloads for archiving to disk.</param>
|
||||
/// <param name="password">The archive password.</param>
|
||||
/// <param name="searchPattern">Search string, such as "*.txt".</param>
|
||||
/// <param name="recursion">If true, files will be searched for recursively; otherwise, not.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Packs all files in the specified directory asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="directory">The directory to compress.</param>
|
||||
/// <param name="archiveStream">The archive output stream.
|
||||
/// Use CompressDirectory( ... string archiveName ... ) overloads for archiving to disk.</param>
|
||||
/// <param name="password">The archive password.</param>
|
||||
/// <param name="searchPattern">Search string, such as "*.txt".</param>
|
||||
/// <param name="recursion">If true, files will be searched for recursively; otherwise, not.</param>
|
||||
#endif
|
||||
public void BeginCompressDirectory(string directory, Stream archiveStream,
|
||||
string password
|
||||
#if CS4
|
||||
= ""
|
||||
#endif
|
||||
, string searchPattern
|
||||
#if CS4
|
||||
= "*"
|
||||
#endif
|
||||
, bool recursion
|
||||
#if CS4
|
||||
= true
|
||||
#endif
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#if CS4
|
||||
= DispatcherPriority.Normal
|
||||
#endif
|
||||
#endif
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new CompressDirectory6Delegate(CompressDirectory)).BeginInvoke(directory, archiveStream,
|
||||
password, searchPattern, recursion, AsyncCallbackImplementation, this);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region BeginCompressStream overloads
|
||||
#if !CS4
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Compresses the specified stream.
|
||||
/// </summary>
|
||||
/// <param name="inStream">The source uncompressed stream.</param>
|
||||
/// <param name="outStream">The destination compressed stream.</param>
|
||||
/// <exception cref="ArgumentException">ArgumentException: at least one of the specified streams is invalid.</exception>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Compresses the specified stream.
|
||||
/// </summary>
|
||||
/// <param name="inStream">The source uncompressed stream.</param>
|
||||
/// <param name="outStream">The destination compressed stream.</param>
|
||||
/// <exception cref="System.ArgumentException">ArgumentException: at least one of the specified streams is invalid.</exception>
|
||||
#endif
|
||||
public void BeginCompressStream(Stream inStream, Stream outStream
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#endif
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new CompressStream1Delegate(CompressStream)).BeginInvoke(inStream, outStream, AsyncCallbackImplementation, this);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Compresses the specified stream.
|
||||
/// </summary>
|
||||
/// <param name="inStream">The source uncompressed stream.</param>
|
||||
/// <param name="outStream">The destination compressed stream.</param>
|
||||
/// <param name="password">The archive password.</param>
|
||||
/// <exception cref="System.ArgumentException">ArgumentException: at least one of the specified streams is invalid.</exception>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Compresses the specified stream.
|
||||
/// </summary>
|
||||
/// <param name="inStream">The source uncompressed stream.</param>
|
||||
/// <param name="outStream">The destination compressed stream.</param>
|
||||
/// <param name="password">The archive password.</param>
|
||||
/// <exception cref="System.ArgumentException">ArgumentException: at least one of the specified streams is invalid.</exception>
|
||||
#endif
|
||||
public void BeginCompressStream(Stream inStream, Stream outStream, string password
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#if CS4
|
||||
= DispatcherPriority.Normal
|
||||
#endif
|
||||
#endif
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new CompressStream2Delegate(CompressStream)).BeginInvoke(inStream, outStream, password, AsyncCallbackImplementation, this);
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region BeginModifyArchive overloads
|
||||
#if !CS4
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Modifies the existing archive asynchronously (renames files or deletes them).
|
||||
/// </summary>
|
||||
/// <param name="archiveName">The archive file name.</param>
|
||||
/// <param name="newFileNames">New file names. Null value to delete the corresponding index.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Modifies the existing archive asynchronously (renames files or deletes them).
|
||||
/// </summary>
|
||||
/// <param name="archiveName">The archive file name.</param>
|
||||
/// <param name="newFileNames">New file names. Null value to delete the corresponding index.</param>
|
||||
#endif
|
||||
public void BeginModifyArchive(string archiveName, Dictionary<int, string> newFileNames
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#endif
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new ModifyArchive1Delegate(ModifyArchive)).BeginInvoke(archiveName, newFileNames, AsyncCallbackImplementation, this);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Modifies the existing archive asynchronously (renames files or deletes them).
|
||||
/// </summary>
|
||||
/// <param name="archiveName">The archive file name.</param>
|
||||
/// <param name="newFileNames">New file names. Null value to delete the corresponding index.</param>
|
||||
/// <param name="password">The archive password.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Modifies the existing archive asynchronously (renames files or deletes them).
|
||||
/// </summary>
|
||||
/// <param name="archiveName">The archive file name.</param>
|
||||
/// <param name="newFileNames">New file names. Null value to delete the corresponding index.</param>
|
||||
/// <param name="password">The archive password.</param>
|
||||
#endif
|
||||
public void BeginModifyArchive(string archiveName, Dictionary<int, string> newFileNames,
|
||||
string password
|
||||
#if CS4
|
||||
= ""
|
||||
#endif
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#if CS4
|
||||
= DispatcherPriority.Normal
|
||||
#endif
|
||||
#endif
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new ModifyArchive2Delegate(ModifyArchive)).BeginInvoke(archiveName, newFileNames, password, AsyncCallbackImplementation, this);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,317 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace SevenZip
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
#if DOTNET20
|
||||
using System.Threading;
|
||||
#else
|
||||
using System.Windows.Threading;
|
||||
#endif
|
||||
|
||||
partial class SevenZipExtractor
|
||||
{
|
||||
#region Asynchronous core methods
|
||||
|
||||
/// <summary>
|
||||
/// Recreates the instance of the SevenZipExtractor class.
|
||||
/// Used in asynchronous methods.
|
||||
/// </summary>
|
||||
private void RecreateInstanceIfNeeded()
|
||||
{
|
||||
if (NeedsToBeRecreated)
|
||||
{
|
||||
NeedsToBeRecreated = false;
|
||||
Stream backupStream = null;
|
||||
string backupFileName = null;
|
||||
if (String.IsNullOrEmpty(_fileName))
|
||||
{
|
||||
backupStream = _inStream;
|
||||
}
|
||||
else
|
||||
{
|
||||
backupFileName = _fileName;
|
||||
}
|
||||
CommonDispose();
|
||||
if (backupStream == null)
|
||||
{
|
||||
Init(backupFileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
Init(backupStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal override void SaveContext(
|
||||
#if !DOTNET20
|
||||
DispatcherPriority eventPriority
|
||||
#if CS4
|
||||
= DispatcherPriority.Normal
|
||||
#endif
|
||||
#endif
|
||||
)
|
||||
{
|
||||
DisposedCheck();
|
||||
_asynchronousDisposeLock = true;
|
||||
base.SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
internal override void ReleaseContext()
|
||||
{
|
||||
base.ReleaseContext();
|
||||
_asynchronousDisposeLock = false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Delegates
|
||||
/// <summary>
|
||||
/// The delegate to use in BeginExtractArchive.
|
||||
/// </summary>
|
||||
/// <param name="directory">The directory where the files are to be unpacked.</param>
|
||||
private delegate void ExtractArchiveDelegate(string directory);
|
||||
|
||||
/// <summary>
|
||||
/// The delegate to use in BeginExtractFile (by file name).
|
||||
/// </summary>
|
||||
/// <param name="fileName">The file full name in the archive file table.</param>
|
||||
/// <param name="stream">The stream where the file is to be unpacked.</param>
|
||||
private delegate void ExtractFileByFileNameDelegate(string fileName, Stream stream);
|
||||
|
||||
/// <summary>
|
||||
/// The delegate to use in BeginExtractFile (by index).
|
||||
/// </summary>
|
||||
/// <param name="index">Index in the archive file table.</param>
|
||||
/// <param name="stream">The stream where the file is to be unpacked.</param>
|
||||
private delegate void ExtractFileByIndexDelegate(int index, Stream stream);
|
||||
|
||||
/// <summary>
|
||||
/// The delegate to use in BeginExtractFiles(string directory, params int[] indexes).
|
||||
/// </summary>
|
||||
/// <param name="indexes">indexes of the files in the archive file table.</param>
|
||||
/// <param name="directory">Directory where the files are to be unpacked.</param>
|
||||
private delegate void ExtractFiles1Delegate(string directory, int[] indexes);
|
||||
|
||||
/// <summary>
|
||||
/// The delegate to use in BeginExtractFiles(string directory, params string[] fileNames).
|
||||
/// </summary>
|
||||
/// <param name="fileNames">Full file names in the archive file table.</param>
|
||||
/// <param name="directory">Directory where the files are to be unpacked.</param>
|
||||
private delegate void ExtractFiles2Delegate(string directory, string[] fileNames);
|
||||
|
||||
/// <summary>
|
||||
/// The delegate to use in BeginExtractFiles(ExtractFileCallback extractFileCallback).
|
||||
/// </summary>
|
||||
/// <param name="extractFileCallback">The callback to call for each file in the archive.</param>
|
||||
private delegate void ExtractFiles3Delegate(ExtractFileCallback extractFileCallback);
|
||||
#endregion
|
||||
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Unpacks the whole archive asynchronously to the specified directory name at the specified priority.
|
||||
/// </summary>
|
||||
/// <param name="directory">The directory where the files are to be unpacked.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Unpacks the whole archive asynchronously to the specified directory name at the specified priority.
|
||||
/// </summary>
|
||||
/// <param name="directory">The directory where the files are to be unpacked.</param>
|
||||
#endif
|
||||
public void BeginExtractArchive(string directory
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#if CS4
|
||||
= DispatcherPriority.Normal
|
||||
#endif
|
||||
#endif
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new ExtractArchiveDelegate(ExtractArchive)).BeginInvoke(directory, AsyncCallbackImplementation, this);
|
||||
}
|
||||
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Unpacks the file asynchronously by its name to the specified stream.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The file full name in the archive file table.</param>
|
||||
/// <param name="stream">The stream where the file is to be unpacked.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Unpacks the file asynchronously by its name to the specified stream.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The file full name in the archive file table.</param>
|
||||
/// <param name="stream">The stream where the file is to be unpacked.</param>
|
||||
#endif
|
||||
public void BeginExtractFile(string fileName, Stream stream
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#if CS4
|
||||
= DispatcherPriority.Normal
|
||||
#endif
|
||||
#endif
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new ExtractFileByFileNameDelegate(ExtractFile)).BeginInvoke(fileName, stream, AsyncCallbackImplementation, this);
|
||||
}
|
||||
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Unpacks the file asynchronously by its index to the specified stream.
|
||||
/// </summary>
|
||||
/// <param name="index">Index in the archive file table.</param>
|
||||
/// <param name="stream">The stream where the file is to be unpacked.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Unpacks the file asynchronously by its index to the specified stream.
|
||||
/// </summary>
|
||||
/// <param name="index">Index in the archive file table.</param>
|
||||
/// <param name="stream">The stream where the file is to be unpacked.</param>
|
||||
#endif
|
||||
public void BeginExtractFile(int index, Stream stream
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#if CS4
|
||||
= DispatcherPriority.Normal
|
||||
#endif
|
||||
#endif
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new ExtractFileByIndexDelegate(ExtractFile)).BeginInvoke(index, stream, AsyncCallbackImplementation, this);
|
||||
}
|
||||
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Unpacks files asynchronously by their indices to the specified directory.
|
||||
/// </summary>
|
||||
/// <param name="indexes">indexes of the files in the archive file table.</param>
|
||||
/// <param name="directory">Directory where the files are to be unpacked.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Unpacks files asynchronously by their indices to the specified directory.
|
||||
/// </summary>
|
||||
/// <param name="indexes">indexes of the files in the archive file table.</param>
|
||||
/// <param name="directory">Directory where the files are to be unpacked.</param>
|
||||
#endif
|
||||
public void BeginExtractFiles(string directory
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#if CS4
|
||||
= DispatcherPriority.Normal
|
||||
#endif
|
||||
#endif
|
||||
, params int[] indexes)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new ExtractFiles1Delegate(ExtractFiles)).BeginInvoke(directory, indexes, AsyncCallbackImplementation, this);
|
||||
}
|
||||
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Unpacks files asynchronously by their full names to the specified directory.
|
||||
/// </summary>
|
||||
/// <param name="fileNames">Full file names in the archive file table.</param>
|
||||
/// <param name="directory">Directory where the files are to be unpacked.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Unpacks files asynchronously by their full names to the specified directory.
|
||||
/// </summary>
|
||||
/// <param name="fileNames">Full file names in the archive file table.</param>
|
||||
/// <param name="directory">Directory where the files are to be unpacked.</param>
|
||||
#endif
|
||||
public void BeginExtractFiles(string directory
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#if CS4
|
||||
= DispatcherPriority.Normal
|
||||
#endif
|
||||
#endif
|
||||
, params string[] fileNames)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new ExtractFiles2Delegate(ExtractFiles)).BeginInvoke(directory, fileNames, AsyncCallbackImplementation, this);
|
||||
}
|
||||
|
||||
#if !DOTNET20
|
||||
/// <summary>
|
||||
/// Extracts files from the archive asynchronously, giving a callback the choice what
|
||||
/// to do with each file. The order of the files is given by the archive.
|
||||
/// 7-Zip (and any other solid) archives are NOT supported.
|
||||
/// </summary>
|
||||
/// <param name="extractFileCallback">The callback to call for each file in the archive.</param>
|
||||
/// <param name="eventPriority">The priority of events, relative to the other pending operations in the System.Windows.Threading.Dispatcher event queue, the specified method is invoked.</param>
|
||||
#else
|
||||
/// <summary>
|
||||
/// Extracts files from the archive asynchronously, giving a callback the choice what
|
||||
/// to do with each file. The order of the files is given by the archive.
|
||||
/// 7-Zip (and any other solid) archives are NOT supported.
|
||||
/// </summary>
|
||||
/// <param name="extractFileCallback">The callback to call for each file in the archive.</param>
|
||||
#endif
|
||||
public void BeginExtractFiles(ExtractFileCallback extractFileCallback
|
||||
#if !DOTNET20
|
||||
, DispatcherPriority eventPriority
|
||||
#if CS4
|
||||
= DispatcherPriority.Normal
|
||||
#endif
|
||||
#endif
|
||||
)
|
||||
{
|
||||
SaveContext(
|
||||
#if !DOTNET20
|
||||
eventPriority
|
||||
#endif
|
||||
);
|
||||
(new ExtractFiles3Delegate(ExtractFiles)).BeginInvoke(extractFileCallback, AsyncCallbackImplementation, this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,499 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Schema;
|
||||
|
||||
namespace SevenZip
|
||||
{
|
||||
#if SFX
|
||||
using SfxSettings = Dictionary<string, string>;
|
||||
|
||||
/// <summary>
|
||||
/// Sfx module choice enumeration
|
||||
/// </summary>
|
||||
public enum SfxModule
|
||||
{
|
||||
/// <summary>
|
||||
/// Default module (leave this if unsure)
|
||||
/// </summary>
|
||||
Default,
|
||||
/// <summary>
|
||||
/// The simple sfx module by Igor Pavlov with no adjustable parameters
|
||||
/// </summary>
|
||||
Simple,
|
||||
/// <summary>
|
||||
/// The installer sfx module by Igor Pavlov
|
||||
/// </summary>
|
||||
Installer,
|
||||
/// <summary>
|
||||
/// The extended installer sfx module by Oleg Scherbakov
|
||||
/// </summary>
|
||||
Extended,
|
||||
/// <summary>
|
||||
/// The custom sfx module. First you must specify the module file name.
|
||||
/// </summary>
|
||||
Custom
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The class for making 7-zip based self-extracting archives.
|
||||
/// </summary>
|
||||
public class SevenZipSfx
|
||||
{
|
||||
private static readonly Dictionary<SfxModule, List<string>> SfxSupportedModuleNames =
|
||||
new Dictionary<SfxModule, List<string>>(3)
|
||||
{
|
||||
{SfxModule.Default, new List<string>(1) {"7zxSD_All.sfx"}},
|
||||
{SfxModule.Simple, new List<string>(2) {"7z.sfx", "7zCon.sfx"}},
|
||||
{SfxModule.Installer, new List<string>(2) {"7zS.sfx", "7zSD.sfx"}},
|
||||
{
|
||||
SfxModule.Extended,
|
||||
new List<string>(4) {"7zxSD_All.sfx", "7zxSD_Deflate", "7zxSD_LZMA", "7zxSD_PPMd"}
|
||||
}
|
||||
};
|
||||
|
||||
private SfxModule _module = SfxModule.Default;
|
||||
private string _moduleFileName;
|
||||
private Dictionary<SfxModule, List<string>> _sfxCommands;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipSfx class.
|
||||
/// </summary>
|
||||
public SevenZipSfx()
|
||||
{
|
||||
_module = SfxModule.Default;
|
||||
CommonInit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipSfx class.
|
||||
/// </summary>
|
||||
/// <param name="module">The sfx module to use as a front-end.</param>
|
||||
public SevenZipSfx(SfxModule module)
|
||||
{
|
||||
if (module == SfxModule.Custom)
|
||||
{
|
||||
throw new ArgumentException("You must specify the custom module executable.", "module");
|
||||
}
|
||||
_module = module;
|
||||
CommonInit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SevenZipSfx class.
|
||||
/// </summary>
|
||||
/// <param name="moduleFileName"></param>
|
||||
public SevenZipSfx(string moduleFileName)
|
||||
{
|
||||
_module = SfxModule.Custom;
|
||||
ModuleFileName = moduleFileName;
|
||||
CommonInit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sfx module type.
|
||||
/// </summary>
|
||||
public SfxModule SfxModule
|
||||
{
|
||||
get
|
||||
{
|
||||
return _module;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the custom sfx module file name
|
||||
/// </summary>
|
||||
public string ModuleFileName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _moduleFileName;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (!File.Exists(value))
|
||||
{
|
||||
throw new ArgumentException("The specified file does not exist.");
|
||||
}
|
||||
_moduleFileName = value;
|
||||
_module = SfxModule.Custom;
|
||||
string sfxName = Path.GetFileName(value);
|
||||
foreach (SfxModule mod in SfxSupportedModuleNames.Keys)
|
||||
{
|
||||
if (SfxSupportedModuleNames[mod].Contains(sfxName))
|
||||
{
|
||||
_module = mod;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CommonInit()
|
||||
{
|
||||
LoadCommandsFromResource("Configs");
|
||||
}
|
||||
|
||||
private static string GetResourceString(string str)
|
||||
{
|
||||
#if !WINCE
|
||||
return "SevenZip.sfx." + str;
|
||||
#else
|
||||
return "SevenZipSharpMobile.sfx." + str;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sfx module enum by the list of supported modules
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
private static SfxModule GetModuleByName(string name)
|
||||
{
|
||||
if (name.IndexOf("7z.sfx", StringComparison.Ordinal) > -1)
|
||||
{
|
||||
return SfxModule.Simple;
|
||||
}
|
||||
if (name.IndexOf("7zS.sfx", StringComparison.Ordinal) > -1)
|
||||
{
|
||||
return SfxModule.Installer;
|
||||
}
|
||||
if (name.IndexOf("7zxSD_All.sfx", StringComparison.Ordinal) > -1)
|
||||
{
|
||||
return SfxModule.Extended;
|
||||
}
|
||||
throw new SevenZipSfxValidationException("The specified configuration is unsupported.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the commands for each supported sfx module configuration
|
||||
/// </summary>
|
||||
/// <param name="xmlDefinitions">The resource name for xml definitions</param>
|
||||
private void LoadCommandsFromResource(string xmlDefinitions)
|
||||
{
|
||||
using (Stream cfg = Assembly.GetExecutingAssembly().GetManifestResourceStream(
|
||||
GetResourceString(xmlDefinitions + ".xml")))
|
||||
{
|
||||
if (cfg == null)
|
||||
{
|
||||
throw new SevenZipSfxValidationException("The configuration \"" + xmlDefinitions +
|
||||
"\" does not exist.");
|
||||
}
|
||||
using (Stream schm = Assembly.GetExecutingAssembly().GetManifestResourceStream(
|
||||
GetResourceString(xmlDefinitions + ".xsd")))
|
||||
{
|
||||
if (schm == null)
|
||||
{
|
||||
throw new SevenZipSfxValidationException("The configuration schema \"" + xmlDefinitions +
|
||||
"\" does not exist.");
|
||||
}
|
||||
var sc = new XmlSchemaSet();
|
||||
using (XmlReader scr = XmlReader.Create(schm))
|
||||
{
|
||||
sc.Add(null, scr);
|
||||
var settings = new XmlReaderSettings {ValidationType = ValidationType.Schema, Schemas = sc};
|
||||
string validationErrors = "";
|
||||
settings.ValidationEventHandler +=
|
||||
((s, t) =>
|
||||
{
|
||||
validationErrors += String.Format(CultureInfo.InvariantCulture, "[{0}]: {1}\n",
|
||||
t.Severity.ToString(), t.Message);
|
||||
});
|
||||
using (XmlReader rdr = XmlReader.Create(cfg, settings))
|
||||
{
|
||||
_sfxCommands = new Dictionary<SfxModule, List<string>>();
|
||||
rdr.Read();
|
||||
rdr.Read();
|
||||
rdr.Read();
|
||||
rdr.Read();
|
||||
rdr.Read();
|
||||
rdr.ReadStartElement("sfxConfigs");
|
||||
rdr.Read();
|
||||
do
|
||||
{
|
||||
SfxModule mod = GetModuleByName(rdr["modules"]);
|
||||
rdr.ReadStartElement("config");
|
||||
rdr.Read();
|
||||
if (rdr.Name == "id")
|
||||
{
|
||||
var cmds = new List<string>();
|
||||
_sfxCommands.Add(mod, cmds);
|
||||
do
|
||||
{
|
||||
cmds.Add(rdr["command"]);
|
||||
rdr.Read();
|
||||
rdr.Read();
|
||||
} while (rdr.Name == "id");
|
||||
rdr.ReadEndElement();
|
||||
rdr.Read();
|
||||
}
|
||||
else
|
||||
{
|
||||
_sfxCommands.Add(mod, null);
|
||||
}
|
||||
} while (rdr.Name == "config");
|
||||
}
|
||||
if (!String.IsNullOrEmpty(validationErrors))
|
||||
{
|
||||
throw new SevenZipSfxValidationException(
|
||||
"\n" + validationErrors.Substring(0, validationErrors.Length - 1));
|
||||
}
|
||||
_sfxCommands.Add(SfxModule.Default, _sfxCommands[SfxModule.Extended]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the sfx scenario commands.
|
||||
/// </summary>
|
||||
/// <param name="settings">The sfx settings dictionary to validate.</param>
|
||||
private void ValidateSettings(SfxSettings settings)
|
||||
{
|
||||
if (_module == SfxModule.Custom)
|
||||
{
|
||||
return;
|
||||
}
|
||||
List<string> commands = _sfxCommands[_module];
|
||||
if (commands == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var invalidCommands = new List<string>();
|
||||
foreach (string command in settings.Keys)
|
||||
{
|
||||
if (!commands.Contains(command))
|
||||
{
|
||||
invalidCommands.Add(command);
|
||||
}
|
||||
}
|
||||
if (invalidCommands.Count > 0)
|
||||
{
|
||||
var invalidText = new StringBuilder("\nInvalid commands:\n");
|
||||
foreach (string str in invalidCommands)
|
||||
{
|
||||
invalidText.Append(str);
|
||||
}
|
||||
throw new SevenZipSfxValidationException(invalidText.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the stream containing the sfx settings.
|
||||
/// </summary>
|
||||
/// <param name="settings">The sfx settings dictionary.</param>
|
||||
/// <returns></returns>
|
||||
private static Stream GetSettingsStream(SfxSettings settings)
|
||||
{
|
||||
var ms = new MemoryStream();
|
||||
byte[] buf = Encoding.UTF8.GetBytes(@";!@Install@!UTF-8!" + '\n');
|
||||
ms.Write(buf, 0, buf.Length);
|
||||
foreach (string command in settings.Keys)
|
||||
{
|
||||
buf =
|
||||
Encoding.UTF8.GetBytes(String.Format(CultureInfo.InvariantCulture, "{0}=\"{1}\"\n", command,
|
||||
settings[command]));
|
||||
ms.Write(buf, 0, buf.Length);
|
||||
}
|
||||
buf = Encoding.UTF8.GetBytes(@";!@InstallEnd@!");
|
||||
ms.Write(buf, 0, buf.Length);
|
||||
return ms;
|
||||
}
|
||||
|
||||
private SfxSettings GetDefaultSettings()
|
||||
{
|
||||
switch (_module)
|
||||
{
|
||||
default:
|
||||
return null;
|
||||
case SfxModule.Installer:
|
||||
var settings = new Dictionary<string, string> {{"Title", "7-Zip self-extracting archive"}};
|
||||
return settings;
|
||||
case SfxModule.Default:
|
||||
case SfxModule.Extended:
|
||||
settings = new Dictionary<string, string>
|
||||
{
|
||||
{"GUIMode", "0"},
|
||||
{"InstallPath", "."},
|
||||
{"GUIFlags", "128+8"},
|
||||
{"ExtractPathTitle", "7-Zip self-extracting archive"},
|
||||
{"ExtractPathText", "Specify the path where to extract the files:"}
|
||||
};
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the whole to the other one.
|
||||
/// </summary>
|
||||
/// <param name="src">The source stream to read from.</param>
|
||||
/// <param name="dest">The destination stream to wrie to.</param>
|
||||
private static void WriteStream(Stream src, Stream dest)
|
||||
{
|
||||
src.Seek(0, SeekOrigin.Begin);
|
||||
var buf = new byte[32768];
|
||||
int bytesRead;
|
||||
while ((bytesRead = src.Read(buf, 0, buf.Length)) > 0)
|
||||
{
|
||||
dest.Write(buf, 0, bytesRead);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes the self-extracting archive.
|
||||
/// </summary>
|
||||
/// <param name="archive">The archive stream.</param>
|
||||
/// <param name="sfxFileName">The name of the self-extracting executable.</param>
|
||||
public void MakeSfx(Stream archive, string sfxFileName)
|
||||
{
|
||||
using (Stream sfxStream = File.Create(sfxFileName))
|
||||
{
|
||||
MakeSfx(archive, GetDefaultSettings(), sfxStream);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes the self-extracting archive.
|
||||
/// </summary>
|
||||
/// <param name="archive">The archive stream.</param>
|
||||
/// <param name="sfxStream">The stream to write the self-extracting executable to.</param>
|
||||
public void MakeSfx(Stream archive, Stream sfxStream)
|
||||
{
|
||||
MakeSfx(archive, GetDefaultSettings(), sfxStream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes the self-extracting archive.
|
||||
/// </summary>
|
||||
/// <param name="archive">The archive stream.</param>
|
||||
/// <param name="settings">The sfx settings.</param>
|
||||
/// <param name="sfxFileName">The name of the self-extracting executable.</param>
|
||||
public void MakeSfx(Stream archive, SfxSettings settings, string sfxFileName)
|
||||
{
|
||||
using (Stream sfxStream = File.Create(sfxFileName))
|
||||
{
|
||||
MakeSfx(archive, settings, sfxStream);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes the self-extracting archive.
|
||||
/// </summary>
|
||||
/// <param name="archive">The archive stream.</param>
|
||||
/// <param name="settings">The sfx settings.</param>
|
||||
/// <param name="sfxStream">The stream to write the self-extracting executable to.</param>
|
||||
public void MakeSfx(Stream archive, SfxSettings settings, Stream sfxStream)
|
||||
{
|
||||
if (!sfxStream.CanWrite)
|
||||
{
|
||||
throw new ArgumentException("The specified output stream can not write.", "sfxStream");
|
||||
}
|
||||
ValidateSettings(settings);
|
||||
using (Stream sfx = _module == SfxModule.Default
|
||||
? Assembly.GetExecutingAssembly().GetManifestResourceStream(
|
||||
GetResourceString(SfxSupportedModuleNames[_module][0]))
|
||||
: new FileStream(_moduleFileName, FileMode.Open, FileAccess.Read,
|
||||
FileShare.ReadWrite))
|
||||
{
|
||||
WriteStream(sfx, sfxStream);
|
||||
}
|
||||
if (_module == SfxModule.Custom || _sfxCommands[_module] != null)
|
||||
{
|
||||
using (Stream set = GetSettingsStream(settings))
|
||||
{
|
||||
WriteStream(set, sfxStream);
|
||||
}
|
||||
}
|
||||
WriteStream(archive, sfxStream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes the self-extracting archive.
|
||||
/// </summary>
|
||||
/// <param name="archiveFileName">The archive file name.</param>
|
||||
/// <param name="sfxFileName">The name of the self-extracting executable.</param>
|
||||
public void MakeSfx(string archiveFileName, string sfxFileName)
|
||||
{
|
||||
using (Stream sfxStream = File.Create(sfxFileName))
|
||||
{
|
||||
using (
|
||||
Stream archive = new FileStream(archiveFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
|
||||
)
|
||||
{
|
||||
MakeSfx(archive, GetDefaultSettings(), sfxStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes the self-extracting archive.
|
||||
/// </summary>
|
||||
/// <param name="archiveFileName">The archive file name.</param>
|
||||
/// <param name="sfxStream">The stream to write the self-extracting executable to.</param>
|
||||
public void MakeSfx(string archiveFileName, Stream sfxStream)
|
||||
{
|
||||
using (Stream archive = new FileStream(archiveFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
|
||||
)
|
||||
{
|
||||
MakeSfx(archive, GetDefaultSettings(), sfxStream);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes the self-extracting archive.
|
||||
/// </summary>
|
||||
/// <param name="archiveFileName">The archive file name.</param>
|
||||
/// <param name="settings">The sfx settings.</param>
|
||||
/// <param name="sfxFileName">The name of the self-extracting executable.</param>
|
||||
public void MakeSfx(string archiveFileName, SfxSettings settings, string sfxFileName)
|
||||
{
|
||||
using (Stream sfxStream = File.Create(sfxFileName))
|
||||
{
|
||||
using (
|
||||
Stream archive = new FileStream(archiveFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
|
||||
)
|
||||
{
|
||||
MakeSfx(archive, settings, sfxStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes the self-extracting archive.
|
||||
/// </summary>
|
||||
/// <param name="archiveFileName">The archive file name.</param>
|
||||
/// <param name="settings">The sfx settings.</param>
|
||||
/// <param name="sfxStream">The stream to write the self-extracting executable to.</param>
|
||||
public void MakeSfx(string archiveFileName, SfxSettings settings, Stream sfxStream)
|
||||
{
|
||||
using (Stream archive = new FileStream(archiveFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
|
||||
)
|
||||
{
|
||||
MakeSfx(archive, settings, sfxStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -1,545 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
#if MONO
|
||||
using SevenZip.Mono.COM;
|
||||
#endif
|
||||
|
||||
namespace SevenZip
|
||||
{
|
||||
#if UNMANAGED
|
||||
|
||||
/// <summary>
|
||||
/// A class that has DisposeStream property.
|
||||
/// </summary>
|
||||
internal class DisposeVariableWrapper
|
||||
{
|
||||
public bool DisposeStream { protected get; set; }
|
||||
|
||||
protected DisposeVariableWrapper(bool disposeStream) { DisposeStream = disposeStream; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stream wrapper used in InStreamWrapper
|
||||
/// </summary>
|
||||
internal class StreamWrapper : DisposeVariableWrapper, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// File name associated with the stream (for date fix)
|
||||
/// </summary>
|
||||
private readonly string _fileName;
|
||||
|
||||
private readonly DateTime _fileTime;
|
||||
|
||||
/// <summary>
|
||||
/// Worker stream for reading, writing and seeking.
|
||||
/// </summary>
|
||||
private Stream _baseStream;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the StreamWrapper class
|
||||
/// </summary>
|
||||
/// <param name="baseStream">Worker stream for reading, writing and seeking</param>
|
||||
/// <param name="fileName">File name associated with the stream (for attributes fix)</param>
|
||||
/// <param name="time">File last write time (for attributes fix)</param>
|
||||
/// <param name="disposeStream">Indicates whether to dispose the baseStream</param>
|
||||
protected StreamWrapper(Stream baseStream, string fileName, DateTime time, bool disposeStream)
|
||||
: base(disposeStream)
|
||||
{
|
||||
_baseStream = baseStream;
|
||||
_fileName = fileName;
|
||||
_fileTime = time;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the StreamWrapper class
|
||||
/// </summary>
|
||||
/// <param name="baseStream">Worker stream for reading, writing and seeking</param>
|
||||
/// <param name="disposeStream">Indicates whether to dispose the baseStream</param>
|
||||
protected StreamWrapper(Stream baseStream, bool disposeStream)
|
||||
: base(disposeStream)
|
||||
{
|
||||
_baseStream = baseStream;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the worker stream for reading, writing and seeking.
|
||||
/// </summary>
|
||||
protected Stream BaseStream
|
||||
{
|
||||
get
|
||||
{
|
||||
return _baseStream;
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
/// <summary>
|
||||
/// Cleans up any resources used and fixes file attributes.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (_baseStream != null && DisposeStream)
|
||||
{
|
||||
try
|
||||
{
|
||||
_baseStream.Dispose();
|
||||
}
|
||||
catch (ObjectDisposedException) { }
|
||||
_baseStream = null;
|
||||
}
|
||||
if (!String.IsNullOrEmpty(_fileName) && File.Exists(_fileName))
|
||||
{
|
||||
try
|
||||
{
|
||||
#if !WINCE
|
||||
|
||||
File.SetLastWriteTime(_fileName, _fileTime);
|
||||
File.SetLastAccessTime(_fileName, _fileTime);
|
||||
File.SetCreationTime(_fileName, _fileTime);
|
||||
#elif WINCE
|
||||
OpenNETCF.IO.FileHelper.SetLastWriteTime(_fileName, _fileTime);
|
||||
OpenNETCF.IO.FileHelper.SetLastAccessTime(_fileName, _fileTime);
|
||||
OpenNETCF.IO.FileHelper.SetCreationTime(_fileName, _fileTime);
|
||||
#endif
|
||||
//TODO: time support for Windows Phone
|
||||
}
|
||||
catch (ArgumentOutOfRangeException) {}
|
||||
}
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public virtual void Seek(long offset, SeekOrigin seekOrigin, IntPtr newPosition)
|
||||
{
|
||||
if (BaseStream != null)
|
||||
{
|
||||
long position = BaseStream.Seek(offset, seekOrigin);
|
||||
if (newPosition != IntPtr.Zero)
|
||||
{
|
||||
Marshal.WriteInt64(newPosition, position);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// IInStream wrapper used in stream read operations.
|
||||
/// </summary>
|
||||
internal sealed class InStreamWrapper : StreamWrapper, ISequentialInStream, IInStream
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the InStreamWrapper class.
|
||||
/// </summary>
|
||||
/// <param name="baseStream">Stream for writing data</param>
|
||||
/// <param name="disposeStream">Indicates whether to dispose the baseStream</param>
|
||||
public InStreamWrapper(Stream baseStream, bool disposeStream) : base(baseStream, disposeStream) { }
|
||||
|
||||
#region ISequentialInStream Members
|
||||
|
||||
/// <summary>
|
||||
/// Reads data from the stream.
|
||||
/// </summary>
|
||||
/// <param name="data">A data array.</param>
|
||||
/// <param name="size">The array size.</param>
|
||||
/// <returns>The read bytes count.</returns>
|
||||
public int Read(byte[] data, uint size)
|
||||
{
|
||||
int readCount = 0;
|
||||
if (BaseStream != null)
|
||||
{
|
||||
readCount = BaseStream.Read(data, 0, (int) size);
|
||||
if (readCount > 0)
|
||||
{
|
||||
OnBytesRead(new IntEventArgs(readCount));
|
||||
}
|
||||
}
|
||||
return readCount;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when IntEventArgs.Value bytes were read from the source.
|
||||
/// </summary>
|
||||
public event EventHandler<IntEventArgs> BytesRead;
|
||||
|
||||
private void OnBytesRead(IntEventArgs e)
|
||||
{
|
||||
if (BytesRead != null)
|
||||
{
|
||||
BytesRead(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// IOutStream wrapper used in stream write operations.
|
||||
/// </summary>
|
||||
internal sealed class OutStreamWrapper : StreamWrapper, ISequentialOutStream, IOutStream
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the OutStreamWrapper class
|
||||
/// </summary>
|
||||
/// <param name="baseStream">Stream for writing data</param>
|
||||
/// <param name="fileName">File name (for attributes fix)</param>
|
||||
/// <param name="time">Time of the file creation (for attributes fix)</param>
|
||||
/// <param name="disposeStream">Indicates whether to dispose the baseStream</param>
|
||||
public OutStreamWrapper(Stream baseStream, string fileName, DateTime time, bool disposeStream) :
|
||||
base(baseStream, fileName, time, disposeStream) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the OutStreamWrapper class
|
||||
/// </summary>
|
||||
/// <param name="baseStream">Stream for writing data</param>
|
||||
/// <param name="disposeStream">Indicates whether to dispose the baseStream</param>
|
||||
public OutStreamWrapper(Stream baseStream, bool disposeStream) :
|
||||
base(baseStream, disposeStream) {}
|
||||
|
||||
#region IOutStream Members
|
||||
|
||||
public int SetSize(long newSize)
|
||||
{
|
||||
BaseStream.SetLength(newSize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ISequentialOutStream Members
|
||||
|
||||
/// <summary>
|
||||
/// Writes data to the stream
|
||||
/// </summary>
|
||||
/// <param name="data">Data array</param>
|
||||
/// <param name="size">Array size</param>
|
||||
/// <param name="processedSize">Count of written bytes</param>
|
||||
/// <returns>Zero if Ok</returns>
|
||||
public int Write(byte[] data, uint size, IntPtr processedSize)
|
||||
{
|
||||
BaseStream.Write(data, 0, (int) size);
|
||||
if (processedSize != IntPtr.Zero)
|
||||
{
|
||||
Marshal.WriteInt32(processedSize, (int) size);
|
||||
}
|
||||
OnBytesWritten(new IntEventArgs((int) size));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when IntEventArgs.Value bytes were written.
|
||||
/// </summary>
|
||||
public event EventHandler<IntEventArgs> BytesWritten;
|
||||
|
||||
private void OnBytesWritten(IntEventArgs e)
|
||||
{
|
||||
if (BytesWritten != null)
|
||||
{
|
||||
BytesWritten(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base multi volume stream wrapper class.
|
||||
/// </summary>
|
||||
internal class MultiStreamWrapper : DisposeVariableWrapper, IDisposable
|
||||
{
|
||||
protected readonly Dictionary<int, KeyValuePair<long, long>> StreamOffsets =
|
||||
new Dictionary<int, KeyValuePair<long, long>>();
|
||||
|
||||
protected readonly List<Stream> Streams = new List<Stream>();
|
||||
protected int CurrentStream;
|
||||
protected long Position;
|
||||
protected long StreamLength;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the MultiStreamWrapper class.
|
||||
/// </summary>
|
||||
/// <param name="dispose">Perform Dispose() if requested to.</param>
|
||||
protected MultiStreamWrapper(bool dispose) : base(dispose) {}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the total length of input data.
|
||||
/// </summary>
|
||||
public long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return StreamLength;
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
/// <summary>
|
||||
/// Cleans up any resources used and fixes file attributes.
|
||||
/// </summary>
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if (DisposeStream)
|
||||
{
|
||||
foreach (Stream stream in Streams)
|
||||
{
|
||||
try
|
||||
{
|
||||
stream.Dispose();
|
||||
}
|
||||
catch (ObjectDisposedException) {}
|
||||
}
|
||||
Streams.Clear();
|
||||
}
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected static string VolumeNumber(int num)
|
||||
{
|
||||
if (num < 10)
|
||||
{
|
||||
return ".00" + num.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
if (num > 9 && num < 100)
|
||||
{
|
||||
return ".0" + num.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
if (num > 99 && num < 1000)
|
||||
{
|
||||
return "." + num.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private int StreamNumberByOffset(long offset)
|
||||
{
|
||||
foreach (int number in StreamOffsets.Keys)
|
||||
{
|
||||
if (StreamOffsets[number].Key <= offset &&
|
||||
StreamOffsets[number].Value >= offset)
|
||||
{
|
||||
return number;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void Seek(long offset, SeekOrigin seekOrigin, IntPtr newPosition)
|
||||
{
|
||||
long absolutePosition = (seekOrigin == SeekOrigin.Current)
|
||||
? Position + offset
|
||||
: offset;
|
||||
CurrentStream = StreamNumberByOffset(absolutePosition);
|
||||
long delta = Streams[CurrentStream].Seek(
|
||||
absolutePosition - StreamOffsets[CurrentStream].Key, SeekOrigin.Begin);
|
||||
Position = StreamOffsets[CurrentStream].Key + delta;
|
||||
if (newPosition != IntPtr.Zero)
|
||||
{
|
||||
Marshal.WriteInt64(newPosition, Position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// IInStream wrapper used in stream multi volume read operations.
|
||||
/// </summary>
|
||||
internal sealed class InMultiStreamWrapper : MultiStreamWrapper, ISequentialInStream, IInStream
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the InMultiStreamWrapper class.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The archive file name.</param>
|
||||
/// <param name="dispose">Perform Dispose() if requested to.</param>
|
||||
public InMultiStreamWrapper(string fileName, bool dispose) :
|
||||
base(dispose)
|
||||
{
|
||||
string baseName = fileName.Substring(0, fileName.Length - 4);
|
||||
int i = 0;
|
||||
while (File.Exists(fileName))
|
||||
{
|
||||
Streams.Add(new FileStream(fileName, FileMode.Open));
|
||||
long length = Streams[i].Length;
|
||||
StreamOffsets.Add(i++, new KeyValuePair<long, long>(StreamLength, StreamLength + length));
|
||||
StreamLength += length;
|
||||
fileName = baseName + VolumeNumber(i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
#region ISequentialInStream Members
|
||||
|
||||
/// <summary>
|
||||
/// Reads data from the stream.
|
||||
/// </summary>
|
||||
/// <param name="data">A data array.</param>
|
||||
/// <param name="size">The array size.</param>
|
||||
/// <returns>The read bytes count.</returns>
|
||||
public int Read(byte[] data, uint size)
|
||||
{
|
||||
var readSize = (int) size;
|
||||
int readCount = Streams[CurrentStream].Read(data, 0, readSize);
|
||||
readSize -= readCount;
|
||||
Position += readCount;
|
||||
while (readCount < (int) size)
|
||||
{
|
||||
if (CurrentStream == Streams.Count - 1)
|
||||
{
|
||||
return readCount;
|
||||
}
|
||||
CurrentStream++;
|
||||
Streams[CurrentStream].Seek(0, SeekOrigin.Begin);
|
||||
int count = Streams[CurrentStream].Read(data, readCount, readSize);
|
||||
readCount += count;
|
||||
readSize -= count;
|
||||
Position += count;
|
||||
}
|
||||
return readCount;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#if COMPRESS
|
||||
/// <summary>
|
||||
/// IOutStream wrapper used in multi volume stream write operations.
|
||||
/// </summary>
|
||||
internal sealed class OutMultiStreamWrapper : MultiStreamWrapper, ISequentialOutStream, IOutStream
|
||||
{
|
||||
private readonly string _archiveName;
|
||||
private readonly int _volumeSize;
|
||||
private long _overallLength;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the OutMultiStreamWrapper class.
|
||||
/// </summary>
|
||||
/// <param name="archiveName">The archive name.</param>
|
||||
/// <param name="volumeSize">The volume size.</param>
|
||||
public OutMultiStreamWrapper(string archiveName, int volumeSize) :
|
||||
base(true)
|
||||
{
|
||||
_archiveName = archiveName;
|
||||
_volumeSize = volumeSize;
|
||||
CurrentStream = -1;
|
||||
NewVolumeStream();
|
||||
}
|
||||
|
||||
#region IOutStream Members
|
||||
|
||||
public int SetSize(long newSize)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ISequentialOutStream Members
|
||||
|
||||
public int Write(byte[] data, uint size, IntPtr processedSize)
|
||||
{
|
||||
int offset = 0;
|
||||
var originalSize = (int) size;
|
||||
Position += size;
|
||||
_overallLength = Math.Max(Position + 1, _overallLength);
|
||||
while (size > _volumeSize - Streams[CurrentStream].Position)
|
||||
{
|
||||
var count = (int) (_volumeSize - Streams[CurrentStream].Position);
|
||||
Streams[CurrentStream].Write(data, offset, count);
|
||||
size -= (uint) count;
|
||||
offset += count;
|
||||
NewVolumeStream();
|
||||
}
|
||||
Streams[CurrentStream].Write(data, offset, (int) size);
|
||||
if (processedSize != IntPtr.Zero)
|
||||
{
|
||||
Marshal.WriteInt32(processedSize, originalSize);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
int lastIndex = Streams.Count - 1;
|
||||
Streams[lastIndex].SetLength(lastIndex > 0? Streams[lastIndex].Position : _overallLength);
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
private void NewVolumeStream()
|
||||
{
|
||||
CurrentStream++;
|
||||
Streams.Add(File.Create(_archiveName + VolumeNumber(CurrentStream + 1)));
|
||||
Streams[CurrentStream].SetLength(_volumeSize);
|
||||
StreamOffsets.Add(CurrentStream, new KeyValuePair<long, long>(0, _volumeSize - 1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
internal sealed class FakeOutStreamWrapper : ISequentialOutStream, IDisposable
|
||||
{
|
||||
#region IDisposable Members
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ISequentialOutStream Members
|
||||
|
||||
/// <summary>
|
||||
/// Does nothing except calling the BytesWritten event
|
||||
/// </summary>
|
||||
/// <param name="data">Data array</param>
|
||||
/// <param name="size">Array size</param>
|
||||
/// <param name="processedSize">Count of written bytes</param>
|
||||
/// <returns>Zero if Ok</returns>
|
||||
public int Write(byte[] data, uint size, IntPtr processedSize)
|
||||
{
|
||||
OnBytesWritten(new IntEventArgs((int) size));
|
||||
if (processedSize != IntPtr.Zero)
|
||||
{
|
||||
Marshal.WriteInt32(processedSize, (int) size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when IntEventArgs.Value bytes were written
|
||||
/// </summary>
|
||||
public event EventHandler<IntEventArgs> BytesWritten;
|
||||
|
||||
private void OnBytesWritten(IntEventArgs e)
|
||||
{
|
||||
if (BytesWritten != null)
|
||||
{
|
||||
BytesWritten(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace SevenZip.Sdk
|
||||
{
|
||||
internal class CRC
|
||||
{
|
||||
public static readonly uint[] Table;
|
||||
|
||||
private uint _value = 0xFFFFFFFF;
|
||||
|
||||
static CRC()
|
||||
{
|
||||
Table = new uint[256];
|
||||
const uint kPoly = 0xEDB88320;
|
||||
for (uint i = 0; i < 256; i++)
|
||||
{
|
||||
uint r = i;
|
||||
for (int j = 0; j < 8; j++)
|
||||
if ((r & 1) != 0)
|
||||
r = (r >> 1) ^ kPoly;
|
||||
else
|
||||
r >>= 1;
|
||||
Table[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
_value = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
public void UpdateByte(byte b)
|
||||
{
|
||||
_value = Table[(((byte) (_value)) ^ b)] ^ (_value >> 8);
|
||||
}
|
||||
|
||||
public void Update(byte[] data, uint offset, uint size)
|
||||
{
|
||||
for (uint i = 0; i < size; i++)
|
||||
_value = Table[(((byte) (_value)) ^ data[offset + i])] ^ (_value >> 8);
|
||||
}
|
||||
|
||||
public uint GetDigest()
|
||||
{
|
||||
return _value ^ 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
private static uint CalculateDigest(byte[] data, uint offset, uint size)
|
||||
{
|
||||
var crc = new CRC();
|
||||
// crc.Init();
|
||||
crc.Update(data, offset, size);
|
||||
return crc.GetDigest();
|
||||
}
|
||||
|
||||
private static bool VerifyDigest(uint digest, byte[] data, uint offset, uint size)
|
||||
{
|
||||
return (CalculateDigest(data, offset, size) == digest);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,119 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace SevenZip.Sdk.Buffer
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements the input buffer work
|
||||
/// </summary>
|
||||
internal class InBuffer
|
||||
{
|
||||
private readonly byte[] m_Buffer;
|
||||
private readonly uint m_BufferSize;
|
||||
private uint m_Limit;
|
||||
private uint m_Pos;
|
||||
private ulong m_ProcessedSize;
|
||||
private Stream m_Stream;
|
||||
private bool m_StreamWasExhausted;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the input buffer
|
||||
/// </summary>
|
||||
/// <param name="bufferSize"></param>
|
||||
private InBuffer(uint bufferSize)
|
||||
{
|
||||
m_Buffer = new byte[bufferSize];
|
||||
m_BufferSize = bufferSize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the class
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
private void Init(Stream stream)
|
||||
{
|
||||
m_Stream = stream;
|
||||
m_ProcessedSize = 0;
|
||||
m_Limit = 0;
|
||||
m_Pos = 0;
|
||||
m_StreamWasExhausted = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the whole block
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private bool ReadBlock()
|
||||
{
|
||||
if (m_StreamWasExhausted)
|
||||
return false;
|
||||
m_ProcessedSize += m_Pos;
|
||||
int aNumProcessedBytes = m_Stream.Read(m_Buffer, 0, (int) m_BufferSize);
|
||||
m_Pos = 0;
|
||||
m_Limit = (uint) aNumProcessedBytes;
|
||||
m_StreamWasExhausted = (aNumProcessedBytes == 0);
|
||||
return (!m_StreamWasExhausted);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases the stream
|
||||
/// </summary>
|
||||
private void ReleaseStream()
|
||||
{
|
||||
// m_Stream.Close();
|
||||
m_Stream = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the byte to check it
|
||||
/// </summary>
|
||||
/// <param name="b"></param>
|
||||
/// <returns></returns>
|
||||
private bool ReadByte(out byte b)
|
||||
{
|
||||
b = 0;
|
||||
if (m_Pos >= m_Limit)
|
||||
if (!ReadBlock())
|
||||
return false;
|
||||
b = m_Buffer[m_Pos++];
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the next byte
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private byte ReadByte()
|
||||
{
|
||||
// return (byte)m_Stream.ReadByte();
|
||||
if (m_Pos >= m_Limit)
|
||||
if (!ReadBlock())
|
||||
return 0xFF;
|
||||
return m_Buffer[m_Pos++];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets processed size
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private ulong GetProcessedSize()
|
||||
{
|
||||
return m_ProcessedSize + m_Pos;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace SevenZip.Sdk.Buffer
|
||||
{
|
||||
internal class OutBuffer
|
||||
{
|
||||
private readonly byte[] m_Buffer;
|
||||
private readonly uint m_BufferSize;
|
||||
private uint m_Pos;
|
||||
private ulong m_ProcessedSize;
|
||||
private Stream m_Stream;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the OutBuffer class
|
||||
/// </summary>
|
||||
/// <param name="bufferSize"></param>
|
||||
public OutBuffer(uint bufferSize)
|
||||
{
|
||||
m_Buffer = new byte[bufferSize];
|
||||
m_BufferSize = bufferSize;
|
||||
}
|
||||
|
||||
public void SetStream(Stream stream)
|
||||
{
|
||||
m_Stream = stream;
|
||||
}
|
||||
|
||||
public void FlushStream()
|
||||
{
|
||||
m_Stream.Flush();
|
||||
}
|
||||
|
||||
public void CloseStream()
|
||||
{
|
||||
m_Stream.Close();
|
||||
}
|
||||
|
||||
public void ReleaseStream()
|
||||
{
|
||||
m_Stream = null;
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
m_ProcessedSize = 0;
|
||||
m_Pos = 0;
|
||||
}
|
||||
|
||||
public void WriteByte(byte b)
|
||||
{
|
||||
m_Buffer[m_Pos++] = b;
|
||||
if (m_Pos >= m_BufferSize)
|
||||
FlushData();
|
||||
}
|
||||
|
||||
public void FlushData()
|
||||
{
|
||||
if (m_Pos == 0)
|
||||
return;
|
||||
m_Stream.Write(m_Buffer, 0, (int) m_Pos);
|
||||
m_Pos = 0;
|
||||
}
|
||||
|
||||
public ulong GetProcessedSize()
|
||||
{
|
||||
return m_ProcessedSize + m_Pos;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace SevenZip.Sdk.Compression.LZ
|
||||
{
|
||||
internal interface IInWindowStream
|
||||
{
|
||||
void SetStream(Stream inStream);
|
||||
void Init();
|
||||
void ReleaseStream();
|
||||
Byte GetIndexByte(Int32 index);
|
||||
UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit);
|
||||
UInt32 GetNumAvailableBytes();
|
||||
}
|
||||
|
||||
internal interface IMatchFinder : IInWindowStream
|
||||
{
|
||||
void Create(UInt32 historySize, UInt32 keepAddBufferBefore,
|
||||
UInt32 matchMaxLen, UInt32 keepAddBufferAfter);
|
||||
|
||||
UInt32 GetMatches(UInt32[] distances);
|
||||
void Skip(UInt32 num);
|
||||
}
|
||||
}
|
|
@ -1,405 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace SevenZip.Sdk.Compression.LZ
|
||||
{
|
||||
internal class BinTree : InWindow, IMatchFinder
|
||||
{
|
||||
private const UInt32 kBT2HashSize = 1 << 16;
|
||||
private const UInt32 kEmptyHashValue = 0;
|
||||
private const UInt32 kHash2Size = 1 << 10;
|
||||
private const UInt32 kHash3Offset = kHash2Size;
|
||||
private const UInt32 kHash3Size = 1 << 16;
|
||||
private const UInt32 kMaxValForNormalize = ((UInt32) 1 << 31) - 1;
|
||||
private const UInt32 kStartMaxLen = 1;
|
||||
private UInt32 _cutValue = 0xFF;
|
||||
private UInt32 _cyclicBufferPos;
|
||||
private UInt32 _cyclicBufferSize;
|
||||
private UInt32[] _hash;
|
||||
|
||||
private UInt32 _hashMask;
|
||||
private UInt32 _hashSizeSum;
|
||||
private UInt32 _matchMaxLen;
|
||||
|
||||
private UInt32[] _son;
|
||||
|
||||
private bool HASH_ARRAY = true;
|
||||
|
||||
private UInt32 kFixHashSize = kHash2Size + kHash3Size;
|
||||
private UInt32 kMinMatchCheck = 4;
|
||||
private UInt32 kNumHashDirectBytes;
|
||||
|
||||
#region IMatchFinder Members
|
||||
|
||||
public new void SetStream(Stream stream)
|
||||
{
|
||||
base.SetStream(stream);
|
||||
}
|
||||
|
||||
public new void ReleaseStream()
|
||||
{
|
||||
base.ReleaseStream();
|
||||
}
|
||||
|
||||
public new void Init()
|
||||
{
|
||||
base.Init();
|
||||
for (UInt32 i = 0; i < _hashSizeSum; i++)
|
||||
_hash[i] = kEmptyHashValue;
|
||||
_cyclicBufferPos = 0;
|
||||
ReduceOffsets(-1);
|
||||
}
|
||||
|
||||
public new Byte GetIndexByte(Int32 index)
|
||||
{
|
||||
return base.GetIndexByte(index);
|
||||
}
|
||||
|
||||
public new UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit)
|
||||
{
|
||||
return base.GetMatchLen(index, distance, limit);
|
||||
}
|
||||
|
||||
public new UInt32 GetNumAvailableBytes()
|
||||
{
|
||||
return base.GetNumAvailableBytes();
|
||||
}
|
||||
|
||||
public void Create(UInt32 historySize, UInt32 keepAddBufferBefore,
|
||||
UInt32 matchMaxLen, UInt32 keepAddBufferAfter)
|
||||
{
|
||||
if (historySize + 256 > kMaxValForNormalize)
|
||||
{
|
||||
throw new ArgumentException("historySize + 256 > kMaxValForNormalize", "historySize");
|
||||
}
|
||||
_cutValue = 16 + (matchMaxLen >> 1);
|
||||
|
||||
UInt32 windowReservSize = (historySize + keepAddBufferBefore +
|
||||
matchMaxLen + keepAddBufferAfter)/2 + 256;
|
||||
|
||||
base.Create(historySize + keepAddBufferBefore, matchMaxLen + keepAddBufferAfter, windowReservSize);
|
||||
|
||||
_matchMaxLen = matchMaxLen;
|
||||
|
||||
UInt32 cyclicBufferSize = historySize + 1;
|
||||
if (_cyclicBufferSize != cyclicBufferSize)
|
||||
_son = new UInt32[(_cyclicBufferSize = cyclicBufferSize)*2];
|
||||
|
||||
UInt32 hs = kBT2HashSize;
|
||||
|
||||
if (HASH_ARRAY)
|
||||
{
|
||||
hs = historySize - 1;
|
||||
hs |= (hs >> 1);
|
||||
hs |= (hs >> 2);
|
||||
hs |= (hs >> 4);
|
||||
hs |= (hs >> 8);
|
||||
hs >>= 1;
|
||||
hs |= 0xFFFF;
|
||||
if (hs > (1 << 24))
|
||||
hs >>= 1;
|
||||
_hashMask = hs;
|
||||
hs++;
|
||||
hs += kFixHashSize;
|
||||
}
|
||||
if (hs != _hashSizeSum)
|
||||
_hash = new UInt32[_hashSizeSum = hs];
|
||||
}
|
||||
|
||||
public UInt32 GetMatches(UInt32[] distances)
|
||||
{
|
||||
UInt32 lenLimit;
|
||||
if (_pos + _matchMaxLen <= _streamPos)
|
||||
lenLimit = _matchMaxLen;
|
||||
else
|
||||
{
|
||||
lenLimit = _streamPos - _pos;
|
||||
if (lenLimit < kMinMatchCheck)
|
||||
{
|
||||
MovePos();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 offset = 0;
|
||||
UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
|
||||
UInt32 cur = _bufferOffset + _pos;
|
||||
UInt32 maxLen = kStartMaxLen; // to avoid items for len < hashSize;
|
||||
UInt32 hashValue, hash2Value = 0, hash3Value = 0;
|
||||
|
||||
if (HASH_ARRAY)
|
||||
{
|
||||
UInt32 temp = CRC.Table[_bufferBase[cur]] ^ _bufferBase[cur + 1];
|
||||
hash2Value = (temp & (((int) kHash2Size) - 1));
|
||||
temp ^= (uint) ((_bufferBase[cur + 2]) << 8);
|
||||
hash3Value = (temp & (((int) kHash3Size) - 1));
|
||||
hashValue = (temp ^ (CRC.Table[_bufferBase[cur + 3]] << 5)) & _hashMask;
|
||||
}
|
||||
else
|
||||
hashValue = _bufferBase[cur] ^ ((UInt32) (_bufferBase[cur + 1]) << 8);
|
||||
|
||||
UInt32 curMatch = _hash[kFixHashSize + hashValue];
|
||||
if (HASH_ARRAY)
|
||||
{
|
||||
UInt32 curMatch2 = _hash[hash2Value];
|
||||
UInt32 curMatch3 = _hash[kHash3Offset + hash3Value];
|
||||
_hash[hash2Value] = _pos;
|
||||
_hash[kHash3Offset + hash3Value] = _pos;
|
||||
if (curMatch2 > matchMinPos)
|
||||
if (_bufferBase[_bufferOffset + curMatch2] == _bufferBase[cur])
|
||||
{
|
||||
distances[offset++] = maxLen = 2;
|
||||
distances[offset++] = _pos - curMatch2 - 1;
|
||||
}
|
||||
if (curMatch3 > matchMinPos)
|
||||
if (_bufferBase[_bufferOffset + curMatch3] == _bufferBase[cur])
|
||||
{
|
||||
if (curMatch3 == curMatch2)
|
||||
offset -= 2;
|
||||
distances[offset++] = maxLen = 3;
|
||||
distances[offset++] = _pos - curMatch3 - 1;
|
||||
curMatch2 = curMatch3;
|
||||
}
|
||||
if (offset != 0 && curMatch2 == curMatch)
|
||||
{
|
||||
offset -= 2;
|
||||
maxLen = kStartMaxLen;
|
||||
}
|
||||
}
|
||||
|
||||
_hash[kFixHashSize + hashValue] = _pos;
|
||||
|
||||
UInt32 ptr0 = (_cyclicBufferPos << 1) + 1;
|
||||
UInt32 ptr1 = (_cyclicBufferPos << 1);
|
||||
|
||||
UInt32 len0, len1;
|
||||
len0 = len1 = kNumHashDirectBytes;
|
||||
|
||||
if (kNumHashDirectBytes != 0)
|
||||
{
|
||||
if (curMatch > matchMinPos)
|
||||
{
|
||||
if (_bufferBase[_bufferOffset + curMatch + kNumHashDirectBytes] !=
|
||||
_bufferBase[cur + kNumHashDirectBytes])
|
||||
{
|
||||
distances[offset++] = maxLen = kNumHashDirectBytes;
|
||||
distances[offset++] = _pos - curMatch - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 count = _cutValue;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (curMatch <= matchMinPos || count-- == 0)
|
||||
{
|
||||
_son[ptr0] = _son[ptr1] = kEmptyHashValue;
|
||||
break;
|
||||
}
|
||||
UInt32 delta = _pos - curMatch;
|
||||
UInt32 cyclicPos = ((delta <= _cyclicBufferPos)
|
||||
?
|
||||
(_cyclicBufferPos - delta)
|
||||
:
|
||||
(_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;
|
||||
|
||||
UInt32 pby1 = _bufferOffset + curMatch;
|
||||
UInt32 len = Math.Min(len0, len1);
|
||||
if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
|
||||
{
|
||||
while (++len != lenLimit)
|
||||
if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
|
||||
break;
|
||||
if (maxLen < len)
|
||||
{
|
||||
distances[offset++] = maxLen = len;
|
||||
distances[offset++] = delta - 1;
|
||||
if (len == lenLimit)
|
||||
{
|
||||
_son[ptr1] = _son[cyclicPos];
|
||||
_son[ptr0] = _son[cyclicPos + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_bufferBase[pby1 + len] < _bufferBase[cur + len])
|
||||
{
|
||||
_son[ptr1] = curMatch;
|
||||
ptr1 = cyclicPos + 1;
|
||||
curMatch = _son[ptr1];
|
||||
len1 = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
_son[ptr0] = curMatch;
|
||||
ptr0 = cyclicPos;
|
||||
curMatch = _son[ptr0];
|
||||
len0 = len;
|
||||
}
|
||||
}
|
||||
MovePos();
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void Skip(UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
UInt32 lenLimit;
|
||||
if (_pos + _matchMaxLen <= _streamPos)
|
||||
lenLimit = _matchMaxLen;
|
||||
else
|
||||
{
|
||||
lenLimit = _streamPos - _pos;
|
||||
if (lenLimit < kMinMatchCheck)
|
||||
{
|
||||
MovePos();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
|
||||
UInt32 cur = _bufferOffset + _pos;
|
||||
|
||||
UInt32 hashValue;
|
||||
|
||||
if (HASH_ARRAY)
|
||||
{
|
||||
UInt32 temp = CRC.Table[_bufferBase[cur]] ^ _bufferBase[cur + 1];
|
||||
UInt32 hash2Value = (temp & (((int) kHash2Size) - 1));
|
||||
_hash[hash2Value] = _pos;
|
||||
temp ^= ((UInt32) (_bufferBase[cur + 2]) << 8);
|
||||
UInt32 hash3Value = (temp & (((int) kHash3Size) - 1));
|
||||
_hash[kHash3Offset + hash3Value] = _pos;
|
||||
hashValue = (temp ^ (CRC.Table[_bufferBase[cur + 3]] << 5)) & _hashMask;
|
||||
}
|
||||
else
|
||||
hashValue = _bufferBase[cur] ^ ((UInt32) (_bufferBase[cur + 1]) << 8);
|
||||
|
||||
UInt32 curMatch = _hash[kFixHashSize + hashValue];
|
||||
_hash[kFixHashSize + hashValue] = _pos;
|
||||
|
||||
UInt32 ptr0 = (_cyclicBufferPos << 1) + 1;
|
||||
UInt32 ptr1 = (_cyclicBufferPos << 1);
|
||||
|
||||
UInt32 len0, len1;
|
||||
len0 = len1 = kNumHashDirectBytes;
|
||||
|
||||
UInt32 count = _cutValue;
|
||||
while (true)
|
||||
{
|
||||
if (curMatch <= matchMinPos || count-- == 0)
|
||||
{
|
||||
_son[ptr0] = _son[ptr1] = kEmptyHashValue;
|
||||
break;
|
||||
}
|
||||
|
||||
UInt32 delta = _pos - curMatch;
|
||||
UInt32 cyclicPos = ((delta <= _cyclicBufferPos)
|
||||
?
|
||||
(_cyclicBufferPos - delta)
|
||||
:
|
||||
(_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;
|
||||
|
||||
UInt32 pby1 = _bufferOffset + curMatch;
|
||||
UInt32 len = Math.Min(len0, len1);
|
||||
if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
|
||||
{
|
||||
while (++len != lenLimit)
|
||||
if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
|
||||
break;
|
||||
if (len == lenLimit)
|
||||
{
|
||||
_son[ptr1] = _son[cyclicPos];
|
||||
_son[ptr0] = _son[cyclicPos + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_bufferBase[pby1 + len] < _bufferBase[cur + len])
|
||||
{
|
||||
_son[ptr1] = curMatch;
|
||||
ptr1 = cyclicPos + 1;
|
||||
curMatch = _son[ptr1];
|
||||
len1 = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
_son[ptr0] = curMatch;
|
||||
ptr0 = cyclicPos;
|
||||
curMatch = _son[ptr0];
|
||||
len0 = len;
|
||||
}
|
||||
}
|
||||
MovePos();
|
||||
} while (--num != 0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void SetType(int numHashBytes)
|
||||
{
|
||||
HASH_ARRAY = (numHashBytes > 2);
|
||||
if (HASH_ARRAY)
|
||||
{
|
||||
kNumHashDirectBytes = 0;
|
||||
kMinMatchCheck = 4;
|
||||
kFixHashSize = kHash2Size + kHash3Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
kNumHashDirectBytes = 2;
|
||||
kMinMatchCheck = 2 + 1;
|
||||
kFixHashSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public new void MovePos()
|
||||
{
|
||||
if (++_cyclicBufferPos >= _cyclicBufferSize)
|
||||
_cyclicBufferPos = 0;
|
||||
base.MovePos();
|
||||
if (_pos == kMaxValForNormalize)
|
||||
Normalize();
|
||||
}
|
||||
|
||||
private static void NormalizeLinks(UInt32[] items, UInt32 numItems, UInt32 subValue)
|
||||
{
|
||||
for (UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
UInt32 value = items[i];
|
||||
if (value <= subValue)
|
||||
value = kEmptyHashValue;
|
||||
else
|
||||
value -= subValue;
|
||||
items[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
private void Normalize()
|
||||
{
|
||||
UInt32 subValue = _pos - _cyclicBufferSize;
|
||||
NormalizeLinks(_son, _cyclicBufferSize*2, subValue);
|
||||
NormalizeLinks(_hash, _hashSizeSum, subValue);
|
||||
ReduceOffsets((Int32) subValue);
|
||||
}
|
||||
|
||||
//public void SetCutValue(UInt32 cutValue) { _cutValue = cutValue; }
|
||||
}
|
||||
}
|
|
@ -1,197 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace SevenZip.Sdk.Compression.LZ
|
||||
{
|
||||
/// <summary>
|
||||
/// Input window class
|
||||
/// </summary>
|
||||
internal class InWindow
|
||||
{
|
||||
/// <summary>
|
||||
/// Size of Allocated memory block
|
||||
/// </summary>
|
||||
public UInt32 _blockSize;
|
||||
|
||||
/// <summary>
|
||||
/// The pointer to buffer with data
|
||||
/// </summary>
|
||||
public Byte[] _bufferBase;
|
||||
|
||||
/// <summary>
|
||||
/// Buffer offset value
|
||||
/// </summary>
|
||||
public UInt32 _bufferOffset;
|
||||
|
||||
/// <summary>
|
||||
/// How many BYTEs must be kept buffer after _pos
|
||||
/// </summary>
|
||||
private UInt32 _keepSizeAfter;
|
||||
|
||||
/// <summary>
|
||||
/// How many BYTEs must be kept in buffer before _pos
|
||||
/// </summary>
|
||||
private UInt32 _keepSizeBefore;
|
||||
|
||||
private UInt32 _pointerToLastSafePosition;
|
||||
|
||||
/// <summary>
|
||||
/// Offset (from _buffer) of curent byte
|
||||
/// </summary>
|
||||
public UInt32 _pos;
|
||||
|
||||
private UInt32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done
|
||||
private Stream _stream;
|
||||
private bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream
|
||||
|
||||
/// <summary>
|
||||
/// Offset (from _buffer) of first not read byte from Stream
|
||||
/// </summary>
|
||||
public UInt32 _streamPos;
|
||||
|
||||
public void MoveBlock()
|
||||
{
|
||||
UInt32 offset = (_bufferOffset) + _pos - _keepSizeBefore;
|
||||
// we need one additional byte, since MovePos moves on 1 byte.
|
||||
if (offset > 0)
|
||||
offset--;
|
||||
|
||||
UInt32 numBytes = (_bufferOffset) + _streamPos - offset;
|
||||
|
||||
// check negative offset ????
|
||||
for (UInt32 i = 0; i < numBytes; i++)
|
||||
_bufferBase[i] = _bufferBase[offset + i];
|
||||
_bufferOffset -= offset;
|
||||
}
|
||||
|
||||
public virtual void ReadBlock()
|
||||
{
|
||||
if (_streamEndWasReached)
|
||||
return;
|
||||
while (true)
|
||||
{
|
||||
var size = (int) ((0 - _bufferOffset) + _blockSize - _streamPos);
|
||||
if (size == 0)
|
||||
return;
|
||||
int numReadBytes = _stream.Read(_bufferBase, (int) (_bufferOffset + _streamPos), size);
|
||||
if (numReadBytes == 0)
|
||||
{
|
||||
_posLimit = _streamPos;
|
||||
UInt32 pointerToPostion = _bufferOffset + _posLimit;
|
||||
if (pointerToPostion > _pointerToLastSafePosition)
|
||||
_posLimit = (_pointerToLastSafePosition - _bufferOffset);
|
||||
|
||||
_streamEndWasReached = true;
|
||||
return;
|
||||
}
|
||||
_streamPos += (UInt32) numReadBytes;
|
||||
if (_streamPos >= _pos + _keepSizeAfter)
|
||||
_posLimit = _streamPos - _keepSizeAfter;
|
||||
}
|
||||
}
|
||||
|
||||
private void Free()
|
||||
{
|
||||
_bufferBase = null;
|
||||
}
|
||||
|
||||
public void Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv)
|
||||
{
|
||||
_keepSizeBefore = keepSizeBefore;
|
||||
_keepSizeAfter = keepSizeAfter;
|
||||
UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
|
||||
if (_bufferBase == null || _blockSize != blockSize)
|
||||
{
|
||||
Free();
|
||||
_blockSize = blockSize;
|
||||
_bufferBase = new Byte[_blockSize];
|
||||
}
|
||||
_pointerToLastSafePosition = _blockSize - keepSizeAfter;
|
||||
}
|
||||
|
||||
public void SetStream(Stream stream)
|
||||
{
|
||||
_stream = stream;
|
||||
}
|
||||
|
||||
public void ReleaseStream()
|
||||
{
|
||||
_stream = null;
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
_bufferOffset = 0;
|
||||
_pos = 0;
|
||||
_streamPos = 0;
|
||||
_streamEndWasReached = false;
|
||||
ReadBlock();
|
||||
}
|
||||
|
||||
public void MovePos()
|
||||
{
|
||||
_pos++;
|
||||
if (_pos > _posLimit)
|
||||
{
|
||||
UInt32 pointerToPostion = _bufferOffset + _pos;
|
||||
if (pointerToPostion > _pointerToLastSafePosition)
|
||||
MoveBlock();
|
||||
ReadBlock();
|
||||
}
|
||||
}
|
||||
|
||||
public Byte GetIndexByte(Int32 index)
|
||||
{
|
||||
return _bufferBase[_bufferOffset + _pos + index];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// index + limit have not to exceed _keepSizeAfter
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="distance"></param>
|
||||
/// <param name="limit"></param>
|
||||
/// <returns></returns>
|
||||
public UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit)
|
||||
{
|
||||
if (_streamEndWasReached)
|
||||
if ((_pos + index) + limit > _streamPos)
|
||||
limit = _streamPos - (UInt32) (_pos + index);
|
||||
distance++;
|
||||
// Byte *pby = _buffer + (size_t)_pos + index;
|
||||
UInt32 pby = _bufferOffset + _pos + (UInt32) index;
|
||||
|
||||
UInt32 i;
|
||||
for (i = 0; i < limit && _bufferBase[pby + i] == _bufferBase[pby + i - distance]; i++) ;
|
||||
return i;
|
||||
}
|
||||
|
||||
public UInt32 GetNumAvailableBytes()
|
||||
{
|
||||
return _streamPos - _pos;
|
||||
}
|
||||
|
||||
public void ReduceOffsets(Int32 subValue)
|
||||
{
|
||||
_bufferOffset += (UInt32) subValue;
|
||||
_posLimit -= (UInt32) subValue;
|
||||
_pos -= (UInt32) subValue;
|
||||
_streamPos -= (UInt32) subValue;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace SevenZip.Sdk.Compression.LZ
|
||||
{
|
||||
internal class OutWindow
|
||||
{
|
||||
private byte[] _buffer;
|
||||
private uint _pos;
|
||||
private Stream _stream;
|
||||
private uint _streamPos;
|
||||
private uint _windowSize;
|
||||
public uint TrainSize;
|
||||
|
||||
public void Create(uint windowSize)
|
||||
{
|
||||
if (_windowSize != windowSize)
|
||||
{
|
||||
// System.GC.Collect();
|
||||
_buffer = new byte[windowSize];
|
||||
}
|
||||
_windowSize = windowSize;
|
||||
_pos = 0;
|
||||
_streamPos = 0;
|
||||
}
|
||||
|
||||
public void Init(Stream stream, bool solid)
|
||||
{
|
||||
ReleaseStream();
|
||||
_stream = stream;
|
||||
if (!solid)
|
||||
{
|
||||
_streamPos = 0;
|
||||
_pos = 0;
|
||||
TrainSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Train(Stream stream)
|
||||
{
|
||||
long len = stream.Length;
|
||||
uint size = (len < _windowSize) ? (uint) len : _windowSize;
|
||||
TrainSize = size;
|
||||
stream.Position = len - size;
|
||||
_streamPos = _pos = 0;
|
||||
while (size > 0)
|
||||
{
|
||||
uint curSize = _windowSize - _pos;
|
||||
if (size < curSize)
|
||||
curSize = size;
|
||||
int numReadBytes = stream.Read(_buffer, (int) _pos, (int) curSize);
|
||||
if (numReadBytes == 0)
|
||||
return false;
|
||||
size -= (uint) numReadBytes;
|
||||
_pos += (uint) numReadBytes;
|
||||
_streamPos += (uint) numReadBytes;
|
||||
if (_pos == _windowSize)
|
||||
_streamPos = _pos = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ReleaseStream()
|
||||
{
|
||||
Flush();
|
||||
_stream = null;
|
||||
}
|
||||
|
||||
public void Flush()
|
||||
{
|
||||
uint size = _pos - _streamPos;
|
||||
if (size == 0)
|
||||
return;
|
||||
_stream.Write(_buffer, (int) _streamPos, (int) size);
|
||||
if (_pos >= _windowSize)
|
||||
_pos = 0;
|
||||
_streamPos = _pos;
|
||||
}
|
||||
|
||||
public void CopyBlock(uint distance, uint len)
|
||||
{
|
||||
uint pos = _pos - distance - 1;
|
||||
if (pos >= _windowSize)
|
||||
pos += _windowSize;
|
||||
for (; len > 0; len--)
|
||||
{
|
||||
if (pos >= _windowSize)
|
||||
pos = 0;
|
||||
_buffer[_pos++] = _buffer[pos++];
|
||||
if (_pos >= _windowSize)
|
||||
Flush();
|
||||
}
|
||||
}
|
||||
|
||||
public void PutByte(byte b)
|
||||
{
|
||||
_buffer[_pos++] = b;
|
||||
if (_pos >= _windowSize)
|
||||
Flush();
|
||||
}
|
||||
|
||||
public byte GetByte(uint distance)
|
||||
{
|
||||
uint pos = _pos - distance - 1;
|
||||
if (pos >= _windowSize)
|
||||
pos += _windowSize;
|
||||
return _buffer[pos];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,108 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace SevenZip.Sdk.Compression.Lzma
|
||||
{
|
||||
internal abstract class Base
|
||||
{
|
||||
public const uint kAlignMask = (kAlignTableSize - 1);
|
||||
public const uint kAlignTableSize = 1 << kNumAlignBits;
|
||||
public const int kDicLogSizeMin = 0;
|
||||
public const uint kEndPosModelIndex = 14;
|
||||
public const uint kMatchMaxLen = kMatchMinLen + kNumLenSymbols - 1;
|
||||
// public const int kDicLogSizeMax = 30;
|
||||
// public const uint kDistTableSizeMax = kDicLogSizeMax * 2;
|
||||
|
||||
public const uint kMatchMinLen = 2;
|
||||
|
||||
public const int kNumAlignBits = 4;
|
||||
|
||||
public const uint kNumFullDistances = 1 << ((int) kEndPosModelIndex/2);
|
||||
public const int kNumHighLenBits = 8;
|
||||
|
||||
public const uint kNumLenSymbols = kNumLowLenSymbols + kNumMidLenSymbols +
|
||||
(1 << kNumHighLenBits);
|
||||
|
||||
public const uint kNumLenToPosStates = 1 << kNumLenToPosStatesBits;
|
||||
public const int kNumLenToPosStatesBits = 2; // it's for speed optimization
|
||||
|
||||
public const uint kNumLitContextBitsMax = 8;
|
||||
public const uint kNumLitPosStatesBitsEncodingMax = 4;
|
||||
|
||||
public const int kNumLowLenBits = 3;
|
||||
public const uint kNumLowLenSymbols = 1 << kNumLowLenBits;
|
||||
public const int kNumMidLenBits = 3;
|
||||
public const uint kNumMidLenSymbols = 1 << kNumMidLenBits;
|
||||
public const uint kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
|
||||
public const int kNumPosSlotBits = 6;
|
||||
public const int kNumPosStatesBitsEncodingMax = 4;
|
||||
public const int kNumPosStatesBitsMax = 4;
|
||||
public const uint kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
|
||||
public const uint kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
|
||||
public const uint kNumRepDistances = 4;
|
||||
public const uint kNumStates = 12;
|
||||
public const uint kStartPosModelIndex = 4;
|
||||
|
||||
public static uint GetLenToPosState(uint len)
|
||||
{
|
||||
len -= kMatchMinLen;
|
||||
if (len < kNumLenToPosStates)
|
||||
return len;
|
||||
return (kNumLenToPosStates - 1);
|
||||
}
|
||||
|
||||
#region Nested type: State
|
||||
|
||||
public struct State
|
||||
{
|
||||
public uint Index;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
Index = 0;
|
||||
}
|
||||
|
||||
public void UpdateChar()
|
||||
{
|
||||
if (Index < 4) Index = 0;
|
||||
else if (Index < 10) Index -= 3;
|
||||
else Index -= 6;
|
||||
}
|
||||
|
||||
public void UpdateMatch()
|
||||
{
|
||||
Index = (uint) (Index < 7 ? 7 : 10);
|
||||
}
|
||||
|
||||
public void UpdateRep()
|
||||
{
|
||||
Index = (uint) (Index < 7 ? 8 : 11);
|
||||
}
|
||||
|
||||
public void UpdateShortRep()
|
||||
{
|
||||
Index = (uint) (Index < 7 ? 9 : 11);
|
||||
}
|
||||
|
||||
public bool IsCharState()
|
||||
{
|
||||
return Index < 7;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,480 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using SevenZip.Sdk.Compression.LZ;
|
||||
using SevenZip.Sdk.Compression.RangeCoder;
|
||||
|
||||
namespace SevenZip.Sdk.Compression.Lzma
|
||||
{
|
||||
/// <summary>
|
||||
/// The LZMA decoder class
|
||||
/// </summary>
|
||||
public class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream
|
||||
{
|
||||
private readonly BitDecoder[] m_IsMatchDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
|
||||
|
||||
private readonly BitDecoder[] m_IsRep0LongDecoders =
|
||||
new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
|
||||
|
||||
private readonly BitDecoder[] m_IsRepDecoders = new BitDecoder[Base.kNumStates];
|
||||
private readonly BitDecoder[] m_IsRepG0Decoders = new BitDecoder[Base.kNumStates];
|
||||
private readonly BitDecoder[] m_IsRepG1Decoders = new BitDecoder[Base.kNumStates];
|
||||
private readonly BitDecoder[] m_IsRepG2Decoders = new BitDecoder[Base.kNumStates];
|
||||
|
||||
private readonly LenDecoder m_LenDecoder = new LenDecoder();
|
||||
|
||||
private readonly LiteralDecoder m_LiteralDecoder = new LiteralDecoder();
|
||||
private readonly OutWindow m_OutWindow = new OutWindow();
|
||||
private readonly BitDecoder[] m_PosDecoders = new BitDecoder[Base.kNumFullDistances - Base.kEndPosModelIndex];
|
||||
private readonly BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates];
|
||||
private readonly RangeCoder.Decoder m_RangeDecoder = new RangeCoder.Decoder();
|
||||
private readonly LenDecoder m_RepLenDecoder = new LenDecoder();
|
||||
private bool _solid;
|
||||
|
||||
private uint m_DictionarySize;
|
||||
private uint m_DictionarySizeCheck;
|
||||
private BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits);
|
||||
|
||||
private uint m_PosStateMask;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the Lzma Decoder class.
|
||||
/// </summary>
|
||||
public Decoder()
|
||||
{
|
||||
m_DictionarySize = 0xFFFFFFFF;
|
||||
for (int i = 0; i < Base.kNumLenToPosStates; i++)
|
||||
m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits);
|
||||
}
|
||||
|
||||
#region ICoder Members
|
||||
|
||||
/// <summary>
|
||||
/// Codes a stream with LZMA algorithm to an output stream
|
||||
/// </summary>
|
||||
/// <param name="inStream">The input stream</param>
|
||||
/// <param name="inSize">The input size</param>
|
||||
/// <param name="outSize">The output size</param>
|
||||
/// <param name="outStream">The output stream</param>
|
||||
/// <param name="progress">Progress interface</param>
|
||||
public void Code(Stream inStream, Stream outStream,
|
||||
Int64 inSize, Int64 outSize, ICodeProgress progress)
|
||||
{
|
||||
Init(inStream, outStream);
|
||||
|
||||
var state = new Base.State();
|
||||
state.Init();
|
||||
uint rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
|
||||
|
||||
UInt64 nowPos64 = 0;
|
||||
var outSize64 = (UInt64) outSize;
|
||||
if (nowPos64 < outSize64)
|
||||
{
|
||||
if (m_IsMatchDecoders[state.Index << Base.kNumPosStatesBitsMax].Decode(m_RangeDecoder) != 0)
|
||||
throw new DataErrorException();
|
||||
state.UpdateChar();
|
||||
byte b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, 0, 0);
|
||||
m_OutWindow.PutByte(b);
|
||||
nowPos64++;
|
||||
}
|
||||
while (nowPos64 < outSize64)
|
||||
{
|
||||
// UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64);
|
||||
// while(nowPos64 < next)
|
||||
{
|
||||
uint posState = (uint) nowPos64 & m_PosStateMask;
|
||||
if (
|
||||
m_IsMatchDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) ==
|
||||
0)
|
||||
{
|
||||
byte b;
|
||||
byte prevByte = m_OutWindow.GetByte(0);
|
||||
if (!state.IsCharState())
|
||||
b = m_LiteralDecoder.DecodeWithMatchByte(m_RangeDecoder,
|
||||
(uint) nowPos64, prevByte,
|
||||
m_OutWindow.GetByte(rep0));
|
||||
else
|
||||
b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, (uint) nowPos64, prevByte);
|
||||
m_OutWindow.PutByte(b);
|
||||
state.UpdateChar();
|
||||
nowPos64++;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint len;
|
||||
if (m_IsRepDecoders[state.Index].Decode(m_RangeDecoder) == 1)
|
||||
{
|
||||
if (m_IsRepG0Decoders[state.Index].Decode(m_RangeDecoder) == 0)
|
||||
{
|
||||
if (
|
||||
m_IsRep0LongDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(
|
||||
m_RangeDecoder) == 0)
|
||||
{
|
||||
state.UpdateShortRep();
|
||||
m_OutWindow.PutByte(m_OutWindow.GetByte(rep0));
|
||||
nowPos64++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 distance;
|
||||
if (m_IsRepG1Decoders[state.Index].Decode(m_RangeDecoder) == 0)
|
||||
{
|
||||
distance = rep1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_IsRepG2Decoders[state.Index].Decode(m_RangeDecoder) == 0)
|
||||
distance = rep2;
|
||||
else
|
||||
{
|
||||
distance = rep3;
|
||||
rep3 = rep2;
|
||||
}
|
||||
rep2 = rep1;
|
||||
}
|
||||
rep1 = rep0;
|
||||
rep0 = distance;
|
||||
}
|
||||
len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen;
|
||||
state.UpdateRep();
|
||||
}
|
||||
else
|
||||
{
|
||||
rep3 = rep2;
|
||||
rep2 = rep1;
|
||||
rep1 = rep0;
|
||||
len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState);
|
||||
state.UpdateMatch();
|
||||
uint posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder);
|
||||
if (posSlot >= Base.kStartPosModelIndex)
|
||||
{
|
||||
var numDirectBits = (int) ((posSlot >> 1) - 1);
|
||||
rep0 = ((2 | (posSlot & 1)) << numDirectBits);
|
||||
if (posSlot < Base.kEndPosModelIndex)
|
||||
rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders,
|
||||
rep0 - posSlot - 1, m_RangeDecoder,
|
||||
numDirectBits);
|
||||
else
|
||||
{
|
||||
rep0 += (m_RangeDecoder.DecodeDirectBits(
|
||||
numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits);
|
||||
rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder);
|
||||
}
|
||||
}
|
||||
else
|
||||
rep0 = posSlot;
|
||||
}
|
||||
if (rep0 >= m_OutWindow.TrainSize + nowPos64 || rep0 >= m_DictionarySizeCheck)
|
||||
{
|
||||
if (rep0 == 0xFFFFFFFF)
|
||||
break;
|
||||
throw new DataErrorException();
|
||||
}
|
||||
m_OutWindow.CopyBlock(rep0, len);
|
||||
nowPos64 += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_OutWindow.Flush();
|
||||
m_OutWindow.ReleaseStream();
|
||||
m_RangeDecoder.ReleaseStream();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ISetDecoderProperties Members
|
||||
|
||||
/// <summary>
|
||||
/// Sets decoder properties
|
||||
/// </summary>
|
||||
/// <param name="properties">Array of byte properties</param>
|
||||
public void SetDecoderProperties(byte[] properties)
|
||||
{
|
||||
if (properties.Length < 5)
|
||||
throw new InvalidParamException();
|
||||
int lc = properties[0]%9;
|
||||
int remainder = properties[0]/9;
|
||||
int lp = remainder%5;
|
||||
int pb = remainder/5;
|
||||
if (pb > Base.kNumPosStatesBitsMax)
|
||||
throw new InvalidParamException();
|
||||
UInt32 dictionarySize = 0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
dictionarySize += ((UInt32) (properties[1 + i])) << (i*8);
|
||||
SetDictionarySize(dictionarySize);
|
||||
SetLiteralProperties(lp, lc);
|
||||
SetPosBitsProperties(pb);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void SetDictionarySize(uint dictionarySize)
|
||||
{
|
||||
if (m_DictionarySize != dictionarySize)
|
||||
{
|
||||
m_DictionarySize = dictionarySize;
|
||||
m_DictionarySizeCheck = Math.Max(m_DictionarySize, 1);
|
||||
uint blockSize = Math.Max(m_DictionarySizeCheck, (1 << 12));
|
||||
m_OutWindow.Create(blockSize);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetLiteralProperties(int lp, int lc)
|
||||
{
|
||||
if (lp > 8)
|
||||
throw new InvalidParamException();
|
||||
if (lc > 8)
|
||||
throw new InvalidParamException();
|
||||
m_LiteralDecoder.Create(lp, lc);
|
||||
}
|
||||
|
||||
private void SetPosBitsProperties(int pb)
|
||||
{
|
||||
if (pb > Base.kNumPosStatesBitsMax)
|
||||
throw new InvalidParamException();
|
||||
uint numPosStates = (uint) 1 << pb;
|
||||
m_LenDecoder.Create(numPosStates);
|
||||
m_RepLenDecoder.Create(numPosStates);
|
||||
m_PosStateMask = numPosStates - 1;
|
||||
}
|
||||
|
||||
private void Init(Stream inStream, Stream outStream)
|
||||
{
|
||||
m_RangeDecoder.Init(inStream);
|
||||
m_OutWindow.Init(outStream, _solid);
|
||||
|
||||
uint i;
|
||||
for (i = 0; i < Base.kNumStates; i++)
|
||||
{
|
||||
for (uint j = 0; j <= m_PosStateMask; j++)
|
||||
{
|
||||
uint index = (i << Base.kNumPosStatesBitsMax) + j;
|
||||
m_IsMatchDecoders[index].Init();
|
||||
m_IsRep0LongDecoders[index].Init();
|
||||
}
|
||||
m_IsRepDecoders[i].Init();
|
||||
m_IsRepG0Decoders[i].Init();
|
||||
m_IsRepG1Decoders[i].Init();
|
||||
m_IsRepG2Decoders[i].Init();
|
||||
}
|
||||
|
||||
m_LiteralDecoder.Init();
|
||||
for (i = 0; i < Base.kNumLenToPosStates; i++)
|
||||
m_PosSlotDecoder[i].Init();
|
||||
// m_PosSpecDecoder.Init();
|
||||
for (i = 0; i < Base.kNumFullDistances - Base.kEndPosModelIndex; i++)
|
||||
m_PosDecoders[i].Init();
|
||||
|
||||
m_LenDecoder.Init();
|
||||
m_RepLenDecoder.Init();
|
||||
m_PosAlignDecoder.Init();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Trains a stream
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream to train.</param>
|
||||
/// <returns>true if Ok; otherwise, false.</returns>
|
||||
public bool Train(Stream stream)
|
||||
{
|
||||
_solid = true;
|
||||
return m_OutWindow.Train(stream);
|
||||
}
|
||||
|
||||
#region Nested type: LenDecoder
|
||||
|
||||
private class LenDecoder
|
||||
{
|
||||
private readonly BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
|
||||
private readonly BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
|
||||
private BitDecoder m_Choice;
|
||||
private BitDecoder m_Choice2;
|
||||
private BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits);
|
||||
private uint m_NumPosStates;
|
||||
|
||||
internal void Create(uint numPosStates)
|
||||
{
|
||||
for (uint posState = m_NumPosStates; posState < numPosStates; posState++)
|
||||
{
|
||||
m_LowCoder[posState] = new BitTreeDecoder(Base.kNumLowLenBits);
|
||||
m_MidCoder[posState] = new BitTreeDecoder(Base.kNumMidLenBits);
|
||||
}
|
||||
m_NumPosStates = numPosStates;
|
||||
}
|
||||
|
||||
internal void Init()
|
||||
{
|
||||
m_Choice.Init();
|
||||
for (uint posState = 0; posState < m_NumPosStates; posState++)
|
||||
{
|
||||
m_LowCoder[posState].Init();
|
||||
m_MidCoder[posState].Init();
|
||||
}
|
||||
m_Choice2.Init();
|
||||
m_HighCoder.Init();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decodes the stream
|
||||
/// </summary>
|
||||
/// <param name="rangeDecoder">The specified RangeCoder</param>
|
||||
/// <param name="posState">The position state</param>
|
||||
/// <returns></returns>
|
||||
public uint Decode(RangeCoder.Decoder rangeDecoder, uint posState)
|
||||
{
|
||||
if (m_Choice.Decode(rangeDecoder) == 0)
|
||||
return m_LowCoder[posState].Decode(rangeDecoder);
|
||||
else
|
||||
{
|
||||
uint symbol = Base.kNumLowLenSymbols;
|
||||
if (m_Choice2.Decode(rangeDecoder) == 0)
|
||||
symbol += m_MidCoder[posState].Decode(rangeDecoder);
|
||||
else
|
||||
{
|
||||
symbol += Base.kNumMidLenSymbols;
|
||||
symbol += m_HighCoder.Decode(rangeDecoder);
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: LiteralDecoder
|
||||
|
||||
private class LiteralDecoder
|
||||
{
|
||||
private Decoder2[] m_Coders;
|
||||
private int m_NumPosBits;
|
||||
private int m_NumPrevBits;
|
||||
private uint m_PosMask;
|
||||
|
||||
public void Create(int numPosBits, int numPrevBits)
|
||||
{
|
||||
if (m_Coders != null && m_NumPrevBits == numPrevBits &&
|
||||
m_NumPosBits == numPosBits)
|
||||
return;
|
||||
m_NumPosBits = numPosBits;
|
||||
m_PosMask = ((uint) 1 << numPosBits) - 1;
|
||||
m_NumPrevBits = numPrevBits;
|
||||
uint numStates = (uint) 1 << (m_NumPrevBits + m_NumPosBits);
|
||||
m_Coders = new Decoder2[numStates];
|
||||
for (uint i = 0; i < numStates; i++)
|
||||
m_Coders[i].Create();
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
uint numStates = (uint) 1 << (m_NumPrevBits + m_NumPosBits);
|
||||
for (uint i = 0; i < numStates; i++)
|
||||
m_Coders[i].Init();
|
||||
}
|
||||
|
||||
private uint GetState(uint pos, byte prevByte)
|
||||
{
|
||||
return ((pos & m_PosMask) << m_NumPrevBits) + (uint) (prevByte >> (8 - m_NumPrevBits));
|
||||
}
|
||||
|
||||
public byte DecodeNormal(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte)
|
||||
{
|
||||
return m_Coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder);
|
||||
}
|
||||
|
||||
public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte, byte matchByte)
|
||||
{
|
||||
return m_Coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte);
|
||||
}
|
||||
|
||||
#region Nested type: Decoder2
|
||||
|
||||
private struct Decoder2
|
||||
{
|
||||
private BitDecoder[] m_Decoders;
|
||||
|
||||
public void Create()
|
||||
{
|
||||
m_Decoders = new BitDecoder[0x300];
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
for (int i = 0; i < 0x300; i++) m_Decoders[i].Init();
|
||||
}
|
||||
|
||||
public byte DecodeNormal(RangeCoder.Decoder rangeDecoder)
|
||||
{
|
||||
uint symbol = 1;
|
||||
do
|
||||
symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder); while (symbol < 0x100);
|
||||
return (byte) symbol;
|
||||
}
|
||||
|
||||
public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, byte matchByte)
|
||||
{
|
||||
uint symbol = 1;
|
||||
do
|
||||
{
|
||||
uint matchBit = (uint) (matchByte >> 7) & 1;
|
||||
matchByte <<= 1;
|
||||
uint bit = m_Decoders[((1 + matchBit) << 8) + symbol].Decode(rangeDecoder);
|
||||
symbol = (symbol << 1) | bit;
|
||||
if (matchBit != bit)
|
||||
{
|
||||
while (symbol < 0x100)
|
||||
symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder);
|
||||
break;
|
||||
}
|
||||
} while (symbol < 0x100);
|
||||
return (byte) symbol;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
} ;
|
||||
|
||||
#endregion
|
||||
|
||||
/*
|
||||
public override bool CanRead { get { return true; }}
|
||||
public override bool CanWrite { get { return true; }}
|
||||
public override bool CanSeek { get { return true; }}
|
||||
public override long Length { get { return 0; }}
|
||||
public override long Position
|
||||
{
|
||||
get { return 0; }
|
||||
set { }
|
||||
}
|
||||
public override void Flush() { }
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
}
|
||||
public override long Seek(long offset, System.IO.SeekOrigin origin)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
public override void SetLength(long value) {}
|
||||
*/
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,249 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace SevenZip.Sdk.Compression.RangeCoder
|
||||
{
|
||||
internal class Encoder
|
||||
{
|
||||
public const uint kTopValue = (1 << 24);
|
||||
private byte _cache;
|
||||
private uint _cacheSize;
|
||||
|
||||
public UInt64 Low;
|
||||
public uint Range;
|
||||
|
||||
private long StartPosition;
|
||||
private Stream Stream;
|
||||
|
||||
public void SetStream(Stream stream)
|
||||
{
|
||||
Stream = stream;
|
||||
}
|
||||
|
||||
public void ReleaseStream()
|
||||
{
|
||||
Stream = null;
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
StartPosition = Stream.Position;
|
||||
|
||||
Low = 0;
|
||||
Range = 0xFFFFFFFF;
|
||||
_cacheSize = 1;
|
||||
_cache = 0;
|
||||
}
|
||||
|
||||
public void FlushData()
|
||||
{
|
||||
for (int i = 0; i < 5; i++)
|
||||
ShiftLow();
|
||||
}
|
||||
|
||||
public void FlushStream()
|
||||
{
|
||||
Stream.Flush();
|
||||
}
|
||||
|
||||
/*public void CloseStream()
|
||||
{
|
||||
Stream.Close();
|
||||
}*/
|
||||
|
||||
/*public void Encode(uint start, uint size, uint total)
|
||||
{
|
||||
Low += start * (Range /= total);
|
||||
Range *= size;
|
||||
while (Range < kTopValue)
|
||||
{
|
||||
Range <<= 8;
|
||||
ShiftLow();
|
||||
}
|
||||
}*/
|
||||
|
||||
public void ShiftLow()
|
||||
{
|
||||
if ((uint) Low < 0xFF000000 || (uint) (Low >> 32) == 1)
|
||||
{
|
||||
byte temp = _cache;
|
||||
do
|
||||
{
|
||||
Stream.WriteByte((byte) (temp + (Low >> 32)));
|
||||
temp = 0xFF;
|
||||
} while (--_cacheSize != 0);
|
||||
_cache = (byte) (((uint) Low) >> 24);
|
||||
}
|
||||
_cacheSize++;
|
||||
Low = ((uint) Low) << 8;
|
||||
}
|
||||
|
||||
public void EncodeDirectBits(uint v, int numTotalBits)
|
||||
{
|
||||
for (int i = numTotalBits - 1; i >= 0; i--)
|
||||
{
|
||||
Range >>= 1;
|
||||
if (((v >> i) & 1) == 1)
|
||||
Low += Range;
|
||||
if (Range < kTopValue)
|
||||
{
|
||||
Range <<= 8;
|
||||
ShiftLow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*public void EncodeBit(uint size0, int numTotalBits, uint symbol)
|
||||
{
|
||||
uint newBound = (Range >> numTotalBits) * size0;
|
||||
if (symbol == 0)
|
||||
Range = newBound;
|
||||
else
|
||||
{
|
||||
Low += newBound;
|
||||
Range -= newBound;
|
||||
}
|
||||
while (Range < kTopValue)
|
||||
{
|
||||
Range <<= 8;
|
||||
ShiftLow();
|
||||
}
|
||||
}*/
|
||||
|
||||
public long GetProcessedSizeAdd()
|
||||
{
|
||||
return _cacheSize +
|
||||
Stream.Position - StartPosition + 4;
|
||||
// (long)Stream.GetProcessedSize();
|
||||
}
|
||||
}
|
||||
|
||||
internal class Decoder
|
||||
{
|
||||
public const uint kTopValue = (1 << 24);
|
||||
public uint Code;
|
||||
public uint Range;
|
||||
// public Buffer.InBuffer Stream = new Buffer.InBuffer(1 << 16);
|
||||
public Stream Stream;
|
||||
|
||||
public void Init(Stream stream)
|
||||
{
|
||||
// Stream.Init(stream);
|
||||
Stream = stream;
|
||||
|
||||
Code = 0;
|
||||
Range = 0xFFFFFFFF;
|
||||
for (int i = 0; i < 5; i++)
|
||||
Code = (Code << 8) | (byte) Stream.ReadByte();
|
||||
}
|
||||
|
||||
public void ReleaseStream()
|
||||
{
|
||||
// Stream.ReleaseStream();
|
||||
Stream = null;
|
||||
}
|
||||
|
||||
/*public void CloseStream()
|
||||
{
|
||||
Stream.Close();
|
||||
}*/
|
||||
|
||||
/*public void Normalize()
|
||||
{
|
||||
while (Range < kTopValue)
|
||||
{
|
||||
Code = (Code << 8) | (byte)Stream.ReadByte();
|
||||
Range <<= 8;
|
||||
}
|
||||
}*/
|
||||
|
||||
/*public void Normalize2()
|
||||
{
|
||||
if (Range < kTopValue)
|
||||
{
|
||||
Code = (Code << 8) | (byte)Stream.ReadByte();
|
||||
Range <<= 8;
|
||||
}
|
||||
}*/
|
||||
|
||||
/*public uint GetThreshold(uint total)
|
||||
{
|
||||
return Code / (Range /= total);
|
||||
}*/
|
||||
|
||||
/*public void Decode(uint start, uint size, uint total)
|
||||
{
|
||||
Code -= start * Range;
|
||||
Range *= size;
|
||||
Normalize();
|
||||
}*/
|
||||
|
||||
public uint DecodeDirectBits(int numTotalBits)
|
||||
{
|
||||
uint range = Range;
|
||||
uint code = Code;
|
||||
uint result = 0;
|
||||
for (int i = numTotalBits; i > 0; i--)
|
||||
{
|
||||
range >>= 1;
|
||||
/*
|
||||
result <<= 1;
|
||||
if (code >= range)
|
||||
{
|
||||
code -= range;
|
||||
result |= 1;
|
||||
}
|
||||
*/
|
||||
uint t = (code - range) >> 31;
|
||||
code -= range & (t - 1);
|
||||
result = (result << 1) | (1 - t);
|
||||
|
||||
if (range < kTopValue)
|
||||
{
|
||||
code = (code << 8) | (byte) Stream.ReadByte();
|
||||
range <<= 8;
|
||||
}
|
||||
}
|
||||
Range = range;
|
||||
Code = code;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*public uint DecodeBit(uint size0, int numTotalBits)
|
||||
{
|
||||
uint newBound = (Range >> numTotalBits) * size0;
|
||||
uint symbol;
|
||||
if (Code < newBound)
|
||||
{
|
||||
symbol = 0;
|
||||
Range = newBound;
|
||||
}
|
||||
else
|
||||
{
|
||||
symbol = 1;
|
||||
Code -= newBound;
|
||||
Range -= newBound;
|
||||
}
|
||||
Normalize();
|
||||
return symbol;
|
||||
}*/
|
||||
|
||||
// ulong GetProcessedSize() {return Stream.GetProcessedSize(); }
|
||||
}
|
||||
}
|
|
@ -1,146 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace SevenZip.Sdk.Compression.RangeCoder
|
||||
{
|
||||
internal struct BitEncoder
|
||||
{
|
||||
public const uint kBitModelTotal = (1 << kNumBitModelTotalBits);
|
||||
public const int kNumBitModelTotalBits = 11;
|
||||
public const int kNumBitPriceShiftBits = 6;
|
||||
private const int kNumMoveBits = 5;
|
||||
private const int kNumMoveReducingBits = 2;
|
||||
private static readonly UInt32[] ProbPrices = new UInt32[kBitModelTotal >> kNumMoveReducingBits];
|
||||
|
||||
private uint Prob;
|
||||
|
||||
static BitEncoder()
|
||||
{
|
||||
const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
|
||||
for (int i = kNumBits - 1; i >= 0; i--)
|
||||
{
|
||||
UInt32 start = (UInt32) 1 << (kNumBits - i - 1);
|
||||
UInt32 end = (UInt32) 1 << (kNumBits - i);
|
||||
for (UInt32 j = start; j < end; j++)
|
||||
ProbPrices[j] = ((UInt32) i << kNumBitPriceShiftBits) +
|
||||
(((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));
|
||||
}
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
Prob = kBitModelTotal >> 1;
|
||||
}
|
||||
|
||||
/*public void UpdateModel(uint symbol)
|
||||
{
|
||||
if (symbol == 0)
|
||||
Prob += (kBitModelTotal - Prob) >> kNumMoveBits;
|
||||
else
|
||||
Prob -= (Prob) >> kNumMoveBits;
|
||||
}*/
|
||||
|
||||
public void Encode(Encoder encoder, uint symbol)
|
||||
{
|
||||
// encoder.EncodeBit(Prob, kNumBitModelTotalBits, symbol);
|
||||
// UpdateModel(symbol);
|
||||
uint newBound = (encoder.Range >> kNumBitModelTotalBits)*Prob;
|
||||
if (symbol == 0)
|
||||
{
|
||||
encoder.Range = newBound;
|
||||
Prob += (kBitModelTotal - Prob) >> kNumMoveBits;
|
||||
}
|
||||
else
|
||||
{
|
||||
encoder.Low += newBound;
|
||||
encoder.Range -= newBound;
|
||||
Prob -= (Prob) >> kNumMoveBits;
|
||||
}
|
||||
if (encoder.Range < Encoder.kTopValue)
|
||||
{
|
||||
encoder.Range <<= 8;
|
||||
encoder.ShiftLow();
|
||||
}
|
||||
}
|
||||
|
||||
public uint GetPrice(uint symbol)
|
||||
{
|
||||
return ProbPrices[(((Prob - symbol) ^ ((-(int) symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
|
||||
}
|
||||
|
||||
public uint GetPrice0()
|
||||
{
|
||||
return ProbPrices[Prob >> kNumMoveReducingBits];
|
||||
}
|
||||
|
||||
public uint GetPrice1()
|
||||
{
|
||||
return ProbPrices[(kBitModelTotal - Prob) >> kNumMoveReducingBits];
|
||||
}
|
||||
}
|
||||
|
||||
internal struct BitDecoder
|
||||
{
|
||||
public const uint kBitModelTotal = (1 << kNumBitModelTotalBits);
|
||||
public const int kNumBitModelTotalBits = 11;
|
||||
private const int kNumMoveBits = 5;
|
||||
|
||||
private uint Prob;
|
||||
|
||||
/*public void UpdateModel(int numMoveBits, uint symbol)
|
||||
{
|
||||
if (symbol == 0)
|
||||
Prob += (kBitModelTotal - Prob) >> numMoveBits;
|
||||
else
|
||||
Prob -= (Prob) >> numMoveBits;
|
||||
}*/
|
||||
|
||||
public void Init()
|
||||
{
|
||||
Prob = kBitModelTotal >> 1;
|
||||
}
|
||||
|
||||
public uint Decode(Decoder rangeDecoder)
|
||||
{
|
||||
uint newBound = (rangeDecoder.Range >> kNumBitModelTotalBits)*Prob;
|
||||
if (rangeDecoder.Code < newBound)
|
||||
{
|
||||
rangeDecoder.Range = newBound;
|
||||
Prob += (kBitModelTotal - Prob) >> kNumMoveBits;
|
||||
if (rangeDecoder.Range < Decoder.kTopValue)
|
||||
{
|
||||
rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte) rangeDecoder.Stream.ReadByte();
|
||||
rangeDecoder.Range <<= 8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rangeDecoder.Range -= newBound;
|
||||
rangeDecoder.Code -= newBound;
|
||||
Prob -= (Prob) >> kNumMoveBits;
|
||||
if (rangeDecoder.Range < Decoder.kTopValue)
|
||||
{
|
||||
rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte) rangeDecoder.Stream.ReadByte();
|
||||
rangeDecoder.Range <<= 8;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,173 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace SevenZip.Sdk.Compression.RangeCoder
|
||||
{
|
||||
internal struct BitTreeEncoder
|
||||
{
|
||||
private readonly BitEncoder[] Models;
|
||||
private readonly int NumBitLevels;
|
||||
|
||||
public BitTreeEncoder(int numBitLevels)
|
||||
{
|
||||
NumBitLevels = numBitLevels;
|
||||
Models = new BitEncoder[1 << numBitLevels];
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
for (uint i = 1; i < (1 << NumBitLevels); i++)
|
||||
Models[i].Init();
|
||||
}
|
||||
|
||||
public void Encode(Encoder rangeEncoder, UInt32 symbol)
|
||||
{
|
||||
UInt32 m = 1;
|
||||
for (int bitIndex = NumBitLevels; bitIndex > 0;)
|
||||
{
|
||||
bitIndex--;
|
||||
UInt32 bit = (symbol >> bitIndex) & 1;
|
||||
Models[m].Encode(rangeEncoder, bit);
|
||||
m = (m << 1) | bit;
|
||||
}
|
||||
}
|
||||
|
||||
public void ReverseEncode(Encoder rangeEncoder, UInt32 symbol)
|
||||
{
|
||||
UInt32 m = 1;
|
||||
for (UInt32 i = 0; i < NumBitLevels; i++)
|
||||
{
|
||||
UInt32 bit = symbol & 1;
|
||||
Models[m].Encode(rangeEncoder, bit);
|
||||
m = (m << 1) | bit;
|
||||
symbol >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
public UInt32 GetPrice(UInt32 symbol)
|
||||
{
|
||||
UInt32 price = 0;
|
||||
UInt32 m = 1;
|
||||
for (int bitIndex = NumBitLevels; bitIndex > 0;)
|
||||
{
|
||||
bitIndex--;
|
||||
UInt32 bit = (symbol >> bitIndex) & 1;
|
||||
price += Models[m].GetPrice(bit);
|
||||
m = (m << 1) + bit;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
|
||||
public UInt32 ReverseGetPrice(UInt32 symbol)
|
||||
{
|
||||
UInt32 price = 0;
|
||||
UInt32 m = 1;
|
||||
for (int i = NumBitLevels; i > 0; i--)
|
||||
{
|
||||
UInt32 bit = symbol & 1;
|
||||
symbol >>= 1;
|
||||
price += Models[m].GetPrice(bit);
|
||||
m = (m << 1) | bit;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
|
||||
public static UInt32 ReverseGetPrice(BitEncoder[] Models, UInt32 startIndex,
|
||||
int NumBitLevels, UInt32 symbol)
|
||||
{
|
||||
UInt32 price = 0;
|
||||
UInt32 m = 1;
|
||||
for (int i = NumBitLevels; i > 0; i--)
|
||||
{
|
||||
UInt32 bit = symbol & 1;
|
||||
symbol >>= 1;
|
||||
price += Models[startIndex + m].GetPrice(bit);
|
||||
m = (m << 1) | bit;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
|
||||
public static void ReverseEncode(BitEncoder[] Models, UInt32 startIndex,
|
||||
Encoder rangeEncoder, int NumBitLevels, UInt32 symbol)
|
||||
{
|
||||
UInt32 m = 1;
|
||||
for (int i = 0; i < NumBitLevels; i++)
|
||||
{
|
||||
UInt32 bit = symbol & 1;
|
||||
Models[startIndex + m].Encode(rangeEncoder, bit);
|
||||
m = (m << 1) | bit;
|
||||
symbol >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal struct BitTreeDecoder
|
||||
{
|
||||
private readonly BitDecoder[] Models;
|
||||
private readonly int NumBitLevels;
|
||||
|
||||
public BitTreeDecoder(int numBitLevels)
|
||||
{
|
||||
NumBitLevels = numBitLevels;
|
||||
Models = new BitDecoder[1 << numBitLevels];
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
for (uint i = 1; i < (1 << NumBitLevels); i++)
|
||||
Models[i].Init();
|
||||
}
|
||||
|
||||
public uint Decode(Decoder rangeDecoder)
|
||||
{
|
||||
uint m = 1;
|
||||
for (int bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)
|
||||
m = (m << 1) + Models[m].Decode(rangeDecoder);
|
||||
return m - ((uint) 1 << NumBitLevels);
|
||||
}
|
||||
|
||||
public uint ReverseDecode(Decoder rangeDecoder)
|
||||
{
|
||||
uint m = 1;
|
||||
uint symbol = 0;
|
||||
for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
||||
{
|
||||
uint bit = Models[m].Decode(rangeDecoder);
|
||||
m <<= 1;
|
||||
m += bit;
|
||||
symbol |= (bit << bitIndex);
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public static uint ReverseDecode(BitDecoder[] Models, UInt32 startIndex,
|
||||
Decoder rangeDecoder, int NumBitLevels)
|
||||
{
|
||||
uint m = 1;
|
||||
uint symbol = 0;
|
||||
for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
||||
{
|
||||
uint bit = Models[startIndex + m].Decode(rangeDecoder);
|
||||
m <<= 1;
|
||||
m += bit;
|
||||
symbol |= (bit << bitIndex);
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,192 +0,0 @@
|
|||
/* This file is part of SevenZipSharp.
|
||||
|
||||
SevenZipSharp is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SevenZipSharp is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace SevenZip.Sdk
|
||||
{
|
||||
/// <summary>
|
||||
/// The exception that is thrown when an error in input stream occurs during decoding.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
internal class DataErrorException : ApplicationException
|
||||
{
|
||||
public DataErrorException() : base("Data Error") {}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The exception that is thrown when the value of an argument is outside the allowable range.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
internal class InvalidParamException : ApplicationException
|
||||
{
|
||||
public InvalidParamException() : base("Invalid Parameter") {}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback progress interface.
|
||||
/// </summary>
|
||||
public interface ICodeProgress
|
||||
{
|
||||
/// <summary>
|
||||
/// Callback progress.
|
||||
/// </summary>
|
||||
/// <param name="inSize">
|
||||
/// Processed input size. -1 if unknown.
|
||||
/// </param>
|
||||
/// <param name="outSize">
|
||||
/// Processed output size. -1 if unknown.
|
||||
/// </param>
|
||||
void SetProgress(Int64 inSize, Int64 outSize);
|
||||
} ;
|
||||
|
||||
/// <summary>
|
||||
/// Stream coder interface
|
||||
/// </summary>
|
||||
public interface ICoder
|
||||
{
|
||||
/// <summary>
|
||||
/// Codes streams.
|
||||
/// </summary>
|
||||
/// <param name="inStream">
|
||||
/// input Stream.
|
||||
/// </param>
|
||||
/// <param name="outStream">
|
||||
/// output Stream.
|
||||
/// </param>
|
||||
/// <param name="inSize">
|
||||
/// input Size. -1 if unknown.
|
||||
/// </param>
|
||||
/// <param name="outSize">
|
||||
/// output Size. -1 if unknown.
|
||||
/// </param>
|
||||
/// <param name="progress">
|
||||
/// callback progress reference.
|
||||
/// </param>
|
||||
/// <exception cref="SevenZip.Sdk.DataErrorException">
|
||||
/// if input stream is not valid
|
||||
/// </exception>
|
||||
void Code(Stream inStream, Stream outStream,
|
||||
Int64 inSize, Int64 outSize, ICodeProgress progress);
|
||||
} ;
|
||||
|
||||
/*
|
||||
public interface ICoder2
|
||||
{
|
||||
void Code(ISequentialInStream []inStreams,
|
||||
const UInt64 []inSizes,
|
||||
ISequentialOutStream []outStreams,
|
||||
UInt64 []outSizes,
|
||||
ICodeProgress progress);
|
||||
};
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Provides the fields that represent properties idenitifiers for compressing.
|
||||
/// </summary>
|
||||
public enum CoderPropId
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies default property.
|
||||
/// </summary>
|
||||
DefaultProp = 0,
|
||||
/// <summary>
|
||||
/// Specifies size of dictionary.
|
||||
/// </summary>
|
||||
DictionarySize,
|
||||
/// <summary>
|
||||
/// Specifies size of memory for PPM*.
|
||||
/// </summary>
|
||||
UsedMemorySize,
|
||||
/// <summary>
|
||||
/// Specifies order for PPM methods.
|
||||
/// </summary>
|
||||
Order,
|
||||
/// <summary>
|
||||
/// Specifies Block Size.
|
||||
/// </summary>
|
||||
BlockSize,
|
||||
/// <summary>
|
||||
/// Specifies number of postion state bits for LZMA (0 <= x <= 4).
|
||||
/// </summary>
|
||||
PosStateBits,
|
||||
/// <summary>
|
||||
/// Specifies number of literal context bits for LZMA (0 <= x <= 8).
|
||||
/// </summary>
|
||||
LitContextBits,
|
||||
/// <summary>
|
||||
/// Specifies number of literal position bits for LZMA (0 <= x <= 4).
|
||||
/// </summary>
|
||||
LitPosBits,
|
||||
/// <summary>
|
||||
/// Specifies number of fast bytes for LZ*.
|
||||
/// </summary>
|
||||
NumFastBytes,
|
||||
/// <summary>
|
||||
/// Specifies match finder. LZMA: "BT2", "BT4" or "BT4B".
|
||||
/// </summary>
|
||||
MatchFinder,
|
||||
/// <summary>
|
||||
/// Specifies the number of match finder cyckes.
|
||||
/// </summary>
|
||||
MatchFinderCycles,
|
||||
/// <summary>
|
||||
/// Specifies number of passes.
|
||||
/// </summary>
|
||||
NumPasses,
|
||||
/// <summary>
|
||||
/// Specifies number of algorithm.
|
||||
/// </summary>
|
||||
Algorithm,
|
||||
/// <summary>
|
||||
/// Specifies the number of threads.
|
||||
/// </summary>
|
||||
NumThreads,
|
||||
/// <summary>
|
||||
/// Specifies mode with end marker.
|
||||
/// </summary>
|
||||
EndMarker = 0x490
|
||||
} ;
|
||||
|
||||
/// <summary>
|
||||
/// The ISetCoderProperties interface
|
||||
/// </summary>
|
||||
internal interface ISetCoderProperties
|
||||
{
|
||||
void SetCoderProperties(CoderPropId[] propIDs, object[] properties);
|
||||
} ;
|
||||
|
||||
/// <summary>
|
||||
/// The IWriteCoderProperties interface
|
||||
/// </summary>
|
||||
internal interface IWriteCoderProperties
|
||||
{
|
||||
void WriteCoderProperties(Stream outStream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The ISetDecoderPropertiesinterface
|
||||
/// </summary>
|
||||
internal interface ISetDecoderProperties
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets decoder properties
|
||||
/// </summary>
|
||||
/// <param name="properties">Array of byte properties</param>
|
||||
void SetDecoderProperties(byte[] properties);
|
||||
}
|
||||
}
|
|
@ -57,6 +57,9 @@
|
|||
<HintPath>..\output\dll\nlua\NLua.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="SharpCompress, Version=0.24.0.0, Culture=neutral, PublicKeyToken=afb0a02973931d96, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SharpCompress.0.24.0\lib\net45\SharpCompress.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data.SQLite, Version=1.0.105.2, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=AMD64">
|
||||
|
@ -79,42 +82,6 @@
|
|||
<Compile Include="..\Version\VersionInfo.cs">
|
||||
<Link>VersionInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="7z\ArchiveEmulationStreamProxy.cs" />
|
||||
<Compile Include="7z\ArchiveExtractCallback.cs" />
|
||||
<Compile Include="7z\ArchiveOpenCallback.cs" />
|
||||
<Compile Include="7z\ArchiveUpdateCallback.cs" />
|
||||
<Compile Include="7z\COM.cs" />
|
||||
<Compile Include="7z\Common.cs" />
|
||||
<Compile Include="7z\EventArgs.cs" />
|
||||
<Compile Include="7z\Exceptions.cs" />
|
||||
<Compile Include="7z\FileSignatureChecker.cs" />
|
||||
<Compile Include="7z\Formats.cs" />
|
||||
<Compile Include="7z\LibraryFeature.cs" />
|
||||
<Compile Include="7z\LibraryManager.cs" />
|
||||
<Compile Include="7z\LzmaDecodeStream.cs" />
|
||||
<Compile Include="7z\LzmaEncodeStream.cs" />
|
||||
<Compile Include="7z\LzmaProgressCallback.cs" />
|
||||
<Compile Include="7z\NativeMethods.cs" />
|
||||
<Compile Include="7z\sdk\Common\CRC.cs" />
|
||||
<Compile Include="7z\sdk\Common\InBuffer.cs" />
|
||||
<Compile Include="7z\sdk\Common\OutBuffer.cs" />
|
||||
<Compile Include="7z\sdk\Compress\LZMA\LzmaBase.cs" />
|
||||
<Compile Include="7z\sdk\Compress\LZMA\LzmaDecoder.cs" />
|
||||
<Compile Include="7z\sdk\Compress\LZMA\LzmaEncoder.cs" />
|
||||
<Compile Include="7z\sdk\Compress\LZ\IMatchFinder.cs" />
|
||||
<Compile Include="7z\sdk\Compress\LZ\LzBinTree.cs" />
|
||||
<Compile Include="7z\sdk\Compress\LZ\LzInWindow.cs" />
|
||||
<Compile Include="7z\sdk\Compress\LZ\LzOutWindow.cs" />
|
||||
<Compile Include="7z\sdk\Compress\RangeCoder\RangeCoder.cs" />
|
||||
<Compile Include="7z\sdk\Compress\RangeCoder\RangeCoderBit.cs" />
|
||||
<Compile Include="7z\sdk\Compress\RangeCoder\RangeCoderBitTree.cs" />
|
||||
<Compile Include="7z\sdk\ICoder.cs" />
|
||||
<Compile Include="7z\SevenZipCompressor.cs" />
|
||||
<Compile Include="7z\SevenZipCompressorAsynchronous.cs" />
|
||||
<Compile Include="7z\SevenZipExtractor.cs" />
|
||||
<Compile Include="7z\SevenZipExtractorAsynchronous.cs" />
|
||||
<Compile Include="7z\SevenZipSfx.cs" />
|
||||
<Compile Include="7z\StreamWrappers.cs" />
|
||||
<Compile Include="Api\CoreSystem.cs" />
|
||||
<Compile Include="Api\JoypadButton.cs" />
|
||||
<Compile Include="BinarySaveStates.cs" />
|
||||
|
@ -260,9 +227,7 @@
|
|||
<Compile Include="RomLoader.cs" />
|
||||
<Compile Include="SaveSlotManager.cs" />
|
||||
<Compile Include="SavestateManager.cs" />
|
||||
<Compile Include="SevenZipSharpArchiveHandler.cs" />
|
||||
<Compile Include="SevenZipWriter.cs" />
|
||||
<Compile Include="SharpZipWriter.cs" />
|
||||
<Compile Include="SharpCompressArchiveHandler.cs" />
|
||||
<Compile Include="SystemInfo.cs" />
|
||||
<Compile Include="tools\Cheat.cs" />
|
||||
<Compile Include="tools\CheatList.cs" />
|
||||
|
@ -323,6 +288,9 @@
|
|||
<Name>BizHawk.Bizware.BizwareGL</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using BizHawk.Common;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Implementation of IHawkFileArchiveHandler using SevenZipSharp pure managed code
|
||||
/// </summary>
|
||||
public class SevenZipSharpArchiveHandler : IHawkFileArchiveHandler
|
||||
{
|
||||
private SevenZip.SevenZipExtractor _extractor;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_extractor != null)
|
||||
{
|
||||
_extractor.Dispose();
|
||||
_extractor = null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CheckSignature(string fileName, out int offset, out bool isExecutable)
|
||||
{
|
||||
SevenZip.FileChecker.ThrowExceptions = false;
|
||||
return SevenZip.FileChecker.CheckSignature(fileName, out offset, out isExecutable) != SevenZip.InArchiveFormat.None;
|
||||
}
|
||||
|
||||
public IHawkFileArchiveHandler Construct(string path)
|
||||
{
|
||||
var ret = new SevenZipSharpArchiveHandler();
|
||||
ret.Open(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void Open(string path)
|
||||
{
|
||||
_extractor = new SevenZip.SevenZipExtractor(path);
|
||||
}
|
||||
|
||||
public List<HawkFileArchiveItem> Scan()
|
||||
{
|
||||
var ret = new List<HawkFileArchiveItem>();
|
||||
for (int i = 0; i < _extractor.ArchiveFileData.Count; i++)
|
||||
{
|
||||
var afd = _extractor.ArchiveFileData[i];
|
||||
if (afd.IsDirectory)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var ai = new HawkFileArchiveItem
|
||||
{
|
||||
Name = HawkFile.Util_FixArchiveFilename(afd.FileName),
|
||||
Size = (long)afd.Size, ArchiveIndex = i, Index = ret.Count
|
||||
};
|
||||
|
||||
ret.Add(ai);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void ExtractFile(int index, Stream stream)
|
||||
{
|
||||
_extractor.ExtractFile(index, stream);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,409 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
public class SevenZipWriter : IZipWriter
|
||||
{
|
||||
private class RangBuffer
|
||||
{
|
||||
private const int Len = 4096;
|
||||
private const int Mask = 4095;
|
||||
|
||||
private readonly byte[] _buff = new byte[Len];
|
||||
|
||||
private readonly object _sharedlock = new object();
|
||||
private readonly ManualResetEvent _full = new ManualResetEvent(true);
|
||||
private readonly ManualResetEvent _empty = new ManualResetEvent(false);
|
||||
|
||||
private int _wpos;
|
||||
private int _rpos;
|
||||
|
||||
private bool _writeclosed;
|
||||
private bool _readclosed;
|
||||
|
||||
public Stream W { get; }
|
||||
public Stream R { get; }
|
||||
|
||||
public RangBuffer()
|
||||
{
|
||||
W = new WStream(this);
|
||||
R = new RStream(this);
|
||||
}
|
||||
|
||||
public int ReadByte()
|
||||
{
|
||||
// slow, but faster than using the other overload with byte[1]
|
||||
while (true)
|
||||
{
|
||||
_empty.WaitOne();
|
||||
lock (_sharedlock)
|
||||
{
|
||||
if (_rpos != _wpos)
|
||||
{
|
||||
byte ret = _buff[_rpos++];
|
||||
_rpos &= Mask;
|
||||
_full.Set();
|
||||
return ret;
|
||||
}
|
||||
else if (_writeclosed)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_empty.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
int ret = 0;
|
||||
while (count > 0)
|
||||
{
|
||||
_empty.WaitOne();
|
||||
lock (_sharedlock)
|
||||
{
|
||||
int start = _rpos;
|
||||
int end = _wpos;
|
||||
if (end < start) // wrap
|
||||
{
|
||||
end = Len;
|
||||
}
|
||||
|
||||
if (end - start > count)
|
||||
{
|
||||
end = start + count;
|
||||
}
|
||||
|
||||
int c = end - start;
|
||||
if (c > 0)
|
||||
{
|
||||
Buffer.BlockCopy(_buff, start, buffer, offset, c);
|
||||
count -= c;
|
||||
ret += c;
|
||||
offset += c;
|
||||
_rpos = end & Mask;
|
||||
_full.Set();
|
||||
}
|
||||
else if (_writeclosed)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
_empty.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void CloseRead()
|
||||
{
|
||||
lock (_sharedlock)
|
||||
{
|
||||
_readclosed = true;
|
||||
_full.Set();
|
||||
}
|
||||
}
|
||||
|
||||
public bool WriteByte(byte value)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
_full.WaitOne();
|
||||
lock (_sharedlock)
|
||||
{
|
||||
int next = (_wpos + 1) & Mask;
|
||||
if (next != _rpos)
|
||||
{
|
||||
_buff[_wpos] = value;
|
||||
_wpos = next;
|
||||
_empty.Set();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_readclosed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_full.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
int ret = 0;
|
||||
while (count > 0)
|
||||
{
|
||||
_full.WaitOne();
|
||||
lock (_sharedlock)
|
||||
{
|
||||
int start = _wpos;
|
||||
int end = (_rpos - 1) & Mask;
|
||||
if (end < start) // wrap
|
||||
{
|
||||
end = Len;
|
||||
}
|
||||
|
||||
if (end - start > count)
|
||||
{
|
||||
end = start + count;
|
||||
}
|
||||
|
||||
int c = end - start;
|
||||
if (c > 0)
|
||||
{
|
||||
Buffer.BlockCopy(buffer, offset, _buff, start, c);
|
||||
count -= c;
|
||||
ret += c;
|
||||
offset += c;
|
||||
_wpos = end & Mask;
|
||||
_empty.Set();
|
||||
}
|
||||
else if (_readclosed)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
_full.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void CloseWrite()
|
||||
{
|
||||
lock (_sharedlock)
|
||||
{
|
||||
_writeclosed = true;
|
||||
_empty.Set();
|
||||
}
|
||||
}
|
||||
|
||||
private class WStream : Stream
|
||||
{
|
||||
public override bool CanRead => false;
|
||||
public override bool CanSeek => false;
|
||||
public override bool CanWrite => true;
|
||||
|
||||
public override void Flush() { }
|
||||
public override long Length { get { throw new NotSupportedException(); } }
|
||||
public override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); }
|
||||
public override void SetLength(long value) { throw new NotSupportedException(); }
|
||||
public override long Position
|
||||
{
|
||||
get { throw new NotSupportedException(); }
|
||||
set { throw new NotSupportedException(); }
|
||||
}
|
||||
|
||||
private RangBuffer _r;
|
||||
private long _total; // bytes written so far
|
||||
public WStream(RangBuffer r)
|
||||
{
|
||||
_r = r;
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
#if true
|
||||
int cnt = _r.Write(buffer, offset, count);
|
||||
_total += cnt;
|
||||
if (cnt < count)
|
||||
{
|
||||
throw new IOException("broken pipe");
|
||||
}
|
||||
#else
|
||||
int end = offset + count;
|
||||
while (offset < end)
|
||||
{
|
||||
WriteByte(buffer[offset++]);
|
||||
_total++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public override void WriteByte(byte value)
|
||||
{
|
||||
if (!_r.WriteByte(value))
|
||||
{
|
||||
throw new IOException("broken pipe");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && _r != null)
|
||||
{
|
||||
_r.CloseWrite();
|
||||
_r = null;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
|
||||
private class RStream : Stream
|
||||
{
|
||||
public override bool CanRead => true;
|
||||
public override bool CanSeek => false;
|
||||
public override bool CanWrite => false;
|
||||
|
||||
public override void Flush() { }
|
||||
public override long Length => 1; // { get { throw new NotSupportedException(); } }
|
||||
public override long Seek(long offset, SeekOrigin origin) { return 0; } // { throw new NotSupportedException(); }
|
||||
public override void SetLength(long value) { throw new NotSupportedException(); }
|
||||
public override long Position
|
||||
{
|
||||
get { throw new NotSupportedException(); }
|
||||
set { throw new NotSupportedException(); }
|
||||
}
|
||||
|
||||
private RangBuffer _r;
|
||||
private long _total; // bytes read so far
|
||||
public RStream(RangBuffer r)
|
||||
{
|
||||
_r = r;
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
#if true
|
||||
int cnt = _r.Read(buffer, offset, count);
|
||||
_total += cnt;
|
||||
return cnt;
|
||||
#else
|
||||
int ret = 0;
|
||||
int end = offset + count;
|
||||
while (offset < end)
|
||||
{
|
||||
int val = ReadByte();
|
||||
if (val == -1)
|
||||
break;
|
||||
buffer[offset] = (byte)val;
|
||||
offset++;
|
||||
ret++;
|
||||
_total++;
|
||||
}
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
public override int ReadByte()
|
||||
{
|
||||
return _r.ReadByte();
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && _r != null)
|
||||
{
|
||||
_r.CloseRead();
|
||||
_r = null;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private readonly SevenZip.SevenZipCompressor _svc;
|
||||
private readonly string _path;
|
||||
|
||||
private bool _first = true;
|
||||
private int _compressionlevel;
|
||||
|
||||
public SevenZipWriter(string path, int compressionlevel)
|
||||
{
|
||||
_path = path;
|
||||
_compressionlevel = compressionlevel;
|
||||
|
||||
_svc = new SevenZip.SevenZipCompressor { ArchiveFormat = SevenZip.OutArchiveFormat.Zip };
|
||||
|
||||
switch (compressionlevel)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
_svc.CompressionLevel = SevenZip.CompressionLevel.None;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
_svc.CompressionLevel = SevenZip.CompressionLevel.Fast;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
_svc.CompressionLevel = SevenZip.CompressionLevel.Low;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
_svc.CompressionLevel = SevenZip.CompressionLevel.Normal;
|
||||
break;
|
||||
case 7:
|
||||
case 8:
|
||||
_svc.CompressionLevel = SevenZip.CompressionLevel.High;
|
||||
break;
|
||||
case 9:
|
||||
_svc.CompressionLevel = SevenZip.CompressionLevel.Ultra;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteItem(string name, Action<Stream> callback)
|
||||
{
|
||||
var dict = new Dictionary<string, Stream>();
|
||||
var r = new RangBuffer();
|
||||
dict[name] = r.R;
|
||||
if (_first)
|
||||
{
|
||||
_first = false;
|
||||
_svc.CompressionMode = SevenZip.CompressionMode.Create;
|
||||
}
|
||||
else
|
||||
{
|
||||
_svc.CompressionMode = SevenZip.CompressionMode.Append;
|
||||
}
|
||||
|
||||
var task = Task.Factory.StartNew(() =>
|
||||
{
|
||||
_svc.CompressStreamDictionary(dict, _path);
|
||||
});
|
||||
try
|
||||
{
|
||||
callback(r.W);
|
||||
}
|
||||
finally
|
||||
{
|
||||
r.W.Dispose();
|
||||
}
|
||||
|
||||
task.Wait();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using BizHawk.Common;
|
||||
|
||||
using SharpCompress.Archives;
|
||||
using SharpCompress.Common;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// An <see cref="IHawkFileArchiveHandler">ArchiveHandler</see> implemented using SharpCompress from NuGet
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Intended for Unix, which can't use SevenZipSharp, but later we might sacrifice whatever speed advantage that library has for the lower workload of one cross-platform library.
|
||||
/// </remarks>
|
||||
/// <seealso cref="SevenZipSharpArchiveHandler"/>
|
||||
public class SharpCompressArchiveHandler : IHawkFileArchiveHandler
|
||||
{
|
||||
private IArchive _archive;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_archive?.Dispose();
|
||||
_archive = null;
|
||||
}
|
||||
|
||||
public bool CheckSignature(string fileName, out int offset, out bool isExecutable)
|
||||
{
|
||||
offset = 0;
|
||||
isExecutable = false;
|
||||
try
|
||||
{
|
||||
using (var arcTest = ArchiveFactory.Open(fileName))
|
||||
switch (arcTest.Type)
|
||||
{
|
||||
case ArchiveType.Zip:
|
||||
case ArchiveType.SevenZip:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception _)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public IHawkFileArchiveHandler Construct(string path)
|
||||
{
|
||||
var ret = new SharpCompressArchiveHandler();
|
||||
ret.Open(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void Open(string path) => _archive = ArchiveFactory.Open(path);
|
||||
|
||||
public List<HawkFileArchiveItem> Scan() =>
|
||||
_archive.Entries.Where(e => !e.IsDirectory)
|
||||
.Select((e, i) => new HawkFileArchiveItem
|
||||
{
|
||||
Name = HawkFile.Util_FixArchiveFilename(e.Key),
|
||||
Size = e.Size,
|
||||
Index = i,
|
||||
ArchiveIndex = i
|
||||
})
|
||||
.ToList();
|
||||
|
||||
public void ExtractFile(int index, Stream stream)
|
||||
{
|
||||
using (var entryStream = _archive.Entries.Where(e => !e.IsDirectory).ElementAt(index).OpenEntryStream())
|
||||
entryStream.CopyTo(stream);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="SharpCompress" version="0.24.0" targetFramework="net461" />
|
||||
</packages>
|
|
@ -198,7 +198,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
*/
|
||||
int offset = 0;
|
||||
bool executable = false;
|
||||
var archiveHandler = new SevenZipSharpArchiveHandler();
|
||||
var archiveHandler = new SharpCompressArchiveHandler();
|
||||
|
||||
if (string.IsNullOrEmpty(archive) && archiveHandler.CheckSignature(file, out offset, out executable))
|
||||
{
|
||||
|
|
|
@ -109,7 +109,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
TempFileManager.Start();
|
||||
|
||||
HawkFile.ArchiveHandlerFactory = new SevenZipSharpArchiveHandler();
|
||||
HawkFile.ArchiveHandlerFactory = new SharpCompressArchiveHandler();
|
||||
|
||||
string cmdConfigFile = ArgParser.GetCmdConfigFile(args);
|
||||
if (cmdConfigFile != null) PathManager.SetDefaultIniPath(cmdConfigFile);
|
||||
|
|
Loading…
Reference in New Issue