diff --git a/SabreTools.Helper/Tools/ArchiveTools.cs b/SabreTools.Helper/Tools/ArchiveTools.cs
index a70c26cc..8a8d06cc 100644
--- a/SabreTools.Helper/Tools/ArchiveTools.cs
+++ b/SabreTools.Helper/Tools/ArchiveTools.cs
@@ -27,8 +27,9 @@ namespace SabreTools.Helper
public static bool CopyFileBetweenArchives(string inputArchive, string outDir,
string sourceEntryName, Rom destEntry, Logger logger)
{
- string tempfile = ExtractSingleItemFromArchive(inputArchive, sourceEntryName, Path.GetTempPath(), logger);
- return WriteToArchive(tempfile, outDir, destEntry);
+ string realName = "";
+ Stream ms = ExtractSingleStreamFromArchive(inputArchive, sourceEntryName, out realName, logger);
+ return WriteToArchive(ms, outDir, destEntry);
}
#endregion
@@ -166,21 +167,56 @@ namespace SabreTools.Helper
/// Attempt to extract a file from an archive
///
/// Name of the archive to be extracted
- /// Name of the entry to be extracted
+ /// Name of the entry to be extracted
/// Temporary directory for archive extraction
/// Logger object for file and console output
/// Name of the extracted file, null on error
- public static string ExtractSingleItemFromArchive(string input, string entryname, string tempDir, Logger logger)
+ public static string ExtractSingleItemFromArchive(string input, string entryName, string tempDir, Logger logger)
{
string outfile = null;
+ string realEntry = "";
+ Stream ms = ExtractSingleStreamFromArchive(input, entryName, out realEntry, logger);
+
+ realEntry = Path.GetFullPath(Path.Combine(tempDir, realEntry));
+ if (!Directory.Exists(Path.GetDirectoryName(outfile)))
+ {
+ Directory.CreateDirectory(Path.GetDirectoryName(outfile));
+ }
+
+ FileStream fs = File.Open(realEntry, FileMode.Create, FileAccess.Write);
+ ms.CopyTo(fs);
+ fs.Flush();
+
+ // Dispose of the streams
+ ms.Dispose();
+ fs.Dispose();
+
+ return outfile;
+ }
+
+ ///
+ /// Attempt to extract a file from an archive
+ ///
+ /// Name of the archive to be extracted
+ /// Name of the entry to be extracted
+ /// Logger object for file and console output
+ /// Name of the extracted file, null on error
+ public static Stream ExtractSingleStreamFromArchive(string input, string entryName, out string realEntry, Logger logger)
+ {
+ // Set the real entry name
+ realEntry = "";
+
+ // Get a writable stream to return
+ Stream st = new MemoryStream();
+
// First get the archive type
ArchiveType? at = GetCurrentArchiveType(input, logger);
// If we got back null, then it's not an archive, so we we return
if (at == null)
{
- return outfile;
+ return st;
}
IReader reader = null;
@@ -188,48 +224,40 @@ namespace SabreTools.Helper
{
if (at == ArchiveType.Zip || at == ArchiveType.SevenZip || at == ArchiveType.Rar)
{
- // Create the temp directory
- Directory.CreateDirectory(tempDir);
-
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))
+ if (reader.Entry != null && reader.Entry.Key.Contains(entryName))
{
- outfile = Path.GetFullPath(Path.Combine(tempDir, reader.Entry.Key));
- if (!Directory.Exists(Path.GetDirectoryName(outfile)))
- {
- Directory.CreateDirectory(Path.GetDirectoryName(outfile));
- }
- reader.WriteEntryToFile(outfile, ExtractOptions.Overwrite);
+ realEntry = reader.Entry.Key;
+ reader.WriteEntryTo(st);
}
}
}
else if (at == ArchiveType.GZip)
{
// Decompress the input stream
- FileStream outstream = File.Create(Path.Combine(tempDir, Path.GetFileNameWithoutExtension(input)));
+ realEntry = Path.GetFileNameWithoutExtension(input);
GZipStream gzstream = new GZipStream(File.OpenRead(input), CompressionMode.Decompress);
- gzstream.CopyTo(outstream);
- outfile = Path.GetFullPath(Path.Combine(tempDir, Path.GetFileNameWithoutExtension(input)));
+ gzstream.CopyTo(st);
// Dispose of the streams
- outstream.Dispose();
+ st.Dispose();
gzstream.Dispose();
}
}
catch (Exception ex)
{
logger.Error(ex.ToString());
- outfile = null;
+ st = null;
}
finally
{
reader?.Dispose();
}
- return outfile;
+ return st;
}
#endregion
@@ -536,10 +564,27 @@ namespace SabreTools.Helper
/// RomData representing the new information
/// True if the archive was written properly, false otherwise
public static bool WriteToArchive(string inputFile, string outDir, Rom rom)
+ {
+ // Get the stream from the input file
+ Stream fs = File.OpenRead(inputFile);
+ bool success = WriteToArchive(fs, outDir, rom);
+ fs.Dispose();
+
+ return success;
+ }
+
+ ///
+ /// Copy a stream to an output archive
+ ///
+ /// Input stream to be written
+ /// Output directory to build to
+ /// RomData representing the new information
+ /// True if the archive was written properly, false otherwise
+ public static bool WriteToArchive(Stream inputStream, string outDir, Rom rom)
{
// Wrap the individual inputs into lists
- List inputFiles = new List();
- inputFiles.Add(inputFile);
+ List inputFiles = new List();
+ inputFiles.Add(inputStream);
List roms = new List();
roms.Add(rom);
@@ -572,6 +617,41 @@ namespace SabreTools.Helper
}
}
+ // Get the streams from the input files
+ List inputStreams = new List();
+ foreach (string inputFile in inputFiles)
+ {
+ inputStreams.Add(File.OpenRead(inputFile));
+ }
+
+ success = WriteToArchive(inputStreams, outDir, roms);
+
+ // Now close all of the streams
+ foreach (Stream inputStream in inputStreams)
+ {
+ inputStream.Dispose();
+ }
+
+ return success;
+ }
+
+ ///
+ /// Copy a set of streams to an output archive (assuming the same output archive name)
+ ///
+ /// Input streams to be moved
+ /// Output directory to build to
+ /// List of Rom representing the new information
+ /// True if the archive was written properly, false otherwise
+ public static bool WriteToArchive(List inputStreams, string outDir, List roms)
+ {
+ bool success = false;
+
+ // If the number of inputs is less than the number of available roms, return
+ if (inputStreams.Count < roms.Count)
+ {
+ return success;
+ }
+
// Get the output archive name from the first rebuild rom
string archiveFileName = Path.Combine(outDir, roms[0].MachineName + ".zip");
@@ -596,15 +676,18 @@ namespace SabreTools.Helper
outarchive = System.IO.Compression.ZipFile.Open(archiveFileName, ZipArchiveMode.Update);
// Now loop through and add all files
- for (int i = 0; i < inputFiles.Count; i++)
+ for (int i = 0; i < inputStreams.Count; i++)
{
- string inputFile = inputFiles[i];
Rom rom = roms[i];
// If the archive doesn't already contain the entry, add it
if (outarchive.GetEntry(rom.Name) == null)
{
- outarchive.CreateEntryFromFile(inputFile, rom.Name, CompressionLevel.Optimal);
+ ZipArchiveEntry ae = outarchive.CreateEntry(rom.Name, CompressionLevel.Optimal);
+ Stream outputStream = ae.Open();
+ inputStreams[i].CopyTo(outputStream);
+ outputStream.Flush();
+ outputStream.Dispose();
}
// If there's a Date attached to the rom, change the entry to that Date