utils: Add new G_FORMAT_SIZE_BITS flag for g_format_size_full()

It will return sizes in bits, rather than bytes.

https://bugzilla.gnome.org/show_bug.cgi?id=789170
This commit is contained in:
Benoît Dejean 2017-10-20 17:43:36 +02:00 committed by Philip Withnall
parent 6036d40073
commit 54f6c56235
3 changed files with 85 additions and 14 deletions

View File

@ -2180,6 +2180,8 @@ g_format_size (guint64 size)
* suffixes. IEC units should only be used for reporting things with
* a strong "power of 2" basis, like RAM sizes or RAID stripe sizes.
* Network and storage sizes should be reported in the normal SI units.
* @G_FORMAT_SIZE_BITS: set the size as a quantity in bits, rather than
* bytes, and return units in bits. For example, Mb rather than MB.
*
* Flags to modify the format of the string returned by g_format_size_full().
*/
@ -2215,10 +2217,12 @@ g_format_size_full (guint64 size,
typedef enum
{
FORMAT_BYTES,
FORMAT_BYTES_IEC
FORMAT_BYTES_IEC,
FORMAT_BITS,
FORMAT_BITS_IEC
} FormatIndex;
const struct Format formats[2][6] = {
const struct Format formats[4][6] = {
{
{ KILOBYTE_FACTOR, N_("%.1f kB") },
{ MEGABYTE_FACTOR, N_("%.1f MB") },
@ -2234,6 +2238,22 @@ g_format_size_full (guint64 size,
{ TEBIBYTE_FACTOR, N_("%.1f TiB") },
{ PEBIBYTE_FACTOR, N_("%.1f PiB") },
{ EXBIBYTE_FACTOR, N_("%.1f EiB") }
},
{
{ KILOBYTE_FACTOR, N_("%.1f kb") },
{ MEGABYTE_FACTOR, N_("%.1f Mb") },
{ GIGABYTE_FACTOR, N_("%.1f Gb") },
{ TERABYTE_FACTOR, N_("%.1f Tb") },
{ PETABYTE_FACTOR, N_("%.1f Pb") },
{ EXABYTE_FACTOR, N_("%.1f Eb") }
},
{
{ KIBIBYTE_FACTOR, N_("%.1f Kib") },
{ MEBIBYTE_FACTOR, N_("%.1f Mib") },
{ GIBIBYTE_FACTOR, N_("%.1f Gib") },
{ TEBIBYTE_FACTOR, N_("%.1f Tib") },
{ PEBIBYTE_FACTOR, N_("%.1f Pib") },
{ EXBIBYTE_FACTOR, N_("%.1f Eib") }
}
};
@ -2242,14 +2262,22 @@ g_format_size_full (guint64 size,
string = g_string_new (NULL);
if (flags & G_FORMAT_SIZE_IEC_UNITS)
{
index = FORMAT_BYTES_IEC;
}
else
switch (flags & ~G_FORMAT_SIZE_LONG_FORMAT)
{
case G_FORMAT_SIZE_DEFAULT:
index = FORMAT_BYTES;
break;
case (G_FORMAT_SIZE_DEFAULT | G_FORMAT_SIZE_IEC_UNITS):
index = FORMAT_BYTES_IEC;
break;
case G_FORMAT_SIZE_BITS:
index = FORMAT_BITS;
break;
case (G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS):
index = FORMAT_BITS_IEC;
break;
default:
g_assert_not_reached ();
}
@ -2261,6 +2289,10 @@ g_format_size_full (guint64 size,
{
format = g_dngettext (GETTEXT_PACKAGE, "%u byte", "%u bytes", (guint) size);
}
else
{
format = g_dngettext (GETTEXT_PACKAGE, "%u bit", "%u bits", (guint) size);
}
g_string_printf (string, format, (guint) size);
@ -2312,19 +2344,27 @@ g_format_size_full (guint64 size,
*/
guint plural_form = size < 1000 ? size : size % 1000 + 1000;
/* Second problem: we need to translate the string "%u byte" and
* "%u bytes" for pluralisation, but the correct number format to
/* Second problem: we need to translate the string "%u byte/bit" and
* "%u bytes/bits" for pluralisation, but the correct number format to
* use for a gsize is different depending on which architecture
* we're on.
*
* Solution: format the number separately and use "%s bytes" on
* Solution: format the number separately and use "%s bytes/bits" on
* all platforms.
*/
const gchar *translated_format;
gchar *formatted_number;
if (index == FORMAT_BYTES || index == FORMAT_BYTES_IEC)
{
/* Translators: the %s in "%s bytes" will always be replaced by a number. */
translated_format = g_dngettext(GETTEXT_PACKAGE, "%s byte", "%s bytes", plural_form);
translated_format = g_dngettext (GETTEXT_PACKAGE, "%s byte", "%s bytes", plural_form);
}
else
{
/* Translators: the %s in "%s bits" will always be replaced by a number. */
translated_format = g_dngettext (GETTEXT_PACKAGE, "%s bit", "%s bits", plural_form);
}
/* XXX: Windows doesn't support the "'" format modifier, so we
* must not use it there. Instead, just display the number
* without separation. Bug #655336 is open until a solution is

View File

@ -181,7 +181,8 @@ typedef enum
{
G_FORMAT_SIZE_DEFAULT = 0,
G_FORMAT_SIZE_LONG_FORMAT = 1 << 0,
G_FORMAT_SIZE_IEC_UNITS = 1 << 1
G_FORMAT_SIZE_IEC_UNITS = 1 << 1,
G_FORMAT_SIZE_BITS = 1 << 2
} GFormatSizeFlags;
GLIB_AVAILABLE_IN_2_30

View File

@ -551,6 +551,36 @@ test_format_size_for_display (void)
check_string (g_format_size_full (238472938, G_FORMAT_SIZE_IEC_UNITS), "227.4 MiB");
check_string (g_format_size_full (238472938, G_FORMAT_SIZE_DEFAULT), "238.5 MB");
check_string (g_format_size_full (238472938, G_FORMAT_SIZE_LONG_FORMAT), "238.5 MB (238472938 bytes)");
check_string (g_format_size_full (0, G_FORMAT_SIZE_BITS), "0 bits");
check_string (g_format_size_full (1, G_FORMAT_SIZE_BITS), "1 bit");
check_string (g_format_size_full (2, G_FORMAT_SIZE_BITS), "2 bits");
check_string (g_format_size_full (2000ULL, G_FORMAT_SIZE_BITS), "2.0 kb");
check_string (g_format_size_full (2000ULL * 1000, G_FORMAT_SIZE_BITS), "2.0 Mb");
check_string (g_format_size_full (2000ULL * 1000 * 1000, G_FORMAT_SIZE_BITS), "2.0 Gb");
check_string (g_format_size_full (2000ULL * 1000 * 1000 * 1000, G_FORMAT_SIZE_BITS), "2.0 Tb");
check_string (g_format_size_full (2000ULL * 1000 * 1000 * 1000 * 1000, G_FORMAT_SIZE_BITS), "2.0 Pb");
check_string (g_format_size_full (2000ULL * 1000 * 1000 * 1000 * 1000 * 1000, G_FORMAT_SIZE_BITS), "2.0 Eb");
check_string (g_format_size_full (238472938, G_FORMAT_SIZE_BITS), "238.5 Mb");
check_string (g_format_size_full (238472938, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_LONG_FORMAT), "238.5 Mb (238472938 bits)");
check_string (g_format_size_full (0, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "0 bits");
check_string (g_format_size_full (1, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "1 bit");
check_string (g_format_size_full (2, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "2 bits");
check_string (g_format_size_full (2048ULL, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "2.0 Kib");
check_string (g_format_size_full (2048ULL * 1024, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "2.0 Mib");
check_string (g_format_size_full (2048ULL * 1024 * 1024, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "2.0 Gib");
check_string (g_format_size_full (2048ULL * 1024 * 1024 * 1024, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "2.0 Tib");
check_string (g_format_size_full (2048ULL * 1024 * 1024 * 1024 * 1024, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "2.0 Pib");
check_string (g_format_size_full (2048ULL * 1024 * 1024 * 1024 * 1024 * 1024, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "2.0 Eib");
check_string (g_format_size_full (238472938, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "227.4 Mib");
check_string (g_format_size_full (238472938, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS | G_FORMAT_SIZE_LONG_FORMAT), "227.4 Mib (238472938 bits)");
}
static void