diff --git a/SabreTools.Helper/Tools/ArchiveTools.cs b/SabreTools.Helper/Tools/ArchiveTools.cs
index 34d5320f..7b8ec6fd 100644
--- a/SabreTools.Helper/Tools/ArchiveTools.cs
+++ b/SabreTools.Helper/Tools/ArchiveTools.cs
@@ -119,7 +119,8 @@ namespace SabreTools.Helper.Tools
#endregion
- // For each item, extract to stream, write to archive
+ // If the input archive is
+
return false;
}
@@ -468,6 +469,129 @@ namespace SabreTools.Helper.Tools
return realEntry;
}
+ ///
+ /// Attempt to extract a stream from an archive
+ ///
+ /// Name of the archive to be extracted
+ /// Name of the entry to be extracted
+ /// Temporary directory for archive extraction
+ /// MemoryStream representing the entry, null on error
+ public static MemoryStream ExtractStream(string input, string entryName, string tempDir)
+ {
+ MemoryStream ms = new MemoryStream();
+
+ // First get the archive type
+ ArchiveType? at = GetCurrentArchiveType(input);
+
+ // If we got back null, then it's not an archive, so we we return
+ if (at == null)
+ {
+ return null;
+ }
+
+ try
+ {
+ switch (at)
+ {
+ case ArchiveType.SevenZip:
+ SevenZipArchive sza = SevenZipArchive.Open(input, new ReaderOptions { LeaveStreamOpen = false, });
+ foreach (SevenZipArchiveEntry entry in sza.Entries)
+ {
+ if (entry != null && !entry.IsDirectory && entry.Key.Contains(entryName))
+ {
+ // Write the file out
+ entry.WriteTo(ms);
+ break;
+ }
+ }
+ sza.Dispose();
+ break;
+
+ case ArchiveType.GZip:
+ // Decompress the input stream
+ GZipStream gzstream = new GZipStream(FileTools.TryOpenRead(input), Ionic.Zlib.CompressionMode.Decompress);
+
+ // Write the file out
+ byte[] gbuffer = new byte[_bufferSize];
+ int glen;
+ while ((glen = gzstream.Read(gbuffer, 0, _bufferSize)) > 0)
+ {
+
+ ms.Write(gbuffer, 0, glen);
+ ms.Flush();
+ }
+
+ // Dispose of the streams
+ gzstream.Dispose();
+ break;
+
+ case ArchiveType.Rar:
+ RarArchive ra = RarArchive.Open(input, new ReaderOptions { LeaveStreamOpen = false, });
+ foreach (RarArchiveEntry entry in ra.Entries)
+ {
+ if (entry != null && !entry.IsDirectory && entry.Key.Contains(entryName))
+ {
+ // Write the file out
+ entry.WriteTo(ms);
+ }
+ }
+ ra.Dispose();
+ break;
+
+ case ArchiveType.Tar:
+ TarArchive ta = TarArchive.Open(input, new ReaderOptions { LeaveStreamOpen = false, });
+ foreach (TarArchiveEntry entry in ta.Entries)
+ {
+ if (entry != null && !entry.IsDirectory && entry.Key.Contains(entryName))
+ {
+ // Write the file out
+ entry.WriteTo(ms);
+ }
+ }
+ 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++)
+ {
+ if (zf.Entries[i].FileName.Contains(entryName))
+ {
+ // Open the read stream
+ zr = zf.OpenReadStream(i, false, out Stream readStream, out ulong streamsize, out SabreTools.Helper.Data.CompressionMethod cm, out uint lastMod);
+
+ // Write the file out
+ byte[] zbuffer = new byte[_bufferSize];
+ int zlen;
+ while ((zlen = readStream.Read(zbuffer, 0, _bufferSize)) > 0)
+ {
+ ms.Write(zbuffer, 0, zlen);
+ ms.Flush();
+ }
+
+ zr = zf.CloseReadStream();
+ }
+ }
+
+ zf.Dispose();
+ break;
+ }
+ }
+ catch (Exception ex)
+ {
+ Globals.Logger.Error(ex.ToString());
+ ms = null;
+ }
+
+ return ms;
+ }
+
#endregion
#region Information