[glib] utils: Add new G_FORMAT_SIZE_BITS flag for g_format_size_full()



commit 54f6c562354d9c988c0ed9eea672d1bce23b20c4
Author: Benoît Dejean <bdejean gmail com>
Date:   Fri Oct 20 17:43:36 2017 +0200

    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

 glib/gutils.c          |   66 ++++++++++++++++++++++++++++++++++++++---------
 glib/gutils.h          |    3 +-
 glib/tests/fileutils.c |   30 +++++++++++++++++++++
 3 files changed, 85 insertions(+), 14 deletions(-)
---
diff --git a/glib/gutils.c b/glib/gutils.c
index e84d8ac..32c5796 100644
--- a/glib/gutils.c
+++ b/glib/gutils.c
@@ -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;
 
-      /* 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);
+      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);
+        }
+      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
diff --git a/glib/gutils.h b/glib/gutils.h
index 356c643..c48699a 100644
--- a/glib/gutils.h
+++ b/glib/gutils.h
@@ -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
diff --git a/glib/tests/fileutils.c b/glib/tests/fileutils.c
index 2fe22cc..78fca7d 100644
--- a/glib/tests/fileutils.c
+++ b/glib/tests/fileutils.c
@@ -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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]