diff --git a/SabreTools.Core.Test/Tools/NumberHelperTests.cs b/SabreTools.Core.Test/Tools/NumberHelperTests.cs index 07ea1dcf..785c501a 100644 --- a/SabreTools.Core.Test/Tools/NumberHelperTests.cs +++ b/SabreTools.Core.Test/Tools/NumberHelperTests.cs @@ -102,5 +102,31 @@ namespace SabreTools.Core.Test.Tools } #endregion + + #region GetBytesReadable + + [Theory] + [InlineData(0, "0 B")] + [InlineData(1, "1 B")] + [InlineData(-1, "-1 B")] + [InlineData(0x400, "1 KB")] + [InlineData(-0x400, "-1 KB")] + [InlineData(1_234, "1.205 KB")] + [InlineData(-1_234, "-1.205 KB")] + [InlineData(0x10_0000, "1 MB")] + [InlineData(-0x10_0000, "-1 MB")] + [InlineData(0x4000_0000, "1 GB")] + [InlineData(-0x4000_0000, "-1 GB")] + [InlineData(0x100_0000_0000, "1 TB")] + [InlineData(-0x100_0000_0000, "-1 TB")] + [InlineData(0x4_0000_0000_0000, "1 PB")] + [InlineData(-0x4_0000_0000_0000, "-1 PB")] + public void GetBytesReadableTest(long input, string expected) + { + string actual = NumberHelper.GetBytesReadable(input); + Assert.Equal(expected, actual); + } + + #endregion } } \ No newline at end of file diff --git a/SabreTools.Core/Tools/NumberHelper.cs b/SabreTools.Core/Tools/NumberHelper.cs index 1c23978a..60063bcc 100644 --- a/SabreTools.Core/Tools/NumberHelper.cs +++ b/SabreTools.Core/Tools/NumberHelper.cs @@ -170,6 +170,62 @@ namespace SabreTools.Core.Tools return true; } + /// + /// Returns the human-readable file size for an arbitrary, 64-bit file size + /// The default format is "0.### XB", e.g. "4.2 KB" or "1.434 GB". + /// + /// http://www.somacon.com/p576.php + /// This uses 1024-byte partitions, not 1000-byte + public static string GetBytesReadable(long input) + { + // Get absolute value + long absolute_i = (input < 0 ? -input : input); + + // Determine the suffix and readable value + string suffix; + double readable; + if (absolute_i >= 0x1000_0000_0000_0000) // Exabyte + { + suffix = "EB"; + readable = (input >> 50); + } + else if (absolute_i >= 0x4_0000_0000_0000) // Petabyte + { + suffix = "PB"; + readable = (input >> 40); + } + else if (absolute_i >= 0x100_0000_0000) // Terabyte + { + suffix = "TB"; + readable = (input >> 30); + } + else if (absolute_i >= 0x4000_0000) // Gigabyte + { + suffix = "GB"; + readable = (input >> 20); + } + else if (absolute_i >= 0x10_0000) // Megabyte + { + suffix = "MB"; + readable = (input >> 10); + } + else if (absolute_i >= 0x400) // Kilobyte + { + suffix = "KB"; + readable = input; + } + else + { + return input.ToString("0 B"); // Byte + } + + // Divide by 1024 to get fractional value + readable /= 1024; + + // Return formatted number with suffix + return readable.ToString("0.### ") + suffix; + } + #if NETFRAMEWORK || NETCOREAPP3_1 || NET5_0 || NET6_0 /// /// Indicates whether a character is categorized as an ASCII hexademical digit. diff --git a/SabreTools.Reports/BaseReport.cs b/SabreTools.Reports/BaseReport.cs index 2a399925..ac20e39e 100644 --- a/SabreTools.Reports/BaseReport.cs +++ b/SabreTools.Reports/BaseReport.cs @@ -41,62 +41,5 @@ namespace SabreTools.Reports /// True if the error that is thrown should be thrown back to the caller, false otherwise /// True if the report was written correctly, false otherwise public abstract bool WriteToFile(string? outfile, bool baddumpCol, bool nodumpCol, bool throwOnError = false); - - /// - /// Returns the human-readable file size for an arbitrary, 64-bit file size - /// The default format is "0.### XB", e.g. "4.2 KB" or "1.434 GB" - /// - /// - /// Human-readable file size - /// http://www.somacon.com/p576.php - protected internal static string GetBytesReadable(long input) - { - // Get absolute value - long absolute_i = (input < 0 ? -input : input); - - // Determine the suffix and readable value - string suffix; - double readable; - if (absolute_i >= 0x1000000000000000) // Exabyte - { - suffix = "EB"; - readable = (input >> 50); - } - else if (absolute_i >= 0x4000000000000) // Petabyte - { - suffix = "PB"; - readable = (input >> 40); - } - else if (absolute_i >= 0x10000000000) // Terabyte - { - suffix = "TB"; - readable = (input >> 30); - } - else if (absolute_i >= 0x40000000) // Gigabyte - { - suffix = "GB"; - readable = (input >> 20); - } - else if (absolute_i >= 0x100000) // Megabyte - { - suffix = "MB"; - readable = (input >> 10); - } - else if (absolute_i >= 0x400) // Kilobyte - { - suffix = "KB"; - readable = input; - } - else - { - return input.ToString("0 B"); // Byte - } - - // Divide by 1024 to get fractional value - readable /= 1024; - - // Return formatted number with suffix - return readable.ToString("0.### ") + suffix; - } } } diff --git a/SabreTools.Reports/Formats/Html.cs b/SabreTools.Reports/Formats/Html.cs index 15bdda86..be69947e 100644 --- a/SabreTools.Reports/Formats/Html.cs +++ b/SabreTools.Reports/Formats/Html.cs @@ -6,6 +6,7 @@ using System.Net; #endif using System.Text; using System.Xml; +using SabreTools.Core.Tools; using SabreTools.DatFiles; using SabreTools.DatItems; using SabreTools.Hashing; @@ -231,7 +232,7 @@ body { xtw.WriteStartElement("td"); xtw.WriteAttributeString("align", "right"); - xtw.WriteString(GetBytesReadable(stat.TotalSize)); + xtw.WriteString(NumberHelper.GetBytesReadable(stat.TotalSize)); xtw.WriteEndElement(); // td xtw.WriteStartElement("td"); diff --git a/SabreTools.Reports/Formats/Textfile.cs b/SabreTools.Reports/Formats/Textfile.cs index 861e1473..956bf68f 100644 --- a/SabreTools.Reports/Formats/Textfile.cs +++ b/SabreTools.Reports/Formats/Textfile.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using SabreTools.Core.Tools; using SabreTools.DatFiles; using SabreTools.DatItems; using SabreTools.Hashing; @@ -94,7 +95,7 @@ namespace SabreTools.Reports.Formats { string line = @"'" + stat.DisplayName + @"': -------------------------------------------------- - Uncompressed size: " + GetBytesReadable(stat!.TotalSize) + @" + Uncompressed size: " + NumberHelper.GetBytesReadable(stat!.TotalSize) + @" Games found: " + stat.MachineCount + @" Roms found: " + stat.GetItemCount(ItemType.Rom) + @" Disks found: " + stat.GetItemCount(ItemType.Disk) + @"