remove our outdated 7z shenanigans with sharpcompress

This commit is contained in:
adelikat 2019-11-01 20:22:05 -05:00
parent 19dd590f2c
commit b862a464ee
43 changed files with 90 additions and 16938 deletions

View File

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

View File

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

View File

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

View File

@ -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&lt;file stream, name of the archive entry&gt;</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&lt;file stream, name of the archive entry&gt;</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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 &lt;= x &lt;= 4).
/// </summary>
PosStateBits,
/// <summary>
/// Specifies number of literal context bits for LZMA (0 &lt;= x &lt;= 8).
/// </summary>
LitContextBits,
/// <summary>
/// Specifies number of literal position bits for LZMA (0 &lt;= x &lt;= 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);
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="SharpCompress" version="0.24.0" targetFramework="net461" />
</packages>

View File

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

View File

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