diff --git a/SevenZip.Tests/SevenZip.Tests.csproj b/SevenZip.Tests/SevenZip.Tests.csproj
index f8ace8a..01d4d11 100644
--- a/SevenZip.Tests/SevenZip.Tests.csproj
+++ b/SevenZip.Tests/SevenZip.Tests.csproj
@@ -18,15 +18,16 @@
true
-
-
+
+
+
-
+
@@ -75,6 +76,24 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
diff --git a/SevenZip.Tests/SevenZipExtractorTests.cs b/SevenZip.Tests/SevenZipExtractorTests.cs
index 94b7d78..0a4ae07 100644
--- a/SevenZip.Tests/SevenZipExtractorTests.cs
+++ b/SevenZip.Tests/SevenZipExtractorTests.cs
@@ -32,6 +32,22 @@ public static List TestFiles
return result;
}
}
+ ///
+ /// TestCaseSource for ReadSolidArchive test
+ ///
+ public static List SolidArchivesFiles
+ {
+ get
+ {
+ var result = new List();
+ foreach (var file in Directory.GetFiles(Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData_solid")))
+ {
+ result.Add(new TestFile(file));
+ }
+
+ return result;
+ }
+ }
[Test]
public void ExtractFilesTest()
@@ -85,7 +101,7 @@ public void ExtractionWithCancellationTest()
e.Cancel = true;
}
};
-
+
tmp.ExtractArchive(OutputDirectory);
Assert.AreEqual(2, Directory.GetFiles(OutputDirectory).Length);
@@ -160,10 +176,10 @@ public void DetectMultiVolumeIndexTest()
[Test]
public void ThreadedExtractionTest()
{
- var destination1 = Path.Combine(OutputDirectory, "t1");
- var destination2 = Path.Combine(OutputDirectory, "t2");
+ var destination1 = Path.Combine(OutputDirectory, "t1");
+ var destination2 = Path.Combine(OutputDirectory, "t2");
- var t1 = new Thread(() =>
+ var t1 = new Thread(() =>
{
using (var tmp = new SevenZipExtractor(@"TestData\multiple_files.7z"))
{
@@ -172,8 +188,8 @@ public void ThreadedExtractionTest()
});
var t2 = new Thread(() =>
{
- using (var tmp = new SevenZipExtractor(@"TestData\multiple_files.7z"))
- {
+ using (var tmp = new SevenZipExtractor(@"TestData\multiple_files.7z"))
+ {
tmp.ExtractArchive(destination2);
}
});
@@ -183,11 +199,11 @@ public void ThreadedExtractionTest()
t1.Join();
t2.Join();
- Assert.IsTrue(Directory.Exists(destination1));
- Assert.IsTrue(Directory.Exists(destination2));
- Assert.AreEqual(3, Directory.GetFiles(destination1).Length);
- Assert.AreEqual(3, Directory.GetFiles(destination2).Length);
- }
+ Assert.IsTrue(Directory.Exists(destination1));
+ Assert.IsTrue(Directory.Exists(destination2));
+ Assert.AreEqual(3, Directory.GetFiles(destination1).Length);
+ Assert.AreEqual(3, Directory.GetFiles(destination2).Length);
+ }
[Test]
public void ExtractArchiveWithLongPath()
@@ -211,7 +227,7 @@ public void ReadArchivedFileNames()
Assert.AreEqual("file3.txt", fileNames[2]);
}
}
-
+
[Test]
public void ReadArchivedFileData()
{
@@ -235,6 +251,108 @@ public void ExtractDifferentFormatsTest(TestFile file)
Assert.AreEqual(1, Directory.GetFiles(OutputDirectory).Length);
}
}
+
+ [Test, TestCaseSource(nameof(SolidArchivesFiles))]
+ public void ReadStreamFromSolidArchiveTest(TestFile file)
+ {
+ using (var extractor = new SevenZipExtractor(file.FilePath))
+ {
+ bool isSolid = Path.GetFileName(file.FilePath).ToLowerInvariant().Contains("solid");
+
+ var fileData = extractor.ArchiveFileData;
+ Assert.AreEqual(isSolid, extractor.IsSolid);
+ Assert.AreEqual(5, fileData.Count);
+
+ // extract files in non-sequential order
+ foreach (int index in new int[] { 2, 4, 1, 3, 0 })
+ {
+ string content = string.Empty;
+ using (var stream = new MemoryStream())
+ {
+ extractor.ExtractFile(index, stream);
+ stream.Seek(0, SeekOrigin.Begin);
+
+ using (TextReader reader = new StreamReader(stream))
+ {
+ content = reader.ReadToEnd();
+ }
+ }
+ Assert.AreEqual("test file", content);
+ }
+ }
+ }
+
+ [Test, TestCaseSource(nameof(SolidArchivesFiles))]
+ public void ExtractSpecificFilesFromSolidArchiveTest(TestFile file)
+ {
+ using (var extractor = new SevenZipExtractor(file.FilePath))
+ {
+ extractor.ExtractFiles(OutputDirectory, 2, 4);
+ Assert.AreEqual(2, Directory.GetFiles(OutputDirectory).Length);
+ }
+
+ Assert.AreEqual(2, Directory.GetFiles(OutputDirectory).Length);
+ Assert.Contains(Path.Combine(OutputDirectory, "test3.txt"), Directory.GetFiles(OutputDirectory));
+ Assert.Contains(Path.Combine(OutputDirectory, "test5.txt"), Directory.GetFiles(OutputDirectory));
+ }
+
+ [Test, TestCaseSource(nameof(SolidArchivesFiles))]
+ public void ExtractFileCallbackFromSolidArchiveTest(TestFile file)
+ {
+ using (var extractor = new SevenZipExtractor(file.FilePath))
+ {
+ extractor.ExtractFiles(args =>
+ {
+ if (args.Reason == ExtractFileCallbackReason.Start &&
+ (args.ArchiveFileInfo.Index == 2 || args.ArchiveFileInfo.Index == 4))
+ {
+ args.ExtractToFile = Path.Combine(OutputDirectory, args.ArchiveFileInfo.FileName);
+ }
+ });
+ }
+
+ Assert.AreEqual(2, Directory.GetFiles(OutputDirectory).Length);
+ Assert.Contains(Path.Combine(OutputDirectory, "test3.txt"), Directory.GetFiles(OutputDirectory));
+ Assert.Contains(Path.Combine(OutputDirectory, "test5.txt"), Directory.GetFiles(OutputDirectory));
+ }
+
+ [Test, TestCaseSource(nameof(SolidArchivesFiles))]
+ public void ReadStreamCallbackFromSolidArchiveTest(TestFile file)
+ {
+ using (var extractor = new SevenZipExtractor(file.FilePath))
+ {
+ extractor.ExtractFiles(args =>
+ {
+ if (args.Reason == ExtractFileCallbackReason.Start)
+ {
+ if (args.ArchiveFileInfo.Index == 2 || args.ArchiveFileInfo.Index == 4)
+ {
+ args.ExtractToStream = new MemoryStream();
+ }
+ }
+ else if (args.Reason == ExtractFileCallbackReason.Done)
+ {
+ if (args.ExtractToStream != null)
+ {
+ string content = string.Empty;
+ args.ExtractToStream.Seek(0, SeekOrigin.Begin);
+ using (TextReader reader = new StreamReader(args.ExtractToStream))
+ {
+ content = reader.ReadToEnd();
+ }
+ Assert.AreEqual("test file", content);
+
+ args.ExtractToStream.Dispose();
+ args.ExtractToStream = null;
+ }
+ }
+ else
+ {
+ Assert.Fail("Extract file failed " + args.Exception?.Message);
+ }
+ });
+ }
+ }
}
///
diff --git a/SevenZip.Tests/TestData_solid/testFiles.7z b/SevenZip.Tests/TestData_solid/testFiles.7z
new file mode 100644
index 0000000..d2fe417
Binary files /dev/null and b/SevenZip.Tests/TestData_solid/testFiles.7z differ
diff --git a/SevenZip.Tests/TestData_solid/testFiles.rar b/SevenZip.Tests/TestData_solid/testFiles.rar
new file mode 100644
index 0000000..7aded5a
Binary files /dev/null and b/SevenZip.Tests/TestData_solid/testFiles.rar differ
diff --git a/SevenZip.Tests/TestData_solid/testFiles.solid.7z b/SevenZip.Tests/TestData_solid/testFiles.solid.7z
new file mode 100644
index 0000000..d3c78c4
Binary files /dev/null and b/SevenZip.Tests/TestData_solid/testFiles.solid.7z differ
diff --git a/SevenZip.Tests/TestData_solid/testFiles.solid.rar b/SevenZip.Tests/TestData_solid/testFiles.solid.rar
new file mode 100644
index 0000000..a3820c5
Binary files /dev/null and b/SevenZip.Tests/TestData_solid/testFiles.solid.rar differ
diff --git a/SevenZip.Tests/TestData_solid/testFiles.tar b/SevenZip.Tests/TestData_solid/testFiles.tar
new file mode 100644
index 0000000..2d03cc1
Binary files /dev/null and b/SevenZip.Tests/TestData_solid/testFiles.tar differ
diff --git a/SevenZip.Tests/TestData_solid/testFiles.zip b/SevenZip.Tests/TestData_solid/testFiles.zip
new file mode 100644
index 0000000..7c3802e
Binary files /dev/null and b/SevenZip.Tests/TestData_solid/testFiles.zip differ
diff --git a/SevenZip/EventArguments/ExtractFileCallbackArgs.cs b/SevenZip/EventArguments/ExtractFileCallbackArgs.cs
index 212c811..ace2fa9 100644
--- a/SevenZip/EventArguments/ExtractFileCallbackArgs.cs
+++ b/SevenZip/EventArguments/ExtractFileCallbackArgs.cs
@@ -89,7 +89,7 @@ public Stream ExtractToStream
get => _extractToStream;
set
{
- if (_extractToStream != null && !_extractToStream.CanWrite)
+ if (value != null && !value.CanWrite)
{
throw new ExtractionFailedException("The specified stream is not writable!");
}
diff --git a/SevenZip/SevenZipExtractor.cs b/SevenZip/SevenZipExtractor.cs
index 9b32f6e..2bf66d5 100644
--- a/SevenZip/SevenZipExtractor.cs
+++ b/SevenZip/SevenZipExtractor.cs
@@ -574,14 +574,9 @@ private void GetArchiveInfo(bool disposeStream)
_archiveProperties = new ReadOnlyCollection(archProps);
- if (!_isSolid.HasValue && _format == InArchiveFormat.Zip)
- {
- _isSolid = false;
- }
-
if (!_isSolid.HasValue)
{
- _isSolid = true;
+ _isSolid = false;
}
#endregion
@@ -618,31 +613,6 @@ private void InitArchiveFileData(bool disposeStream)
}
}
- ///
- /// Produces an array of indexes from 0 to the maximum value in the specified array
- ///
- /// The source array
- /// The array of indexes from 0 to the maximum value in the specified array
- private static uint[] SolidIndexes(uint[] indexes)
- {
- var max = indexes.Aggregate(0, (current, i) => Math.Max(current, (int) i));
-
- if (max > 0)
- {
- max++;
- var res = new uint[max];
-
- for (var i = 0; i < max; i++)
- {
- res[i] = (uint)i;
- }
-
- return res;
- }
-
- return indexes;
- }
-
///
/// Checks whether all the indexes are valid.
///
@@ -1085,12 +1055,6 @@ public void ExtractFile(int index, Stream stream)
try
{
var indexes = new[] { (uint)index };
- var entry = _archiveFileData[index];
-
- if (_isSolid.Value && !entry.Method.Equals("Copy", StringComparison.InvariantCultureIgnoreCase))
- {
- indexes = SolidIndexes(indexes);
- }
using (var aec = GetArchiveExtractCallback(stream, (uint) index, indexes.Length))
{
@@ -1163,11 +1127,6 @@ public void ExtractFiles(string directory, params int[] indexes)
origIndexes.Sort();
uindexes = origIndexes.ToArray();
- if (_isSolid.Value)
- {
- uindexes = SolidIndexes(uindexes);
- }
-
#endregion
try
@@ -1272,11 +1231,6 @@ public void ExtractFiles(ExtractFileCallback extractFileCallback)
DisposedCheck();
InitArchiveFileData(false);
- if (IsSolid)
- {
- throw new SevenZipExtractionFailedException("Solid archives are not supported.");
- }
-
foreach (var archiveFileInfo in ArchiveFileData)
{
var extractFileCallbackArgs = new ExtractFileCallbackArgs(archiveFileInfo);