[glib] utils: refactor g_format_size_full



commit 7ccbd86537d74a366f1ff386c3129bc0ee3b3eba
Author: BenoƮt Dejean <bdejean gmail com>
Date:   Fri Oct 20 18:46:47 2017 +0200

    utils: refactor g_format_size_full
    
    Refactor g_format_size_full to avoid duplicate code and make it easier to
    add more units.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=789170

 glib/gutils.c |  105 +++++++++++++++++++++++++++++++++++----------------------
 1 files changed, 65 insertions(+), 40 deletions(-)
---
diff --git a/glib/gutils.c b/glib/gutils.c
index eb44f17..60370d5 100644
--- a/glib/gutils.c
+++ b/glib/gutils.c
@@ -2197,63 +2197,88 @@ gchar *
 g_format_size_full (guint64          size,
                     GFormatSizeFlags flags)
 {
-  GString *string;
+  struct Format
+  {
+    guint64 factor;
+    char string[9];
+  };
 
-  string = g_string_new (NULL);
+  typedef enum
+  {
+    FORMAT_BYTES,
+    FORMAT_BYTES_IEC
+  } FormatIndex;
 
-  if (flags & G_FORMAT_SIZE_IEC_UNITS)
+  const struct Format formats[2][6] = {
     {
-      if (size < KIBIBYTE_FACTOR)
-        {
-          g_string_printf (string,
-                           g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes", (guint) size),
-                           (guint) size);
-          flags &= ~G_FORMAT_SIZE_LONG_FORMAT;
-        }
-
-      else if (size < MEBIBYTE_FACTOR)
-        g_string_printf (string, _("%.1f KiB"), (gdouble) size / (gdouble) KIBIBYTE_FACTOR);
-      else if (size < GIBIBYTE_FACTOR)
-        g_string_printf (string, _("%.1f MiB"), (gdouble) size / (gdouble) MEBIBYTE_FACTOR);
+      { 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") }
+    }
+  };
 
-      else if (size < TEBIBYTE_FACTOR)
-        g_string_printf (string, _("%.1f GiB"), (gdouble) size / (gdouble) GIBIBYTE_FACTOR);
+  GString *string;
+  FormatIndex index;
 
-      else if (size < PEBIBYTE_FACTOR)
-        g_string_printf (string, _("%.1f TiB"), (gdouble) size / (gdouble) TEBIBYTE_FACTOR);
+  string = g_string_new (NULL);
 
-      else if (size < EXBIBYTE_FACTOR)
-        g_string_printf (string, _("%.1f PiB"), (gdouble) size / (gdouble) PEBIBYTE_FACTOR);
 
-      else
-        g_string_printf (string, _("%.1f EiB"), (gdouble) size / (gdouble) EXBIBYTE_FACTOR);
+  if (flags & G_FORMAT_SIZE_IEC_UNITS)
+    {
+      index = FORMAT_BYTES_IEC;
     }
   else
     {
-      if (size < KILOBYTE_FACTOR)
+      index = FORMAT_BYTES;
+    }
+
+
+  if (size < formats[index][0].factor)
+    {
+      const char * format;
+
+      if (index == FORMAT_BYTES || index == FORMAT_BYTES_IEC)
         {
-          g_string_printf (string,
-                           g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes", (guint) size),
-                           (guint) size);
-          flags &= ~G_FORMAT_SIZE_LONG_FORMAT;
+          format = g_dngettext (GETTEXT_PACKAGE, "%u byte", "%u bytes", (guint) size);
         }
 
-      else if (size < MEGABYTE_FACTOR)
-        g_string_printf (string, _("%.1f kB"), (gdouble) size / (gdouble) KILOBYTE_FACTOR);
+      g_string_printf (string, format, (guint) size);
 
-      else if (size < GIGABYTE_FACTOR)
-        g_string_printf (string, _("%.1f MB"), (gdouble) size / (gdouble) MEGABYTE_FACTOR);
+      flags &= ~G_FORMAT_SIZE_LONG_FORMAT;
+    }
+  else
+    {
+      const gsize n = G_N_ELEMENTS (formats[index]);
+      gsize i;
 
-      else if (size < TERABYTE_FACTOR)
-        g_string_printf (string, _("%.1f GB"), (gdouble) size / (gdouble) GIGABYTE_FACTOR);
-      else if (size < PETABYTE_FACTOR)
-        g_string_printf (string, _("%.1f TB"), (gdouble) size / (gdouble) TERABYTE_FACTOR);
+      /*
+       * Point the last format (the highest unit) by default
+       * and then then scan all formats, starting with the 2nd one
+       * because the 1st is already managed by with the plural form
+       */
+      const struct Format * f = &formats[index][n - 1];
 
-      else if (size < EXABYTE_FACTOR)
-        g_string_printf (string, _("%.1f PB"), (gdouble) size / (gdouble) PETABYTE_FACTOR);
+      for (i = 1; i < n; i++)
+        {
+          if (size < formats[index][i].factor)
+            {
+              f = &formats[index][i - 1];
+              break;
+            }
+        }
 
-      else
-        g_string_printf (string, _("%.1f EB"), (gdouble) size / (gdouble) EXABYTE_FACTOR);
+      g_string_printf (string, _(f->string), (gdouble) size / (gdouble) f->factor);
     }
 
   if (flags & G_FORMAT_SIZE_LONG_FORMAT)


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