[ArchiveTools] Get TAR working properly

This commit is contained in:
Matt Nadareski
2017-01-27 17:07:08 -08:00
parent 8d6fa2c908
commit cb0e6a0106

View File

@@ -1102,6 +1102,13 @@ namespace SabreTools.Helper.Tools
public static bool WriteTAR(List<string> inputFiles, string outDir, List<Rom> roms, Logger logger, bool date = false) public static bool WriteTAR(List<string> inputFiles, string outDir, List<Rom> roms, Logger logger, bool date = false)
{ {
bool success = false; bool success = false;
string tempFile = Path.GetTempFileName();
// If either list of roms is null or empty, return
if (inputFiles == null || roms == null || inputFiles.Count == 0 || roms.Count == 0)
{
return success;
}
// If the number of inputs is less than the number of available roms, return // If the number of inputs is less than the number of available roms, return
if (inputFiles.Count < roms.Count) if (inputFiles.Count < roms.Count)
@@ -1122,8 +1129,8 @@ namespace SabreTools.Helper.Tools
string archiveFileName = Path.Combine(outDir, Style.RemovePathUnsafeCharacters(roms[0].Machine.Name) + (roms[0].Machine.Name.EndsWith(".tar") ? "" : ".tar")); string archiveFileName = Path.Combine(outDir, Style.RemovePathUnsafeCharacters(roms[0].Machine.Name) + (roms[0].Machine.Name.EndsWith(".tar") ? "" : ".tar"));
// Set internal variables // Set internal variables
Stream tarstream = new MemoryStream(); TarArchive oldTarFile = TarArchive.Create();
TarArchive tarchive = TarArchive.Create(); TarArchive tarFile = TarArchive.Create();
try try
{ {
@@ -1133,42 +1140,120 @@ namespace SabreTools.Helper.Tools
Directory.CreateDirectory(Path.GetDirectoryName(archiveFileName)); Directory.CreateDirectory(Path.GetDirectoryName(archiveFileName));
} }
// We can only overwrite at this point, sorry // If the archive doesn't exist, create it and put the single file
tarstream = File.Open(archiveFileName, FileMode.Create, FileAccess.Write); if (!File.Exists(archiveFileName))
// Map all inputs to index
Dictionary<string, int> inputIndexMap = new Dictionary<string, int>();
for (int i = 0; i < inputFiles.Count; i++)
{ {
inputIndexMap.Add(roms[i].Name.Replace('\\', '/'), i); // Map all inputs to index
Dictionary<string, int> inputIndexMap = new Dictionary<string, int>();
for (int i = 0; i < inputFiles.Count; i++)
{
inputIndexMap.Add(roms[i].Name.Replace('\\', '/'), i);
}
// Sort the keys in TZIP order
List<string> keys = inputIndexMap.Keys.ToList();
keys.Sort(ZipFile.TorrentZipStringCompare);
// Now add all of the files in order
foreach (string key in keys)
{
// Get the index mapped to the key
int index = inputIndexMap[key];
// Copy the input stream to the output
tarFile.AddEntry(roms[index].Name, inputFiles[index]);
}
} }
// Sort the keys in TZIP order // Otherwise, sort the input files and write out in the correct order
List<string> keys = inputIndexMap.Keys.ToList(); else
keys.Sort(ZipFile.TorrentZipStringCompare);
// Now add each of the files
foreach (string key in keys)
{ {
int index = inputIndexMap[key]; // Open the old archive for reading
tarchive.AddEntry(key, inputFiles[index]); oldTarFile = TarArchive.Open(archiveFileName);
// Get a list of all current entries
List<string> entries = oldTarFile.Entries.Select(i => i.Key).ToList();
// Map all inputs to index
Dictionary<string, int> inputIndexMap = new Dictionary<string, int>();
for (int i = 0; i < inputFiles.Count; i++)
{
// If the old one contains the new file, then just skip out
if (entries.Contains(roms[i].Name.Replace('\\', '/')))
{
continue;
}
inputIndexMap.Add(roms[i].Name.Replace('\\', '/'), -(i + 1));
}
// Then add all of the old entries to it too
for (int i = 0; i < entries.Count; i++)
{
inputIndexMap.Add(entries[i], i);
}
// If the number of entries is the same as the old archive, skip out
if (inputIndexMap.Keys.Count <= entries.Count)
{
success = true;
return success;
}
// Get the order for the entries with the new file
List<string> keys = inputIndexMap.Keys.ToList();
keys.Sort(ZipFile.TorrentZipStringCompare);
// Copy over all files to the new archive
foreach (string key in keys)
{
// Get the index mapped to the key
int index = inputIndexMap[key];
// If we have the input file, add it now
if (index < 0)
{
// Copy the input file to the output
tarFile.AddEntry(roms[-index - 1].Name, inputFiles[-index - 1]);
}
// Otherwise, copy the file from the old archive
else
{
// Get the stream from the original archive
string tempEntry = Path.GetTempFileName();
oldTarFile.Entries.Where(e => e.Key == key).ToList()[0].WriteToFile(tempEntry);
// Copy the input stream to the output
tarFile.AddEntry(key, tempEntry);
}
}
} }
tarchive.SaveTo(tarstream, new WriterOptions(CompressionType.None)); // Close the output tar file
tarFile.SaveTo(tempFile, new WriterOptions(CompressionType.None));
success = true; success = true;
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex);
success = false; success = false;
logger.Error(ex.ToString());
} }
finally finally
{ {
tarstream?.Dispose(); tarFile.Dispose();
tarchive?.Dispose(); oldTarFile.Dispose();
} }
return success; // If the old file exists, delete it and replace
if (File.Exists(archiveFileName))
{
File.Delete(archiveFileName);
}
File.Move(tempFile, archiveFileName);
return true;
} }
/// <summary> /// <summary>