summaryrefslogtreecommitdiffstats
path: root/util/types.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 19:41:32 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 19:41:32 +0000
commitf26f66d866ba1a9f3204e6fdfe2b07e67b5492ad (patch)
treec953c007cbe4f60a147ab62f97937d58abb2e9ca /util/types.c
parentInitial commit. (diff)
downloadnvme-cli-f26f66d866ba1a9f3204e6fdfe2b07e67b5492ad.tar.xz
nvme-cli-f26f66d866ba1a9f3204e6fdfe2b07e67b5492ad.zip
Adding upstream version 2.8.upstream/2.8
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'util/types.c')
-rw-r--r--util/types.c204
1 files changed, 204 insertions, 0 deletions
diff --git a/util/types.c b/util/types.c
new file mode 100644
index 0000000..376c734
--- /dev/null
+++ b/util/types.c
@@ -0,0 +1,204 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <locale.h>
+#include <time.h>
+
+#include <ccan/endian/endian.h>
+
+#include "types.h"
+#include "util/suffix.h"
+
+nvme_uint128_t le128_to_cpu(__u8 *data)
+{
+ nvme_uint128_t u;
+ nvme_uint128_t tmp;
+
+ memcpy(tmp.bytes, data, 16);
+ u.words[0] = le32_to_cpu(tmp.words[3]);
+ u.words[1] = le32_to_cpu(tmp.words[2]);
+ u.words[2] = le32_to_cpu(tmp.words[1]);
+ u.words[3] = le32_to_cpu(tmp.words[0]);
+ return u;
+}
+
+long double int128_to_double(__u8 *data)
+{
+ long double result = 0;
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ result *= 256;
+ result += data[15 - i];
+ }
+ return result;
+}
+
+uint64_t int48_to_long(__u8 *data)
+{
+ int i;
+ uint64_t result = 0;
+
+ for (i = 0; i < 6; i++) {
+ result *= 256;
+ result += data[5 - i];
+ }
+ return result;
+}
+
+static long double uint128_t_to_double(nvme_uint128_t data)
+{
+ long double result = 0;
+ int i;
+
+ for (i = 0; i < sizeof(data.words) / sizeof(*data.words); i++) {
+ result *= 4294967296;
+ result += data.words[i];
+ }
+
+ return result;
+}
+
+static char *__uint128_t_to_string(nvme_uint128_t val, bool l10n)
+{
+ static char str[60];
+ int idx = 60;
+ __u64 div, rem;
+ char *sep = NULL;
+ int i, len = 0, cl = 0;
+
+ if (l10n) {
+ sep = localeconv()->thousands_sep;
+ len = strlen(sep);
+ cl = 1;
+ }
+
+ /* terminate at the end, and build up from the ones */
+ str[--idx] = '\0';
+
+ do {
+ if (len && !((sizeof(str) - idx) % (3 + cl))) {
+ for (i = 0; i < len; i++)
+ str[--idx] = sep[len - i - 1];
+ }
+
+ rem = val.words[0];
+
+ div = rem / 10;
+ rem = ((rem - div * 10) << 32) + val.words[1];
+ val.words[0] = div;
+
+ div = rem / 10;
+ rem = ((rem - div * 10) << 32) + val.words[2];
+ val.words[1] = div;
+
+ div = rem / 10;
+ rem = ((rem - div * 10) << 32) + val.words[3];
+ val.words[2] = div;
+
+ div = rem / 10;
+ rem = rem - div * 10;
+ val.words[3] = div;
+
+ str[--idx] = '0' + rem;
+ } while (val.words[0] || val.words[1] || val.words[2] || val.words[3]);
+
+ return str + idx;
+}
+
+char *uint128_t_to_string(nvme_uint128_t val)
+{
+ return __uint128_t_to_string(val, false);
+}
+
+char *uint128_t_to_l10n_string(nvme_uint128_t val)
+{
+ return __uint128_t_to_string(val, true);
+}
+
+char *uint128_t_to_si_string(nvme_uint128_t val, __u32 bytes_per_unit)
+{
+ long double bytes = uint128_t_to_double(val) * bytes_per_unit;
+ static char str[40];
+ const char *suffix = suffix_si_get_ld(&bytes);
+ int n = snprintf(str, sizeof(str), "%.2Lf %sB", bytes, suffix);
+
+ if (n <= 0)
+ return "";
+
+ if (n >= sizeof(str))
+ str[sizeof(str) - 1] = '\0';
+
+ return str;
+}
+
+const char *util_uuid_to_string(unsigned char uuid[NVME_UUID_LEN])
+{
+ static char uuid_str[NVME_UUID_LEN_STRING];
+
+ nvme_uuid_to_string(uuid, uuid_str);
+
+ return uuid_str;
+}
+
+const char *util_fw_to_string(char *c)
+{
+ static char ret[9];
+ int i;
+
+ for (i = 0; i < 8; i++)
+ ret[i] = c[i] >= '!' && c[i] <= '~' ? c[i] : '.';
+ ret[i] = '\0';
+ return ret;
+}
+
+int convert_ts(time_t time, char *ts_buf)
+{
+ struct tm time_info;
+ time_t time_human, time_ms;
+ char buf[80];
+
+ time_human = time / 1000;
+ time_ms = time % 1000;
+
+ gmtime_r((const time_t *)&time_human, &time_info);
+
+ strftime(buf, sizeof(buf), "%Y-%m-%dD|%H:%M:%S", &time_info);
+ sprintf(ts_buf, "%s:%03ld", buf, time_ms);
+
+ return 0;
+}
+
+void util_spinner(const char *disp_name, float percent)
+{
+ static const char dash[51] = {[0 ... 49] = '=', '\0'};
+ static const char space[51] = {[0 ... 49] = ' ', '\0'};
+ static const char spin[] = {'-', '\\', '|', '/' };
+ static int progress;
+ static int i;
+ const char *dn = disp_name ? disp_name : "";
+
+ if (percent < 0)
+ percent = 0;
+ else if (percent > 1)
+ percent = 1;
+
+ progress = (int)(percent * 100.0);
+ if (progress < 2)
+ printf("\r%s [%c%.*s] %3d%%", dn,
+ spin[i % 4], 49,
+ space, progress);
+ else if (progress < 100)
+ printf("\r%s [%.*s%c%.*s] %3d%%", dn,
+ progress / 2 - 1, dash,
+ spin[i % 4], 50 - progress / 2,
+ space, progress);
+ else
+ printf("\r%s [%.*s] %3d%%\n", dn,
+ 50, dash, 100);
+ i++;
+
+ fflush(stdout);
+}