summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2019-10-19 18:20:00 +0100
committerVincent Sanders <vince@kyllikki.org>2019-10-19 18:20:00 +0100
commite01c24cef73d2cb70088af1381b90924129a112f (patch)
tree50ac71c3698e2ab35118e09a0b0408e5576cc52e /utils
parenta54cbb5aeaba6f6ecf6c04de38acda79733583ed (diff)
downloadnetsurf-e01c24cef73d2cb70088af1381b90924129a112f.tar.gz
netsurf-e01c24cef73d2cb70088af1381b90924129a112f.tar.bz2
improve human_friendly_bytesize to cope with sizes up to 16 exibytes
Diffstat (limited to 'utils')
-rw-r--r--utils/string.h2
-rw-r--r--utils/utils.c72
2 files changed, 58 insertions, 16 deletions
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;
}