diff --git a/SabreTools.Core/ConcurrentList.cs b/SabreTools.Core/ConcurrentList.cs index b1c2b484..938486f1 100644 --- a/SabreTools.Core/ConcurrentList.cs +++ b/SabreTools.Core/ConcurrentList.cs @@ -18,7 +18,7 @@ namespace SabreTools.Core set { lock (_lock) _list[index] = value; } } - object IList.this[int index] + object? IList.this[int index] { get { lock (_lock) return ((IList)_list)[index]; } set { lock (_lock) ((IList)_list)[index] = value; } @@ -43,7 +43,7 @@ namespace SabreTools.Core _list.Add(item); } - public int Add(object value) + public int Add(object? value) { lock (_lock) return ((IList)_list).Add(value); @@ -67,7 +67,7 @@ namespace SabreTools.Core return _list.Contains(item); } - public bool Contains(object value) + public bool Contains(object? value) { lock (_lock) return ((IList)_list).Contains(value); @@ -109,7 +109,7 @@ namespace SabreTools.Core return _list.IndexOf(item); } - public int IndexOf(object value) + public int IndexOf(object? value) { lock (_lock) return ((IList)_list).IndexOf(value); @@ -121,7 +121,7 @@ namespace SabreTools.Core _list.Insert(index, item); } - public void Insert(int index, object value) + public void Insert(int index, object? value) { lock (_lock) ((IList)_list).Insert(index, value); @@ -133,7 +133,7 @@ namespace SabreTools.Core return _list.Remove(item); } - public void Remove(object value) + public void Remove(object? value) { lock (_lock) ((IList)_list).Remove(value); diff --git a/SabreTools.Core/NaturalSort/NaturalComparer.cs b/SabreTools.Core/NaturalSort/NaturalComparer.cs index c08cbd93..ae3a55b9 100644 --- a/SabreTools.Core/NaturalSort/NaturalComparer.cs +++ b/SabreTools.Core/NaturalSort/NaturalComparer.cs @@ -14,82 +14,91 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; +// TODO: Split into separate library namespace NaturalSort { - public class NaturalComparer : Comparer, IDisposable - { - private Dictionary table; + public class NaturalComparer : Comparer, IDisposable + { + private readonly Dictionary table; - public NaturalComparer() - { - table = new Dictionary(); - } + public NaturalComparer() + { + table = new Dictionary(); + } public void Dispose() - { - table.Clear(); - table = null; - } + { + table.Clear(); + } - public override int Compare(string x, string y) - { - if (x.ToLowerInvariant() == y.ToLowerInvariant()) - { - return x.CompareTo(y); - } - if (!table.TryGetValue(x, out string[] x1)) - { - //x1 = Regex.Split(x.Replace(" ", string.Empty), "([0-9]+)"); - x1 = Regex.Split(x.ToLowerInvariant(), "([0-9]+)").Where(s => !string.IsNullOrWhiteSpace(s)).ToArray(); - table.Add(x, x1); - } - if (!table.TryGetValue(y, out string[] y1)) - { - //y1 = Regex.Split(y.Replace(" ", string.Empty), "([0-9]+)"); - y1 = Regex.Split(y.ToLowerInvariant(), "([0-9]+)").Where(s => !string.IsNullOrWhiteSpace(s)).ToArray(); - table.Add(y, y1); - } + public override int Compare(string? x, string? y) + { + if (x == null || y == null) + { + if (x == null && y != null) + return -1; + else if (x != null && y == null) + return 1; + else + return 0; + } + if (x.ToLowerInvariant() == y.ToLowerInvariant()) + { + return x.CompareTo(y); + } + if (!table.TryGetValue(x, out string[]? x1)) + { + //x1 = Regex.Split(x.Replace(" ", string.Empty), "([0-9]+)"); + x1 = Regex.Split(x.ToLowerInvariant(), "([0-9]+)").Where(s => !string.IsNullOrWhiteSpace(s)).ToArray(); + table.Add(x, x1); + } + if (!table.TryGetValue(y, out string[]? y1)) + { + //y1 = Regex.Split(y.Replace(" ", string.Empty), "([0-9]+)"); + y1 = Regex.Split(y.ToLowerInvariant(), "([0-9]+)").Where(s => !string.IsNullOrWhiteSpace(s)).ToArray(); + table.Add(y, y1); + } - for (int i = 0; i < x1.Length && i < y1.Length; i++) - { - if (x1[i] != y1[i]) - { - return PartCompare(x1[i], y1[i]); - } - } - if (y1.Length > x1.Length) - { - return 1; - } - else if (x1.Length > y1.Length) - { - return -1; - } - else - { - return x.CompareTo(y); - } - } + for (int i = 0; i < x1.Length && i < y1.Length; i++) + { + if (x1[i] != y1[i]) + { + return PartCompare(x1[i], y1[i]); + } + } + if (y1.Length > x1.Length) + { + return 1; + } + else if (x1.Length > y1.Length) + { + return -1; + } + else + { + return x.CompareTo(y); + } + } - private static int PartCompare(string left, string right) - { - if (!long.TryParse(left, out long x)) - { - return NaturalComparerUtil.CompareNumeric(left, right); - } + private static int PartCompare(string left, string right) + { + if (!long.TryParse(left, out long x)) + { + return NaturalComparerUtil.CompareNumeric(left, right); + } - if (!long.TryParse(right, out long y)) - { - return NaturalComparerUtil.CompareNumeric(left, right); - } + if (!long.TryParse(right, out long y)) + { + return NaturalComparerUtil.CompareNumeric(left, right); + } - // If we have an equal part, then make sure that "longer" ones are taken into account - if (x.CompareTo(y) == 0) - { - return left.Length - right.Length; - } + // If we have an equal part, then make sure that "longer" ones are taken into account + if (x.CompareTo(y) == 0) + { + return left.Length - right.Length; + } - return x.CompareTo(y); - } - } + return x.CompareTo(y); + } + } } diff --git a/SabreTools.Core/NaturalSort/NaturalComparerUtil.cs b/SabreTools.Core/NaturalSort/NaturalComparerUtil.cs index d13318c3..86158295 100644 --- a/SabreTools.Core/NaturalSort/NaturalComparerUtil.cs +++ b/SabreTools.Core/NaturalSort/NaturalComparerUtil.cs @@ -1,78 +1,79 @@ using System.IO; +// TODO: Split into separate library namespace NaturalSort { public static class NaturalComparerUtil { - public static int CompareNumeric(string s1, string s2) - { - // Save the orginal strings, for later comparison - string s1orig = s1; - string s2orig = s2; + public static int CompareNumeric(string s1, string s2) + { + // Save the orginal strings, for later comparison + string s1orig = s1; + string s2orig = s2; - // We want to normalize the strings, so we set both to lower case - s1 = s1.ToLowerInvariant(); - s2 = s2.ToLowerInvariant(); + // We want to normalize the strings, so we set both to lower case + s1 = s1.ToLowerInvariant(); + s2 = s2.ToLowerInvariant(); - // If the strings are the same exactly, return - if (s1 == s2) - return s1orig.CompareTo(s2orig); + // If the strings are the same exactly, return + if (s1 == s2) + return s1orig.CompareTo(s2orig); - // If one is null, then say that's less than - if (s1 == null) - return -1; - if (s2 == null) - return 1; + // If one is null, then say that's less than + if (s1 == null) + return -1; + if (s2 == null) + 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); + // 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; - } + // 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; + // 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 s1orig.CompareTo(s2orig); - } + return s1orig.CompareTo(s2orig); + } - 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++) - { - int s1c = s1[i]; - int s2c = s2[i]; + 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++) + { + int s1c = s1[i]; + int s2c = s2[i]; - // If the characters are the same, continue - if (s1c == s2c) - continue; + // If the characters are the same, continue + if (s1c == s2c) + continue; - // If they're different, check which one was larger - if (s1c > s2c) - return 1; - if (s1c < s2c) - return -1; - } + // If they're different, check which one was larger + if (s1c > s2c) + return 1; + if (s1c < s2c) + return -1; + } - // If we got out here, then it looped through at least one of the strings - if (s1.Length > s2.Length) - return 1; - if (s1.Length < s2.Length) - return -1; + // If we got out here, then it looped through at least one of the strings + if (s1.Length > s2.Length) + return 1; + if (s1.Length < s2.Length) + return -1; - return 0; - } - } + return 0; + } + } } diff --git a/SabreTools.Core/NaturalSort/NaturalReversedComparer.cs b/SabreTools.Core/NaturalSort/NaturalReversedComparer.cs index da591f1a..d0a44975 100644 --- a/SabreTools.Core/NaturalSort/NaturalReversedComparer.cs +++ b/SabreTools.Core/NaturalSort/NaturalReversedComparer.cs @@ -14,82 +14,91 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; +// TODO: Split into separate library namespace NaturalSort { - public class NaturalReversedComparer : Comparer, IDisposable - { - private Dictionary table; + public class NaturalReversedComparer : Comparer, IDisposable + { + private readonly Dictionary table; - public NaturalReversedComparer() - { - table = new Dictionary(); - } + public NaturalReversedComparer() + { + table = new Dictionary(); + } - public void Dispose() - { - table.Clear(); - table = null; - } + public void Dispose() + { + table.Clear(); + } - public override int Compare(string x, string y) - { - if (y.ToLowerInvariant() == x.ToLowerInvariant()) - { - return y.CompareTo(x); - } - if (!table.TryGetValue(x, out string[] x1)) - { - //x1 = Regex.Split(x.Replace(" ", string.Empty), "([0-9]+)"); - x1 = Regex.Split(x.ToLowerInvariant(), "([0-9]+)").Where(s => !string.IsNullOrWhiteSpace(s)).ToArray(); - table.Add(x, x1); - } - if (!table.TryGetValue(y, out string[] y1)) - { - //y1 = Regex.Split(y.Replace(" ", string.Empty), "([0-9]+)"); - y1 = Regex.Split(y.ToLowerInvariant(), "([0-9]+)").Where(s => !string.IsNullOrWhiteSpace(s)).ToArray(); - table.Add(y, y1); - } + public override int Compare(string? x, string? y) + { + if (x == null || y == null) + { + if (x == null && y != null) + return -1; + else if (x != null && y == null) + return 1; + else + return 0; + } + if (y.ToLowerInvariant() == x.ToLowerInvariant()) + { + return y.CompareTo(x); + } + if (!table.TryGetValue(x, out string[]? x1)) + { + //x1 = Regex.Split(x.Replace(" ", string.Empty), "([0-9]+)"); + x1 = Regex.Split(x.ToLowerInvariant(), "([0-9]+)").Where(s => !string.IsNullOrWhiteSpace(s)).ToArray(); + table.Add(x, x1); + } + if (!table.TryGetValue(y, out string[]? y1)) + { + //y1 = Regex.Split(y.Replace(" ", string.Empty), "([0-9]+)"); + y1 = Regex.Split(y.ToLowerInvariant(), "([0-9]+)").Where(s => !string.IsNullOrWhiteSpace(s)).ToArray(); + table.Add(y, y1); + } - for (int i = 0; i < x1.Length && i < y1.Length; i++) - { - if (x1[i] != y1[i]) - { - return PartCompare(x1[i], y1[i]); - } - } - if (y1.Length > x1.Length) - { - return 1; - } - else if (x1.Length > y1.Length) - { - return -1; - } - else - { - return y.CompareTo(x); - } - } + for (int i = 0; i < x1.Length && i < y1.Length; i++) + { + if (x1[i] != y1[i]) + { + return PartCompare(x1[i], y1[i]); + } + } + if (y1.Length > x1.Length) + { + return 1; + } + else if (x1.Length > y1.Length) + { + return -1; + } + else + { + return y.CompareTo(x); + } + } - private static int PartCompare(string left, string right) - { - if (!long.TryParse(left, out long x)) - { - return NaturalComparerUtil.CompareNumeric(right, left); - } + private static int PartCompare(string left, string right) + { + if (!long.TryParse(left, out long x)) + { + return NaturalComparerUtil.CompareNumeric(right, left); + } - if (!long.TryParse(right, out long y)) - { - return NaturalComparerUtil.CompareNumeric(right, left); - } + if (!long.TryParse(right, out long y)) + { + return NaturalComparerUtil.CompareNumeric(right, left); + } - // If we have an equal part, then make sure that "longer" ones are taken into account - if (y.CompareTo(x) == 0) - { - return right.Length - left.Length; - } + // If we have an equal part, then make sure that "longer" ones are taken into account + if (y.CompareTo(x) == 0) + { + return right.Length - left.Length; + } - return y.CompareTo(x); - } - } + return y.CompareTo(x); + } + } } diff --git a/SabreTools.Core/Prepare.cs b/SabreTools.Core/Prepare.cs index 1070fb87..551fb86c 100644 --- a/SabreTools.Core/Prepare.cs +++ b/SabreTools.Core/Prepare.cs @@ -13,7 +13,7 @@ namespace SabreTools.Core /// The current toolset version to be used by all child applications /// public readonly static string Version = $"v1.1.2"; - + /// /// Readies the console and outputs the header /// @@ -30,9 +30,6 @@ namespace SabreTools.Core if (!Console.IsOutputRedirected) { // Set the console to ready state - if (Environment.OSVersion.Platform == PlatformID.Win32NT) - Console.SetBufferSize(Console.BufferWidth, 999); - ConsoleColor formertext = Console.ForegroundColor; ConsoleColor formerback = Console.BackgroundColor; Console.ForegroundColor = ConsoleColor.Yellow; @@ -48,7 +45,7 @@ namespace SabreTools.Core // Return the console to the original text and background colors Console.ForegroundColor = formertext; - Console.BackgroundColor = formerback; + Console.BackgroundColor = formerback; } } } diff --git a/SabreTools.Core/SabreTools.Core.csproj b/SabreTools.Core/SabreTools.Core.csproj index 0f080476..9e23202e 100644 --- a/SabreTools.Core/SabreTools.Core.csproj +++ b/SabreTools.Core/SabreTools.Core.csproj @@ -2,6 +2,7 @@ net6.0;net7.0 + enable diff --git a/SabreTools.Core/Tools/Aaru/SpamSumContext.cs b/SabreTools.Core/Tools/Aaru/SpamSumContext.cs index cd4eb26a..94e4ea28 100644 --- a/SabreTools.Core/Tools/Aaru/SpamSumContext.cs +++ b/SabreTools.Core/Tools/Aaru/SpamSumContext.cs @@ -454,7 +454,7 @@ namespace Aaru.Checksums /// Length of the data buffer to hash. /// null /// Base64 representation of SpamSum $blocksize:$hash:$hash - public static string Data(byte[] data, uint len, out byte[] hash) + public static string Data(byte[] data, uint len, out byte[]? hash) { var fuzzyContext = new SpamSumContext(); @@ -469,7 +469,7 @@ namespace Aaru.Checksums /// Data buffer. /// null /// Base64 representation of SpamSum $blocksize:$hash:$hash - public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash); + public static string Data(byte[] data, out byte[]? hash) => Data(data, (uint)data.Length, out hash); // Converts an ASCII null-terminated string to .NET string [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/SabreTools.Core/Tools/AttributeHelper.cs b/SabreTools.Core/Tools/AttributeHelper.cs index 8c31f5eb..1014904c 100644 --- a/SabreTools.Core/Tools/AttributeHelper.cs +++ b/SabreTools.Core/Tools/AttributeHelper.cs @@ -10,7 +10,7 @@ namespace SabreTools.Core.Tools /// /// Value to use /// MappingAttribute attached to the value - public static MappingAttribute GetAttribute(T value) + public static MappingAttribute? GetAttribute(T? value) { // Null value in, null value out if (value == null) @@ -22,7 +22,7 @@ namespace SabreTools.Core.Tools enumType = Nullable.GetUnderlyingType(enumType); // If the value returns a null on ToString, just return null - string valueStr = value.ToString(); + string? valueStr = value.ToString(); if (string.IsNullOrWhiteSpace(valueStr)) return null; @@ -42,7 +42,7 @@ namespace SabreTools.Core.Tools return null; // Return the first attribute, if possible - return (MappingAttribute)attributes.FirstOrDefault(); + return (MappingAttribute?)attributes.FirstOrDefault(); } } } \ No newline at end of file diff --git a/SabreTools.Core/Tools/Converters.cs b/SabreTools.Core/Tools/Converters.cs index 9843f0b3..854f0182 100644 --- a/SabreTools.Core/Tools/Converters.cs +++ b/SabreTools.Core/Tools/Converters.cs @@ -43,7 +43,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// ChipType value corresponding to the string - public static ChipType AsChipType(this string chipType) + public static ChipType AsChipType(this string? chipType) => AsEnumValue(chipType); /// @@ -51,7 +51,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// ControlType value corresponding to the string - public static ControlType AsControlType(this string controlType) + public static ControlType AsControlType(this string? controlType) => AsEnumValue(controlType); /// @@ -59,7 +59,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// DatHeaderField value corresponding to the string - public static DatHeaderField AsDatHeaderField(this string input) + public static DatHeaderField AsDatHeaderField(this string? input) { // If the input is empty, we return null if (string.IsNullOrEmpty(input)) @@ -89,7 +89,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// DatItemField value corresponding to the string - public static DatItemField AsDatItemField(this string input) + public static DatItemField AsDatItemField(this string? input) { // If the input is empty, we return null if (string.IsNullOrEmpty(input)) @@ -119,7 +119,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// DeviceType value corresponding to the string - public static DeviceType AsDeviceType(this string deviceType) + public static DeviceType AsDeviceType(this string? deviceType) => AsEnumValue(deviceType); /// @@ -127,7 +127,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// DisplayType value corresponding to the string - public static DisplayType AsDisplayType(this string displayType) + public static DisplayType AsDisplayType(this string? displayType) => AsEnumValue(displayType); /// @@ -135,7 +135,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// Endianness value corresponding to the string - public static Endianness AsEndianness(this string endianness) + public static Endianness AsEndianness(this string? endianness) => AsEnumValue(endianness); /// @@ -143,7 +143,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// FeatureStatus value corresponding to the string - public static FeatureStatus AsFeatureStatus(this string featureStatus) + public static FeatureStatus AsFeatureStatus(this string? featureStatus) => AsEnumValue(featureStatus); /// @@ -151,7 +151,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// FeatureType value corresponding to the string - public static FeatureType AsFeatureType(this string featureType) + public static FeatureType AsFeatureType(this string? featureType) => AsEnumValue(featureType); /// @@ -159,7 +159,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// ItemStatus value corresponding to the string - public static ItemStatus AsItemStatus(this string status) + public static ItemStatus AsItemStatus(this string? status) => AsEnumValue(status); /// @@ -167,7 +167,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// ItemType? value corresponding to the string - public static ItemType AsItemType(this string itemType) + public static ItemType AsItemType(this string? itemType) => AsEnumValue(itemType); /// @@ -175,7 +175,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// LoadFlag value corresponding to the string - public static LoadFlag AsLoadFlag(this string loadFlag) + public static LoadFlag AsLoadFlag(this string? loadFlag) => AsEnumValue(loadFlag); /// @@ -183,7 +183,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// LogLevel value corresponding to the string - public static LogLevel AsLogLevel(this string logLevel) + public static LogLevel AsLogLevel(this string? logLevel) => AsEnumValue(logLevel); /// @@ -191,7 +191,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// MachineField value corresponding to the string - public static MachineField AsMachineField(this string input) + public static MachineField AsMachineField(this string? input) { // If the input is empty, we return null if (string.IsNullOrEmpty(input)) @@ -221,7 +221,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// MachineType value corresponding to the string - public static MachineType AsMachineType(this string gametype) + public static MachineType AsMachineType(this string? gametype) => AsEnumValue(gametype); /// @@ -229,7 +229,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// MergingFlag value corresponding to the string - public static MergingFlag AsMergingFlag(this string merging) + public static MergingFlag AsMergingFlag(this string? merging) => AsEnumValue(merging); /// @@ -237,7 +237,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// NodumpFlag value corresponding to the string - public static NodumpFlag AsNodumpFlag(this string nodump) + public static NodumpFlag AsNodumpFlag(this string? nodump) => AsEnumValue(nodump); /// @@ -245,7 +245,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// OpenMSXSubType value corresponding to the string - public static OpenMSXSubType AsOpenMSXSubType(this string subType) + public static OpenMSXSubType AsOpenMSXSubType(this string? subType) => AsEnumValue(subType); /// @@ -253,7 +253,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// PackingFlag value corresponding to the string - public static PackingFlag AsPackingFlag(this string packing) + public static PackingFlag AsPackingFlag(this string? packing) => AsEnumValue(packing); /// @@ -261,7 +261,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// Relation value corresponding to the string - public static Relation AsRelation(this string relation) + public static Relation AsRelation(this string? relation) => AsEnumValue(relation); /// @@ -269,7 +269,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// Runnable value corresponding to the string - public static Runnable AsRunnable(this string runnable) + public static Runnable AsRunnable(this string? runnable) => AsEnumValue(runnable); /// @@ -277,7 +277,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// SoftwareListStatus value corresponding to the string - public static SoftwareListStatus AsSoftwareListStatus(this string status) + public static SoftwareListStatus AsSoftwareListStatus(this string? status) => AsEnumValue(status); /// @@ -285,7 +285,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// Supported value corresponding to the string - public static Supported AsSupported(this string supported) + public static Supported AsSupported(this string? supported) => AsEnumValue(supported); /// @@ -293,7 +293,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// SupportStatus value corresponding to the string - public static SupportStatus AsSupportStatus(this string supportStatus) + public static SupportStatus AsSupportStatus(this string? supportStatus) => AsEnumValue(supportStatus); /// @@ -301,7 +301,7 @@ namespace SabreTools.Core.Tools /// /// String to get value from /// bool? corresponding to the string - public static bool? AsYesNo(this string yesno) + public static bool? AsYesNo(this string? yesno) { return yesno?.ToLowerInvariant() switch { @@ -317,7 +317,7 @@ namespace SabreTools.Core.Tools /// String value to parse/param> /// Enum type that is expected /// Enum value representing the input, default on error - internal static T AsEnumValue(string value) + internal static T? AsEnumValue(string? value) { // Get the mapping dictionary var mappings = GenerateToEnum(); @@ -352,7 +352,7 @@ namespace SabreTools.Core.Tools foreach (T value in values) { // Try to get the mapping attribute - MappingAttribute attr = AttributeHelper.GetAttribute(value); + MappingAttribute? attr = AttributeHelper.GetAttribute(value); if (attr?.Mappings == null || !attr.Mappings.Any()) continue; @@ -383,7 +383,7 @@ namespace SabreTools.Core.Tools /// /// ChipType to get value from /// String value corresponding to the ChipType - public static string FromChipType(this ChipType chipType) + public static string? FromChipType(this ChipType chipType) => AsStringValue(chipType); /// @@ -391,7 +391,7 @@ namespace SabreTools.Core.Tools /// /// ControlType to get value from /// String value corresponding to the ControlType - public static string FromControlType(this ControlType controlType) + public static string? FromControlType(this ControlType controlType) => AsStringValue(controlType); /// @@ -399,7 +399,7 @@ namespace SabreTools.Core.Tools /// /// vDeviceType to get value from /// String value corresponding to the DeviceType - public static string FromDeviceType(this DeviceType deviceType) + public static string? FromDeviceType(this DeviceType deviceType) => AsStringValue(deviceType); /// @@ -407,7 +407,7 @@ namespace SabreTools.Core.Tools /// /// DisplayType to get value from /// String value corresponding to the DisplayType - public static string FromDisplayType(this DisplayType displayType) + public static string? FromDisplayType(this DisplayType displayType) => AsStringValue(displayType); /// @@ -415,7 +415,7 @@ namespace SabreTools.Core.Tools /// /// Endianness to get value from /// String value corresponding to the Endianness - public static string FromEndianness(this Endianness endianness) + public static string? FromEndianness(this Endianness endianness) => AsStringValue(endianness); /// @@ -423,7 +423,7 @@ namespace SabreTools.Core.Tools /// /// FeatureStatus to get value from /// String value corresponding to the FeatureStatus - public static string FromFeatureStatus(this FeatureStatus featureStatus) + public static string? FromFeatureStatus(this FeatureStatus featureStatus) => AsStringValue(featureStatus); /// @@ -431,7 +431,7 @@ namespace SabreTools.Core.Tools /// /// FeatureType to get value from /// String value corresponding to the FeatureType - public static string FromFeatureType(this FeatureType featureType) + public static string? FromFeatureType(this FeatureType featureType) => AsStringValue(featureType); /// @@ -440,7 +440,7 @@ namespace SabreTools.Core.Tools /// ItemStatus to get value from /// True to use Yes/No format instead /// String value corresponding to the ItemStatus - public static string FromItemStatus(this ItemStatus status, bool yesno) + public static string? FromItemStatus(this ItemStatus status, bool yesno) => AsStringValue(status, yesno); /// @@ -448,7 +448,7 @@ namespace SabreTools.Core.Tools /// /// ItemType? to get value from /// String value corresponding to the ItemType? - public static string FromItemType(this ItemType itemType) + public static string? FromItemType(this ItemType itemType) => AsStringValue(itemType); /// @@ -456,7 +456,7 @@ namespace SabreTools.Core.Tools /// /// LoadFlag to get value from /// String value corresponding to the LoadFlag - public static string FromLoadFlag(this LoadFlag loadFlag) + public static string? FromLoadFlag(this LoadFlag loadFlag) => AsStringValue(loadFlag); /// @@ -465,7 +465,7 @@ namespace SabreTools.Core.Tools /// MachineType to get value from /// True to use old naming instead /// String value corresponding to the MachineType - public static string FromMachineType(this MachineType gametype, bool old) + public static string? FromMachineType(this MachineType gametype, bool old) => AsStringValue(gametype, old); /// @@ -474,7 +474,7 @@ namespace SabreTools.Core.Tools /// MergingFlag to get value from /// True to use RomCenter naming instead /// String value corresponding to the MergingFlag - public static string FromMergingFlag(this MergingFlag merging, bool romCenter) + public static string? FromMergingFlag(this MergingFlag merging, bool romCenter) => AsStringValue(merging, romCenter); /// @@ -482,7 +482,7 @@ namespace SabreTools.Core.Tools /// /// NodumpFlag to get value from /// String value corresponding to the NodumpFlag - public static string FromNodumpFlag(this NodumpFlag nodump) + public static string? FromNodumpFlag(this NodumpFlag nodump) => AsStringValue(nodump); /// @@ -490,7 +490,7 @@ namespace SabreTools.Core.Tools /// /// OpenMSXSubType to get value from /// String value corresponding to the OpenMSXSubType - public static string FromOpenMSXSubType(this OpenMSXSubType subType) + public static string? FromOpenMSXSubType(this OpenMSXSubType subType) => AsStringValue(subType); /// @@ -499,7 +499,7 @@ namespace SabreTools.Core.Tools /// PackingFlag to get value from /// True to use Yes/No format instead /// String value corresponding to the PackingFlag - public static string FromPackingFlag(this PackingFlag packing, bool yesno) + public static string? FromPackingFlag(this PackingFlag packing, bool yesno) => AsStringValue(packing, yesno); /// @@ -507,7 +507,7 @@ namespace SabreTools.Core.Tools /// /// Relation to get value from /// String value corresponding to the Relation - public static string FromRelation(this Relation relation) + public static string? FromRelation(this Relation relation) => AsStringValue(relation); /// @@ -515,7 +515,7 @@ namespace SabreTools.Core.Tools /// /// Runnable to get value from /// String value corresponding to the Runnable - public static string FromRunnable(this Runnable runnable) + public static string? FromRunnable(this Runnable runnable) => AsStringValue(runnable); /// @@ -523,7 +523,7 @@ namespace SabreTools.Core.Tools /// /// SoftwareListStatus to get value from /// String value corresponding to the SoftwareListStatus - public static string FromSoftwareListStatus(this SoftwareListStatus status) + public static string? FromSoftwareListStatus(this SoftwareListStatus status) => AsStringValue(status); /// @@ -532,7 +532,7 @@ namespace SabreTools.Core.Tools /// Supported to get value from /// True to use verbose output, false otherwise /// String value corresponding to the Supported - public static string FromSupported(this Supported supported, bool verbose) + public static string? FromSupported(this Supported supported, bool verbose) => AsStringValue(supported, verbose); /// @@ -540,7 +540,7 @@ namespace SabreTools.Core.Tools /// /// SupportStatus to get value from /// String value corresponding to the SupportStatus - public static string FromSupportStatus(this SupportStatus supportStatus) + public static string? FromSupportStatus(this SupportStatus supportStatus) => AsStringValue(supportStatus); /// @@ -548,7 +548,7 @@ namespace SabreTools.Core.Tools /// /// bool? to get value from /// String corresponding to the bool? - public static string FromYesNo(this bool? yesno) + public static string? FromYesNo(this bool? yesno) { return yesno switch { @@ -565,7 +565,7 @@ namespace SabreTools.Core.Tools /// True to use the second mapping option, if it exists /// Enum type that is expected /// String value representing the input, default on error - internal static string? AsStringValue(T value, bool useSecond = false) + internal static string? AsStringValue(T value, bool useSecond = false) where T : notnull { // Get the mapping dictionary var mappings = GenerateToString(useSecond); @@ -584,7 +584,7 @@ namespace SabreTools.Core.Tools /// True to use the second mapping option, if it exists /// Enum type that is expected /// Dictionary of enum to string values - internal static Dictionary GenerateToString(bool useSecond) + internal static Dictionary GenerateToString(bool useSecond) where T : notnull { try { @@ -596,7 +596,7 @@ namespace SabreTools.Core.Tools foreach (T value in values) { // Try to get the mapping attribute - MappingAttribute attr = AttributeHelper.GetAttribute(value); + MappingAttribute? attr = AttributeHelper.GetAttribute(value); if (attr?.Mappings == null || !attr.Mappings.Any()) continue; diff --git a/SabreTools.Core/Tools/Hasher.cs b/SabreTools.Core/Tools/Hasher.cs index 871efcd7..3e91d25e 100644 --- a/SabreTools.Core/Tools/Hasher.cs +++ b/SabreTools.Core/Tools/Hasher.cs @@ -12,7 +12,7 @@ namespace SabreTools.Core.Tools public class Hasher { public Hash HashType { get; private set; } - private IDisposable _hasher; + private IDisposable? _hasher; public Hasher(Hash hashType) { @@ -59,7 +59,7 @@ namespace SabreTools.Core.Tools public void Dispose() { - _hasher.Dispose(); + _hasher?.Dispose(); } /// @@ -67,22 +67,37 @@ namespace SabreTools.Core.Tools /// public void Process(byte[] buffer, int size) { - switch (HashType) + if (_hasher == null) + return; + + switch (_hasher) { - case Hash.CRC: - (_hasher as OptimizedCRC.OptimizedCRC).Update(buffer, 0, size); + case OptimizedCRC.OptimizedCRC crc: + crc.Update(buffer, 0, size); break; - case Hash.MD5: - case Hash.SHA1: - case Hash.SHA256: - case Hash.SHA384: - case Hash.SHA512: - (_hasher as HashAlgorithm).TransformBlock(buffer, 0, size, null, 0); + case MD5 md5: + md5.TransformBlock(buffer, 0, size, null, 0); break; - case Hash.SpamSum: - (_hasher as SpamSumContext).Update(buffer); + case SHA1 sha1: + sha1.TransformBlock(buffer, 0, size, null, 0); + break; + + case SHA256 sha256: + sha256.TransformBlock(buffer, 0, size, null, 0); + break; + + case SHA384 sha384: + sha384.TransformBlock(buffer, 0, size, null, 0); + break; + + case SHA512 sha512: + sha512.TransformBlock(buffer, 0, size, null, 0); + break; + + case SpamSumContext spamSum: + spamSum.Update(buffer); break; } } @@ -92,22 +107,37 @@ namespace SabreTools.Core.Tools /// public void Terminate() { + if (_hasher == null) + return; + byte[] emptyBuffer = Array.Empty(); - switch (HashType) + switch (_hasher) { - case Hash.CRC: - (_hasher as OptimizedCRC.OptimizedCRC).Update(emptyBuffer, 0, 0); + case OptimizedCRC.OptimizedCRC crc: + crc.Update(emptyBuffer, 0, 0); break; - case Hash.MD5: - case Hash.SHA1: - case Hash.SHA256: - case Hash.SHA384: - case Hash.SHA512: - (_hasher as HashAlgorithm).TransformFinalBlock(emptyBuffer, 0, 0); + case MD5 md5: + md5.TransformFinalBlock(emptyBuffer, 0, 0); break; - case Hash.SpamSum: + case SHA1 sha1: + sha1.TransformFinalBlock(emptyBuffer, 0, 0); + break; + + case SHA256 sha256: + sha256.TransformFinalBlock(emptyBuffer, 0, 0); + break; + + case SHA384 sha384: + sha384.TransformFinalBlock(emptyBuffer, 0, 0); + break; + + case SHA512 sha512: + sha512.TransformFinalBlock(emptyBuffer, 0, 0); + break; + + case SpamSumContext: // No finalization step needed break; } @@ -116,17 +146,17 @@ namespace SabreTools.Core.Tools /// /// Get internal hash as a byte array /// - public byte[] GetHash() + public byte[]? GetHash() { - return HashType switch + return _hasher switch { - Hash.CRC => BitConverter.GetBytes((_hasher as OptimizedCRC.OptimizedCRC).Value).Reverse().ToArray(), - Hash.MD5 => (_hasher as HashAlgorithm).Hash, - Hash.SHA1 => (_hasher as HashAlgorithm).Hash, - Hash.SHA256 => (_hasher as HashAlgorithm).Hash, - Hash.SHA384 => (_hasher as HashAlgorithm).Hash, - Hash.SHA512 => (_hasher as HashAlgorithm).Hash, - Hash.SpamSum => (_hasher as SpamSumContext).Final(), + OptimizedCRC.OptimizedCRC crc => BitConverter.GetBytes(crc.Value).Reverse().ToArray(), + MD5 md5 => md5.Hash, + SHA1 sha1 => sha1.Hash, + SHA256 sha256 => sha256.Hash, + SHA384 sha384 => sha384.Hash, + SHA512 sha512 => sha512.Hash, + SpamSumContext spamSum => spamSum.Final(), _ => null, }; } diff --git a/SabreTools.Core/Tools/OptimizedCRC.cs b/SabreTools.Core/Tools/OptimizedCRC.cs index 160a7757..700800be 100644 --- a/SabreTools.Core/Tools/OptimizedCRC.cs +++ b/SabreTools.Core/Tools/OptimizedCRC.cs @@ -142,7 +142,7 @@ namespace OptimizedCRC static public int Compute(ArraySegment block) { - return Compute(block.Array, block.Offset, block.Count); + return Compute(block.Array!, block.Offset, block.Count); } public void Dispose() diff --git a/SabreTools.Core/Tools/Utilities.cs b/SabreTools.Core/Tools/Utilities.cs index 95d30c10..0940b17f 100644 --- a/SabreTools.Core/Tools/Utilities.cs +++ b/SabreTools.Core/Tools/Utilities.cs @@ -16,7 +16,7 @@ namespace SabreTools.Core.Tools /// Byte array to convert /// Hex string representing the byte array /// http://stackoverflow.com/questions/311165/how-do-you-convert-byte-array-to-hexadecimal-string-and-vice-versa - public static string ByteArrayToString(byte[] bytes) + public static string? ByteArrayToString(byte[]? bytes) { // If we get null in, we send null out if (bytes == null) @@ -39,10 +39,10 @@ namespace SabreTools.Core.Tools /// Hex string to convert /// Byte array represenging the hex string /// http://stackoverflow.com/questions/311165/how-do-you-convert-byte-array-to-hexadecimal-string-and-vice-versa - public static byte[] StringToByteArray(string hex) + public static byte[]? StringToByteArray(string? hex) { // If we get null in, we send null out - if (hex == null) + if (string.IsNullOrWhiteSpace(hex)) return null; try @@ -102,7 +102,7 @@ namespace SabreTools.Core.Tools /// SHA-1 hash to get the path for /// Positive value representing the depth of the depot /// Subfolder path for the given hash - public static string GetDepotPath(string hash, int depth) + public static string? GetDepotPath(string? hash, int depth) { // If the hash is null or empty, then we return null if (string.IsNullOrEmpty(hash)) diff --git a/SabreTools.DatFiles/DatFile.cs b/SabreTools.DatFiles/DatFile.cs index 8af548ff..7fc9e370 100644 --- a/SabreTools.DatFiles/DatFile.cs +++ b/SabreTools.DatFiles/DatFile.cs @@ -397,7 +397,7 @@ namespace SabreTools.DatFiles Header.UseRomName = true; // Get the name to update - string name = (Header.UseRomName ? item.GetName() : item.Machine.Name) ?? string.Empty; + string? name = (Header.UseRomName ? item.GetName() : item.Machine.Name) ?? string.Empty; // Create the proper Prefix and Postfix string pre = CreatePrefixPostfix(item, true); @@ -411,7 +411,7 @@ namespace SabreTools.DatFiles // We can only write out if there's a SHA-1 if (!string.IsNullOrWhiteSpace(disk.SHA1)) { - name = Utilities.GetDepotPath(disk.SHA1, Header.OutputDepot.Depth).Replace('\\', '/'); + name = Utilities.GetDepotPath(disk.SHA1, Header.OutputDepot.Depth)?.Replace('\\', '/'); item.SetName($"{pre}{name}{post}"); } } @@ -420,7 +420,7 @@ namespace SabreTools.DatFiles // We can only write out if there's a SHA-1 if (!string.IsNullOrWhiteSpace(media.SHA1)) { - name = Utilities.GetDepotPath(media.SHA1, Header.OutputDepot.Depth).Replace('\\', '/'); + name = Utilities.GetDepotPath(media.SHA1, Header.OutputDepot.Depth)?.Replace('\\', '/'); item.SetName($"{pre}{name}{post}"); } } @@ -429,7 +429,7 @@ namespace SabreTools.DatFiles // We can only write out if there's a SHA-1 if (!string.IsNullOrWhiteSpace(rom.SHA1)) { - name = Utilities.GetDepotPath(rom.SHA1, Header.OutputDepot.Depth).Replace('\\', '/'); + name = Utilities.GetDepotPath(rom.SHA1, Header.OutputDepot.Depth)?.Replace('\\', '/'); item.SetName($"{pre}{name}{post}"); } } diff --git a/SabreTools.DatFiles/Formats/ClrMamePro.Reader.cs b/SabreTools.DatFiles/Formats/ClrMamePro.Reader.cs index ae24b3d0..a8d9e449 100644 --- a/SabreTools.DatFiles/Formats/ClrMamePro.Reader.cs +++ b/SabreTools.DatFiles/Formats/ClrMamePro.Reader.cs @@ -60,11 +60,11 @@ namespace SabreTools.DatFiles.Formats Header.HeaderSkipper ??= cmp.Header; Header.Type ??= cmp.Type; if (Header.ForceMerging == MergingFlag.None) - Header.ForceMerging = cmp.ForceMerging.AsMergingFlag(); + Header.ForceMerging = cmp.ForceMerging?.AsMergingFlag() ?? MergingFlag.None; if (Header.ForcePacking == PackingFlag.None) - Header.ForcePacking = cmp.ForceZipping.AsPackingFlag(); + Header.ForcePacking = cmp.ForceZipping?.AsPackingFlag() ?? PackingFlag.None; if (Header.ForcePacking == PackingFlag.None) - Header.ForcePacking = cmp.ForcePacking.AsPackingFlag(); + Header.ForcePacking = cmp.ForcePacking?.AsPackingFlag() ?? PackingFlag.None; // Handle implied SuperDAT if (cmp.Name?.Contains(" - SuperDAT") == true && keep) diff --git a/SabreTools.DatFiles/ItemDictionary.cs b/SabreTools.DatFiles/ItemDictionary.cs index 29767dd7..2092a6c4 100644 --- a/SabreTools.DatFiles/ItemDictionary.cs +++ b/SabreTools.DatFiles/ItemDictionary.cs @@ -1040,7 +1040,9 @@ namespace SabreTools.DatFiles Parallel.ForEach(keys, Globals.ParallelOptions, key => { // Get the possibly unsorted list - ConcurrentList sortedlist = this[key].ToConcurrentList(); + ConcurrentList? sortedlist = this[key]?.ToConcurrentList(); + if (sortedlist == null) + return; // Sort the list of items to be consistent DatItem.Sort(ref sortedlist, false); diff --git a/SabreTools.DatFiles/ItemDictionaryDB.cs b/SabreTools.DatFiles/ItemDictionaryDB.cs index 35d4133d..c42b4b19 100644 --- a/SabreTools.DatFiles/ItemDictionaryDB.cs +++ b/SabreTools.DatFiles/ItemDictionaryDB.cs @@ -1240,7 +1240,9 @@ CREATE TABLE IF NOT EXISTS groups ( Parallel.ForEach(keys, Globals.ParallelOptions, key => { // Get the possibly unsorted list - ConcurrentList sortedlist = this[key].ToConcurrentList(); + ConcurrentList? sortedlist = this[key]?.ToConcurrentList(); + if (sortedlist == null) + return; // Sort the list of items to be consistent DatItem.Sort(ref sortedlist, false); diff --git a/SabreTools.Filter/FilterObject.cs b/SabreTools.Filter/FilterObject.cs index 57edd7ec..1679937f 100644 --- a/SabreTools.Filter/FilterObject.cs +++ b/SabreTools.Filter/FilterObject.cs @@ -353,10 +353,8 @@ namespace SabreTools.Filter return value.ToLowerInvariant() switch { - "true" => true, - "yes" => true, - "false" => false, - "no" => false, + "true" or "yes" => true, + "false" or "no" => false, _ => null, }; } diff --git a/SabreTools.Models/Internal/DictionaryBase.cs b/SabreTools.Models/Internal/DictionaryBase.cs index c0909aac..9424042e 100644 --- a/SabreTools.Models/Internal/DictionaryBase.cs +++ b/SabreTools.Models/Internal/DictionaryBase.cs @@ -32,10 +32,8 @@ namespace SabreTools.Models.Internal string? asString = Read(key); return asString?.ToLowerInvariant() switch { - "true" => true, - "yes" => true, - "false" => false, - "no" => false, + "true" or "yes" => true, + "false" or "no" => false, _ => null, }; }