You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2018/11/26 04:25:40 UTC

svn commit: r1847451 - in /subversion/trunk/subversion/svn: cl.h filesize.c info-cmd.c list-cmd.c

Author: brane
Date: Mon Nov 26 04:25:40 2018
New Revision: 1847451

URL: http://svn.apache.org/viewvc?rev=1847451&view=rev
Log:
Combine base-2 and base-10 unit file size conversion into a single API,
with a common implementation for the identical bits.

* subversion/svn/cl.h
  (svn_cl__unit_base_t): New enumeration.
  (svn_cl__get_base2_unit_file_size,
   svn_cl__get_base10_unit_file_size): Removed. Replaced by ...
  (svn_cl__get_unit_file_size): ... this new function.

* subversion/svn/filesize.c
  (filesize_order_t): New common struct.
  (get_order_index, format_size): New; refactored common code.
  (get_base2_unit_file_size): Reworked from svn_cl__get_base2_unit_file_size.
  (get_base10_unit_file_size): Reworked from svn_cl__get_base10_unit_file_size.
  (svn_cl__get_unit_file_size): Implement.

* subversion/svn/info-cmd.c (print_info): Use svn_cl__get_unit_file_size().
* subversion/svn/list-cmd.c (print_dirent): Likewise.

Modified:
    subversion/trunk/subversion/svn/cl.h
    subversion/trunk/subversion/svn/filesize.c
    subversion/trunk/subversion/svn/info-cmd.c
    subversion/trunk/subversion/svn/list-cmd.c

