mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-04-07 11:08:36 +00:00
Add strn_to_uint32()
Use to implement str_to_unit32()
This commit is contained in:
parent
ad8d02827b
commit
c17fb19bd4
29
str.c
29
str.c
@ -663,14 +663,29 @@ int str_to_int32(const char *str, unsigned base, int32_t *result, const char **a
|
||||
|
||||
int str_to_uint32(const char *str, unsigned base, uint32_t *result, const char **afterp)
|
||||
{
|
||||
if (isspace(*str))
|
||||
return 0;
|
||||
const char *end = str;
|
||||
errno = 0;
|
||||
unsigned long value = strtoul(str, (char**)&end, base);
|
||||
return strn_to_uint32(str, 0, base, result, afterp);
|
||||
}
|
||||
|
||||
int strn_to_uint32(const char *str, size_t strlen, unsigned base, uint32_t *result, const char **afterp)
|
||||
{
|
||||
assert(base > 0);
|
||||
assert(base <= 16);
|
||||
uint32_t value = 0;
|
||||
uint32_t newvalue = 0;
|
||||
const char *const end = str + strlen;
|
||||
const char *s;
|
||||
for (s = str; strlen ? s < end : *s; ++s) {
|
||||
int digit = hexvalue(*s);
|
||||
if (digit < 0 || (unsigned)digit >= base)
|
||||
break;
|
||||
newvalue = value * base + digit;
|
||||
if (newvalue < value) // overflow
|
||||
break;
|
||||
value = newvalue;
|
||||
}
|
||||
if (afterp)
|
||||
*afterp = end;
|
||||
if (errno == ERANGE || end == str || value > UINT32_MAX || isdigit(*end) || (!afterp && *end))
|
||||
*afterp = s;
|
||||
if (s == str || value > UINT32_MAX || value != newvalue || (!afterp && (strlen ? s != end : *s)))
|
||||
return 0;
|
||||
if (result)
|
||||
*result = value;
|
||||
|
13
str.h
13
str.h
@ -396,6 +396,19 @@ int str_to_uint32(const char *str, unsigned base, uint32_t *result, const char *
|
||||
int str_to_int64(const char *str, unsigned base, int64_t *result, const char **afterp);
|
||||
int str_to_uint64(const char *str, unsigned base, uint64_t *result, const char **afterp);
|
||||
|
||||
/* Parse a length-bound string as an integer in ASCII radix notation in the given 'base' (eg,
|
||||
* base=10 means decimal).
|
||||
*
|
||||
* Returns 1 if a valid integer is parsed, storing the value in *result (unless result is NULL) and
|
||||
* storing a pointer to the immediately succeeding character in *afterp. If afterp is NULL then
|
||||
* returns 0 unless all 'strlen' characters of the string were consumed. If no integer is parsed or
|
||||
* if the integer overflows (too many digits), then returns 0, leaving *result unchanged and setting
|
||||
* setting *afterp to point to the character where parsing failed.
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
int strn_to_uint32(const char *str, size_t strlen, unsigned base, uint32_t *result, const char **afterp);
|
||||
|
||||
/* Parse a string as an integer in ASCII radix notation in the given 'base' (eg, base=10 means
|
||||
* decimal) and scale the result by a factor given by an optional suffix "scaling" character in the
|
||||
* set {kKmMgG}: 'k' = 1e3, 'K' = 1<<10, 'm' = 1e6, 'M' = 1<<20, 'g' = 1e9, 'G' = * 1<<30.
|
||||
|
Loading…
x
Reference in New Issue
Block a user