Mercurial > minori
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)); }