Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 30 additions & 12 deletions common/utils/StringUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,16 @@ bool StringToBoolTolerant(const string &value, bool *output) {
return false;
}

bool StringToInt(const string &value, unsigned int *output, bool strict) {
bool StringToInt(const string &value,
unsigned int *output,
bool strict,
uint8_t base) {
if (value.empty()) {
return false;
}
char *end_ptr;
errno = 0;
long long l = strtoll(value.data(), &end_ptr, 10); // NOLINT(runtime/int)
long long l = strtoll(value.data(), &end_ptr, base); // NOLINT(runtime/int)
if (l < 0 || (l == 0 && errno != 0)) {
return false;
}
Expand All @@ -175,9 +178,12 @@ bool StringToInt(const string &value, unsigned int *output, bool strict) {
return true;
}

bool StringToInt(const string &value, uint16_t *output, bool strict) {
bool StringToInt(const string &value,
uint16_t *output,
bool strict,
uint8_t base) {
unsigned int v;
if (!StringToInt(value, &v, strict)) {
if (!StringToInt(value, &v, strict, base)) {
return false;
}
if (v > UINT16_MAX) {
Expand All @@ -187,9 +193,12 @@ bool StringToInt(const string &value, uint16_t *output, bool strict) {
return true;
}

bool StringToInt(const string &value, uint8_t *output, bool strict) {
bool StringToInt(const string &value,
uint8_t *output,
bool strict,
uint8_t base) {
unsigned int v;
if (!StringToInt(value, &v, strict)) {
if (!StringToInt(value, &v, strict, base)) {
return false;
}
if (v > UINT8_MAX) {
Expand All @@ -199,13 +208,16 @@ bool StringToInt(const string &value, uint8_t *output, bool strict) {
return true;
}

bool StringToInt(const string &value, int *output, bool strict) {
bool StringToInt(const string &value,
int *output,
bool strict,
uint8_t base) {
if (value.empty()) {
return false;
}
char *end_ptr;
errno = 0;
long long l = strtoll(value.data(), &end_ptr, 10); // NOLINT(runtime/int)
long long l = strtoll(value.data(), &end_ptr, base); // NOLINT(runtime/int)
if (l == 0 && errno != 0) {
return false;
}
Expand All @@ -222,9 +234,12 @@ bool StringToInt(const string &value, int *output, bool strict) {
return true;
}

bool StringToInt(const string &value, int16_t *output, bool strict) {
bool StringToInt(const string &value,
int16_t *output,
bool strict,
uint8_t base) {
int v;
if (!StringToInt(value, &v, strict)) {
if (!StringToInt(value, &v, strict, base)) {
return false;
}
if (v < INT16_MIN || v > INT16_MAX) {
Expand All @@ -234,9 +249,12 @@ bool StringToInt(const string &value, int16_t *output, bool strict) {
return true;
}

bool StringToInt(const string &value, int8_t *output, bool strict) {
bool StringToInt(const string &value,
int8_t *output,
bool strict,
uint8_t base) {
int v;
if (!StringToInt(value, &v, strict)) {
if (!StringToInt(value, &v, strict, base)) {
return false;
}
if (v < INT8_MIN || v > INT8_MAX) {
Expand Down
27 changes: 26 additions & 1 deletion common/utils/StringUtilsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ void StringUtilsTest::testStringToBoolTolerant() {


void StringUtilsTest::testStringToUInt() {
unsigned int value;
unsigned int value, value2;
OLA_ASSERT_FALSE(StringToInt("", &value));
OLA_ASSERT_FALSE(StringToInt("-1", &value));
OLA_ASSERT_TRUE(StringToInt("0", &value));
Expand All @@ -561,6 +561,31 @@ void StringUtilsTest::testStringToUInt() {
OLA_ASSERT_FALSE(StringToInt("1 bar baz", &value, true));
OLA_ASSERT_FALSE(StringToInt("65537cat", &value, true));
OLA_ASSERT_FALSE(StringToInt("4294967295bat bar", &value, true));

// Base8 test
OLA_ASSERT_TRUE(StringToInt("377", &value, false, 8));
OLA_ASSERT_EQ(value, 255u);

OLA_ASSERT_FALSE(StringToInt("999", &value, false, 8));

// Base16 test
OLA_ASSERT_TRUE(StringToInt("ff00", &value, false, 16));
OLA_ASSERT_EQ(value, 65280u);

OLA_ASSERT_FALSE(StringToInt("gg00", &value, false, 16));

// Base36 test
OLA_ASSERT_TRUE(StringToInt("12FZ9A", &value, false, 36));
OLA_ASSERT_TRUE(StringToInt("12fz9a", &value2, false, 36));
OLA_ASSERT_EQ(value, value2);
OLA_ASSERT_EQ(value, 64570942u);

OLA_ASSERT_TRUE(StringToInt("STRIC7", &value, true, 36));
OLA_ASSERT_TRUE(StringToInt("stric7", &value2, true, 36));
OLA_ASSERT_EQ(value, value2);
OLA_ASSERT_EQ(value, 1743045271u);

OLA_ASSERT_FALSE(StringToInt("STRICT1", &value, true, 36));
}

void StringUtilsTest::testStringToUIntOrDefault() {
Expand Down
34 changes: 26 additions & 8 deletions include/ola/StringUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,89 +262,107 @@ bool StringToBoolTolerant(const std::string &value, bool *output);
* @param[in] value the string to convert
* @param[out] output a pointer where the value will be stored.
* @param[in] strict this controls if trailing characters produce an error.
* @param[in] base the base of the number being read
* @returns true if the value was converted, false if the string was not an int
* or the value was too large / small for the type.
*/
bool StringToInt(const std::string &value,
unsigned int *output,
bool strict = false);
bool strict = false,
uint8_t base = 10);

/**
* @brief Convert a string to a uint16_t.
* @param[in] value the string to convert
* @param[out] output a pointer where the value will be stored.
* @param[in] strict this controls if trailing characters produce an error.
* @param[in] base the base of the number being read
* @returns true if the value was converted, false if the string was not an int
* or the value was too large / small for the type.
* @sa StringToInt.
*/
bool StringToInt(const std::string &value,
uint16_t *output,
bool strict = false);
bool strict = false,
uint8_t base = 10);

/**
* @brief Convert a string to a uint8_t.
* @param[in] value the string to convert
* @param[out] output a pointer where the value will be stored.
* @param[in] strict this controls if trailing characters produce an error.
* @param[in] base the base of the number being read
* @returns true if the value was converted, false if the string was not an int
* or the value was too large / small for the type.
* @sa StringToInt.
*/
bool StringToInt(const std::string &value,
uint8_t *output,
bool strict = false);
bool strict = false,
uint8_t base = 10);

/**
* @brief Convert a string to a int.
* @param[in] value the string to convert
* @param[out] output a pointer where the value will be stored.
* @param[in] strict this controls if trailing characters produce an error.
* @param[in] base the base of the number being read
* @returns true if the value was converted, false if the string was not an int
* or the value was too large / small for the type.
* @sa StringToInt.
*/
bool StringToInt(const std::string &value, int *output, bool strict = false);
bool StringToInt(const std::string &value,
int *output,
bool strict = false,
uint8_t base = 10);

/**
* @brief Convert a string to a int16_t.
* @param[in] value the string to convert
* @param[out] output a pointer where the value will be stored.
* @param[in] strict this controls if trailing characters produce an error.
* @param[in] base the base of the number being read
* @returns true if the value was converted, false if the string was not an int
* or the value was too large / small for the type.
* @sa StringToInt.
*/
bool StringToInt(const std::string &value,
int16_t *output,
bool strict = false);
bool strict = false,
uint8_t base = 10);

/**
* @brief Convert a string to a int8_t.
* @param[in] value the string to convert
* @param[out] output a pointer where the value will be stored.
* @param[in] strict this controls if trailing characters produce an error.
* @param[in] base the base of the number being read
* @returns true if the value was converted, false if the string was not an int
* or the value was too large / small for the type.
* @sa StringToInt.
*/
bool StringToInt(const std::string &value, int8_t *output, bool strict = false);
bool StringToInt(const std::string &value,
int8_t *output,
bool strict = false,
uint8_t base = 10);

/**
* @brief Convert a string to an int type or return a default if it failed.
* @tparam int_type the type to convert to
* @param value the string to convert
* @param alternative the default value to return if conversion failed.
* @param[in] strict this controls if trailing characters produce an error.
* @param[in] base the base of the number being read
* @returns the value if it converted successfully or the default if the string
* was not an int or the value was too large / small for the type.
*/
template <typename int_type>
int_type StringToIntOrDefault(const std::string &value,
int_type alternative,
bool strict = false) {
bool strict = false,
uint8_t base = 10) {
int_type output;
return (StringToInt(value, &output, strict)) ? output : alternative;
return (StringToInt(value, &output, strict, base)) ? output : alternative;
}

/**
Expand Down