improve str_to_buf and buf_to_str helpers
Improve types: use void * and unsigned. Move all variables to point of first use. Move radix guessing logic to new str_radix_guess helper.
This commit is contained in:
parent
5a43bd2e18
commit
d50caa97d1
|
@ -169,43 +169,36 @@ int ceil_f_to_u32(float x)
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* buf_to_str(const uint8_t *buf, int buf_len, int radix)
|
char* buf_to_str(const void *_buf, unsigned buf_len, unsigned radix)
|
||||||
{
|
{
|
||||||
const char *DIGITS = "0123456789ABCDEF";
|
|
||||||
float factor;
|
float factor;
|
||||||
char *str;
|
switch (radix) {
|
||||||
int str_len;
|
case 16:
|
||||||
int b256_len = CEIL(buf_len, 8);
|
|
||||||
uint32_t tmp;
|
|
||||||
|
|
||||||
int j; /* base-256 digits */
|
|
||||||
int i; /* output digits (radix) */
|
|
||||||
|
|
||||||
if (radix == 16)
|
|
||||||
{
|
|
||||||
factor = 2.0; /* log(256) / log(16) = 2.0 */
|
factor = 2.0; /* log(256) / log(16) = 2.0 */
|
||||||
}
|
break;
|
||||||
else if (radix == 10)
|
case 10:
|
||||||
{
|
|
||||||
factor = 2.40824; /* log(256) / log(10) = 2.40824 */
|
factor = 2.40824; /* log(256) / log(10) = 2.40824 */
|
||||||
}
|
break;
|
||||||
else if (radix == 8)
|
case 8:
|
||||||
{
|
|
||||||
factor = 2.66667; /* log(256) / log(8) = 2.66667 */
|
factor = 2.66667; /* log(256) / log(8) = 2.66667 */
|
||||||
}
|
break;
|
||||||
else
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
str_len = ceil_f_to_u32(CEIL(buf_len, 8) * factor);
|
unsigned str_len = ceil_f_to_u32(CEIL(buf_len, 8) * factor);
|
||||||
str = calloc(str_len + 1, 1);
|
char *str = calloc(str_len + 1, 1);
|
||||||
|
|
||||||
for (i = b256_len - 1; i >= 0; i--)
|
const uint8_t *buf = _buf;
|
||||||
|
int b256_len = CEIL(buf_len, 8);
|
||||||
|
for (int i = b256_len - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
tmp = buf[i];
|
uint32_t tmp = buf[i];
|
||||||
if ((i == (buf_len / 8)) && (buf_len % 8))
|
if (((unsigned)i == (buf_len / 8)) && (buf_len % 8))
|
||||||
tmp &= (0xff >> (8 - (buf_len % 8)));
|
tmp &= (0xff >> (8 - (buf_len % 8)));
|
||||||
|
|
||||||
for (j = str_len; j > 0; j--)
|
/* base-256 digits */
|
||||||
|
for (unsigned j = str_len; j > 0; j--)
|
||||||
{
|
{
|
||||||
tmp += (uint32_t)str[j-1] * 256;
|
tmp += (uint32_t)str[j-1] * 256;
|
||||||
str[j-1] = (uint8_t)(tmp % radix);
|
str[j-1] = (uint8_t)(tmp % radix);
|
||||||
|
@ -213,27 +206,23 @@ char* buf_to_str(const uint8_t *buf, int buf_len, int radix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 0; j < str_len; j++)
|
const char *DIGITS = "0123456789ABCDEF";
|
||||||
|
for (unsigned j = 0; j < str_len; j++)
|
||||||
str[j] = DIGITS[(int)str[j]];
|
str[j] = DIGITS[(int)str[j]];
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
int str_to_buf(const char *str, int str_len, uint8_t *buf, int buf_len, int radix)
|
/// identify radix, and skip radix-prefix (0, 0x or 0X)
|
||||||
|
static void str_radix_guess(const char **_str, unsigned *_str_len,
|
||||||
|
unsigned *_radix)
|
||||||
{
|
{
|
||||||
char *charbuf;
|
unsigned radix = *_radix;
|
||||||
uint32_t tmp;
|
if (0 != radix)
|
||||||
float factor;
|
return;
|
||||||
uint8_t *b256_buf;
|
const char *str = *_str;
|
||||||
int b256_len;
|
unsigned str_len = *_str_len;
|
||||||
|
if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
|
||||||
int j; /* base-256 digits */
|
|
||||||
int i; /* input digits (ASCII) */
|
|
||||||
|
|
||||||
if (radix == 0)
|
|
||||||
{
|
|
||||||
/* identify radix, and skip radix-prefix (0, 0x or 0X) */
|
|
||||||
if ((str[0] == '0') && (str[1] && ((str[1] == 'x') || (str[1] == 'X'))))
|
|
||||||
{
|
{
|
||||||
radix = 16;
|
radix = 16;
|
||||||
str += 2;
|
str += 2;
|
||||||
|
@ -249,8 +238,17 @@ int str_to_buf(const char *str, int str_len, uint8_t *buf, int buf_len, int radi
|
||||||
{
|
{
|
||||||
radix = 10;
|
radix = 10;
|
||||||
}
|
}
|
||||||
}
|
*_str = str;
|
||||||
|
*_str_len = str_len;
|
||||||
|
*_radix = radix;
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_to_buf(const char *str, unsigned str_len,
|
||||||
|
void *_buf, unsigned buf_len, unsigned radix)
|
||||||
|
{
|
||||||
|
str_radix_guess(&str, &str_len, &radix);
|
||||||
|
|
||||||
|
float factor;
|
||||||
if (radix == 16)
|
if (radix == 16)
|
||||||
factor = 0.5; /* log(16) / log(256) = 0.5 */
|
factor = 0.5; /* log(16) / log(256) = 0.5 */
|
||||||
else if (radix == 10)
|
else if (radix == 10)
|
||||||
|
@ -261,18 +259,20 @@ int str_to_buf(const char *str, int str_len, uint8_t *buf, int buf_len, int radi
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* copy to zero-terminated buffer */
|
/* copy to zero-terminated buffer */
|
||||||
charbuf = malloc(str_len + 1);
|
char *charbuf = malloc(str_len + 1);
|
||||||
memcpy(charbuf, str, str_len);
|
memcpy(charbuf, str, str_len);
|
||||||
charbuf[str_len] = '\0';
|
charbuf[str_len] = '\0';
|
||||||
|
|
||||||
/* number of digits in base-256 notation */
|
/* number of digits in base-256 notation */
|
||||||
b256_len = ceil_f_to_u32(str_len * factor);
|
unsigned b256_len = ceil_f_to_u32(str_len * factor);
|
||||||
b256_buf = calloc(b256_len, 1);
|
uint8_t *b256_buf = calloc(b256_len, 1);
|
||||||
|
|
||||||
/* go through zero terminated buffer */
|
/* go through zero terminated buffer */
|
||||||
|
/* input digits (ASCII) */
|
||||||
|
unsigned i;
|
||||||
for (i = 0; charbuf[i]; i++)
|
for (i = 0; charbuf[i]; i++)
|
||||||
{
|
{
|
||||||
tmp = charbuf[i];
|
uint32_t tmp = charbuf[i];
|
||||||
if ((tmp >= '0') && (tmp <= '9'))
|
if ((tmp >= '0') && (tmp <= '9'))
|
||||||
tmp = (tmp - '0');
|
tmp = (tmp - '0');
|
||||||
else if ((tmp >= 'a') && (tmp <= 'f'))
|
else if ((tmp >= 'a') && (tmp <= 'f'))
|
||||||
|
@ -281,10 +281,11 @@ int str_to_buf(const char *str, int str_len, uint8_t *buf, int buf_len, int radi
|
||||||
tmp = (tmp - 'A' + 10);
|
tmp = (tmp - 'A' + 10);
|
||||||
else continue; /* skip characters other than [0-9,a-f,A-F] */
|
else continue; /* skip characters other than [0-9,a-f,A-F] */
|
||||||
|
|
||||||
if (tmp >= (uint32_t)radix)
|
if (tmp >= radix)
|
||||||
continue; /* skip digits invalid for the current radix */
|
continue; /* skip digits invalid for the current radix */
|
||||||
|
|
||||||
for (j = 0; j < b256_len; j++)
|
/* base-256 digits */
|
||||||
|
for (unsigned j = 0; j < b256_len; j++)
|
||||||
{
|
{
|
||||||
tmp += (uint32_t)b256_buf[j] * radix;
|
tmp += (uint32_t)b256_buf[j] * radix;
|
||||||
b256_buf[j] = (uint8_t)(tmp & 0xFF);
|
b256_buf[j] = (uint8_t)(tmp & 0xFF);
|
||||||
|
@ -293,7 +294,8 @@ int str_to_buf(const char *str, int str_len, uint8_t *buf, int buf_len, int radi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 0; j < CEIL(buf_len, 8); j++)
|
uint8_t *buf = _buf;
|
||||||
|
for (unsigned j = 0; j < CEIL(buf_len, 8); j++)
|
||||||
{
|
{
|
||||||
if (j < b256_len)
|
if (j < b256_len)
|
||||||
buf[j] = b256_buf[j];
|
buf[j] = b256_buf[j];
|
||||||
|
|
|
@ -79,9 +79,9 @@ uint8_t* buf_set_ones(uint8_t *buf, int count);
|
||||||
uint8_t* buf_set_buf(const uint8_t *src, int src_start,
|
uint8_t* buf_set_buf(const uint8_t *src, int src_start,
|
||||||
uint8_t *dst, int dst_start, int len);
|
uint8_t *dst, int dst_start, int len);
|
||||||
|
|
||||||
int str_to_buf(const char *str, int len,
|
int str_to_buf(const char *str, unsigned len,
|
||||||
uint8_t *bin_buf, int buf_size, int radix);
|
void *bin_buf, unsigned buf_size, unsigned radix);
|
||||||
char* buf_to_str(const uint8_t *buf, int size, int radix);
|
char* buf_to_str(const void *buf, unsigned size, unsigned radix);
|
||||||
|
|
||||||
#define CEIL(m, n) (((m) + (n) - 1) / (n))
|
#define CEIL(m, n) (((m) + (n) - 1) / (n))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue