diff src/core/strings.cc @ 273:f31305b9f60a

*: various code safety changes this also makes the code build on Qt 5.7. I can't test it though because I don't have it working... FAIL!
author Paper <paper@paper.us.eu.org>
date Thu, 18 Apr 2024 16:53:17 -0400
parents 9a04802848c0
children f6a756c19bfb
line wrap: on
line diff
--- a/src/core/strings.cc	Thu Apr 18 16:51:35 2024 -0400
+++ b/src/core/strings.cc	Thu Apr 18 16:53:17 2024 -0400
@@ -13,6 +13,7 @@
 #include <cctype>
 #include <codecvt>
 #include <iostream>
+#include <iomanip>
 #include <locale>
 #include <string>
 #include <unordered_map>
@@ -243,11 +244,16 @@
 /* util funcs */
 uint64_t HumanReadableSizeToBytes(const std::string& str) {
 	static const std::unordered_map<std::string, uint64_t> bytes_map = {
-	    {"KB", 1ull << 10},
-	    {"MB", 1ull << 20},
-	    {"GB", 1ull << 30},
-	    {"TB", 1ull << 40},
-	    {"PB", 1ull << 50}  /* surely we won't need more than this */
+		{"KB", 1000ull},
+		{"MB", 1000000ull},
+		{"GB", 1000000000ull},
+		{"TB", 1000000000000ull},
+		{"PB", 1000000000000000ull},
+	    {"KiB", 1ull << 10},
+	    {"MiB", 1ull << 20},
+	    {"GiB", 1ull << 30},
+	    {"TiB", 1ull << 40},
+	    {"PiB", 1ull << 50}  /* surely we won't need more than this */
 	};
 
 	for (const auto& suffix : bytes_map) {
@@ -264,6 +270,35 @@
 	return ToInt(str, 0);
 }
 
+std::string BytesToHumanReadableSize(uint64_t bytes, int precision) {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
+	/* QLocale in Qt >= 5.10.0 has a function for this */
+	return Strings::ToUtf8String(session.config.locale.GetLocale().formattedDataSize(bytes), precision);
+#else
+	static const std::unordered_map<uint64_t, std::string> map = {
+		{1ull << 10, "KiB"},
+		{1ull << 20, "MiB"},
+		{1ull << 30, "GiB"},
+		{1ull << 40, "TiB"},
+		{1ull << 50, "PiB"}
+	};
+
+	for (const auto& suffix : map) {
+		if (bytes / suffix.first < 1)
+			continue;
+
+		std::stringstream ss;
+		ss << std::setprecision(precision)
+		   << (static_cast<double>(bytes) / suffix.first) << " "
+		   << suffix.second;
+		return ss.str();
+	}
+
+	/* better luck next time */
+	return "0 bytes";
+#endif
+}
+
 void RemoveLeadingChars(std::string& s, const char c) {
 	s.erase(0, std::min(s.find_first_not_of(c), s.size() - 1));
 }