summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--resources/FatMessages9
-rw-r--r--test/utils.c33
-rw-r--r--utils/string.h2
-rw-r--r--utils/utils.c72
4 files changed, 87 insertions, 29 deletions
diff --git a/resources/FatMessages b/resources/FatMessages
index 912586674..12d81bd5e 100644
--- a/resources/FatMessages
+++ b/resources/FatMessages
@@ -119,6 +119,7 @@ nl.all.FrameDrag:frames aan het aanpassen
# Units
# =====
#
+# Decimal prefix
en.all.Bytes: B
de.all.Bytes: B
fr.all.Bytes: octets
@@ -139,7 +140,13 @@ de.all.GBytes: GB
fr.all.GBytes: Go
it.all.GBytes: GB
nl.all.GBytes: GB
-
+# Binary prefix
+en.all.KiBytes: KiB
+en.all.MiBytes: MiB
+en.all.GiBytes: GiB
+en.all.TiBytes: TiB
+en.all.PiBytes: PiB
+en.all.EiBytes: EiB
# Content Forms
# =============
diff --git a/test/utils.c b/test/utils.c
index 3d5319a28..9fe6747c3 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -37,22 +37,31 @@
#define SLEN(x) (sizeof((x)) - 1)
struct test_pairs {
- const unsigned long test;
+ const unsigned long long int test;
const char* res;
};
static const struct test_pairs human_friendly_bytesize_test_vec[] = {
- { 0, "0.00Bytes" },
- { 1024, "1024.00Bytes" },
- { 1025, "1.00kBytes" },
- { 1048576, "1024.00kBytes" },
- { 1048577, "1.00MBytes" },
- { 1073741824, "1024.00MBytes" },
- { 1073741888, "1024.00MBytes" }, /* spot the rounding error */
- { 1073741889, "1.00GBytes" },
- { 2147483648, "2.00GBytes" },
- { 3221225472, "3.00GBytes" },
- { 4294967295, "4.00GBytes" },
+ { 0ULL, "0Bytes" },
+ { 0x2AULL, "42Bytes" },
+ { 0x400ULL, "1024Bytes" },
+ { 0x401ULL, "1.00KiBytes" },
+ { 0xA9AEULL, "42.42KiBytes" },
+ { 0x100000ULL, "1024.00KiBytes" },
+ { 0x100001ULL, "1.00MiBytes" },
+ { 0x2A6B852ULL, "42.42MiBytes" },
+ { 0x40000000ULL, "1024.00MiBytes" },
+ { 0x40000001ULL, "1.00GiBytes" },
+ { 0x80000000ULL, "2.00GiBytes" },
+ { 0xC0000000ULL, "3.00GiBytes" },
+ { 0x100000000ULL, "4.00GiBytes" },
+ { 0x10000000000ULL, "1024.00GiBytes" },
+ { 0x10000000001ULL, "1.00TiBytes" },
+ { 0x4000000000000ULL, "1024.00TiBytes" },
+ { 0x4000000000001ULL, "1.00PiBytes" },
+ { 0x1000000000000000ULL, "1024.00PiBytes" },
+ { 0x1000000000000100ULL, "1.00EiBytes" }, /* precision loss */
+ { 0xFFFFFFFFFFFFFFFFULL, "16.00EiBytes" },
};
/**
diff --git a/utils/string.h b/utils/string.h
index 03d891700..abb343154 100644
--- a/utils/string.h
+++ b/utils/string.h
@@ -64,7 +64,7 @@ char *cnv_space2nbsp(const char *s);
* @param bytesize The size in bytes.
* @return A human readable string representing the size.
*/
-char *human_friendly_bytesize(unsigned long bytesize);
+char *human_friendly_bytesize(unsigned long long int bytesize);
/**
diff --git a/utils/utils.c b/utils/utils.c
index aec0116a0..c5c1529a3 100644
--- a/utils/utils.c
+++ b/utils/utils.c
@@ -192,26 +192,43 @@ nserror snstrjoin(char **str, size_t *size, char sep, size_t nelm, ...)
/**
* The size of buffers within human_friendly_bytesize.
*
- * We can have a fairly good estimate of how long the buffer needs to
- * be. The unsigned long can store a value representing a maximum
- * size of around 4 GB. Therefore the greatest space required is to
- * represent 1023MB. Currently that would be represented as "1023MB"
- * so 12 including a null terminator. Ideally we would be able to
- * know this value for sure, in the mean time the following should
- * suffice.
+ * We can have a fairly good estimate of the output buffers maximum length.
+ *
+ * The unsigned long long int can store a value representing a maximum
+ * size of 16 EiB (exibytes). Therefore the greatest space required is to
+ * represent 1023 PiB.
+ * Currently that would be represented as "1023.00PiBytes" in english
+ * giving a 15 byte length including a null terminator.
+ * Ideally we would be able to accurately know this length for other
+ * languages, in the mean time a largeish buffer size is selected
+ * and should suffice.
*/
-#define BYTESIZE_BUFFER_SIZE 20
+#define BYTESIZE_BUFFER_SIZE 32
/* exported interface documented in utils/string.h */
-char *human_friendly_bytesize(unsigned long bsize) {
+char *human_friendly_bytesize(unsigned long long int bsize) {
static char buffer1[BYTESIZE_BUFFER_SIZE];
static char buffer2[BYTESIZE_BUFFER_SIZE];
static char buffer3[BYTESIZE_BUFFER_SIZE];
static char *curbuffer = buffer3;
- enum {bytes, kilobytes, megabytes, gigabytes} unit = bytes;
- static char units[][7] = {"Bytes", "kBytes", "MBytes", "GBytes"};
-
- float bytesize = (float)bsize;
+ enum {
+ bytes,
+ kilobytes,
+ megabytes,
+ gibibytes,
+ tebibytes,
+ pebibytes,
+ exbibytes } unit = bytes;
+ static const char *const units[] = {
+ "Bytes",
+ "KiBytes",
+ "MiBytes",
+ "GiBytes",
+ "TiBytes",
+ "PiBytes",
+ "EiBytes" };
+ double bytesize = (double)bsize;
+ const char *fmt;
if (curbuffer == buffer1)
curbuffer = buffer2;
@@ -232,10 +249,35 @@ char *human_friendly_bytesize(unsigned long bsize) {
if (bytesize > 1024) {
bytesize /= 1024;
- unit = gigabytes;
+ unit = gibibytes;
+ }
+
+ if (bytesize > 1024) {
+ bytesize /= 1024;
+ unit = tebibytes;
+ }
+
+ if (bytesize > 1024) {
+ bytesize /= 1024;
+ unit = pebibytes;
+ }
+
+ if (bytesize > 1024) {
+ bytesize /= 1024;
+ unit = exbibytes;
+ }
+
+ if (unit == bytes) {
+ fmt = "%.0f%s";
+ } else {
+ fmt = "%3.2f%s";
}
- snprintf(curbuffer, BYTESIZE_BUFFER_SIZE, "%3.2f%s", bytesize, messages_get(units[unit]));
+ snprintf(curbuffer,
+ BYTESIZE_BUFFER_SIZE,
+ fmt,
+ bytesize,
+ messages_get(units[unit]));
return curbuffer;
}