diff --git a/include/ircd/lex_cast.h b/include/ircd/lex_cast.h index c2a36092c..a92a44215 100644 --- a/include/ircd/lex_cast.h +++ b/include/ircd/lex_cast.h @@ -36,6 +36,9 @@ namespace ircd const_buffer a2u(const mutable_buffer &out, const const_buffer &in); string_view u2a(const mutable_buffer &out, const const_buffer &in); std::string u2a(const const_buffer &in); + + string_view pretty_iec_unit(const mutable_buffer &out, const uint64_t &value); + std::string pretty_iec_unit(const uint64_t &value); } namespace ircd diff --git a/ircd/lexical.cc b/ircd/lexical.cc index 42bcc65ec..65da4c74a 100644 --- a/ircd/lexical.cc +++ b/ircd/lexical.cc @@ -22,6 +22,42 @@ // misc util // +std::string +ircd::pretty_iec_unit(const uint64_t &value) +{ + return util::string(32, [&value] + (const mutable_buffer &out) + { + return pretty_iec_unit(out, value); + }); +} + +ircd::string_view +ircd::pretty_iec_unit(const mutable_buffer &out, + const uint64_t &value) +try +{ + auto pos(0); + auto v(value); + for(; v > 1024; v /= 1024, ++pos); + static const std::array unit + { + "B", " KiB", "MiB", "GiB", "TiB", "PiB", "EiB" + }; + + return fmt::sprintf + { + out, "%lu %s", v, unit.at(pos) + }; +} +catch(const std::out_of_range &e) +{ + return fmt::sprintf + { + out, "%lu B", value + }; +} + std::string ircd::u2a(const const_buffer &in) {