apply sevenzipsharp r84075 (17-jun-2013) which contained fixes including locks for the static library initialization that was striking us in the multi-threaded movie scanning code

This commit is contained in:
zeromus 2014-07-22 07:47:21 +00:00
parent ebf8bea920
commit 5f4ca3fe62
10 changed files with 386 additions and 186 deletions

View File

@ -35,7 +35,18 @@ namespace SevenZip
private FileInfo _fileInfo;
private Dictionary<string, InStreamWrapper> _wrappers =
new Dictionary<string, InStreamWrapper>();
public readonly List<string> VolumeFileNames = new List<string>();
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.
@ -46,7 +57,21 @@ namespace SevenZip
if (!String.IsNullOrEmpty(fileName))
{
_fileInfo = new FileInfo(fileName);
VolumeFileNames.Add(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);
}
}
}
}
@ -127,7 +152,7 @@ namespace SevenZip
return 1;
}
}
VolumeFileNames.Add(name);
_volumeFileNames.Add(name);
if (_wrappers.ContainsKey(name))
{
inStream = _wrappers[name];

View File

@ -780,7 +780,7 @@ namespace SevenZip
private void IntEventArgsHandler(object sender, IntEventArgs e)
{
lock (this)
lock (_files)
{
var pold = (byte) ((_bytesWrittenOld*100)/_bytesCount);
_bytesWritten += e.Value;

View File

@ -56,7 +56,7 @@ namespace SevenZip
/// <summary>
/// SevenZip Extractor/Compressor base class. Implements Password string, ReportErrors flag.
/// </summary>
public class SevenZipBase : MarshalByRefObject
public abstract class SevenZipBase : MarshalByRefObject
{
private readonly string _password;
private readonly bool _reportErrors;
@ -74,18 +74,18 @@ namespace SevenZip
/// AsyncCallback implementation used in asynchronous invocations.
/// </summary>
/// <param name="ar">IAsyncResult instance.</param>
internal static void AsyncCallbackMethod(IAsyncResult ar)
internal static void AsyncCallbackMethod(IAsyncResult ar)
{
var result = (AsyncResult) 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
DispatcherPriority priority = DispatcherPriority.Normal
#endif
)
)
{
#if !DOTNET20
Dispatcher = Dispatcher.CurrentDispatcher;
@ -96,7 +96,7 @@ namespace SevenZip
NeedsToBeRecreated = true;
}
internal void ReleaseContext()
virtual internal void ReleaseContext()
{
#if !DOTNET20
Dispatcher = null;
@ -104,11 +104,12 @@ namespace SevenZip
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
internal void OnEvent<T>(EventHandler<T> handler, T e, bool synchronous) where T : EventArgs
{
try
{
@ -125,7 +126,7 @@ namespace SevenZip
}
if (
#if !DOTNET20
Dispatcher == null
Dispatcher == null
#else
Context == null
#endif
@ -221,6 +222,9 @@ namespace SevenZip
private static int GetUniqueID()
{
lock(Identificators)
{
int id;
var rnd = new Random(DateTime.Now.Millisecond);
do
@ -230,6 +234,7 @@ namespace SevenZip
while (Identificators.Contains(id));
Identificators.Add(id);
return id;
}
}
#region Constructors
@ -264,7 +269,11 @@ namespace SevenZip
/// </summary>
~SevenZipBase()
{
Identificators.Remove(_uniqueID);
// This lock probably isn't necessary but just in case...
lock (Identificators)
{
Identificators.Remove(_uniqueID);
}
}
/// <summary>
@ -330,7 +339,7 @@ namespace SevenZip
throw e[0];
}
return false;
}
}
internal void ThrowUserException()
{
@ -348,7 +357,7 @@ namespace SevenZip
/// <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 (hresult != (int)OperationResult.Ok || handler.HasExceptions)
{
if (!handler.HasExceptions)
{
@ -386,6 +395,7 @@ namespace SevenZip
/// <summary>
/// Gets the current library features.
/// </summary>
[CLSCompliant(false)]
public static LibraryFeature CurrentLibraryFeatures
{
get
@ -434,7 +444,7 @@ namespace SevenZip
type = "SevenZipCompressor";
}
return string.Format("{0} [{1}]", type, _uniqueID);
}
}
}
internal class CallbackBase : MarshalByRefObject
@ -571,6 +581,7 @@ namespace SevenZip
/// <summary>
/// Gets or sets index of the file in the archive file table.
/// </summary>
[CLSCompliant(false)]
public int Index { get; set; }
/// <summary>
@ -596,16 +607,19 @@ namespace SevenZip
/// <summary>
/// Gets or sets size of the file (unpacked).
/// </summary>
[CLSCompliant(false)]
public ulong Size { get; set; }
/// <summary>
/// Gets or sets CRC checksum of the file.
/// </summary>
[CLSCompliant(false)]
public uint Crc { get; set; }
/// <summary>
/// Gets or sets file attributes.
/// </summary>
[CLSCompliant(false)]
public uint Attributes { get; set; }
/// <summary>
@ -630,7 +644,7 @@ namespace SevenZip
/// <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;
return (obj is ArchiveFileInfo) ? Equals((ArchiveFileInfo)obj) : false;
}
/// <summary>
@ -706,7 +720,7 @@ namespace SevenZip
/// <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;
return (obj is ArchiveProperty) ? Equals((ArchiveProperty)obj) : false;
}
/// <summary>

View File

@ -19,6 +19,17 @@ 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>
@ -50,12 +61,7 @@ namespace SevenZip
{
return _percentDone;
}
}
/// <summary>
/// Gets or sets whether to stop the current archive operation.
/// </summary>
public bool Cancel { get; set; }
}
/// <summary>
/// Converts a [0, 1] rate to its percent equivalent.
@ -107,7 +113,7 @@ namespace SevenZip
/// <summary>
/// EventArgs used to report the file information which is going to be packed.
/// </summary>
public sealed class FileInfoEventArgs : PercentDoneEventArgs
public sealed class FileInfoEventArgs : PercentDoneEventArgs, ICancellable
{
private readonly ArchiveFileInfo _fileInfo;
@ -122,6 +128,11 @@ namespace SevenZip
_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>
@ -145,6 +156,7 @@ namespace SevenZip
/// Initializes a new instance of the OpenEventArgs class
/// </summary>
/// <param name="totalSize">Size of unpacked archive data</param>
[CLSCompliant(false)]
public OpenEventArgs(ulong totalSize)
{
_totalSize = totalSize;
@ -153,6 +165,7 @@ namespace SevenZip
/// <summary>
/// Gets the size of unpacked archive data
/// </summary>
[CLSCompliant(false)]
public ulong TotalSize
{
get
@ -193,7 +206,7 @@ namespace SevenZip
/// <summary>
/// EventArgs class which stores the file name.
/// </summary>
public sealed class FileNameEventArgs : PercentDoneEventArgs
public sealed class FileNameEventArgs : PercentDoneEventArgs, ICancellable
{
private readonly string _fileName;
@ -208,6 +221,11 @@ namespace SevenZip
_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>

View File

@ -22,6 +22,7 @@ namespace SevenZip
/// The set of features supported by the library.
/// </summary>
[Flags]
[CLSCompliant(false)]
public enum LibraryFeature : uint
{
/// <summary>

View File

@ -39,9 +39,18 @@ namespace SevenZip
/// 7-zip library low-level wrapper.
/// </summary>
internal static class SevenZipLibraryManager
{
#if !WINCE && !MONO
{
/// <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.
@ -52,7 +61,8 @@ namespace SevenZip
/// 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), "7z.dll");
private static string _libraryFileName = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "7z.dll");
#endif
#if WINCE
private static string _libraryFileName =
@ -68,9 +78,9 @@ namespace SevenZip
/// </summary>
private static LibraryFeature? _features;
private static Dictionary<object, Dictionary<InArchiveFormat, IInArchive>> _inArchives;
private static Dictionary<object, Dictionary<InArchiveFormat, IInArchive>> _inArchives;
#if COMPRESS
private static Dictionary<object, Dictionary<OutArchiveFormat, IOutArchive>> _outArchives;
private static Dictionary<object, Dictionary<OutArchiveFormat, IOutArchive>> _outArchives;
#endif
private static int _totalUsers;
@ -120,6 +130,8 @@ namespace SevenZip
/// <param name="format">Archive format</param>
public static void LoadLibrary(object user, Enum format)
{
lock (_syncRoot)
{
if (_inArchives == null
#if COMPRESS
|| _outArchives == null
@ -149,6 +161,7 @@ namespace SevenZip
throw new SevenZipLibraryException("library is invalid.");
}
}
}
#endif
if (format is InArchiveFormat)
{
@ -164,6 +177,7 @@ namespace SevenZip
#endif
throw new ArgumentException(
"Enum " + format + " is not a valid archive format attribute!");
}
/*/// <summary>
@ -192,30 +206,32 @@ namespace SevenZip
{
get
{
if (!_modifyCapabale.HasValue)
lock (_syncRoot)
{
if (!_modifyCapabale.HasValue)
{
#if !WINCE && !MONO
FileVersionInfo dllVersionInfo = FileVersionInfo.GetVersionInfo(_libraryFileName);
_modifyCapabale = dllVersionInfo.FileMajorPart >= 9;
FileVersionInfo dllVersionInfo = FileVersionInfo.GetVersionInfo(_libraryFileName);
_modifyCapabale = dllVersionInfo.FileMajorPart >= 9;
#else
_modifyCapabale = true;
#endif
#endif
}
return _modifyCapabale.Value;
}
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;
{
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
@ -225,7 +241,7 @@ namespace SevenZip
extr.ExtractFile(0, outStream);
}
}
catch(Exception)
catch (Exception)
{
return false;
}
@ -239,7 +255,7 @@ namespace SevenZip
{
try
{
var compr = new SevenZipCompressor {ArchiveFormat = format, CompressionMethod = method};
var compr = new SevenZipCompressor { ArchiveFormat = format, CompressionMethod = method };
compr.CompressStream(inStream, outStream);
}
catch (Exception)
@ -254,93 +270,96 @@ namespace SevenZip
{
get
{
if (_features != null && _features.HasValue)
lock (_syncRoot)
{
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))
if (_features != null && _features.HasValue)
{
i++;
return _features.Value;
}
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);
_features = LibraryFeature.None;
#region Benchmark
#region Extraction features
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);
ExtractionBenchmark("Test.lzma.7z", outStream, ref _features, LibraryFeature.Extract7z);
ExtractionBenchmark("Test.lzma2.7z", outStream, ref _features, LibraryFeature.Extract7zLZMA2);
int i = 0;
if (CompressionBenchmark(inStream, outStream,
OutArchiveFormat.SevenZip, CompressionMethod.BZip2,
ref _features, _features.Value))
if (ExtractionBenchmark("Test.bzip2.7z", outStream, ref _features, _features.Value))
{
i++;
}
if (CompressionBenchmark(inStream, outStream,
OutArchiveFormat.SevenZip, CompressionMethod.Ppmd,
ref _features, _features.Value))
if (ExtractionBenchmark("Test.ppmd.7z", outStream, ref _features, _features.Value))
{
i++;
if (i == 2 && (_features & LibraryFeature.Compress7z) != 0 &&
(_features & LibraryFeature.Compress7zLZMA2) != 0)
if (i == 2 && (_features & LibraryFeature.Extract7z) != 0 &&
(_features & LibraryFeature.Extract7zLZMA2) != 0)
{
_features |= LibraryFeature.Compress7zAll;
_features |= LibraryFeature.Extract7zAll;
}
}
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);
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;
}
#endregion
#endregion
if (ModifyCapable && (_features.Value & LibraryFeature.Compress7z) != 0)
{
_features |= LibraryFeature.Modify;
}
return _features.Value;
}
}
@ -355,7 +374,9 @@ namespace SevenZip
var sp = new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);
sp.Demand();
#endif
if (_modulePtr != IntPtr.Zero)
lock (_syncRoot)
{
if (_modulePtr != IntPtr.Zero)
{
if (format is InArchiveFormat)
{
@ -417,6 +438,7 @@ namespace SevenZip
}
}
}
}
}
/// <summary>
@ -426,10 +448,8 @@ namespace SevenZip
/// <param name="user">Archive format user.</param>
public static IInArchive InArchive(InArchiveFormat format, object user)
{
#if !WINCE && !MONO
lock (_libraryFileName)
lock (_syncRoot)
{
#endif
if (_inArchives[user][format] == null)
{
#if !WINCE && !MONO
@ -453,7 +473,7 @@ namespace SevenZip
throw new SevenZipLibraryException();
}
#endif
object result;
object result;
Guid interfaceId =
#if !WINCE && !MONO
typeof(IInArchive).GUID;
@ -478,10 +498,10 @@ namespace SevenZip
InitUserInFormat(user, format);
_inArchives[user][format] = result as IInArchive;
}
return _inArchives[user][format];
#if !WINCE && !MONO
}
#endif
return _inArchives[user][format];
}
#if COMPRESS
@ -492,10 +512,8 @@ namespace SevenZip
/// <param name="user">Archive format user.</param>
public static IOutArchive OutArchive(OutArchiveFormat format, object user)
{
#if !WINCE && !MONO
lock (_libraryFileName)
lock (_syncRoot)
{
#endif
if (_outArchives[user][format] == null)
{
#if !WINCE && !MONO
@ -539,10 +557,11 @@ namespace SevenZip
InitUserOutFormat(user, format);
_outArchives[user][format] = result as IOutArchive;
}
return _outArchives[user][format];
#if !WINCE && !MONO
}
#endif
return _outArchives[user][format];
}
#endif
#if !WINCE && !MONO

View File

@ -37,8 +37,12 @@ namespace SevenZip
{
#if COMPRESS
/// <summary>
/// Class for packing files into 7-zip archives
/// Class to pack data into archives supported by 7-Zip.
/// </summary>
/// <example>
/// var compr = new SevenZipCompressor();
/// compr.CompressDirectory(@"C:\Dir", @"C:\Archive.7z");
/// </example>
public sealed partial class SevenZipCompressor
#if UNMANAGED
: SevenZipBase
@ -105,7 +109,7 @@ namespace SevenZip
public bool FastCompression { get; set; }
#endregion
#endif
private static int _lzmaDictionarySize = 1 << 22;
private static volatile int _lzmaDictionarySize = 1 << 22;
#if UNMANAGED
@ -125,7 +129,7 @@ namespace SevenZip
/// Initializes a new instance of the SevenZipCompressor class.
/// </summary>
public SevenZipCompressor()
{
{
try
{
#if !WINCE
@ -143,7 +147,7 @@ namespace SevenZip
throw new SevenZipCompressionFailedException(
"Path.GetTempPath() threw a System.Security.SecurityException. You must call SevenZipCompressor constructor overload with your own temporary path.");
}
CommonInit();
CommonInit();
}
/// <summary>
@ -191,7 +195,7 @@ namespace SevenZip
using (ArchiveOpenCallback openCallback = GetArchiveOpenCallback())
{
ulong checkPos = 1 << 15;
if (inArchive.Open(inArchiveStream, ref checkPos, openCallback) != (int) OperationResult.Ok)
if (inArchive.Open(inArchiveStream, ref checkPos, openCallback) != (int)OperationResult.Ok)
{
if (
!ThrowException(null, new SevenZipArchiveException("Can not update the archive: Open() failed.")))
@ -201,7 +205,7 @@ namespace SevenZip
}
_oldFilesCount = inArchive.GetNumberOfItems();
}
return (IOutArchive) inArchive;
return (IOutArchive)inArchive;
}
/// <summary>
@ -248,9 +252,9 @@ namespace SevenZip
break;
default:
ISetProperties setter = CompressionMode == CompressionMode.Create && _updateData.FileNamesToModify == null
? (ISetProperties) SevenZipLibraryManager.OutArchive(
? (ISetProperties)SevenZipLibraryManager.OutArchive(
_archiveFormat, this)
: (ISetProperties) SevenZipLibraryManager.InArchive(
: (ISetProperties)SevenZipLibraryManager.InArchive(
Formats.InForOutFormats[_archiveFormat], this);
if (setter == null)
{
@ -312,10 +316,10 @@ namespace SevenZip
: Marshal.StringToBSTR("0"));
values.Add(new PropVariant());
var pv = new PropVariant
{
VarType = VarEnum.VT_BSTR,
Value = Marshal.StringToBSTR(Formats.MethodNames[_compressionMethod])
};
{
VarType = VarEnum.VT_BSTR,
Value = Marshal.StringToBSTR(Formats.MethodNames[_compressionMethod])
};
values.Add(pv);
foreach (var pair in CustomParameters)
{
@ -372,7 +376,7 @@ namespace SevenZip
!SwitchIsInCustomParameters("he"))
{
names.Add(Marshal.StringToBSTR("he"));
var tmp = new PropVariant {VarType = VarEnum.VT_BSTR, Value = Marshal.StringToBSTR("on")};
var tmp = new PropVariant { VarType = VarEnum.VT_BSTR, Value = Marshal.StringToBSTR("on") };
values.Add(tmp);
}
@ -389,7 +393,7 @@ namespace SevenZip
VarType = VarEnum.VT_BSTR,
Value = Marshal.StringToBSTR(
#if !WINCE
Enum.GetName(typeof (ZipEncryptionMethod), ZipEncryptionMethod))
Enum.GetName(typeof(ZipEncryptionMethod), ZipEncryptionMethod))
#else
OpenNETCF.Enum2.GetName(typeof (ZipEncryptionMethod), ZipEncryptionMethod))
#endif
@ -579,7 +583,8 @@ namespace SevenZip
{
string[] splittedAfn = f.Substring(commonRootLength).Split(Path.DirectorySeparatorChar);
string cfn = commonRoot;
foreach (string t in splittedAfn) {
foreach (string t in splittedAfn)
{
cfn += Path.DirectorySeparatorChar + t;
if (!fns.Contains(cfn))
{
@ -630,10 +635,10 @@ namespace SevenZip
{
try
{
using (fi.OpenWrite()) {}
using (fi.OpenWrite()) { }
files.Add(fi.FullName);
}
catch (IOException) {}
catch (IOException) { }
}
}
foreach (DirectoryInfo cdi in di.GetDirectories())
@ -660,7 +665,7 @@ namespace SevenZip
auc.Compressing += CompressingEventProxy;
auc.FileCompressionFinished += FileCompressionFinishedEventProxy;
auc.DefaultItemName = DefaultItemName;
auc.FastCompression = FastCompression;
auc.FastCompression = FastCompression;
}
private float GetDictionarySize()
@ -825,7 +830,7 @@ namespace SevenZip
{
if (_updateData.FileNamesToModify == null)
{
var updateData = new UpdateData {Mode = (InternalCompressionMode) ((int) CompressionMode)};
var updateData = new UpdateData { Mode = (InternalCompressionMode)((int)CompressionMode) };
switch (CompressionMode)
{
case CompressionMode.Create:
@ -986,7 +991,7 @@ namespace SevenZip
{
_compressionMethod = !MethodIsValid(value) ? CompressionMethod.Default : value;
}
}
}
/// <summary>
/// Gets or sets the size in bytes of an archive volume (0 for no volumes).
@ -1094,7 +1099,7 @@ namespace SevenZip
_archiveName = archiveName;
using (FileStream fs = GetArchiveFileStream(archiveName))
{
if (fs == null)
if (fs == null && _volumeSize == 0)
{
return;
}
@ -1177,7 +1182,7 @@ namespace SevenZip
if (files != null) //ReSharper
CheckedExecute(
outArchive.UpdateItems(
sequentialArchiveStream, (uint) files.Length + _oldFilesCount, auc),
sequentialArchiveStream, (uint)files.Length + _oldFilesCount, auc),
SevenZipCompressionFailedException.DEFAULT_MESSAGE, auc);
}
finally
@ -1379,7 +1384,7 @@ namespace SevenZip
CompressDirectory(directory, fs, password, searchPattern, recursion);
}
FinalizeUpdate();
}
}
#if !CS4
/// <summary>
@ -1482,7 +1487,7 @@ namespace SevenZip
CompressFileDictionary(fileDictionary, archiveStream, "");
}
#endif
#if !CS4
/// <summary>
/// Packs the specified file dictionary.
@ -1509,15 +1514,15 @@ namespace SevenZip
_archiveName = archiveName;
using (FileStream fs = GetArchiveFileStream(archiveName))
{
if (fs == null)
if (fs == null && _volumeSize == 0)
{
return;
}
CompressFileDictionary(fileDictionary, fs, password);
}
FinalizeUpdate();
}
}
#if !CS4
/// <summary>
/// Packs the specified file dictionary.
@ -1593,7 +1598,7 @@ namespace SevenZip
CompressStreamDictionary(streamDictionary, archiveStream, "");
}
#endif
#if !CS4
/// <summary>
/// Packs the specified stream dictionary.
@ -1620,15 +1625,15 @@ namespace SevenZip
_archiveName = archiveName;
using (FileStream fs = GetArchiveFileStream(archiveName))
{
if (fs == null)
if (fs == null && _volumeSize == 0)
{
return;
}
CompressStreamDictionary(streamDictionary, fs, password);
}
FinalizeUpdate();
}
}
#if !CS4
/// <summary>
/// Packs the specified stream dictionary.
@ -1673,7 +1678,8 @@ namespace SevenZip
pair => pair.Value != null && (!pair.Value.CanSeek || !pair.Value.CanRead)).Any(
pair => !ThrowException(null,
new ArgumentException("The specified stream dictionary contains an invalid stream corresponding to the archive entry \""
+ pair.Key + "\".", "streamDictionary")))) {
+ pair.Key + "\".", "streamDictionary"))))
{
return;
}
#else
@ -1689,7 +1695,7 @@ namespace SevenZip
}
}
}
#endif
#endif
try
{
ISequentialOutStream sequentialArchiveStream;
@ -1829,7 +1835,7 @@ namespace SevenZip
ModifyArchive(archiveName, newFileNames, "");
}
#endif
/// <summary>
/// Modifies the existing archive (renames files or deletes them).
/// </summary>
@ -1927,7 +1933,7 @@ namespace SevenZip
{
FreeCompressionCallback(auc);
}
}
}
}
}
}
@ -1942,7 +1948,7 @@ namespace SevenZip
OnEvent(CompressionFinished, EventArgs.Empty, false);
}
ThrowUserException();
}
}
#endregion
#endregion
@ -2016,7 +2022,7 @@ namespace SevenZip
long streamSize = inLength.HasValue ? inLength.Value : inStream.Length;
for (int i = 0; i < 8; i++)
{
outStream.WriteByte((byte) (streamSize >> (8*i)));
outStream.WriteByte((byte)(streamSize >> (8 * i)));
}
encoder.Code(inStream, outStream, -1, -1, new LzmaProgressCallback(streamSize, codeProgressEvent));
}
@ -2037,7 +2043,7 @@ namespace SevenZip
encoder.WriteCoderProperties(outStream);
long streamSize = inStream.Length;
for (int i = 0; i < 8; i++)
outStream.WriteByte((byte) (streamSize >> (8*i)));
outStream.WriteByte((byte)(streamSize >> (8 * i)));
encoder.Code(inStream, outStream, -1, -1, null);
return outStream.ToArray();
}

View File

@ -1,4 +1,20 @@
namespace SevenZip
/* 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;

View File

@ -33,8 +33,14 @@ using SevenZip.Mono.COM;
namespace SevenZip
{
/// <summary>
/// Class for extracting and getting information about 7-zip archives
/// Class to unpack data from archives supported by 7-Zip.
/// </summary>
/// <example>
/// using (var extr = new SevenZipExtractor(@"C:\Test.7z"))
/// {
/// extr.ExtractArchive(@"C:\TestDirectory");
/// }
/// </example>
public sealed partial class SevenZipExtractor
#if UNMANAGED
: SevenZipBase, IDisposable
@ -54,10 +60,14 @@ namespace SevenZip
private bool? _isSolid;
private bool _opened;
private bool _disposed;
private InArchiveFormat _format;
private InArchiveFormat _format = (InArchiveFormat)(-1);
private ReadOnlyCollection<ArchiveFileInfo> _archiveFileInfoCollection;
private ReadOnlyCollection<ArchiveProperty> _archiveProperties;
private ReadOnlyCollection<string> _volumeFileNames;
private ReadOnlyCollection<string> _volumeFileNames;
/// <summary>
/// This is used to lock possible Dispose() calls.
/// </summary>
private bool _asynchronousDisposeLock;
#region Constructors
/// <summary>
@ -67,8 +77,11 @@ namespace SevenZip
private void Init(string archiveFullName)
{
_fileName = archiveFullName;
bool isExecutable;
_format = FileChecker.CheckSignature(archiveFullName, out _offset, out isExecutable);
bool isExecutable = false;
if ((int)_format == -1)
{
_format = FileChecker.CheckSignature(archiveFullName, out _offset, out isExecutable);
}
PreserveDirectoryStructure = true;
SevenZipLibraryManager.LoadLibrary(this, _format);
try
@ -107,8 +120,11 @@ namespace SevenZip
private void Init(Stream stream)
{
ValidateStream(stream);
bool isExecutable;
_format = FileChecker.CheckSignature(stream, out _offset, out isExecutable);
bool isExecutable = false;
if ((int)_format == -1)
{
_format = FileChecker.CheckSignature(stream, out _offset, out isExecutable);
}
PreserveDirectoryStructure = true;
SevenZipLibraryManager.LoadLibrary(this, _format);
try
@ -155,14 +171,41 @@ namespace SevenZip
}
/// <summary>
/// Initializes a new instance of SevenZipExtractor class
/// Initializes a new instance of SevenZipExtractor class.
/// </summary>
/// <param name="archiveFullName">The archive full file name</param>
/// <param name="archiveStream">The stream to read the archive from.
/// Use SevenZipExtractor(string) to extract from disk, though it is not necessary.</param>
/// <param name="format">Manual archive format setup. You SHOULD NOT normally specify it this way.
/// Instead, use SevenZipExtractor(Stream archiveStream), that constructor
/// automatically detects the archive format.</param>
public SevenZipExtractor(Stream archiveStream, InArchiveFormat format)
{
_format = format;
Init(archiveStream);
}
/// <summary>
/// Initializes a new instance of SevenZipExtractor class.
/// </summary>
/// <param name="archiveFullName">The archive full file name.</param>
public SevenZipExtractor(string archiveFullName)
{
Init(archiveFullName);
}
/// <summary>
/// Initializes a new instance of SevenZipExtractor class.
/// </summary>
/// <param name="archiveFullName">The archive full file name.</param>
/// <param name="format">Manual archive format setup. You SHOULD NOT normally specify it this way.
/// Instead, use SevenZipExtractor(string archiveFullName), that constructor
/// automatically detects the archive format.</param>
public SevenZipExtractor(string archiveFullName, InArchiveFormat format)
{
_format = format;
Init(archiveFullName);
}
/// <summary>
/// Initializes a new instance of SevenZipExtractor class.
/// </summary>
@ -174,19 +217,48 @@ namespace SevenZip
Init(archiveFullName);
}
/// <summary>
/// Initializes a new instance of SevenZipExtractor class.
/// </summary>
/// <param name="archiveFullName">The archive full file name.</param>
/// <param name="password">Password for an encrypted archive.</param>
/// <param name="format">Manual archive format setup. You SHOULD NOT normally specify it this way.
/// Instead, use SevenZipExtractor(string archiveFullName, string password), that constructor
/// automatically detects the archive format.</param>
public SevenZipExtractor(string archiveFullName, string password, InArchiveFormat format)
: base(password)
{
_format = format;
Init(archiveFullName);
}
/// <summary>
/// Initializes a new instance of SevenZipExtractor class.
/// </summary>
/// <param name="archiveStream">The stream to read the archive from.</param>
/// <param name="password">Password for an encrypted archive.</param>
/// <remarks>The archive format is guessed by the signature.</remarks>
public SevenZipExtractor(
Stream archiveStream, string password)
public SevenZipExtractor(Stream archiveStream, string password)
: base(password)
{
Init(archiveStream);
}
/// <summary>
/// Initializes a new instance of SevenZipExtractor class.
/// </summary>
/// <param name="archiveStream">The stream to read the archive from.</param>
/// <param name="password">Password for an encrypted archive.</param>
/// <param name="format">Manual archive format setup. You SHOULD NOT normally specify it this way.
/// Instead, use SevenZipExtractor(Stream archiveStream, string password), that constructor
/// automatically detects the archive format.</param>
public SevenZipExtractor(Stream archiveStream, string password, InArchiveFormat format)
: base(password)
{
_format = format;
Init(archiveStream);
}
#endregion
#region Properties
@ -251,17 +323,15 @@ namespace SevenZip
{
GetArchiveInfo(true);
}
if (_isSolid != null)
{
return _isSolid.Value;
}
throw new SevenZipException("_isSolid == null");
Debug.Assert(_isSolid != null);
return _isSolid.Value;
}
}
/// <summary>
/// Gets the number of files in the archive
/// </summary>
[CLSCompliant(false)]
public uint FilesCount
{
get
@ -271,11 +341,8 @@ namespace SevenZip
{
GetArchiveInfo(true);
}
if (_filesCount != null)
{
return _filesCount.Value;
}
throw new SevenZipException("_filesCount == null");
Debug.Assert(_filesCount != null);
return _filesCount.Value;
}
}
@ -292,7 +359,7 @@ namespace SevenZip
}
/// <summary>
/// Gets or sets the value indicatin whether to preserve the directory structure of extracted files.
/// Gets or sets the value indicating whether to preserve the directory structure of extracted files.
/// </summary>
public bool PreserveDirectoryStructure { get; set; }
#endregion
@ -343,7 +410,8 @@ namespace SevenZip
}
else
{
if (!_fileName.EndsWith(".001", StringComparison.OrdinalIgnoreCase))
if (!_fileName.EndsWith(".001", StringComparison.OrdinalIgnoreCase)
|| (_volumeFileNames.Count == 1))
{
_archiveStream = new InStreamWrapper(
new ArchiveEmulationStreamProxy(new FileStream(
@ -692,6 +760,10 @@ namespace SevenZip
_archiveFileData = null;
_archiveProperties = null;
_archiveFileInfoCollection = null;
if (_inStream != null)
{
_inStream.Dispose();
}
_inStream = null;
if (_openCallback != null)
{
@ -726,6 +798,11 @@ namespace SevenZip
/// </summary>
public void Dispose()
{
if (_asynchronousDisposeLock)
{
throw new InvalidOperationException("SevenZipExtractor instance must not be disposed " +
"while making an asynchronous method call.");
}
if (!_disposed)
{
CommonDispose();
@ -916,6 +993,7 @@ namespace SevenZip
{
_archive.Close();
}
((InStreamWrapper)_archiveStream).Dispose();
_archiveStream = null;
_opened = false;
}

View File

@ -1,4 +1,20 @@
namespace SevenZip
/* 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;
@ -53,6 +69,7 @@
)
{
DisposedCheck();
_asynchronousDisposeLock = true;
base.SaveContext(
#if !DOTNET20
eventPriority
@ -61,6 +78,12 @@
}
internal override void ReleaseContext()
{
base.ReleaseContext();
_asynchronousDisposeLock = false;
}
#endregion
#region Delegates