Luna/libluna/src/Units.cpp
apio 5911b052dc
All checks were successful
continuous-integration/drone/push Build is passing
libluna: Add more options to to_dynamic_unit()
Also, make the output look more like how it is on linux.
2023-05-13 12:01:09 +02:00

45 lines
1.3 KiB
C++

#include <luna/Alloc.h>
#include <luna/CType.h>
#include <luna/Result.h>
#include <luna/ScopeGuard.h>
#include <luna/Units.h>
Result<String> to_dynamic_unit(usize value, usize round_after, bool separate, Unit unit, bool display_unit)
{
const usize multiplier = (usize)unit;
if (value < multiplier) { return String::format("%zu%s"_sv, value, display_unit ? " bytes" : ""); }
bool si = unit == Unit::SI;
const char* unit_prefixes = "KMGTPE";
if (si) unit_prefixes = "kMGTPE";
while (value > (multiplier * multiplier))
{
value /= multiplier;
unit_prefixes++;
}
const usize divider = (si ? 100 : 103);
usize fixed = value / multiplier;
usize rest = (value % multiplier) / divider;
bool round = fixed >= round_after;
if (round)
{
if (value % multiplier) fixed++;
return String::format("%zu%s%c%s"_sv, fixed, separate ? " " : "", *unit_prefixes,
display_unit ? (si ? "B" : "iB") : "");
}
if ((value % multiplier) % divider) rest++;
if (rest > 9)
{
rest = 0;
fixed++;
}
return String::format("%zu.%zu%s%c%s"_sv, fixed, rest, separate ? " " : "", *unit_prefixes,
display_unit ? (si ? "B" : "iB") : "");
}