mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-04-07 11:08:36 +00:00
Add uint64_scaled_to_str() function in str.c
This commit is contained in:
parent
5430b70640
commit
aeeef0e972
50
str.c
50
str.c
@ -20,6 +20,7 @@
|
||||
#define __STR_INLINE
|
||||
#include "str.h"
|
||||
#include "strbuf_helpers.h"
|
||||
#include "constants.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@ -181,17 +182,29 @@ char *str_str(char *haystack, const char *needle, int haystack_len)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct scale_factor {
|
||||
char symbol;
|
||||
uint64_t factor;
|
||||
}
|
||||
scale_factors[] = {
|
||||
{ 'G', 1024LL * 1024LL * 1024LL },
|
||||
{ 'g', 1000LL * 1000LL * 1000LL },
|
||||
{ 'M', 1024LL * 1024LL },
|
||||
{ 'm', 1000LL * 1000LL },
|
||||
{ 'K', 1024LL },
|
||||
{ 'k', 1000LL }
|
||||
};
|
||||
|
||||
uint64_t scale_factor(const char *str, const char **afterp)
|
||||
{
|
||||
uint64_t factor = 1;
|
||||
switch (str[0]) {
|
||||
case 'k': ++str; factor = 1000LL; break;
|
||||
case 'K': ++str; factor = 1024LL; break;
|
||||
case 'm': ++str; factor = 1000LL * 1000LL; break;
|
||||
case 'M': ++str; factor = 1024LL * 1024LL; break;
|
||||
case 'g': ++str; factor = 1000LL * 1000LL * 1000LL; break;
|
||||
case 'G': ++str; factor = 1024LL * 1024LL * 1024LL; break;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i != NELS(scale_factors); ++i)
|
||||
if (scale_factors[i].symbol == str[0]) {
|
||||
++str;
|
||||
factor = scale_factors[i].factor;
|
||||
break;
|
||||
}
|
||||
if (afterp)
|
||||
*afterp = str;
|
||||
else if (*str)
|
||||
@ -201,7 +214,7 @@ uint64_t scale_factor(const char *str, const char **afterp)
|
||||
|
||||
int str_to_int64_scaled(const char *str, int base, int64_t *result, const char **afterp)
|
||||
{
|
||||
if (!(isdigit(*str) || *str == '-' || *str == '+'))
|
||||
if (isspace(*str))
|
||||
return 0;
|
||||
const char *end = str;
|
||||
long long value = strtoll(str, (char**)&end, base);
|
||||
@ -218,7 +231,7 @@ int str_to_int64_scaled(const char *str, int base, int64_t *result, const char *
|
||||
|
||||
int str_to_uint64_scaled(const char *str, int base, uint64_t *result, const char **afterp)
|
||||
{
|
||||
if (!isdigit(*str))
|
||||
if (isspace(*str))
|
||||
return 0;
|
||||
const char *end = str;
|
||||
unsigned long long value = strtoull(str, (char**)&end, base);
|
||||
@ -233,6 +246,23 @@ int str_to_uint64_scaled(const char *str, int base, uint64_t *result, const char
|
||||
return 1;
|
||||
}
|
||||
|
||||
int uint64_scaled_to_str(char *str, size_t len, uint64_t value)
|
||||
{
|
||||
char symbol = '\0';
|
||||
int i;
|
||||
for (i = 0; i != NELS(scale_factors); ++i)
|
||||
if (value % scale_factors[i].factor == 0) {
|
||||
value /= scale_factors[i].factor;
|
||||
symbol = scale_factors[i].symbol;
|
||||
break;
|
||||
}
|
||||
strbuf b = strbuf_local(str, len);
|
||||
strbuf_sprintf(b, "%llu", (unsigned long long) value);
|
||||
if (symbol)
|
||||
strbuf_putc(b, symbol);
|
||||
return strbuf_overrun(b) ? 0 : 1;
|
||||
}
|
||||
|
||||
/* Format a buffer of data as a printable representation, eg: "Abc\x0b\n\0", for display
|
||||
in log messages.
|
||||
@author Andrew Bettison <andrew@servalproject.com>
|
||||
|
11
str.h
11
str.h
@ -160,6 +160,17 @@ int str_to_int64_scaled(const char *str, int base, int64_t *result, const char *
|
||||
int str_to_uint64_scaled(const char *str, int base, uint64_t *result, const char **afterp);
|
||||
uint64_t scale_factor(const char *str, const char **afterp);
|
||||
|
||||
/* Format a string as a decimal integer in ASCII radix notation with a scale suffix character in the
|
||||
* set {kKmMgG}: 'k' = 1e3, 'K' = 1<<10, 'm' = 1e6, 'M' = 1<<20, 'g' = 1e9, 'G' = * 1<<30 if the
|
||||
* value is an exact multiple.
|
||||
*
|
||||
* Return 1 if the supplied string buffer was large enough to hold the formatted result plus a
|
||||
* terminating nul character, 0 otherwise.
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
int uint64_scaled_to_str(char *str, size_t len, uint64_t value);
|
||||
|
||||
/* Return true if the string resembles a nul-terminated URI.
|
||||
* Based on RFC-3986 generic syntax, assuming nothing about the hierarchical part.
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user