mirror of
https://github.com/espressif/openthread.git
synced 2026-08-11 05:07:47 +00:00
[string] add ParseDigit(), ParseHexDigit(), and other helper functions (#10282)
This commit adds a set of helper functions to parse a given digit or hex digit character to its numeric value, or to check if a given character is a digit, uppercase, or lowercase letter.
This commit is contained in:
@@ -202,13 +202,15 @@ Error StringParseUint8(const char *&aString, uint8_t &aUint8, uint8_t aMaxValue)
|
||||
Error error = kErrorParse;
|
||||
const char *cur = aString;
|
||||
uint16_t value = 0;
|
||||
uint8_t digit;
|
||||
|
||||
for (; (*cur >= '0') && (*cur <= '9'); cur++)
|
||||
while (ParseDigit(*cur, digit) == kErrorNone)
|
||||
{
|
||||
value *= 10;
|
||||
value += static_cast<uint8_t>(*cur - '0');
|
||||
value += digit;
|
||||
VerifyOrExit(value <= aMaxValue, error = kErrorParse);
|
||||
error = kErrorNone;
|
||||
cur++;
|
||||
}
|
||||
|
||||
aString = cur;
|
||||
@@ -236,7 +238,7 @@ void StringConvertToUppercase(char *aString)
|
||||
|
||||
char ToLowercase(char aChar)
|
||||
{
|
||||
if ((aChar >= 'A') && (aChar <= 'Z'))
|
||||
if (IsUppercase(aChar))
|
||||
{
|
||||
aChar += 'a' - 'A';
|
||||
}
|
||||
@@ -246,7 +248,7 @@ char ToLowercase(char aChar)
|
||||
|
||||
char ToUppercase(char aChar)
|
||||
{
|
||||
if ((aChar >= 'a') && (aChar <= 'z'))
|
||||
if (IsLowercase(aChar))
|
||||
{
|
||||
aChar -= 'a' - 'A';
|
||||
}
|
||||
@@ -254,6 +256,43 @@ char ToUppercase(char aChar)
|
||||
return aChar;
|
||||
}
|
||||
|
||||
bool IsDigit(char aChar) { return ('0' <= aChar && aChar <= '9'); }
|
||||
|
||||
bool IsUppercase(char aChar) { return ('A' <= aChar && aChar <= 'Z'); }
|
||||
|
||||
bool IsLowercase(char aChar) { return ('a' <= aChar && aChar <= 'z'); }
|
||||
|
||||
Error ParseDigit(char aDigitChar, uint8_t &aValue)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(IsDigit(aDigitChar), error = kErrorInvalidArgs);
|
||||
aValue = static_cast<uint8_t>(aDigitChar - '0');
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error ParseHexDigit(char aHexChar, uint8_t &aValue)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
if (('A' <= aHexChar) && (aHexChar <= 'F'))
|
||||
{
|
||||
ExitNow(aValue = static_cast<uint8_t>(aHexChar - 'A' + 10));
|
||||
}
|
||||
|
||||
if (('a' <= aHexChar) && (aHexChar <= 'f'))
|
||||
{
|
||||
ExitNow(aValue = static_cast<uint8_t>(aHexChar - 'a' + 10));
|
||||
}
|
||||
|
||||
error = ParseDigit(aHexChar, aValue);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
const char *ToYesNo(bool aBool)
|
||||
{
|
||||
static const char *const kYesNoStrings[] = {"no", "yes"};
|
||||
|
||||
@@ -282,6 +282,63 @@ char ToLowercase(char aChar);
|
||||
*/
|
||||
char ToUppercase(char aChar);
|
||||
|
||||
/**
|
||||
* Checks whether a given character is an uppercase letter ('A'-'Z').
|
||||
*
|
||||
* @param[in] aChar The character to check.
|
||||
*
|
||||
* @retval TRUE @p aChar is an uppercase letter.
|
||||
* @retval FALSE @p aChar is not an uppercase letter.
|
||||
*
|
||||
*/
|
||||
bool IsUppercase(char aChar);
|
||||
|
||||
/**
|
||||
* Checks whether a given character is a lowercase letter ('a'-'z').
|
||||
*
|
||||
* @param[in] aChar The character to check.
|
||||
*
|
||||
* @retval TRUE @p aChar is a lowercase letter.
|
||||
* @retval FALSE @p aChar is not a lowercase letter.
|
||||
*
|
||||
*/
|
||||
bool IsLowercase(char aChar);
|
||||
|
||||
/**
|
||||
* Checks whether a given character is a digit character ('0'-'9').
|
||||
*
|
||||
* @param[in] aChar The character to check.
|
||||
*
|
||||
* @retval TRUE @p aChar is a digit character.
|
||||
* @retval FALSE @p aChar is not a digit character.
|
||||
*
|
||||
*/
|
||||
bool IsDigit(char aChar);
|
||||
|
||||
/**
|
||||
* Parse a given digit character to its numeric value.
|
||||
*
|
||||
* @param[in] aDigitChar The digit character to parse.
|
||||
* @param[out] aValue A reference to return the parsed value on success.
|
||||
*
|
||||
* @retval kErrorNone Successfully parsed the digit, @p aValue is updated.
|
||||
* @retval kErrorInvalidArgs @p aDigitChar is not a valid digit character.
|
||||
*
|
||||
*/
|
||||
Error ParseDigit(char aDigitChar, uint8_t &aValue);
|
||||
|
||||
/**
|
||||
* Parse a given hex digit character ('0'-'9', 'A'-'F', or 'a'-'f') to its numeric value.
|
||||
*
|
||||
* @param[in] aHexChar The hex digit character to parse.
|
||||
* @param[out] aValue A reference to return the parsed value on success.
|
||||
*
|
||||
* @retval kErrorNone Successfully parsed the digit, @p aValue is updated.
|
||||
* @retval kErrorInvalidArgs @p aHexChar is not a valid hex digit character.
|
||||
*
|
||||
*/
|
||||
Error ParseHexDigit(char aHexChar, uint8_t &aValue);
|
||||
|
||||
/**
|
||||
* Coverts a boolean to "yes" or "no" string.
|
||||
*
|
||||
|
||||
@@ -95,7 +95,7 @@ bool JoinerPskd::IsPskdValid(const char *aPskdString)
|
||||
{
|
||||
char c = aPskdString[i];
|
||||
|
||||
VerifyOrExit(isdigit(c) || isupper(c));
|
||||
VerifyOrExit(IsDigit(c) || IsUppercase(c));
|
||||
VerifyOrExit(c != 'I' && c != 'O' && c != 'Q' && c != 'Z');
|
||||
}
|
||||
|
||||
|
||||
@@ -586,22 +586,9 @@ Error Address::ParseFrom(const char *aString, char aTerminatorChar)
|
||||
|
||||
while (true)
|
||||
{
|
||||
char c = *aString;
|
||||
uint8_t digit;
|
||||
|
||||
if (('A' <= c) && (c <= 'F'))
|
||||
{
|
||||
digit = static_cast<uint8_t>(c - 'A' + 10);
|
||||
}
|
||||
else if (('a' <= c) && (c <= 'f'))
|
||||
{
|
||||
digit = static_cast<uint8_t>(c - 'a' + 10);
|
||||
}
|
||||
else if (('0' <= c) && (c <= '9'))
|
||||
{
|
||||
digit = static_cast<uint8_t>(c - '0');
|
||||
}
|
||||
else
|
||||
if (ParseHexDigit(*aString, digit) != kErrorNone)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -48,37 +48,6 @@ static bool IsSeparator(char aChar) { return (aChar == ' ') || (aChar == '\t') |
|
||||
|
||||
static bool IsEscapable(char aChar) { return IsSeparator(aChar) || (aChar == '\\'); }
|
||||
|
||||
static Error ParseDigit(char aDigitChar, uint8_t &aValue)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(('0' <= aDigitChar) && (aDigitChar <= '9'), error = kErrorInvalidArgs);
|
||||
aValue = static_cast<uint8_t>(aDigitChar - '0');
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
static Error ParseHexDigit(char aHexChar, uint8_t &aValue)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
if (('A' <= aHexChar) && (aHexChar <= 'F'))
|
||||
{
|
||||
ExitNow(aValue = static_cast<uint8_t>(aHexChar - 'A' + 10));
|
||||
}
|
||||
|
||||
if (('a' <= aHexChar) && (aHexChar <= 'f'))
|
||||
{
|
||||
ExitNow(aValue = static_cast<uint8_t>(aHexChar - 'a' + 10));
|
||||
}
|
||||
|
||||
error = ParseDigit(aHexChar, aValue);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error ParseCmd(char *aCommandString, Arg aArgs[], uint8_t aArgsMaxLength)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
@@ -337,6 +337,8 @@ void TestStringParseUint8(void)
|
||||
{"0256", kErrorParse}, // Larger than max `uint8_t`
|
||||
};
|
||||
|
||||
uint8_t digit;
|
||||
|
||||
printf("\nTest 11: TestStringParseUint8() function\n");
|
||||
|
||||
for (const TestCase &testCase : kTestCases)
|
||||
@@ -363,6 +365,64 @@ void TestStringParseUint8(void)
|
||||
}
|
||||
}
|
||||
|
||||
for (char c = '0'; c <= '9'; c++)
|
||||
{
|
||||
VerifyOrQuit(IsDigit(c));
|
||||
VerifyOrQuit(!IsUppercase(c));
|
||||
VerifyOrQuit(!IsLowercase(c));
|
||||
|
||||
SuccessOrQuit(ParseDigit(c, digit));
|
||||
VerifyOrQuit(digit == (c - '0'));
|
||||
|
||||
SuccessOrQuit(ParseHexDigit(c, digit));
|
||||
VerifyOrQuit(digit == (c - '0'));
|
||||
}
|
||||
|
||||
for (char c = 'A'; c <= 'Z'; c++)
|
||||
{
|
||||
VerifyOrQuit(!IsDigit(c));
|
||||
VerifyOrQuit(IsUppercase(c));
|
||||
VerifyOrQuit(!IsLowercase(c));
|
||||
VerifyOrQuit(ParseDigit(c, digit) != kErrorNone);
|
||||
|
||||
if (c <= 'F')
|
||||
{
|
||||
SuccessOrQuit(ParseHexDigit(c, digit));
|
||||
VerifyOrQuit(digit == (c - 'A' + 10));
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrQuit(ParseHexDigit(c, digit) != kErrorNone);
|
||||
}
|
||||
}
|
||||
|
||||
for (char c = 'a'; c <= 'z'; c++)
|
||||
{
|
||||
VerifyOrQuit(!IsDigit(c));
|
||||
VerifyOrQuit(!IsUppercase(c));
|
||||
VerifyOrQuit(IsLowercase(c));
|
||||
VerifyOrQuit(ParseDigit(c, digit) != kErrorNone);
|
||||
|
||||
if (c <= 'f')
|
||||
{
|
||||
SuccessOrQuit(ParseHexDigit(c, digit));
|
||||
VerifyOrQuit(digit == (c - 'a' + 10));
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrQuit(ParseHexDigit(c, digit) != kErrorNone);
|
||||
}
|
||||
}
|
||||
|
||||
VerifyOrQuit(!IsDigit(static_cast<char>('0' - 1)));
|
||||
VerifyOrQuit(!IsDigit(static_cast<char>('9' + 1)));
|
||||
|
||||
VerifyOrQuit(!IsUppercase(static_cast<char>('A' - 1)));
|
||||
VerifyOrQuit(!IsUppercase(static_cast<char>('Z' + 1)));
|
||||
|
||||
VerifyOrQuit(!IsLowercase(static_cast<char>('a' - 1)));
|
||||
VerifyOrQuit(!IsLowercase(static_cast<char>('z' + 1)));
|
||||
|
||||
printf("\n\n -- PASS\n");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user