summaryrefslogtreecommitdiff
path: root/src/util/string.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/string.cpp')
-rw-r--r--src/util/string.cpp42
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)
{