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