mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-03-21 21:20:07 +01:00
util: ParseByteUnits - Parse a string with suffix unit [k|K|m|M|g|G|t|T]
A convenience utility for human readable arguments/config e.g. -maxuploadtarget=500g
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
|
||||
static const std::string CHARS_ALPHA_NUM = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
@@ -526,3 +527,48 @@ std::string HexStr(const Span<const uint8_t> s)
|
||||
assert(it == rv.end());
|
||||
return rv;
|
||||
}
|
||||
|
||||
std::optional<uint64_t> ParseByteUnits(const std::string& str, ByteUnit default_multiplier)
|
||||
{
|
||||
if (str.empty()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
auto multiplier = default_multiplier;
|
||||
char unit = str.back();
|
||||
switch (unit) {
|
||||
case 'k':
|
||||
multiplier = ByteUnit::k;
|
||||
break;
|
||||
case 'K':
|
||||
multiplier = ByteUnit::K;
|
||||
break;
|
||||
case 'm':
|
||||
multiplier = ByteUnit::m;
|
||||
break;
|
||||
case 'M':
|
||||
multiplier = ByteUnit::M;
|
||||
break;
|
||||
case 'g':
|
||||
multiplier = ByteUnit::g;
|
||||
break;
|
||||
case 'G':
|
||||
multiplier = ByteUnit::G;
|
||||
break;
|
||||
case 't':
|
||||
multiplier = ByteUnit::t;
|
||||
break;
|
||||
case 'T':
|
||||
multiplier = ByteUnit::T;
|
||||
break;
|
||||
default:
|
||||
unit = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
uint64_t unit_amount = static_cast<uint64_t>(multiplier);
|
||||
auto parsed_num = ToIntegral<uint64_t>(unit ? str.substr(0, str.size() - 1) : str);
|
||||
if (!parsed_num || parsed_num > std::numeric_limits<uint64_t>::max() / unit_amount) { // check overflow
|
||||
return std::nullopt;
|
||||
}
|
||||
return *parsed_num * unit_amount;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user