From e463fa498f6a623a07bb2659a401917fda3cdf3d Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 14 Aug 2018 15:44:10 +0200 Subject: [PATCH] [platform] simpler unit formatting code; SI-compliant info units ... also drops unused code and pushes non-RT methods back into 'util' --- .../openapi/util/text/StringUtilRt.java | 82 ++----------------- .../openapi/util/text/StringUtil.java | 55 ++++++++----- .../intellij/util/text/StringUtilTest.java | 38 +++------ 3 files changed, 51 insertions(+), 124 deletions(-) diff --git a/platform/util-rt/src/com/intellij/openapi/util/text/StringUtilRt.java b/platform/util-rt/src/com/intellij/openapi/util/text/StringUtilRt.java index bd85898972b1..7db0c0674ef9 100644 --- a/platform/util-rt/src/com/intellij/openapi/util/text/StringUtilRt.java +++ b/platform/util-rt/src/com/intellij/openapi/util/text/StringUtilRt.java @@ -5,6 +5,7 @@ import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; @@ -364,20 +365,6 @@ public class StringUtilRt { return result; } - @NotNull - @Contract(pure = true) - public static String formatNumber(long number) { - return formatNumber(number, ""); - } - - @NotNull - @Contract(pure = true) - public static String formatNumber(long number, @NotNull String unitSeparator) { - return formatValue(number, null, unitSeparator, - new String[]{"", "K", "M", "G", "T", "P", "E"}, - new long[]{1, 1000, 1000, 1000, 1000, 1000, 1000}); - } - @NotNull @Contract(pure = true) public static String formatFileSize(long fileSize) { @@ -387,67 +374,12 @@ public class StringUtilRt { @NotNull @Contract(pure = true) public static String formatFileSize(long fileSize, @NotNull String unitSeparator) { - return formatValue(fileSize, null, unitSeparator, - new String[]{"B", "KB", "MB", "GB", "TB", "PB", "EB"}, - new long[]{1, 1024, 1024, 1024, 1024, 1024, 1024}); - } - - @NotNull - @Contract(pure = true) - public static String formatDuration(long duration) { - return formatDuration(duration, " "); - } - - @NotNull - @Contract(pure = true) - public static String formatDuration(long duration, @NotNull String unitSeparator) { - return formatValue(duration, " ", unitSeparator, - new String[]{"ms", "s", "m", "h", "d", "mo", "yr", "c", "ml", "ep"}, - new long[]{1, 1000, 60, 60, 24, 30, 12, 100, 10, 10000}); - } - - @NotNull - private static String formatValue(long value, @Nullable String partSeparator, String unitSeparator, String[] units, long[] multipliers) { - if (units.length != multipliers.length) { - throw new IllegalArgumentException(units.length + " != " + multipliers.length); - } - StringBuilder sb = new StringBuilder(); - long count = value; - long remainder = 0; - int i = 1; - for (; i < units.length && count > 0; i++) { - long multiplier = multipliers[i]; - if (count < multiplier) break; - remainder = count % multiplier; - count /= multiplier; - if (partSeparator != null && (remainder != 0 || sb.length() > 0)) { - if (units[i - 1].length() > 0) { - sb.insert(0, units[i - 1]); - sb.insert(0, unitSeparator); - } - sb.insert(0, remainder).insert(0, partSeparator); - } - else { - remainder = Math.round(remainder * 100 / (double)multiplier); - count += remainder / 100; - remainder %= 100; - } - } - if (partSeparator != null || remainder == 0) { - if (units[i - 1].length() > 0) { - sb.insert(0, units[i - 1]); - sb.insert(0, unitSeparator); - } - sb.insert(0, count); - } - else if (remainder > 0) { - sb.append(count).append(".").append(remainder / 10 == 0 ? "0" : "").append(remainder); - if (units[i - 1].length() > 0) { - sb.append(unitSeparator); - sb.append(units[i - 1]); - } - } - return sb.toString(); + if (fileSize < 0) throw new IllegalArgumentException("Invalid value: " + fileSize); + if (fileSize == 0) return '0' + unitSeparator + 'B'; + int rank = (int)(Math.log10(fileSize) / 3); + double value = fileSize / Math.pow(1000, rank); + String[] units = {"B", "kB", "MB", "GB", "TB", "PB", "EB"}; + return new DecimalFormat("#,##0.##").format(value) + unitSeparator + units[rank]; } @Contract(pure = true) diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java index d849e7875179..f92bbe5732d3 100644 --- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java +++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java @@ -1547,47 +1547,60 @@ public class StringUtil extends StringUtilRt { return text; } - @NotNull - @Contract(pure = true) - public static String formatNumber(long number) { - return StringUtilRt.formatNumber(number); - } - - @NotNull - @Contract(pure = true) - public static String formatNumber(long number, @NotNull String unitSeparator) { - return StringUtilRt.formatNumber(number, unitSeparator); - } - - /** - * Formats the specified file size as a string. - * - * @param fileSize the size to format. - * @return the size formatted as a string. - * @since 5.0.1 - */ + /** Formats given file size in metric (1 kB = 1000 B) units (example: {@code formatFileSize(1234) = "1.23 KB"}). */ @NotNull @Contract(pure = true) public static String formatFileSize(long fileSize) { return StringUtilRt.formatFileSize(fileSize); } + /** Formats given file size in metric (1 kB = 1000 B) units (example: {@code formatFileSize(1234, "") = "1.23KB"}). */ @NotNull @Contract(pure = true) public static String formatFileSize(long fileSize, @NotNull String unitSeparator) { return StringUtilRt.formatFileSize(fileSize, unitSeparator); } + /** Formats given duration as a sum of time units (example: {@code formatDuration(123456) = "2 m 3 s 456 ms"}). */ @NotNull @Contract(pure = true) public static String formatDuration(long duration) { - return StringUtilRt.formatDuration(duration); + return formatDuration(duration, " "); } + /** Formats given duration as a sum of time units (example: {@code formatDuration(123456, "") = "2m 3s 456ms"}). */ @NotNull @Contract(pure = true) public static String formatDuration(long duration, @NotNull String unitSeparator) { - return StringUtilRt.formatDuration(duration, unitSeparator); + String[] units = {"ms", "s", "m", "h", "d", "mo", "yr", "c", "ml", "ep"}; + long[] multipliers = {1, 1000, 60, 60, 24, 30, 12, 100, 10, 10000}; + + StringBuilder sb = new StringBuilder(); + long count = duration, remainder; + int i = 1; + for (; i < units.length && count > 0; i++) { + long multiplier = multipliers[i]; + if (count < multiplier) break; + remainder = count % multiplier; + count /= multiplier; + if (remainder != 0 || sb.length() > 0) { + if (units[i - 1].length() > 0) { + sb.insert(0, units[i - 1]); + sb.insert(0, unitSeparator); + } + sb.insert(0, remainder).insert(0, " "); + } + else { + remainder = Math.round(remainder * 100 / (double)multiplier); + count += remainder / 100; + } + } + if (units[i - 1].length() > 0) { + sb.insert(0, units[i - 1]); + sb.insert(0, unitSeparator); + } + sb.insert(0, count); + return sb.toString(); } /** diff --git a/platform/util/testSrc/com/intellij/util/text/StringUtilTest.java b/platform/util/testSrc/com/intellij/util/text/StringUtilTest.java index f6d22f997c75..7db218353752 100644 --- a/platform/util/testSrc/com/intellij/util/text/StringUtilTest.java +++ b/platform/util/testSrc/com/intellij/util/text/StringUtilTest.java @@ -492,36 +492,18 @@ public class StringUtilTest { public void testFormatFileSize() { assertEquals("0 B", StringUtil.formatFileSize(0)); assertEquals("1 B", StringUtil.formatFileSize(1)); - assertEquals("2 GB", StringUtil.formatFileSize(Integer.MAX_VALUE)); - assertEquals("8 EB", StringUtil.formatFileSize(Long.MAX_VALUE)); + assertEquals("2.15 GB", StringUtil.formatFileSize(Integer.MAX_VALUE)); + assertEquals("9.22 EB", StringUtil.formatFileSize(Long.MAX_VALUE)); - assertEquals("58.69 KB", StringUtil.formatFileSize(60100)); + assertEquals("60.1 kB", StringUtil.formatFileSize(60100)); - assertEquals("1.21 KB", StringUtil.formatFileSize(1234)); - assertEquals("12.06 KB", StringUtil.formatFileSize(12345)); - assertEquals("120.56 KB", StringUtil.formatFileSize(123456)); - assertEquals("1.18 MB", StringUtil.formatFileSize(1234567)); - assertEquals("11.77 MB", StringUtil.formatFileSize(12345678)); - assertEquals("117.74 MB", StringUtil.formatFileSize(123456789)); - assertEquals("1.15 GB", StringUtil.formatFileSize(1234567890)); - } - - @Test - public void testFormatNumber() { - assertEquals("0", StringUtil.formatNumber(0)); - assertEquals("1", StringUtil.formatNumber(1)); - assertEquals("2.15G", StringUtil.formatNumber(Integer.MAX_VALUE)); - assertEquals("9.22E", StringUtil.formatNumber(Long.MAX_VALUE)); - - assertEquals("60.10K", StringUtil.formatNumber(60100)); - - assertEquals("1.23K", StringUtil.formatNumber(1234)); - assertEquals("12.35K", StringUtil.formatNumber(12345)); - assertEquals("123.46K", StringUtil.formatNumber(123456)); - assertEquals("1.23M", StringUtil.formatNumber(1234567)); - assertEquals("12.35M", StringUtil.formatNumber(12345678)); - assertEquals("123.46M", StringUtil.formatNumber(123456789)); - assertEquals("1.23G", StringUtil.formatNumber(1234567890)); + assertEquals("1.23 kB", StringUtil.formatFileSize(1234)); + assertEquals("12.35 kB", StringUtil.formatFileSize(12345)); + assertEquals("123.46 kB", StringUtil.formatFileSize(123456)); + assertEquals("1.23 MB", StringUtil.formatFileSize(1234567)); + assertEquals("12.35 MB", StringUtil.formatFileSize(12345678)); + assertEquals("123.46 MB", StringUtil.formatFileSize(123456789)); + assertEquals("1.23 GB", StringUtil.formatFileSize(1234567890)); } @Test