qemu-block
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]