mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-19 17:48:33 -04:00
Update Reliance Edge fail safe file system to the latest version.
This commit is contained in:
parent
8d041c8e21
commit
67def3c14b
30 changed files with 5877 additions and 5544 deletions
|
@ -1,478 +1,478 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements utilities that convert strings to numbers.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
#include <redtestutils.h>
|
||||
|
||||
|
||||
#define ISHEXDIGITU(c) (((c) >= 'A') && ((c) <= 'F'))
|
||||
#define ISHEXDIGITL(c) (((c) >= 'a') && ((c) <= 'f'))
|
||||
#define ISHEXDIGIT(c) (ISHEXDIGITL(c) || ISHEXDIGITU(c))
|
||||
|
||||
|
||||
/** @brief Converts an ASCII number into an int32_t.
|
||||
|
||||
Converts all decimal digit numbers up to the end of the string or to the
|
||||
first non-numerical character.
|
||||
|
||||
@note This function does *not* ignore leading white space.
|
||||
|
||||
@param pszNum Pointer to a constant array of characters.
|
||||
|
||||
@return The integer represented in the string.
|
||||
*/
|
||||
int32_t RedAtoI(
|
||||
const char *pszNum)
|
||||
{
|
||||
int32_t lValue = 0;
|
||||
int32_t lNegative = 1;
|
||||
uint32_t ulIdx = 0U;
|
||||
|
||||
if(pszNum[ulIdx] == '+')
|
||||
{
|
||||
ulIdx++;
|
||||
}
|
||||
else if(pszNum[ulIdx] == '-')
|
||||
{
|
||||
ulIdx++;
|
||||
lNegative = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No sign, implicitly positive.
|
||||
*/
|
||||
}
|
||||
|
||||
while(ISDIGIT(pszNum[ulIdx]))
|
||||
{
|
||||
lValue *= 10;
|
||||
lValue += pszNum[ulIdx] - '0';
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
lValue *= lNegative;
|
||||
|
||||
return lValue;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Convert a hexadecimal ASCII number into a uint32_t value.
|
||||
|
||||
The function processes all hex digits up to a NUL-terminator, or to the
|
||||
first non-hex character. Only hexadecimal digits are processed, so leading
|
||||
white space, or a leading "0x" prefix are not allowed.
|
||||
|
||||
If pachNum points to an empty string (points to a NUL), this function will
|
||||
return NULL, and the value at *pulNum will not be modified.
|
||||
|
||||
@note This function does not check for overflow. If there are more
|
||||
significant digits than can be represented in a uint32_t variable, the
|
||||
output is unspecified.
|
||||
|
||||
@param pachNum A pointer to a constant array of hex characters.
|
||||
@param pulNum A pointer to the location in which to store the uint32_t
|
||||
result. Upon return, this value will be modified ONLY if
|
||||
the function succeeds and the returned pointer is valid (not
|
||||
NULL).
|
||||
|
||||
@return A pointer to the byte following the converted number or NULL to
|
||||
indicate failure.
|
||||
*/
|
||||
const char *RedHtoUL(
|
||||
const char *pszNum,
|
||||
uint32_t *pulNum)
|
||||
{
|
||||
uint64_t ullValue;
|
||||
const char *pszReturn;
|
||||
|
||||
pszReturn = RedHtoULL(pszNum, &ullValue);
|
||||
if(pszReturn != NULL)
|
||||
{
|
||||
if(ullValue < UINT32_MAX)
|
||||
{
|
||||
*pulNum = (uint32_t)ullValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pszReturn;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Convert a hexadecimal ASCII number into a D_UINT64 value.
|
||||
|
||||
The function processes all hex digits up to a NUL-terminator, or to the
|
||||
first non-hex character. Only hexadecimal digits are processed, so leading
|
||||
white space, or a leading "0x" prefix are not allowed.
|
||||
|
||||
If pachNum points to an empty string (points to a NUL), this function will
|
||||
return NULL, and the value at *pulNum will not be modified.
|
||||
|
||||
@note This function does not check for overflow. If there are more
|
||||
significant digits than can be represented in a uint64_t variable, the
|
||||
output is unspecified.
|
||||
|
||||
@param pszNum A pointer to a constant array of hex characters.
|
||||
@param pullNum A pointer to the location in which to store the uint64_t
|
||||
result. Upon return, this value will be modified ONLY if
|
||||
the function succeeds and the returned pointer is valid (not
|
||||
NULL).
|
||||
|
||||
@return A pointer to the byte following the converted number, or NULL to
|
||||
indicate failure.
|
||||
*/
|
||||
const char *RedHtoULL(
|
||||
const char *pszNum,
|
||||
uint64_t *pullNum)
|
||||
{
|
||||
uint64_t ullValue = 0U;
|
||||
const char *pszReturn = NULL;
|
||||
uint32_t ulIdx = 0U;
|
||||
|
||||
REDASSERT(pszNum != NULL);
|
||||
REDASSERT(pullNum != NULL);
|
||||
|
||||
while(pszNum[ulIdx] != '\0')
|
||||
{
|
||||
char cDigit = pszNum[ulIdx];
|
||||
|
||||
if(ISDIGIT(cDigit))
|
||||
{
|
||||
cDigit -= '0';
|
||||
}
|
||||
else if(ISHEXDIGITU(cDigit))
|
||||
{
|
||||
cDigit -= ('A' - 10);
|
||||
}
|
||||
else if(ISHEXDIGITL(cDigit))
|
||||
{
|
||||
cDigit -= ('a' - 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
REDASSERT((ullValue & UINT64_SUFFIX(0xF000000000000000)) == 0U);
|
||||
|
||||
ullValue <<= 4U;
|
||||
ullValue += cDigit;
|
||||
|
||||
ulIdx++;
|
||||
pszReturn = &pszNum[ulIdx];
|
||||
}
|
||||
|
||||
/* Modify the number returned only if we found one or more valid hex
|
||||
digits.
|
||||
*/
|
||||
if(pszReturn != NULL)
|
||||
{
|
||||
*pullNum = ullValue;
|
||||
}
|
||||
|
||||
return pszReturn;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Convert the ASCII number to a uint32_t value.
|
||||
|
||||
The number may be hex or decimal. Hex numbers must be prefixed by '0x', and
|
||||
they may be upper or lower case. The conversion process will stop with the
|
||||
first non hex or decimal digit.
|
||||
|
||||
If the number is negative (the first character is a '-' sign), the value
|
||||
will be range checked and returned as the equivalent unsigned value.
|
||||
|
||||
@note This function will NOT fail for numbers which exceed the size of a
|
||||
uint32_t value.
|
||||
|
||||
@param pszNum A pointer to the ASCII number to convert
|
||||
@param pulNum A pointer to the uint32_t location to store the result.
|
||||
This value will be modified on return only if the function
|
||||
succeeds and the returned pointer is valid (not NULL).
|
||||
|
||||
@return A pointer to the byte following the converted number, or NULL to
|
||||
indicate failure.
|
||||
*/
|
||||
const char *RedNtoUL(
|
||||
const char *pszNum,
|
||||
uint32_t *pulNum)
|
||||
{
|
||||
bool fNegative = false;
|
||||
uint32_t ulIdx = 0U;
|
||||
const char *pszReturn;
|
||||
|
||||
REDASSERT(pszNum != NULL);
|
||||
REDASSERT(pulNum != NULL);
|
||||
|
||||
if(pszNum[ulIdx] == '-')
|
||||
{
|
||||
fNegative = true;
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
/* Hex numbers must be prefixed with '0x'.
|
||||
*/
|
||||
if((pszNum[ulIdx] == '0') && ((pszNum[ulIdx + 1U] == 'x') || (pszNum[ulIdx + 1U] == 'X')))
|
||||
{
|
||||
ulIdx += 2U;
|
||||
|
||||
if(ISDIGIT(pszNum[ulIdx]) || ISHEXDIGIT(pszNum[ulIdx]))
|
||||
{
|
||||
pszReturn = RedHtoUL(&pszNum[ulIdx], pulNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
}
|
||||
else if(ISDIGIT(pszNum[ulIdx]))
|
||||
{
|
||||
uint32_t ulTemp;
|
||||
|
||||
ulTemp = RedAtoI(&pszNum[ulIdx]);
|
||||
|
||||
while(ISDIGIT(pszNum[ulIdx]))
|
||||
{
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
if(fNegative)
|
||||
{
|
||||
/* Fail if the number is out of range.
|
||||
*/
|
||||
if(ulTemp > INT32_MAX)
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulNum = -((int32_t)ulTemp);
|
||||
pszReturn = &pszNum[ulIdx];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulNum = ulTemp;
|
||||
pszReturn = &pszNum[ulIdx];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return an error if there is not at least one hex or decimal digit.
|
||||
*/
|
||||
pszReturn = NULL;
|
||||
}
|
||||
|
||||
return pszReturn;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Convert the ASCII number pointed to by pachNum to a uint64_t value.
|
||||
|
||||
The number may be hex or decimal. Hex numbers must be prefixed by '0x', and
|
||||
they may be upper or lower case. The conversion process will stop with the
|
||||
first non hex or decimal digit.
|
||||
|
||||
If the number is negative (the first character is a '-' sign), the value
|
||||
will be range checked and returned as the equivalent unsigned value.
|
||||
|
||||
@param pszNum A pointer to the ASCII number to convert.
|
||||
@param pullNum A pointer to the uint64_t location to store the result.
|
||||
This value will be modified on return only if the function
|
||||
succeeds and the returned pointer is valid (not NULL).
|
||||
|
||||
@return A pointer to the byte following the converted number, or NULL to
|
||||
indicate failure.
|
||||
*/
|
||||
const char *RedNtoULL(
|
||||
const char *pszNum,
|
||||
uint64_t *pullNum)
|
||||
{
|
||||
bool fNegative = false;
|
||||
uint32_t ulIdx = 0U;
|
||||
const char *pszReturn;
|
||||
|
||||
REDASSERT(pszNum != NULL);
|
||||
REDASSERT(pullNum != NULL);
|
||||
|
||||
if(pszNum[ulIdx] == '-')
|
||||
{
|
||||
fNegative = true;
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
/* Hex numbers must be prefixed with '0x'.
|
||||
*/
|
||||
if((pszNum[ulIdx] == '0') && ((pszNum[ulIdx + 1U] == 'x') || (pszNum[ulIdx + 1U] == 'X')))
|
||||
{
|
||||
ulIdx += 2U;
|
||||
|
||||
if(ISDIGIT(pszNum[ulIdx]) || ISHEXDIGIT(pszNum[ulIdx]))
|
||||
{
|
||||
pszReturn = RedHtoULL(&pszNum[ulIdx], pullNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
}
|
||||
else if(ISDIGIT(pszNum[ulIdx]))
|
||||
{
|
||||
uint64_t ullTemp = 0U;
|
||||
|
||||
while(ISDIGIT(pszNum[ulIdx]))
|
||||
{
|
||||
ullTemp *= 10U;
|
||||
ullTemp += pszNum[ulIdx] - '0';
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
if(fNegative)
|
||||
{
|
||||
/* Fail if the number is out of range.
|
||||
*/
|
||||
if(ullTemp > INT64_MAX)
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pullNum = (uint64_t)(-((int64_t)ullTemp));
|
||||
pszReturn = &pszNum[ulIdx];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*pullNum = ullTemp;
|
||||
pszReturn = &pszNum[ulIdx];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return an error if there is not at least one hex or decimal digit.
|
||||
*/
|
||||
pszReturn = NULL;
|
||||
}
|
||||
|
||||
return pszReturn;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Convert an ASCII hex or decimal number, which may may have a "B",
|
||||
"KB", or "MB" suffix (case insensitive), to a binary value.
|
||||
|
||||
Hex numbers must be prefixed with "0x".
|
||||
|
||||
@note If there is no postfix, KB is assumed!
|
||||
|
||||
May fail due to bad formatting or overflow.
|
||||
|
||||
@param pszNum A pointer to the ASCII number to convert.
|
||||
@param pulResult A pointer to a uint32_t in which to place the result.
|
||||
|
||||
@return A pointer to the byte following the string, or NULL to indicate an
|
||||
error. In the event of an error, *pulResult will not be modified.
|
||||
*/
|
||||
const char *RedSizeToUL(
|
||||
const char *pszNum,
|
||||
uint32_t *pulResult)
|
||||
{
|
||||
uint32_t ulResult;
|
||||
const char *pszSuffix;
|
||||
const char *pszReturn;
|
||||
uint32_t ulIdx = 0U;
|
||||
|
||||
REDASSERT(pszNum != NULL);
|
||||
REDASSERT(pulResult != NULL);
|
||||
|
||||
/* Do the basic hex/decimal conversion
|
||||
*/
|
||||
pszSuffix = RedNtoUL(pszNum, &ulResult);
|
||||
if(pszSuffix != NULL)
|
||||
{
|
||||
if((pszSuffix[ulIdx] == 'B') || (pszSuffix[ulIdx] == 'b'))
|
||||
{
|
||||
ulIdx++;
|
||||
pszReturn = &pszSuffix[ulIdx];
|
||||
}
|
||||
else if( ((pszSuffix[ulIdx] == 'M') || (pszSuffix[ulIdx] == 'm'))
|
||||
&& ((pszSuffix[ulIdx + 1U] == 'B') || (pszSuffix[ulIdx + 1U] == 'b')))
|
||||
{
|
||||
ulIdx += 2U;
|
||||
|
||||
if(ulResult > (UINT32_MAX / (1024U * 1024U)))
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulResult *= 1024U * 1024U;
|
||||
pszReturn = &pszSuffix[ulIdx];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The number is either postfixed with "KB" or something
|
||||
else (we don't care), but we must increment the pointer
|
||||
if it is something recognize.
|
||||
*/
|
||||
if( ((pszSuffix[ulIdx] == 'K') || (pszSuffix[ulIdx] == 'k'))
|
||||
&& ((pszSuffix[ulIdx + 1U] == 'B') || (pszSuffix[ulIdx + 1U] == 'b')))
|
||||
{
|
||||
ulIdx += 2U;
|
||||
}
|
||||
|
||||
/* "B" or "MB" were not specified, so it must be "KB"
|
||||
*/
|
||||
if(ulResult > (UINT32_MAX / 1024U))
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulResult *= 1024UL;
|
||||
pszReturn = &pszSuffix[ulIdx];
|
||||
}
|
||||
}
|
||||
|
||||
if(pszReturn != NULL)
|
||||
{
|
||||
*pulResult = ulResult;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
|
||||
return pszReturn;
|
||||
}
|
||||
|
||||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements utilities that convert strings to numbers.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
#include <redtestutils.h>
|
||||
|
||||
|
||||
#define ISHEXDIGITU(c) (((c) >= 'A') && ((c) <= 'F'))
|
||||
#define ISHEXDIGITL(c) (((c) >= 'a') && ((c) <= 'f'))
|
||||
#define ISHEXDIGIT(c) (ISHEXDIGITL(c) || ISHEXDIGITU(c))
|
||||
|
||||
|
||||
/** @brief Converts an ASCII number into an int32_t.
|
||||
|
||||
Converts all decimal digit numbers up to the end of the string or to the
|
||||
first non-numerical character.
|
||||
|
||||
@note This function does *not* ignore leading white space.
|
||||
|
||||
@param pszNum Pointer to a constant array of characters.
|
||||
|
||||
@return The integer represented in the string.
|
||||
*/
|
||||
int32_t RedAtoI(
|
||||
const char *pszNum)
|
||||
{
|
||||
int32_t lValue = 0;
|
||||
int32_t lNegative = 1;
|
||||
uint32_t ulIdx = 0U;
|
||||
|
||||
if(pszNum[ulIdx] == '+')
|
||||
{
|
||||
ulIdx++;
|
||||
}
|
||||
else if(pszNum[ulIdx] == '-')
|
||||
{
|
||||
ulIdx++;
|
||||
lNegative = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No sign, implicitly positive.
|
||||
*/
|
||||
}
|
||||
|
||||
while(ISDIGIT(pszNum[ulIdx]))
|
||||
{
|
||||
lValue *= 10;
|
||||
lValue += pszNum[ulIdx] - '0';
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
lValue *= lNegative;
|
||||
|
||||
return lValue;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Convert a hexadecimal ASCII number into a uint32_t value.
|
||||
|
||||
The function processes all hex digits up to a NUL-terminator, or to the
|
||||
first non-hex character. Only hexadecimal digits are processed, so leading
|
||||
white space, or a leading "0x" prefix are not allowed.
|
||||
|
||||
If pachNum points to an empty string (points to a NUL), this function will
|
||||
return NULL, and the value at *pulNum will not be modified.
|
||||
|
||||
@note This function does not check for overflow. If there are more
|
||||
significant digits than can be represented in a uint32_t variable, the
|
||||
output is unspecified.
|
||||
|
||||
@param pszNum A pointer to a constant array of hex characters.
|
||||
@param pulNum A pointer to the location in which to store the uint32_t
|
||||
result. Upon return, this value will be modified ONLY if
|
||||
the function succeeds and the returned pointer is valid (not
|
||||
NULL).
|
||||
|
||||
@return A pointer to the byte following the converted number or NULL to
|
||||
indicate failure.
|
||||
*/
|
||||
const char *RedHtoUL(
|
||||
const char *pszNum,
|
||||
uint32_t *pulNum)
|
||||
{
|
||||
uint64_t ullValue;
|
||||
const char *pszReturn;
|
||||
|
||||
pszReturn = RedHtoULL(pszNum, &ullValue);
|
||||
if(pszReturn != NULL)
|
||||
{
|
||||
if(ullValue < UINT32_MAX)
|
||||
{
|
||||
*pulNum = (uint32_t)ullValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pszReturn;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Convert a hexadecimal ASCII number into a D_UINT64 value.
|
||||
|
||||
The function processes all hex digits up to a NUL-terminator, or to the
|
||||
first non-hex character. Only hexadecimal digits are processed, so leading
|
||||
white space, or a leading "0x" prefix are not allowed.
|
||||
|
||||
If pachNum points to an empty string (points to a NUL), this function will
|
||||
return NULL, and the value at *pulNum will not be modified.
|
||||
|
||||
@note This function does not check for overflow. If there are more
|
||||
significant digits than can be represented in a uint64_t variable, the
|
||||
output is unspecified.
|
||||
|
||||
@param pszNum A pointer to a constant array of hex characters.
|
||||
@param pullNum A pointer to the location in which to store the uint64_t
|
||||
result. Upon return, this value will be modified ONLY if
|
||||
the function succeeds and the returned pointer is valid (not
|
||||
NULL).
|
||||
|
||||
@return A pointer to the byte following the converted number, or NULL to
|
||||
indicate failure.
|
||||
*/
|
||||
const char *RedHtoULL(
|
||||
const char *pszNum,
|
||||
uint64_t *pullNum)
|
||||
{
|
||||
uint64_t ullValue = 0U;
|
||||
const char *pszReturn = NULL;
|
||||
uint32_t ulIdx = 0U;
|
||||
|
||||
REDASSERT(pszNum != NULL);
|
||||
REDASSERT(pullNum != NULL);
|
||||
|
||||
while(pszNum[ulIdx] != '\0')
|
||||
{
|
||||
char cDigit = pszNum[ulIdx];
|
||||
|
||||
if(ISDIGIT(cDigit))
|
||||
{
|
||||
cDigit -= '0';
|
||||
}
|
||||
else if(ISHEXDIGITU(cDigit))
|
||||
{
|
||||
cDigit -= ('A' - 10);
|
||||
}
|
||||
else if(ISHEXDIGITL(cDigit))
|
||||
{
|
||||
cDigit -= ('a' - 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
REDASSERT((ullValue & UINT64_SUFFIX(0xF000000000000000)) == 0U);
|
||||
|
||||
ullValue <<= 4U;
|
||||
ullValue += cDigit;
|
||||
|
||||
ulIdx++;
|
||||
pszReturn = &pszNum[ulIdx];
|
||||
}
|
||||
|
||||
/* Modify the number returned only if we found one or more valid hex
|
||||
digits.
|
||||
*/
|
||||
if(pszReturn != NULL)
|
||||
{
|
||||
*pullNum = ullValue;
|
||||
}
|
||||
|
||||
return pszReturn;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Convert the ASCII number to a uint32_t value.
|
||||
|
||||
The number may be hex or decimal. Hex numbers must be prefixed by '0x', and
|
||||
they may be upper or lower case. The conversion process will stop with the
|
||||
first non hex or decimal digit.
|
||||
|
||||
If the number is negative (the first character is a '-' sign), the value
|
||||
will be range checked and returned as the equivalent unsigned value.
|
||||
|
||||
@note This function will NOT fail for numbers which exceed the size of a
|
||||
uint32_t value.
|
||||
|
||||
@param pszNum A pointer to the ASCII number to convert
|
||||
@param pulNum A pointer to the uint32_t location to store the result.
|
||||
This value will be modified on return only if the function
|
||||
succeeds and the returned pointer is valid (not NULL).
|
||||
|
||||
@return A pointer to the byte following the converted number, or NULL to
|
||||
indicate failure.
|
||||
*/
|
||||
const char *RedNtoUL(
|
||||
const char *pszNum,
|
||||
uint32_t *pulNum)
|
||||
{
|
||||
bool fNegative = false;
|
||||
uint32_t ulIdx = 0U;
|
||||
const char *pszReturn;
|
||||
|
||||
REDASSERT(pszNum != NULL);
|
||||
REDASSERT(pulNum != NULL);
|
||||
|
||||
if(pszNum[ulIdx] == '-')
|
||||
{
|
||||
fNegative = true;
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
/* Hex numbers must be prefixed with '0x'.
|
||||
*/
|
||||
if((pszNum[ulIdx] == '0') && ((pszNum[ulIdx + 1U] == 'x') || (pszNum[ulIdx + 1U] == 'X')))
|
||||
{
|
||||
ulIdx += 2U;
|
||||
|
||||
if(ISDIGIT(pszNum[ulIdx]) || ISHEXDIGIT(pszNum[ulIdx]))
|
||||
{
|
||||
pszReturn = RedHtoUL(&pszNum[ulIdx], pulNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
}
|
||||
else if(ISDIGIT(pszNum[ulIdx]))
|
||||
{
|
||||
uint32_t ulTemp;
|
||||
|
||||
ulTemp = RedAtoI(&pszNum[ulIdx]);
|
||||
|
||||
while(ISDIGIT(pszNum[ulIdx]))
|
||||
{
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
if(fNegative)
|
||||
{
|
||||
/* Fail if the number is out of range.
|
||||
*/
|
||||
if(ulTemp > INT32_MAX)
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulNum = -((int32_t)ulTemp);
|
||||
pszReturn = &pszNum[ulIdx];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulNum = ulTemp;
|
||||
pszReturn = &pszNum[ulIdx];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return an error if there is not at least one hex or decimal digit.
|
||||
*/
|
||||
pszReturn = NULL;
|
||||
}
|
||||
|
||||
return pszReturn;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Convert the ASCII number pointed to by pachNum to a uint64_t value.
|
||||
|
||||
The number may be hex or decimal. Hex numbers must be prefixed by '0x', and
|
||||
they may be upper or lower case. The conversion process will stop with the
|
||||
first non hex or decimal digit.
|
||||
|
||||
If the number is negative (the first character is a '-' sign), the value
|
||||
will be range checked and returned as the equivalent unsigned value.
|
||||
|
||||
@param pszNum A pointer to the ASCII number to convert.
|
||||
@param pullNum A pointer to the uint64_t location to store the result.
|
||||
This value will be modified on return only if the function
|
||||
succeeds and the returned pointer is valid (not NULL).
|
||||
|
||||
@return A pointer to the byte following the converted number, or NULL to
|
||||
indicate failure.
|
||||
*/
|
||||
const char *RedNtoULL(
|
||||
const char *pszNum,
|
||||
uint64_t *pullNum)
|
||||
{
|
||||
bool fNegative = false;
|
||||
uint32_t ulIdx = 0U;
|
||||
const char *pszReturn;
|
||||
|
||||
REDASSERT(pszNum != NULL);
|
||||
REDASSERT(pullNum != NULL);
|
||||
|
||||
if(pszNum[ulIdx] == '-')
|
||||
{
|
||||
fNegative = true;
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
/* Hex numbers must be prefixed with '0x'.
|
||||
*/
|
||||
if((pszNum[ulIdx] == '0') && ((pszNum[ulIdx + 1U] == 'x') || (pszNum[ulIdx + 1U] == 'X')))
|
||||
{
|
||||
ulIdx += 2U;
|
||||
|
||||
if(ISDIGIT(pszNum[ulIdx]) || ISHEXDIGIT(pszNum[ulIdx]))
|
||||
{
|
||||
pszReturn = RedHtoULL(&pszNum[ulIdx], pullNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
}
|
||||
else if(ISDIGIT(pszNum[ulIdx]))
|
||||
{
|
||||
uint64_t ullTemp = 0U;
|
||||
|
||||
while(ISDIGIT(pszNum[ulIdx]))
|
||||
{
|
||||
ullTemp *= 10U;
|
||||
ullTemp += pszNum[ulIdx] - '0';
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
if(fNegative)
|
||||
{
|
||||
/* Fail if the number is out of range.
|
||||
*/
|
||||
if(ullTemp > INT64_MAX)
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pullNum = (uint64_t)(-((int64_t)ullTemp));
|
||||
pszReturn = &pszNum[ulIdx];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*pullNum = ullTemp;
|
||||
pszReturn = &pszNum[ulIdx];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return an error if there is not at least one hex or decimal digit.
|
||||
*/
|
||||
pszReturn = NULL;
|
||||
}
|
||||
|
||||
return pszReturn;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Convert an ASCII hex or decimal number, which may may have a "B",
|
||||
"KB", or "MB" suffix (case insensitive), to a binary value.
|
||||
|
||||
Hex numbers must be prefixed with "0x".
|
||||
|
||||
@note If there is no postfix, KB is assumed!
|
||||
|
||||
May fail due to bad formatting or overflow.
|
||||
|
||||
@param pszNum A pointer to the ASCII number to convert.
|
||||
@param pulResult A pointer to a uint32_t in which to place the result.
|
||||
|
||||
@return A pointer to the byte following the string, or NULL to indicate an
|
||||
error. In the event of an error, *pulResult will not be modified.
|
||||
*/
|
||||
const char *RedSizeToUL(
|
||||
const char *pszNum,
|
||||
uint32_t *pulResult)
|
||||
{
|
||||
uint32_t ulResult;
|
||||
const char *pszSuffix;
|
||||
const char *pszReturn;
|
||||
uint32_t ulIdx = 0U;
|
||||
|
||||
REDASSERT(pszNum != NULL);
|
||||
REDASSERT(pulResult != NULL);
|
||||
|
||||
/* Do the basic hex/decimal conversion
|
||||
*/
|
||||
pszSuffix = RedNtoUL(pszNum, &ulResult);
|
||||
if(pszSuffix != NULL)
|
||||
{
|
||||
if((pszSuffix[ulIdx] == 'B') || (pszSuffix[ulIdx] == 'b'))
|
||||
{
|
||||
ulIdx++;
|
||||
pszReturn = &pszSuffix[ulIdx];
|
||||
}
|
||||
else if( ((pszSuffix[ulIdx] == 'M') || (pszSuffix[ulIdx] == 'm'))
|
||||
&& ((pszSuffix[ulIdx + 1U] == 'B') || (pszSuffix[ulIdx + 1U] == 'b')))
|
||||
{
|
||||
ulIdx += 2U;
|
||||
|
||||
if(ulResult > (UINT32_MAX / (1024U * 1024U)))
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulResult *= 1024U * 1024U;
|
||||
pszReturn = &pszSuffix[ulIdx];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The number is either postfixed with "KB" or something
|
||||
else (we don't care), but we must increment the pointer
|
||||
if it is something recognize.
|
||||
*/
|
||||
if( ((pszSuffix[ulIdx] == 'K') || (pszSuffix[ulIdx] == 'k'))
|
||||
&& ((pszSuffix[ulIdx + 1U] == 'B') || (pszSuffix[ulIdx + 1U] == 'b')))
|
||||
{
|
||||
ulIdx += 2U;
|
||||
}
|
||||
|
||||
/* "B" or "MB" were not specified, so it must be "KB"
|
||||
*/
|
||||
if(ulResult > (UINT32_MAX / 1024U))
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulResult *= 1024UL;
|
||||
pszReturn = &pszSuffix[ulIdx];
|
||||
}
|
||||
}
|
||||
|
||||
if(pszReturn != NULL)
|
||||
{
|
||||
*pulResult = ulResult;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
|
||||
return pszReturn;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue