diff options
Diffstat (limited to 'src/util/string.cpp')
-rw-r--r-- | src/util/string.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/util/string.cpp b/src/util/string.cpp index 914f1f74..4ad3decd 100644 --- a/src/util/string.cpp +++ b/src/util/string.cpp @@ -114,6 +114,48 @@ parse_signed(std::string_view value, } } +nonstd::expected<uint64_t, std::string> +parse_size(const std::string& value) +{ + errno = 0; + + char* p; + double result = strtod(value.c_str(), &p); + if (errno != 0 || result < 0 || p == value.c_str() || value.empty()) { + return nonstd::make_unexpected(FMT("invalid size: \"{}\"", value)); + } + + while (isspace(*p)) { + ++p; + } + + if (*p != '\0') { + unsigned multiplier = *(p + 1) == 'i' ? 1024 : 1000; + switch (*p) { + case 'T': + result *= multiplier; + [[fallthrough]]; + case 'G': + result *= multiplier; + [[fallthrough]]; + case 'M': + result *= multiplier; + [[fallthrough]]; + case 'K': + case 'k': + result *= multiplier; + break; + default: + return nonstd::make_unexpected(FMT("invalid size: \"{}\"", value)); + } + } else { + // Default suffix: G. + result *= 1000 * 1000 * 1000; + } + + return static_cast<uint64_t>(result); +} + nonstd::expected<mode_t, std::string> parse_umask(std::string_view value) { |