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 } }