Author: brane
Date: Mon Nov 26 03:23:58 2018
New Revision: 1847448
URL: http://svn.apache.org/viewvc?rev=1847448&view=rev
Log:
Add a function for converting file sizes to base-10 units for display.
* subversion/svn/cl.h (svn_cl__get_base10_unit_file_size): New prototype.
* subversion/svn/filesize.c (svn_cl__get_base10_unit_file_size): Implement it.
Modified:
subversion/trunk/subversion/svn/cl.h
subversion/trunk/subversion/svn/filesize.c
Modified: subversion/trunk/subversion/svn/cl.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl.h?rev=1847448&r1=1847447&r2=1847448&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/cl.h (original)
+++ subversion/trunk/subversion/svn/cl.h Mon Nov 26 03:23:58 2018
@@ -734,6 +734,14 @@ svn_cl__get_base2_unit_file_size(svn_fil
svn_boolean_t long_units,
apr_pool_t *result_pool);
+/* 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);
+
+
/** Provides an XML name for a given OPERATION.
* Note: POOL is currently not used.
*/
Modified: subversion/trunk/subversion/svn/filesize.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/filesize.c?rev=1847448&r1=1847447&r2=1847448&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/filesize.c (original)
+++ subversion/trunk/subversion/svn/filesize.c Mon Nov 26 03:23:58 2018
@@ -116,3 +116,73 @@ svn_cl__get_base2_unit_file_size(svn_fil
return apr_pstrcat(result_pool, buffer, suffix, SVN_VA_NULL);
}
}
+
+
+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[] =
+ {
+ {APR_INT64_C( 0), " B", "B"}, /* byte */
+ {APR_INT64_C( 999), " kB", "k"}, /* kilo */
+ {APR_INT64_C( 999999), " MB", "M"}, /* mega */
+ {APR_INT64_C( 999999999), " GB", "G"}, /* giga */
+ {APR_INT64_C( 999999999999), " TB", "T"}, /* tera */
+ {APR_INT64_C( 999999999999999), " EB", "E"}, /* exa */
+ {APR_INT64_C(999999999999999999), " PB", "P"} /* peta */
+ };
+ static const apr_size_t order_size = sizeof(order) / sizeof(order[0]);
+
+ const svn_filesize_t abs_size = ((size < 0) ? -size : 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
+ magnitude of the size. For large file sizes, we split the operation
+ into an integer and a floating-point division, so that we don't
+ overflow the mantissa. */
+ if (index == 0)
+ human_readable_size = (double)size;
+ else if (index <= 3)
+ human_readable_size = (double)size / (order[index].mask + 1);
+ else
+ {
+ /* [ Keep integer division here! ] */
+ const double divisor = (double)((order[index].mask + 1) / 1000000);
+ human_readable_size = (size / 1000000) / divisor;
+ /* [ 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];
+
+ /* 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);
+ }
+}