Modified: subversion/trunk/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl.h?rev=1847451&r1=1847450&r2=1847451&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/cl.h (original)
+++ subversion/trunk/subversion/svn/cl.h Mon Nov 26 04:25:40 2018
@@ -723,23 +723,27 @@ svn_cl__node_kind_str_xml(svn_node_kind_
 const char *
 svn_cl__node_kind_str_human_readable(svn_node_kind_t kind);
 
-/* Return the size of a file, formatted to 3 colums in base-2 units.
+/* Supported unit bases for file size conversion. */
+typedef enum svn_cl__unit_base_t
+  {
+    SVN_CL__BASE_10_UNIT = 1000, /* Use base-10 SI units. */
+    SVN_CL__BASE_2_UNIT = 1024   /* Use base-2 SI units. */
+  } svn_cl__unit_base_t;
+
+/* Set *RESULT to the size of a file, formatted to 3 colums in BASE units.
    if LONG_UNITS is TRUE, unit suffixes will be the whole SI symbol,
    e.g., KiB, MiB, etc; otherwise only the first letters will be used.
 
    File sizes are never negative, so we don't handle that case other than
-   making sure that the scale adjustment will work. */
-const char *
-svn_cl__get_base2_unit_file_size(svn_filesize_t size,
-                                 svn_boolean_t long_units,
-                                 apr_pool_t *result_pool);
+   making sure that the scale adjustment will work.
 
-/* Like svn_cl__get_base2_unit_file_size() but using base-10 units,
-   e.g., kB, MB, etc. (and short variabts k, M, etc.). */
-const char *
-svn_cl__get_base10_unit_file_size(svn_filesize_t size,
-                                  svn_boolean_t long_units,
-                                  apr_pool_t *result_pool);
+   The result will be allocated from RESULT_POOL. */
+svn_error_t *
+svn_cl__get_unit_file_size(const char **result,
+                           svn_filesize_t size,
+                           svn_cl__unit_base_t base,
+                           svn_boolean_t long_units,
+                           apr_pool_t *result_pool);
 
 
 /** Provides an XML name for a given OPERATION.

Modified: subversion/trunk/subversion/svn/filesize.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/filesize.c?rev=1847451&r1=1847450&r2=1847451&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/filesize.c (original)
+++ subversion/trunk/subversion/svn/filesize.c Mon Nov 26 04:25:40 2018
@@ -35,18 +35,78 @@
 
 /*** Code. ***/
 
-const char *
-svn_cl__get_base2_unit_file_size(svn_filesize_t size,
-                                 svn_boolean_t long_units,
-                                 apr_pool_t *result_pool)
-{
-  static const struct
-  {
-    svn_filesize_t mask;
-    const char *suffix;
-    const char *short_suffix;
-  }
-  order[] =
+/* The structure that describes the units and their magnitudes. */
+typedef struct filesize_order_t
+{
+  svn_filesize_t mask;
+  const char *suffix;
+  const char *short_suffix;
+} filesize_order_t;
+
+
+/* Get the index of the order of magnitude of the given SIZE.
+   The returned index will be within [0 .. order_size - 1]. */
+static apr_size_t
+get_order_index(svn_filesize_t abs_size,
+                const filesize_order_t *order,
+                apr_size_t order_size)
+{
+  /* It would be sexy to do a binary search here, but with only 7 elements
+     in the arrays ... we should ### FIXME: do the binary search anyway. */
+  apr_size_t index = order_size;
+  while (index > 0)
+    {
+      --index;
+      if (abs_size > order[index].mask)
+        break;
+    }
+  return index;
+}
+
+
+/* Format the adjusted size with the given units. */
+static const char *
+format_size(double human_readable_size,
+            svn_boolean_t long_units,
+            const filesize_order_t *order,
+            apr_size_t index,
+            apr_pool_t *result_pool)
+{
+  /* NOTE: We want to display a locale-specific decimal sepratator, but
+           APR's formatter completely ignores the locale. So we use the
+           good, old, standard, *dangerous* sprintf() to format the size.
+
+           But, on the brigt side, we require sure that the number has
+           no more than 3 non-fractional digits. So the call to sprintf()
+           here should be safe. */
+  const double absolute_human_readable_size = fabs(human_readable_size);
+  const char *const suffix = (long_units ? order[index].suffix
+                              : order[index].short_suffix);
+
+  /*   3 digits (or 2 digits and 1 decimal separator)
+     + 1 negative sign (which should not appear under normal circumstances)
+     + 1 nul terminator
+     ---
+     = 5 characters of space needed in the buffer. */
+    char buffer[8];
+
+    assert(absolute_human_readable_size < 1000.0);
+
+    /* When the adjusted size has only one significant digit left of the
+       decimal point, show tenths of a unit, too. */
+    sprintf(buffer, "%.*f",
+            absolute_human_readable_size < 10.0 ? 1 : 0,
+            human_readable_size);
+    return apr_pstrcat(result_pool, buffer, suffix, SVN_VA_NULL);
+}
+
+
+static const char *
+get_base2_unit_file_size(svn_filesize_t size,
+                         svn_boolean_t long_units,
+                         apr_pool_t *result_pool)
+{
+  static const filesize_order_t order[] =
     {
       {APR_INT64_C(0x0000000000000000), " B",   "B"}, /* byte */
       {APR_INT64_C(0x00000000000003FF), " KiB", "K"}, /* kibi */
@@ -59,18 +119,9 @@ svn_cl__get_base2_unit_file_size(svn_fil
   static const apr_size_t order_size = sizeof(order) / sizeof(order[0]);
 
   const svn_filesize_t abs_size = ((size < 0) ? -size : size);
+  apr_size_t index = get_order_index(abs_size, order, order_size);
   double human_readable_size;
 
-  /* Find the size mask for the (absolute) file size. It would be sexy to
-     do a binary search here, but with only 7 elements in the array ... */
-  apr_size_t index = order_size;
-  while (index > 0)
-    {
-      --index;
-      if (abs_size > order[index].mask)
-        break;
-    }
-
   /* Adjust the size to the given order of magnitude.
 
      This is division by (order[index].mask + 1), which is the base-2^10
@@ -90,46 +141,17 @@ svn_cl__get_base2_unit_file_size(svn_fil
   human_readable_size = (index == 0 ? (double)size
                          : (size >> 3 * index) / 128.0 / index);
 
-  /* NOTE: We want to display a locale-specific decimal sepratator, but
-           APR's formatter completely ignores the locale. So we use the
-           good, old, standard, *dangerous* sprintf() to format the size.
-
-           But, on the brigt side, we've just made sure that the number has
-           no more than 3 non-fractional digits. So the call to sprintf()
-           here should be safe. */
-  {
-    const char *const suffix = (long_units ? order[index].suffix
-                                : order[index].short_suffix);
-
-    /*   3 digits (or 2 digits and 1 decimal separator)
-       + 1 negative sign (which should not appear under normal circumstances)
-       + 1 nul terminator
-       ---
-       = 5 characters of space needed in the buffer. */
-    char buffer[8];
-
-    /* When the adjusted size has only one significant digit left of the
-       decimal point, show tenths of a unit, too. */
-    sprintf(buffer, "%.*f",
-            fabs(human_readable_size) < 10.0 ? 1 : 0,
-            human_readable_size);
-    return apr_pstrcat(result_pool, buffer, suffix, SVN_VA_NULL);
-  }
+  return format_size(human_readable_size,
+                     long_units, order, index, result_pool);
 }
 
 
-const char *
-svn_cl__get_base10_unit_file_size(svn_filesize_t size,
-                                  svn_boolean_t long_units,
-                                  apr_pool_t *result_pool)
-{
-  static const struct
-  {
-    svn_filesize_t mask;
-    const char *suffix;
-    const char *short_suffix;
-  }
-  order[] =
+static const char *
+get_base10_unit_file_size(svn_filesize_t size,
+                          svn_boolean_t long_units,
+                          apr_pool_t *result_pool)
+{
+  static const filesize_order_t order[] =
     {
       {APR_INT64_C(                 0), " B",  "B"}, /* byte */
       {APR_INT64_C(               999), " kB", "k"}, /* kilo */
@@ -142,18 +164,9 @@ svn_cl__get_base10_unit_file_size(svn_fi
   static const apr_size_t order_size = sizeof(order) / sizeof(order[0]);
 
   const svn_filesize_t abs_size = ((size < 0) ? -size : size);
+  apr_size_t index = get_order_index(abs_size, order, order_size);
   double human_readable_size;
 
-  /* Find the size mask for the (absolute) file size. It would be sexy to
-     do a binary search here, but with only 7 elements in the array ... */
-  apr_size_t index = order_size;
-  while (index > 0)
-    {
-      --index;
-      if (abs_size > order[index].mask)
-        break;
-    }
-
   /* Adjust the size to the given order of magnitude.
 
      This is division by (order[index].mask + 1), which is the base-1000
@@ -172,17 +185,31 @@ svn_cl__get_base10_unit_file_size(svn_fi
       /*                    [   And here!  ] */
     }
 
-  /* NOTE: See localisation note in svn_cl__get_base2_unit_file_size(). */
-  {
-    const char *const suffix = (long_units ? order[index].suffix
-                                : order[index].short_suffix);
-    char buffer[8];
+  return format_size(human_readable_size,
+                     long_units, order, index, result_pool);
+}
 
-    /* When the adjusted size has only one significant digit left of the
-       decimal point, show tenths of a unit, too. */
-    sprintf(buffer, "%.*f",
-            fabs(human_readable_size) < 10.0 ? 1 : 0,
-            human_readable_size);
-    return apr_pstrcat(result_pool, buffer, suffix, SVN_VA_NULL);
-  }
+
+svn_error_t *
+svn_cl__get_unit_file_size(const char **result,
+                           svn_filesize_t size,
+                           svn_cl__unit_base_t base,
+                           svn_boolean_t long_units,
+                           apr_pool_t *result_pool)
+{
+  switch (base)
+    {
+    case SVN_CL__BASE_2_UNIT:
+      *result = get_base2_unit_file_size(size, long_units, result_pool);
+      break;
+
+    case SVN_CL__BASE_10_UNIT:
+      *result = get_base10_unit_file_size(size, long_units, result_pool);
+      break;
+
+    default:
+      SVN_ERR_MALFUNCTION();
+    }
+
+  return SVN_NO_ERROR;
 }

Modified: subversion/trunk/subversion/svn/info-cmd.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/info-cmd.c?rev=1847451&r1=1847450&r2=1847451&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/info-cmd.c (original)
+++ subversion/trunk/subversion/svn/info-cmd.c Mon Nov 26 04:25:40 2018
@@ -767,11 +767,17 @@ print_info(void *baton,
 
   if (info->kind == svn_node_file && info->size != SVN_INVALID_FILESIZE)
     {
-      const char *const sizestr =
-        (receiver_baton->human_readable
-         ? svn_cl__get_base2_unit_file_size(info->size, TRUE, pool)
-         : apr_psprintf(pool, "%" SVN_FILESIZE_T_FMT,
-                        info->size));
+      const char *sizestr;
+      if (receiver_baton->human_readable)
+        {
+          SVN_ERR(svn_cl__get_unit_file_size(&sizestr, info->size,
+                                             SVN_CL__BASE_2_UNIT,
+                                             TRUE, pool));
+        }
+      else
+        {
+          sizestr = apr_psprintf(pool, "%" SVN_FILESIZE_T_FMT, info->size);
+        }
       SVN_ERR(svn_cmdline_printf(pool, _("Size in Repository: %s\n"),
                                  sizestr));
     }

Modified: subversion/trunk/subversion/svn/list-cmd.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/list-cmd.c?rev=1847451&r1=1847450&r2=1847451&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/list-cmd.c (original)
+++ subversion/trunk/subversion/svn/list-cmd.c Mon Nov 26 04:25:40 2018
@@ -182,11 +182,16 @@ print_dirent(void *baton,
       if (dirent->kind == svn_node_file)
         {
           if (pb->human_readable)
-            sizestr = svn_cl__get_base2_unit_file_size(dirent->size, FALSE,
-                                                       scratch_pool);
+            {
+              SVN_ERR(svn_cl__get_unit_file_size(&sizestr, dirent->size,
+                                                 SVN_CL__BASE_2_UNIT,
+                                                 FALSE, scratch_pool));
+            }
           else
-            sizestr = apr_psprintf(scratch_pool, "%" SVN_FILESIZE_T_FMT,
-                                   dirent->size);
+            {
+              sizestr = apr_psprintf(scratch_pool, "%" SVN_FILESIZE_T_FMT,
+                                     dirent->size);
+            }
         }
 
       return svn_cmdline_printf