diff --git a/SabreTools.Helper/Dats/DatFile.cs b/SabreTools.Helper/Dats/DatFile.cs
index 2974d537..23e72055 100644
--- a/SabreTools.Helper/Dats/DatFile.cs
+++ b/SabreTools.Helper/Dats/DatFile.cs
@@ -864,7 +864,7 @@ namespace SabreTools.Helper.Dats
}
// Sort the list first
- newInputFileNames.Sort(new NaturalComparer());
+ newInputFileNames = Style.OrderByAlphaNumeric(newInputFileNames, s => s).ToList();
// If we're in inverse cascade, reverse the list
if ((diff & DiffMode.ReverseCascade) != 0)
@@ -4320,6 +4320,12 @@ namespace SabreTools.Helper.Dats
new ParallelOptions { MaxDegreeOfParallelism = maxDegreeOfParallelism },
file =>
{
+ // If we somehow have a null filename, return
+ if (file == null)
+ {
+ return;
+ }
+
// Define the temporary directory
string tempSubDir = Path.GetFullPath(Path.Combine(tempDir, Path.GetRandomFileName())) + Path.DirectorySeparatorChar;
diff --git a/SabreTools.Helper/Tools/ArchiveTools.cs b/SabreTools.Helper/Tools/ArchiveTools.cs
index 6d3581cc..bba9a7f9 100644
--- a/SabreTools.Helper/Tools/ArchiveTools.cs
+++ b/SabreTools.Helper/Tools/ArchiveTools.cs
@@ -434,6 +434,32 @@ namespace SabreTools.Helper.Tools
});
}
}
+ else if (at == ArchiveType.SevenZip)
+ {
+ SevenZipArchive sza = SevenZipArchive.Open(input, new ReaderOptions { LeaveStreamOpen = false });
+ foreach (SevenZipArchiveEntry entry in sza.Entries)
+ {
+ if (entry != null && !entry.IsDirectory)
+ {
+ logger.Verbose("Entry found: '" + entry.Key + "': "
+ + (size == 0 ? entry.Size : size) + ", "
+ + (crc == "" ? entry.Crc.ToString("X").ToLowerInvariant() : crc));
+
+ roms.Add(new Rom
+ {
+ Type = ItemType.Rom,
+ Name = entry.Key,
+ Size = (size == 0 ? entry.Size : size),
+ CRC = (crc == "" ? entry.Crc.ToString("X").ToLowerInvariant() : crc),
+
+ Machine = new Machine
+ {
+ Name = gamename,
+ },
+ });
+ }
+ }
+ }
else if (at != ArchiveType.Tar)
{
reader = ReaderFactory.Open(File.OpenRead(input));
@@ -557,9 +583,14 @@ namespace SabreTools.Helper.Tools
/// ArchiveType of inputted file (null on error)
public static ArchiveType? GetCurrentArchiveType(string input, Logger logger)
{
-
ArchiveType? outtype = null;
+ // If the file is null, then we have no archive type
+ if (input == null)
+ {
+ return outtype;
+ }
+
// First line of defense is going to be the extension, for better or worse
string ext = Path.GetExtension(input).ToLowerInvariant();
if (ext.StartsWith("."))
diff --git a/SabreTools.Helper/Tools/FileTools.cs b/SabreTools.Helper/Tools/FileTools.cs
index dd3311d6..1f324867 100644
--- a/SabreTools.Helper/Tools/FileTools.cs
+++ b/SabreTools.Helper/Tools/FileTools.cs
@@ -49,7 +49,7 @@ namespace SabreTools.Helper.Tools
// Then recurse through and add from the directories
List dirs = Directory.EnumerateDirectories(directory, "*", SearchOption.TopDirectoryOnly).ToList();
- dirs.Sort(new NaturalComparer());
+ dirs = Style.OrderByAlphaNumeric(dirs, s => s).ToList();
foreach (string dir in dirs)
{
infiles = RetrieveFiles(dir, infiles);
diff --git a/SabreTools.Helper/Tools/Style.cs b/SabreTools.Helper/Tools/Style.cs
index fdb019de..1de3ccff 100644
--- a/SabreTools.Helper/Tools/Style.cs
+++ b/SabreTools.Helper/Tools/Style.cs
@@ -304,6 +304,43 @@ namespace SabreTools.Helper.Tools
return 1;
}
+ // Now split into path parts after converting AltDirSeparator to DirSeparator
+ s1 = s1.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
+ s2 = s2.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
+ string[] s1parts = s1.Split(Path.DirectorySeparatorChar);
+ string[] s2parts = s2.Split(Path.DirectorySeparatorChar);
+
+ // Then compare each part in turn
+ for (int j = 0; j < s1parts.Length && j < s2parts.Length; j++)
+ {
+ int compared = CompareNumericPart(s1parts[j], s2parts[j]);
+ if (compared != 0)
+ {
+ return compared;
+ }
+ }
+
+ // If we got out here, then it looped through at least one of the strings
+ if (s1parts.Length > s2parts.Length)
+ {
+ return 1;
+ }
+ if (s1parts.Length < s2parts.Length)
+ {
+ return -1;
+ }
+
+ return 0;
+ }
+
+ ///
+ /// Helper for CompareNumeric
+ ///
+ /// First string to compare
+ /// Second string to compare
+ /// -1 if s1 comes before s2, 0 if s1 and s2 are equal, 1 if s1 comes after s2
+ private static int CompareNumericPart(string s1, string s2)
+ {
// Otherwise, loop through until we have an answer
for (int i = 0; i < s1.Length && i < s2.Length; i++)
{
@@ -676,6 +713,18 @@ namespace SabreTools.Helper.Tools
return localTime;
}
+ ///
+ /// http://stackoverflow.com/questions/248603/natural-sort-order-in-c-sharp
+ ///
+ public static IEnumerable OrderByAlphaNumeric(this IEnumerable source, Func selector)
+ {
+ int max = source
+ .SelectMany(i => Regex.Matches(selector(i), @"\d+").Cast().Select(m => (int?)m.Value.Length))
+ .Max() ?? 0;
+
+ return source.OrderBy(i => Regex.Replace(selector(i), @"\d+", m => m.Value.PadLeft(max, '0')));
+ }
+
#endregion
}
}