string: implement ParseUInt64Hex

This commit is contained in:
Matthew Zipkin 2025-03-12 13:31:47 -04:00
parent f259121f30
commit 4c83785d1d
No known key found for this signature in database
GPG key ID: E7E2984B6289C93A
3 changed files with 46 additions and 0 deletions

View file

@ -1045,6 +1045,26 @@ BOOST_AUTO_TEST_CASE(test_ParseUInt64)
BOOST_CHECK(!ParseUInt64("-1234", &n));
}
BOOST_AUTO_TEST_CASE(test_ParseUInt64Hex)
{
uint64_t n;
// Valid values
BOOST_CHECK(ParseUInt64Hex("1234", nullptr));
BOOST_CHECK(ParseUInt64Hex("1234", &n) && n == 4660);
BOOST_CHECK(ParseUInt64Hex("a", &n) && n == 10);
BOOST_CHECK(ParseUInt64Hex("0000000a", &n) && n == 10);
BOOST_CHECK(ParseUInt64Hex("100", &n) && n == 256);
BOOST_CHECK(ParseUInt64Hex("DEADbeef", &n) && n == 3735928559);
BOOST_CHECK(ParseUInt64Hex("FfFfFfFf", &n) && n == 4294967295);
// Invalid values
BOOST_CHECK(!ParseUInt64Hex("123456789", &n));
BOOST_CHECK(!ParseUInt64Hex("", &n));
BOOST_CHECK(!ParseUInt64Hex("-1", &n));
BOOST_CHECK(!ParseUInt64Hex("10 00", &n));
BOOST_CHECK(!ParseUInt64Hex("1 ", &n));
BOOST_CHECK(!ParseUInt64Hex("0xAB", &n));
}
BOOST_AUTO_TEST_CASE(test_FormatParagraph)
{
BOOST_CHECK_EQUAL(FormatParagraph("", 79, 0), "");

View file

@ -251,6 +251,24 @@ bool ParseUInt64(std::string_view str, uint64_t* out)
return ParseIntegral<uint64_t>(str, out);
}
bool ParseUInt64Hex(std::string_view str, uint64_t* out)
{
if (str.size() > 8) return false;
if (str.size() < 1) return false;
uint64_t total{0};
auto it = str.begin();
while (it != str.end()) {
auto v = HexDigit(*(it++));
if (v < 0) return false;
total <<= 4;
total |= v;
}
if (out != nullptr) {
*out = total;
}
return true;
}
std::string FormatParagraph(std::string_view in, size_t width, size_t indent)
{
assert(width >= indent);

View file

@ -229,6 +229,14 @@ std::optional<T> ToIntegral(std::string_view str)
*/
[[nodiscard]] bool ParseUInt64(std::string_view str, uint64_t *out);
/**
* Convert hexadecimal string to unsigned 64-bit integer, with 4-bit
* resolution (odd length strings are acceptable without leading "0")
* @returns true if the entire string could be parsed as valid integer,
* false if not, or in case of overflow.
*/
[[nodiscard]] bool ParseUInt64Hex(std::string_view str, uint64_t *out);
/**
* Format a paragraph of text to a fixed width, adding spaces for
* indentation to any added line.