[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PATCH v2 1/6] cutils: add helpers for formatting sized val
From: |
Daniel P. Berrange |
Subject: |
[Qemu-block] [PATCH v2 1/6] cutils: add helpers for formatting sized values |
Date: |
Fri, 9 Sep 2016 18:41:56 +0100 |
Introduce qemu_sztostr which takes an int and turns it
into a sized string. Variants are added for both signed
and unsigned integers.
Signed-off-by: Daniel P. Berrange <address@hidden>
---
include/qemu/cutils.h | 12 +++++++
tests/test-cutils.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++
util/cutils.c | 78 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 186 insertions(+)
diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h
index 3e4ea23..31f6bff 100644
--- a/include/qemu/cutils.h
+++ b/include/qemu/cutils.h
@@ -158,6 +158,18 @@ int64_t qemu_strtosz_suffix(const char *nptr, char **end,
const char default_suffix);
int64_t qemu_strtosz_suffix_unit(const char *nptr, char **end,
const char default_suffix, int64_t unit);
+
+char *qemu_sztostr(int64_t val);
+char *qemu_sztostr_full(int64_t val,
+ const char default_suffix,
+ bool long_suffix,
+ const char *separator);
+char *qemu_szutostr(uint64_t val);
+char *qemu_szutostr_full(uint64_t val,
+ const char default_suffix,
+ bool long_suffix,
+ const char *separator);
+
#define K_BYTE (1ULL << 10)
#define M_BYTE (1ULL << 20)
#define G_BYTE (1ULL << 30)
diff --git a/tests/test-cutils.c b/tests/test-cutils.c
index 20b0f59..b067c68 100644
--- a/tests/test-cutils.c
+++ b/tests/test-cutils.c
@@ -1437,8 +1437,94 @@ static void test_qemu_strtosz_suffix_unit(void)
g_assert_cmpint(res, ==, 12345000);
}
+
+static struct SzToStrData {
+ const char *path;
+ int64_t val;
+ const char *expected;
+ const char default_suffix;
+ bool long_suffix;
+ const char *separator;
+} test_qemu_sztostr_data[] = {
+ { "/cutils/sztostr/simple", -42, "-42B", '\0', true, NULL },
+ { "/cutils/sztostr/simple-suffix", -1729, "-1.69KiB", '\0', true, NULL },
+ { "/cutils/sztostr/default-suffix", 1729, "1.69",
+ QEMU_STRTOSZ_DEFSUFFIX_KB, true, NULL },
+ { "/cutils/sztostr/short-suffix", 1729, "1.69 K", '\0', false, " " },
+ { "/cutils/sztostr/simple-sepator", -1729, "-1.69",
+ QEMU_STRTOSZ_DEFSUFFIX_KB, true, " " },
+ { "/cutils/sztostr/simple-suffix-sepator", -1729, "-1.69 KiB",
+ '\0', true, " " },
+ { "/cutils/sztostr/ulong-max", ULLONG_MAX, "-1B", '\0', true, NULL },
+ { "/cutils/sztostr/long-max", LONG_MAX, "8EiB", '\0', true, NULL },
+ { "/cutils/sztostr/long-min", -LONG_MAX - 1, "-8EiB", '\0', true, NULL },
+};
+
+static void test_qemu_sztostr(const void *opaque)
+{
+ const struct SzToStrData *data = opaque;
+ char *actual;
+
+ if (data->separator || data->default_suffix) {
+ actual = qemu_sztostr_full(data->val,
+ data->default_suffix,
+ data->long_suffix,
+ data->separator);
+ } else {
+ actual = qemu_sztostr(data->val);
+ }
+
+ g_assert_cmpstr(actual, ==, data->expected);
+
+ g_free(actual);
+}
+
+
+static struct SzUToStrData {
+ const char *path;
+ uint64_t val;
+ const char *expected;
+ const char default_suffix;
+ bool long_suffix;
+ const char *separator;
+} test_qemu_szutostr_data[] = {
+ { "/cutils/szutostr/simple", 42, "42B", '\0', true, NULL },
+ { "/cutils/szutostr/simple-suffix", 1729, "1.69KiB", '\0', true, NULL },
+ { "/cutils/szutostr/default-suffix", 1729, "1.69",
+ QEMU_STRTOSZ_DEFSUFFIX_KB, true, NULL },
+ { "/cutils/szutostr/short-suffix", 1729, "1.69 K", '\0', false, " " },
+ { "/cutils/szutostr/simple-sepator", 1729, "1.69",
+ QEMU_STRTOSZ_DEFSUFFIX_KB, true, " " },
+ { "/cutils/szutostr/simple-suffix-sepator", 1729, "1.69 KiB",
+ '\0', true, " " },
+ { "/cutils/szutostr/ulong-max", ULLONG_MAX, "16EiB", '\0', true, NULL },
+ { "/cutils/szutostr/long-max", LONG_MAX, "8EiB", '\0', true, NULL },
+};
+
+static void test_qemu_szutostr(const void *opaque)
+{
+ const struct SzUToStrData *data = opaque;
+ char *actual;
+
+ if (data->separator || data->default_suffix) {
+ actual = qemu_szutostr_full(data->val,
+ data->default_suffix,
+ data->long_suffix,
+ data->separator);
+ } else {
+ actual = qemu_szutostr(data->val);
+ }
+
+ g_assert_cmpstr(actual, ==, data->expected);
+
+ g_free(actual);
+}
+
+
int main(int argc, char **argv)
{
+ gsize i;
+
g_test_init(&argc, &argv, NULL);
g_test_add_func("/cutils/parse_uint/null", test_parse_uint_null);
@@ -1598,5 +1684,15 @@ int main(int argc, char **argv)
g_test_add_func("/cutils/strtosz/suffix-unit",
test_qemu_strtosz_suffix_unit);
+ for (i = 0; i < G_N_ELEMENTS(test_qemu_sztostr_data); i++) {
+ g_test_add_data_func(test_qemu_sztostr_data[i].path,
+ &(test_qemu_sztostr_data[i]),
+ test_qemu_sztostr);
+ }
+ for (i = 0; i < G_N_ELEMENTS(test_qemu_szutostr_data); i++) {
+ g_test_add_data_func(test_qemu_szutostr_data[i].path,
+ &(test_qemu_szutostr_data[i]),
+ test_qemu_szutostr);
+ }
return g_test_run();
}
diff --git a/util/cutils.c b/util/cutils.c
index 7505fda..bdc3fc1 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -503,6 +503,84 @@ int64_t qemu_strtosz(const char *nptr, char **end)
return qemu_strtosz_suffix(nptr, end, QEMU_STRTOSZ_DEFSUFFIX_MB);
}
+
+static char *qemu_sztostr_impl(uint64_t val,
+ const char default_suffix,
+ bool long_suffix,
+ const char *separator,
+ bool allowSigned)
+{
+ static const char *suffixes[] = {
+ "B", "K", "M", "G", "T", "P", "E" };
+ const char *extra_suffix = "";
+ uint64_t div;
+ int i;
+ const char *sign = "";
+ const char *suffix = "";
+
+ /* The exponent (returned in i) minus one gives us
+ * floor(log2(val * 1024 / 1000). The correction makes us
+ * switch to the higher power when the integer part is >= 1000.
+ */
+ if (allowSigned && ((int64_t)val < 0)) {
+ val = ((int64_t)val) * -1;
+ sign = "-";
+ }
+
+ frexp(val / (1000.0 / 1024.0), &i);
+ i = (i - 1) / 10;
+ assert(i < ARRAY_SIZE(suffixes));
+ div = 1ULL << (i * 10);
+
+ if (suffixes[i][0] != default_suffix) {
+ suffix = suffixes[i];
+ if (i > 0 && long_suffix) {
+ extra_suffix = "iB";
+ }
+ } else {
+ separator = NULL;
+ }
+
+ return g_strdup_printf("%s%0.3g%s%s%s",
+ sign,
+ (double)val / div,
+ separator ? separator : "",
+ suffix, extra_suffix);
+}
+
+
+char *qemu_sztostr(int64_t val)
+{
+ return qemu_sztostr_impl((uint64_t)val, '\0', true, "", true);
+}
+
+
+char *qemu_sztostr_full(int64_t val,
+ const char default_suffix,
+ bool long_suffix,
+ const char *separator)
+{
+ return qemu_sztostr_impl((uint64_t)val, default_suffix,
+ long_suffix, separator, true);
+}
+
+
+char *qemu_szutostr(uint64_t val)
+{
+ return qemu_sztostr_impl(val, '\0', true, "", false);
+}
+
+
+char *qemu_szutostr_full(uint64_t val,
+ const char default_suffix,
+ bool long_suffix,
+ const char *separator)
+{
+ return qemu_sztostr_impl(val, default_suffix,
+ long_suffix, separator, false);
+}
+
+
/**
* Helper function for qemu_strto*l() functions.
*/
--
2.7.4
- [Qemu-block] [PATCH v2 0/6] Stable output of blockdev format specific info, Daniel P. Berrange, 2016/09/09
- [Qemu-block] [PATCH v2 1/6] cutils: add helpers for formatting sized values,
Daniel P. Berrange <=
- [Qemu-block] [PATCH v2 2/6] qapi: convert StringOutputVisitor to use qemu_szutostr, Daniel P. Berrange, 2016/09/09
- [Qemu-block] [PATCH v2 3/6] qapi: assert that visitor impls have required callbacks, Daniel P. Berrange, 2016/09/09
- [Qemu-block] [PATCH v2 4/6] qapi: add a text output visitor for pretty printing types, Daniel P. Berrange, 2016/09/09
- [Qemu-block] [PATCH v2 5/6] block: convert to use the qemu_szutostr functions, Daniel P. Berrange, 2016/09/09
- [Qemu-block] [PATCH v2 6/6] block: convert to use qapi_stringify_ImageInfoSpecific, Daniel P. Berrange, 2016/09/09
- Re: [Qemu-block] [Qemu-devel] [PATCH v2 0/6] Stable output of blockdev format specific info, Markus Armbruster, 2016/09/13