From f06d22d6f01e657ebbc0c8ef082739cd468e47b5 Mon Sep 17 00:00:00 2001
From: Isaac Marovitz <42140194+IsaacMarovitz@users.noreply.github.com>
Date: Sun, 11 Feb 2024 02:09:18 +0000
Subject: Infra: Capitalisation Consistency (#6296)
* Rename Ryujinx.UI.Common
* Rename Ryujinx.UI.LocaleGenerator
* Update in Files
AboutWindow
* Configuration State
* Rename projects
* Ryujinx/UI
* Fix build
* Main remaining inconsistencies
* HLE.UI Namespace
* HLE.UI Files
* Namespace
* Ryujinx.UI.Common.Configuration.UI
* Ryujinx.UI.Common,Configuration.UI Files
* More instances
---
src/Ryujinx.UI.Common/Helper/ValueFormatUtils.cs | 219 +++++++++++++++++++++++
1 file changed, 219 insertions(+)
create mode 100644 src/Ryujinx.UI.Common/Helper/ValueFormatUtils.cs
(limited to 'src/Ryujinx.UI.Common/Helper/ValueFormatUtils.cs')
diff --git a/src/Ryujinx.UI.Common/Helper/ValueFormatUtils.cs b/src/Ryujinx.UI.Common/Helper/ValueFormatUtils.cs
new file mode 100644
index 00000000..8ea3e721
--- /dev/null
+++ b/src/Ryujinx.UI.Common/Helper/ValueFormatUtils.cs
@@ -0,0 +1,219 @@
+using System;
+using System.Globalization;
+using System.Linq;
+
+namespace Ryujinx.UI.Common.Helper
+{
+ public static class ValueFormatUtils
+ {
+ private static readonly string[] _fileSizeUnitStrings =
+ {
+ "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", // Base 10 units, used for formatting and parsing
+ "KB", "MB", "GB", "TB", "PB", "EB", // Base 2 units, used for parsing legacy values
+ };
+
+ ///
+ /// Used by .
+ ///
+ public enum FileSizeUnits
+ {
+ Auto = -1,
+ Bytes = 0,
+ Kibibytes = 1,
+ Mebibytes = 2,
+ Gibibytes = 3,
+ Tebibytes = 4,
+ Pebibytes = 5,
+ Exbibytes = 6,
+ Kilobytes = 7,
+ Megabytes = 8,
+ Gigabytes = 9,
+ Terabytes = 10,
+ Petabytes = 11,
+ Exabytes = 12,
+ }
+
+ private const double SizeBase10 = 1000;
+ private const double SizeBase2 = 1024;
+ private const int UnitEBIndex = 6;
+
+ #region Value formatters
+
+ ///
+ /// Creates a human-readable string from a .
+ ///
+ /// The to be formatted.
+ /// A formatted string that can be displayed in the UI.
+ public static string FormatTimeSpan(TimeSpan? timeSpan)
+ {
+ if (!timeSpan.HasValue || timeSpan.Value.TotalSeconds < 1)
+ {
+ // Game was never played
+ return TimeSpan.Zero.ToString("c", CultureInfo.InvariantCulture);
+ }
+
+ if (timeSpan.Value.TotalDays < 1)
+ {
+ // Game was played for less than a day
+ return timeSpan.Value.ToString("c", CultureInfo.InvariantCulture);
+ }
+
+ // Game was played for more than a day
+ TimeSpan onlyTime = timeSpan.Value.Subtract(TimeSpan.FromDays(timeSpan.Value.Days));
+ string onlyTimeString = onlyTime.ToString("c", CultureInfo.InvariantCulture);
+
+ return $"{timeSpan.Value.Days}d, {onlyTimeString}";
+ }
+
+ ///
+ /// Creates a human-readable string from a .
+ ///
+ /// The to be formatted. This is expected to be UTC-based.
+ /// The that's used in formatting. Defaults to .
+ /// A formatted string that can be displayed in the UI.
+ public static string FormatDateTime(DateTime? utcDateTime, CultureInfo culture = null)
+ {
+ culture ??= CultureInfo.CurrentCulture;
+
+ if (!utcDateTime.HasValue)
+ {
+ // In the Avalonia UI, this is turned into a localized version of "Never" by LocalizedNeverConverter.
+ return "Never";
+ }
+
+ return utcDateTime.Value.ToLocalTime().ToString(culture);
+ }
+
+ ///
+ /// Creates a human-readable file size string.
+ ///
+ /// The file size in bytes.
+ /// Formats the passed size value as this unit, bypassing the automatic unit choice.
+ /// A human-readable file size string.
+ public static string FormatFileSize(long size, FileSizeUnits forceUnit = FileSizeUnits.Auto)
+ {
+ if (size <= 0)
+ {
+ return $"0 {_fileSizeUnitStrings[0]}";
+ }
+
+ int unitIndex = (int)forceUnit;
+ if (forceUnit == FileSizeUnits.Auto)
+ {
+ unitIndex = Convert.ToInt32(Math.Floor(Math.Log(size, SizeBase10)));
+
+ // Apply an upper bound so that exabytes are the biggest unit used when formatting.
+ if (unitIndex > UnitEBIndex)
+ {
+ unitIndex = UnitEBIndex;
+ }
+ }
+
+ double sizeRounded;
+
+ if (unitIndex > UnitEBIndex)
+ {
+ sizeRounded = Math.Round(size / Math.Pow(SizeBase10, unitIndex - UnitEBIndex), 1);
+ }
+ else
+ {
+ sizeRounded = Math.Round(size / Math.Pow(SizeBase2, unitIndex), 1);
+ }
+
+ string sizeFormatted = sizeRounded.ToString(CultureInfo.InvariantCulture);
+
+ return $"{sizeFormatted} {_fileSizeUnitStrings[unitIndex]}";
+ }
+
+ #endregion
+
+ #region Value parsers
+
+ ///
+ /// Parses a string generated by and returns the original .
+ ///
+ /// A string representing a .
+ /// A object. If the input string couldn't been parsed, is returned.
+ public static TimeSpan ParseTimeSpan(string timeSpanString)
+ {
+ TimeSpan returnTimeSpan = TimeSpan.Zero;
+
+ // An input string can either look like "01:23:45" or "1d, 01:23:45" if the timespan represents a duration of more than a day.
+ // Here, we split the input string to check if it's the former or the latter.
+ var valueSplit = timeSpanString.Split(", ");
+ if (valueSplit.Length > 1)
+ {
+ var dayPart = valueSplit[0].Split("d")[0];
+ if (int.TryParse(dayPart, out int days))
+ {
+ returnTimeSpan = returnTimeSpan.Add(TimeSpan.FromDays(days));
+ }
+ }
+
+ if (TimeSpan.TryParse(valueSplit.Last(), out TimeSpan parsedTimeSpan))
+ {
+ returnTimeSpan = returnTimeSpan.Add(parsedTimeSpan);
+ }
+
+ return returnTimeSpan;
+ }
+
+ ///
+ /// Parses a string generated by and returns the original .
+ ///
+ /// The string representing a .
+ /// A object. If the input string couldn't be parsed, is returned.
+ public static DateTime ParseDateTime(string dateTimeString)
+ {
+ if (!DateTime.TryParse(dateTimeString, CultureInfo.CurrentCulture, out DateTime parsedDateTime))
+ {
+ // Games that were never played are supposed to appear before the oldest played games in the list,
+ // so returning DateTime.UnixEpoch here makes sense.
+ return DateTime.UnixEpoch;
+ }
+
+ return parsedDateTime;
+ }
+
+ ///
+ /// Parses a string generated by and returns a representing a number of bytes.
+ ///
+ /// A string representing a file size formatted with .
+ /// A representing a number of bytes.
+ public static long ParseFileSize(string sizeString)
+ {
+ // Enumerating over the units backwards because otherwise, sizeString.EndsWith("B") would exit the loop in the first iteration.
+ for (int i = _fileSizeUnitStrings.Length - 1; i >= 0; i--)
+ {
+ string unit = _fileSizeUnitStrings[i];
+ if (!sizeString.EndsWith(unit))
+ {
+ continue;
+ }
+
+ string numberString = sizeString.Split(" ")[0];
+ if (!double.TryParse(numberString, CultureInfo.InvariantCulture, out double number))
+ {
+ break;
+ }
+
+ double sizeBase = SizeBase2;
+
+ // If the unit index is one that points to a base 10 unit in the FileSizeUnitStrings array, subtract 6 to arrive at a usable power value.
+ if (i > UnitEBIndex)
+ {
+ i -= UnitEBIndex;
+ sizeBase = SizeBase10;
+ }
+
+ number *= Math.Pow(sizeBase, i);
+
+ return Convert.ToInt64(number);
+ }
+
+ return 0;
+ }
+
+ #endregion
+ }
+}
--
cgit v1.2.3