diff --git a/SabreTools.Helper/Tools/ArchiveTools.cs b/SabreTools.Helper/Tools/ArchiveTools.cs
index bba9a7f9..dbdd6fc0 100644
--- a/SabreTools.Helper/Tools/ArchiveTools.cs
+++ b/SabreTools.Helper/Tools/ArchiveTools.cs
@@ -14,6 +14,7 @@ using Alphaleonis.Win32.Filesystem;
using Ionic.Zlib;
using ROMVault2.SupportedFiles.Zip;
using SharpCompress.Archives;
+using SharpCompress.Archives.Rar;
using SharpCompress.Archives.SevenZip;
using SharpCompress.Archives.Tar;
using SharpCompress.Common;
@@ -37,28 +38,6 @@ namespace SabreTools.Helper.Tools
{
private const int _bufferSize = 4096 * 128;
- #region Archive-to-Archive Handling
-
- ///
- /// Attempt to copy a file between archives
- ///
- /// Source archive name
- /// Destination archive name
- /// Input entry name
- /// Output entry name
- /// Logger object for file and console output
- /// True if the copy was a success, false otherwise
- public static bool CopyFileBetweenArchives(string inputArchive, string outDir, string sourceEntryName, Rom destEntry, Logger logger)
- {
- string temp = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
- string realName = ExtractItem(inputArchive, sourceEntryName, temp, logger);
- bool success = WriteTorrentZip(realName, outDir, destEntry, logger);
- Directory.Delete(temp, true);
- return success;
- }
-
- #endregion
-
#region Extraction
///
@@ -84,6 +63,7 @@ namespace SabreTools.Helper.Tools
try
{
+ // 7-zip
if (at == ArchiveType.SevenZip && (archiveScanLevel & ArchiveScanLevel.SevenZipInternal) != 0)
{
logger.Verbose("Found archive of type: " + at);
@@ -93,14 +73,15 @@ namespace SabreTools.Helper.Tools
// Extract all files to the temp directory
SevenZipArchive sza = SevenZipArchive.Open(File.OpenRead(input));
- foreach (IArchiveEntry iae in sza.Entries)
+ foreach (SevenZipArchiveEntry entry in sza.Entries)
{
- iae.WriteToDirectory(tempDir, new ExtractionOptions{ PreserveFileTime = true, ExtractFullPath = true, Overwrite = true });
+ entry.WriteToDirectory(tempDir, new ExtractionOptions{ PreserveFileTime = true, ExtractFullPath = true, Overwrite = true });
}
encounteredErrors = false;
sza.Dispose();
-
}
+
+ // GZip
else if (at == ArchiveType.GZip && (archiveScanLevel & ArchiveScanLevel.GZipInternal) != 0)
{
logger.Verbose("Found archive of type: " + at);
@@ -119,6 +100,44 @@ namespace SabreTools.Helper.Tools
encounteredErrors = false;
}
+
+ // RAR
+ else if (at == ArchiveType.Rar && (archiveScanLevel & ArchiveScanLevel.RarInternal) != 0)
+ {
+ logger.Verbose("Found archive of type: " + at);
+
+ // Create the temp directory
+ Directory.CreateDirectory(tempDir);
+
+ // Extract all files to the temp directory
+ RarArchive ra = RarArchive.Open(input);
+ foreach (RarArchiveEntry entry in ra.Entries)
+ {
+ entry.WriteToDirectory(tempDir, new ExtractionOptions { PreserveFileTime = true, ExtractFullPath = true, Overwrite = true });
+ }
+ encounteredErrors = false;
+ ra.Dispose();
+ }
+
+ // TAR
+ else if (at == ArchiveType.Tar && (archiveScanLevel & ArchiveScanLevel.TarInternal) != 0)
+ {
+ logger.Verbose("Found archive of type: " + at);
+
+ // Create the temp directory
+ Directory.CreateDirectory(tempDir);
+
+ // Extract all files to the temp directory
+ TarArchive ta = TarArchive.Open(input);
+ foreach (TarArchiveEntry entry in ta.Entries)
+ {
+ entry.WriteToDirectory(tempDir, new ExtractionOptions { PreserveFileTime = true, ExtractFullPath = true, Overwrite = true });
+ }
+ encounteredErrors = false;
+ ta.Dispose();
+ }
+
+ // Zip
else if (at == ArchiveType.Zip && (archiveScanLevel & ArchiveScanLevel.ZipInternal) != 0)
{
logger.Verbose("Found archive of type: " + at);
@@ -173,24 +192,6 @@ namespace SabreTools.Helper.Tools
}
encounteredErrors = false;
}
- else if (at == ArchiveType.Rar && (archiveScanLevel & ArchiveScanLevel.RarInternal) != 0)
- {
- logger.Verbose("Found archive of type: " + at);
-
- // Create the temp directory
- Directory.CreateDirectory(tempDir);
-
- // Extract all files to the temp directory
- IReader reader = ReaderFactory.Open(File.OpenRead(input));
- bool succeeded = reader.MoveToNextEntry();
- while (succeeded)
- {
- reader.WriteEntryToDirectory(tempDir, new ExtractionOptions { PreserveFileTime = true, ExtractFullPath = true, Overwrite = true });
- succeeded = reader.MoveToNextEntry();
- }
- encounteredErrors = false;
- reader.Dispose();
- }
}
catch (EndOfStreamException)
{
@@ -270,67 +271,100 @@ namespace SabreTools.Helper.Tools
return st;
}
- IReader reader = null;
try
{
- if (at == ArchiveType.Zip)
+ switch (at)
{
- ZipFile zf = new ZipFile();
- ZipReturn zr = zf.Open(input, new FileInfo(input).LastWriteTime.Ticks, true);
- if (zr != ZipReturn.ZipGood)
- {
- throw new Exception(ZipFile.ZipErrorMessageText(zr));
- }
-
- for (int i = 0; i < zf.EntriesCount && zr == ZipReturn.ZipGood; i++)
- {
- logger.Verbose("Current entry name: '" + zf.Entries[i].FileName + "'");
- if (zf.Entries[i].FileName.Contains(entryName))
+ case ArchiveType.SevenZip:
+ SevenZipArchive sza = SevenZipArchive.Open(input, new ReaderOptions { LeaveStreamOpen = false, });
+ foreach (SevenZipArchiveEntry entry in sza.Entries)
{
- realEntry = zf.Entries[i].FileName;
-
- // Set defaults before writing out
- Stream readStream;
- ulong streamsize = 0;
- CompressionMethod cm = CompressionMethod.Stored;
- uint lastMod = 0;
-
- zr = zf.OpenReadStream(i, false, out readStream, out streamsize, out cm, out lastMod);
-
- byte[] ibuffer = new byte[_bufferSize];
- int ilen;
- while ((ilen = readStream.Read(ibuffer, 0, _bufferSize)) > 0)
+ logger.Verbose("Current entry name: '" + entry.Key + "'");
+ if (entry != null && !entry.IsDirectory && entry.Key.Contains(entryName))
{
- st.Write(ibuffer, 0, ilen);
- st.Flush();
+ realEntry = entry.Key;
+ entry.WriteTo(st);
+ break;
}
-
- zr = zf.CloseReadStream();
}
- }
- }
- else if (at == ArchiveType.SevenZip || at == ArchiveType.Rar)
- {
- reader = ReaderFactory.Open(File.OpenRead(input));
- while (reader.MoveToNextEntry())
- {
- logger.Verbose("Current entry name: '" + reader.Entry.Key + "'");
- if (reader.Entry != null && reader.Entry.Key.Contains(entryName))
+ sza.Dispose();
+ break;
+
+ case ArchiveType.GZip:
+ // Decompress the input stream
+ realEntry = Path.GetFileNameWithoutExtension(input);
+ GZipStream gzstream = new GZipStream(File.OpenRead(input), CompressionMode.Decompress);
+ gzstream.CopyTo(st);
+
+ // Dispose of the stream
+ gzstream.Dispose();
+ break;
+
+ case ArchiveType.Rar:
+ RarArchive ra = RarArchive.Open(input, new ReaderOptions { LeaveStreamOpen = false, });
+ foreach (RarArchiveEntry entry in ra.Entries)
{
- realEntry = reader.Entry.Key;
- reader.WriteEntryTo(st);
+ logger.Verbose("Current entry name: '" + entry.Key + "'");
+ if (entry != null && !entry.IsDirectory && entry.Key.Contains(entryName))
+ {
+ realEntry = entry.Key;
+ entry.WriteTo(st);
+ break;
+ }
}
- }
- }
- else if (at == ArchiveType.GZip)
- {
- // Decompress the input stream
- realEntry = Path.GetFileNameWithoutExtension(input);
- GZipStream gzstream = new GZipStream(File.OpenRead(input), CompressionMode.Decompress);
- gzstream.CopyTo(st);
+ ra.Dispose();
+ break;
- // Dispose of the stream
- gzstream.Dispose();
+ case ArchiveType.Tar:
+ TarArchive ta = TarArchive.Open(input, new ReaderOptions { LeaveStreamOpen = false, });
+ foreach (TarArchiveEntry entry in ta.Entries)
+ {
+ logger.Verbose("Current entry name: '" + entry.Key + "'");
+ if (entry != null && !entry.IsDirectory && entry.Key.Contains(entryName))
+ {
+ realEntry = entry.Key;
+ entry.WriteTo(st);
+ break;
+ }
+ }
+ ta.Dispose();
+ break;
+
+ case ArchiveType.Zip:
+ ZipFile zf = new ZipFile();
+ ZipReturn zr = zf.Open(input, new FileInfo(input).LastWriteTime.Ticks, true);
+ if (zr != ZipReturn.ZipGood)
+ {
+ throw new Exception(ZipFile.ZipErrorMessageText(zr));
+ }
+
+ for (int i = 0; i < zf.EntriesCount && zr == ZipReturn.ZipGood; i++)
+ {
+ logger.Verbose("Current entry name: '" + zf.Entries[i].FileName + "'");
+ if (zf.Entries[i].FileName.Contains(entryName))
+ {
+ realEntry = zf.Entries[i].FileName;
+
+ // Set defaults before writing out
+ Stream readStream;
+ ulong streamsize = 0;
+ CompressionMethod cm = CompressionMethod.Stored;
+ uint lastMod = 0;
+
+ zr = zf.OpenReadStream(i, false, out readStream, out streamsize, out cm, out lastMod);
+
+ byte[] ibuffer = new byte[_bufferSize];
+ int ilen;
+ while ((ilen = readStream.Read(ibuffer, 0, _bufferSize)) > 0)
+ {
+ st.Write(ibuffer, 0, ilen);
+ st.Flush();
+ }
+
+ zr = zf.CloseReadStream();
+ }
+ }
+ break;
}
}
catch (Exception ex)
@@ -338,10 +372,6 @@ namespace SabreTools.Helper.Tools
logger.Error(ex.ToString());
st = null;
}
- finally
- {
- reader?.Dispose();
- }
st.Position = 0;
return st;