Move more numerical functions to wsutil/to_str.h

This commit is contained in:
João Valverde 2021-09-16 16:04:11 +01:00
parent cc1e5b8334
commit 8c4a479c52
5 changed files with 210 additions and 237 deletions

View File

@ -3354,15 +3354,6 @@ add_ether_byip(const guint ip, const guint8 *eth)
} /* add_ether_byip */
gchar *
ipxnet_to_str_punct(wmem_allocator_t *allocator, const guint32 ad, const char punct)
{
gchar *buf = (gchar *)wmem_alloc(allocator, 12);
*dword_to_hex_punct(buf, ad, punct) = '\0';
return buf;
}
gchar *
get_ipxnet_name(wmem_allocator_t *allocator, const guint32 addr)
{

View File

@ -30,120 +30,6 @@
*/
#define BUF_TOO_SMALL_ERR "[Buffer too small]"
static int
guint32_to_str_buf_len(const guint32 u)
{
/* ((2^32)-1) == 2147483647 */
if (u >= 1000000000)return 10;
if (u >= 100000000) return 9;
if (u >= 10000000) return 8;
if (u >= 1000000) return 7;
if (u >= 100000) return 6;
if (u >= 10000) return 5;
if (u >= 1000) return 4;
if (u >= 100) return 3;
if (u >= 10) return 2;
return 1;
}
static int
guint64_to_str_buf_len(const guint64 u)
{
/* ((2^64)-1) == 18446744073709551615 */
if (u >= G_GUINT64_CONSTANT(10000000000000000000)) return 20;
if (u >= G_GUINT64_CONSTANT(1000000000000000000)) return 19;
if (u >= G_GUINT64_CONSTANT(100000000000000000)) return 18;
if (u >= G_GUINT64_CONSTANT(10000000000000000)) return 17;
if (u >= G_GUINT64_CONSTANT(1000000000000000)) return 16;
if (u >= G_GUINT64_CONSTANT(100000000000000)) return 15;
if (u >= G_GUINT64_CONSTANT(10000000000000)) return 14;
if (u >= G_GUINT64_CONSTANT(1000000000000)) return 13;
if (u >= G_GUINT64_CONSTANT(100000000000)) return 12;
if (u >= G_GUINT64_CONSTANT(10000000000)) return 11;
if (u >= G_GUINT64_CONSTANT(1000000000)) return 10;
if (u >= G_GUINT64_CONSTANT(100000000)) return 9;
if (u >= G_GUINT64_CONSTANT(10000000)) return 8;
if (u >= G_GUINT64_CONSTANT(1000000)) return 7;
if (u >= G_GUINT64_CONSTANT(100000)) return 6;
if (u >= G_GUINT64_CONSTANT(10000)) return 5;
if (u >= G_GUINT64_CONSTANT(1000)) return 4;
if (u >= G_GUINT64_CONSTANT(100)) return 3;
if (u >= G_GUINT64_CONSTANT(10)) return 2;
return 1;
}
static const char fast_strings[][4] = {
"0", "1", "2", "3", "4", "5", "6", "7",
"8", "9", "10", "11", "12", "13", "14", "15",
"16", "17", "18", "19", "20", "21", "22", "23",
"24", "25", "26", "27", "28", "29", "30", "31",
"32", "33", "34", "35", "36", "37", "38", "39",
"40", "41", "42", "43", "44", "45", "46", "47",
"48", "49", "50", "51", "52", "53", "54", "55",
"56", "57", "58", "59", "60", "61", "62", "63",
"64", "65", "66", "67", "68", "69", "70", "71",
"72", "73", "74", "75", "76", "77", "78", "79",
"80", "81", "82", "83", "84", "85", "86", "87",
"88", "89", "90", "91", "92", "93", "94", "95",
"96", "97", "98", "99", "100", "101", "102", "103",
"104", "105", "106", "107", "108", "109", "110", "111",
"112", "113", "114", "115", "116", "117", "118", "119",
"120", "121", "122", "123", "124", "125", "126", "127",
"128", "129", "130", "131", "132", "133", "134", "135",
"136", "137", "138", "139", "140", "141", "142", "143",
"144", "145", "146", "147", "148", "149", "150", "151",
"152", "153", "154", "155", "156", "157", "158", "159",
"160", "161", "162", "163", "164", "165", "166", "167",
"168", "169", "170", "171", "172", "173", "174", "175",
"176", "177", "178", "179", "180", "181", "182", "183",
"184", "185", "186", "187", "188", "189", "190", "191",
"192", "193", "194", "195", "196", "197", "198", "199",
"200", "201", "202", "203", "204", "205", "206", "207",
"208", "209", "210", "211", "212", "213", "214", "215",
"216", "217", "218", "219", "220", "221", "222", "223",
"224", "225", "226", "227", "228", "229", "230", "231",
"232", "233", "234", "235", "236", "237", "238", "239",
"240", "241", "242", "243", "244", "245", "246", "247",
"248", "249", "250", "251", "252", "253", "254", "255"
};
void
guint32_to_str_buf(guint32 u, gchar *buf, int buf_len)
{
int str_len = guint32_to_str_buf_len(u)+1;
gchar *bp = &buf[str_len];
if (buf_len < str_len) {
(void) g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len); /* Let the unexpected value alert user */
return;
}
*--bp = '\0';
uint_to_str_back(bp, u);
}
void
guint64_to_str_buf(guint64 u, gchar *buf, int buf_len)
{
int str_len = guint64_to_str_buf_len(u)+1;
gchar *bp = &buf[str_len];
if (buf_len < str_len) {
(void) g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len); /* Let the unexpected value alert user */
return;
}
*--bp = '\0';
uint64_to_str_back(bp, u);
}
static const char mon_names[12][4] = {
"Jan",
"Feb",
@ -812,83 +698,6 @@ decode_bits_in_field(const guint bit_offset, const gint no_of_bits, const guint6
return str;
}
/*
This function is very fast and this function is called a lot.
XXX update the address_to_str stuff to use this function.
*/
void
ip_to_str_buf(const guint8 *ad, gchar *buf, const int buf_len)
{
register gchar const *p;
register gchar *b=buf;
if (buf_len < WS_INET_ADDRSTRLEN) {
(void) g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len); /* Let the unexpected value alert user */
return;
}
p=fast_strings[*ad++];
do {
*b++=*p;
p++;
} while(*p);
*b++='.';
p=fast_strings[*ad++];
do {
*b++=*p;
p++;
} while(*p);
*b++='.';
p=fast_strings[*ad++];
do {
*b++=*p;
p++;
} while(*p);
*b++='.';
p=fast_strings[*ad];
do {
*b++=*p;
p++;
} while(*p);
*b=0;
}
int
ip6_to_str_buf_with_pfx(const ws_in6_addr *addr, gchar *buf, int buf_size, const char *prefix)
{
int bytes; /* the number of bytes which would be produced if the buffer was large enough. */
gchar addr_buf[WS_INET6_ADDRSTRLEN];
int len;
if (prefix == NULL)
prefix = "";
bytes = g_snprintf(buf, buf_size, "%s%s", prefix, ws_inet_ntop6(addr, addr_buf, sizeof(addr_buf)));
len = bytes - 1;
if (len > buf_size - 1) { /* size minus nul terminator */
len = (int)g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_size); /* Let the unexpected value alert user */
}
return len;
}
int
ip6_to_str_buf(const ws_in6_addr *addr, gchar *buf, int buf_size)
{
gchar addr_buf[WS_INET6_ADDRSTRLEN];
int len;
/* slightly more efficient than ip6_to_str_buf_with_pfx(addr, buf, buf_size, NULL) */
len = (int)g_strlcpy(buf, ws_inet_ntop6(addr, addr_buf, sizeof(addr_buf)), buf_size); /* this returns len = strlen(addr_buf) */
if (len > buf_size - 1) { /* size minus nul terminator */
len = (int)g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_size); /* Let the unexpected value alert user */
}
return len;
}
gchar *
guid_to_str(wmem_allocator_t *scope, const e_guid_t *guid)
{
@ -923,23 +732,6 @@ guid_to_str_buf(const e_guid_t *guid, gchar *buf, int buf_len)
return buf;
}
gchar *
eui64_to_str(wmem_allocator_t *scope, const guint64 ad) {
gchar *buf, *tmp;
guint8 *p_eui64;
p_eui64=(guint8 *)wmem_alloc(NULL, 8);
buf=(gchar *)wmem_alloc(scope, EUI64_STR_LEN);
/* Copy and convert the address to network byte order. */
*(guint64 *)(void *)(p_eui64) = pntoh64(&(ad));
tmp = bytes_to_hexstr_punct(buf, p_eui64, 8, ':');
*tmp = '\0'; /* NULL terminate */
wmem_free(NULL, p_eui64);
return buf;
}
const gchar *
port_type_to_str (port_type type)
{

View File

@ -38,14 +38,6 @@ extern "C" {
* but for which no more specific module applies.
*/
/*
************** Numerical
*/
WS_DLL_PUBLIC void guint32_to_str_buf(guint32 u, gchar *buf, int buf_len);
WS_DLL_PUBLIC void guint64_to_str_buf(guint64 u, gchar *buf, int buf_len);
/*
************** Address
*/
@ -82,18 +74,6 @@ WS_DLL_PUBLIC gchar *address_to_display(wmem_allocator_t *allocator, const addre
WS_DLL_PUBLIC void address_to_str_buf(const address *addr, gchar *buf, int buf_len);
WS_DLL_LOCAL void ip_to_str_buf(const guint8 *ad, gchar *buf, const int buf_len);
/* Returns length of the result. */
WS_DLL_LOCAL int ip6_to_str_buf(const ws_in6_addr *ad, gchar *buf, int buf_size);
/* Returns length of the result. Takes a prefix to be inserted before the address. */
WS_DLL_LOCAL int ip6_to_str_buf_with_pfx(const ws_in6_addr *ad, gchar *buf, int buf_size, const char *prefix);
WS_DLL_LOCAL gchar *ipxnet_to_str_punct(wmem_allocator_t *scope, const guint32 ad, const char punct);
WS_DLL_PUBLIC gchar *eui64_to_str(wmem_allocator_t *scope, const guint64 ad);
WS_DLL_PUBLIC const gchar *port_type_to_str (port_type type);
/*

View File

@ -19,7 +19,16 @@
#include <wsutil/utf8_entities.h>
#include <wsutil/wslog.h>
#include <wsutil/inet_addr.h>
#include <wsutil/pint.h>
/*
* If a user _does_ pass in a too-small buffer, this is probably
* going to be too long to fit. However, even a partial string
* starting with "[Buf" should provide enough of a clue to be
* useful.
*/
#define BUF_TOO_SMALL_ERR "[Buffer too small]"
static const char fast_strings[][4] = {
"0", "1", "2", "3", "4", "5", "6", "7",
@ -446,6 +455,190 @@ int64_to_str_back(char *ptr, gint64 value)
return ptr;
}
static int
guint32_to_str_buf_len(const guint32 u)
{
/* ((2^32)-1) == 2147483647 */
if (u >= 1000000000)return 10;
if (u >= 100000000) return 9;
if (u >= 10000000) return 8;
if (u >= 1000000) return 7;
if (u >= 100000) return 6;
if (u >= 10000) return 5;
if (u >= 1000) return 4;
if (u >= 100) return 3;
if (u >= 10) return 2;
return 1;
}
void
guint32_to_str_buf(guint32 u, gchar *buf, int buf_len)
{
int str_len = guint32_to_str_buf_len(u)+1;
gchar *bp = &buf[str_len];
if (buf_len < str_len) {
(void) g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len); /* Let the unexpected value alert user */
return;
}
*--bp = '\0';
uint_to_str_back(bp, u);
}
static int
guint64_to_str_buf_len(const guint64 u)
{
/* ((2^64)-1) == 18446744073709551615 */
if (u >= G_GUINT64_CONSTANT(10000000000000000000)) return 20;
if (u >= G_GUINT64_CONSTANT(1000000000000000000)) return 19;
if (u >= G_GUINT64_CONSTANT(100000000000000000)) return 18;
if (u >= G_GUINT64_CONSTANT(10000000000000000)) return 17;
if (u >= G_GUINT64_CONSTANT(1000000000000000)) return 16;
if (u >= G_GUINT64_CONSTANT(100000000000000)) return 15;
if (u >= G_GUINT64_CONSTANT(10000000000000)) return 14;
if (u >= G_GUINT64_CONSTANT(1000000000000)) return 13;
if (u >= G_GUINT64_CONSTANT(100000000000)) return 12;
if (u >= G_GUINT64_CONSTANT(10000000000)) return 11;
if (u >= G_GUINT64_CONSTANT(1000000000)) return 10;
if (u >= G_GUINT64_CONSTANT(100000000)) return 9;
if (u >= G_GUINT64_CONSTANT(10000000)) return 8;
if (u >= G_GUINT64_CONSTANT(1000000)) return 7;
if (u >= G_GUINT64_CONSTANT(100000)) return 6;
if (u >= G_GUINT64_CONSTANT(10000)) return 5;
if (u >= G_GUINT64_CONSTANT(1000)) return 4;
if (u >= G_GUINT64_CONSTANT(100)) return 3;
if (u >= G_GUINT64_CONSTANT(10)) return 2;
return 1;
}
void
guint64_to_str_buf(guint64 u, gchar *buf, int buf_len)
{
int str_len = guint64_to_str_buf_len(u)+1;
gchar *bp = &buf[str_len];
if (buf_len < str_len) {
(void) g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len); /* Let the unexpected value alert user */
return;
}
*--bp = '\0';
uint64_to_str_back(bp, u);
}
/*
This function is very fast and this function is called a lot.
XXX update the address_to_str stuff to use this function.
*/
void
ip_to_str_buf(const guint8 *ad, gchar *buf, const int buf_len)
{
register gchar const *p;
register gchar *b=buf;
if (buf_len < WS_INET_ADDRSTRLEN) {
(void) g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len); /* Let the unexpected value alert user */
return;
}
p=fast_strings[*ad++];
do {
*b++=*p;
p++;
} while(*p);
*b++='.';
p=fast_strings[*ad++];
do {
*b++=*p;
p++;
} while(*p);
*b++='.';
p=fast_strings[*ad++];
do {
*b++=*p;
p++;
} while(*p);
*b++='.';
p=fast_strings[*ad];
do {
*b++=*p;
p++;
} while(*p);
*b=0;
}
int
ip6_to_str_buf(const ws_in6_addr *addr, gchar *buf, int buf_size)
{
gchar addr_buf[WS_INET6_ADDRSTRLEN];
int len;
/* slightly more efficient than ip6_to_str_buf_with_pfx(addr, buf, buf_size, NULL) */
len = (int)g_strlcpy(buf, ws_inet_ntop6(addr, addr_buf, sizeof(addr_buf)), buf_size); /* this returns len = strlen(addr_buf) */
if (len > buf_size - 1) { /* size minus nul terminator */
len = (int)g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_size); /* Let the unexpected value alert user */
}
return len;
}
int
ip6_to_str_buf_with_pfx(const ws_in6_addr *addr, gchar *buf, int buf_size, const char *prefix)
{
int bytes; /* the number of bytes which would be produced if the buffer was large enough. */
gchar addr_buf[WS_INET6_ADDRSTRLEN];
int len;
if (prefix == NULL)
prefix = "";
bytes = g_snprintf(buf, buf_size, "%s%s", prefix, ws_inet_ntop6(addr, addr_buf, sizeof(addr_buf)));
len = bytes - 1;
if (len > buf_size - 1) { /* size minus nul terminator */
len = (int)g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_size); /* Let the unexpected value alert user */
}
return len;
}
gchar *
ipxnet_to_str_punct(wmem_allocator_t *allocator, const guint32 ad, const char punct)
{
gchar *buf = (gchar *)wmem_alloc(allocator, 12);
*dword_to_hex_punct(buf, ad, punct) = '\0';
return buf;
}
#define WS_EUI64_STRLEN 24
gchar *
eui64_to_str(wmem_allocator_t *scope, const guint64 ad) {
gchar *buf, *tmp;
guint8 *p_eui64;
p_eui64=(guint8 *)wmem_alloc(NULL, 8);
buf=(gchar *)wmem_alloc(scope, WS_EUI64_STRLEN);
/* Copy and convert the address to network byte order. */
*(guint64 *)(void *)(p_eui64) = pntoh64(&(ad));
tmp = bytes_to_hexstr_punct(buf, p_eui64, 8, ':');
*tmp = '\0'; /* NULL terminate */
wmem_free(NULL, p_eui64);
return buf;
}
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*

View File

@ -15,6 +15,7 @@
#include <ws_symbol_export.h>
#include <wsutil/wmem/wmem.h>
#include <wsutil/inet_ipv6.h>
#ifdef __cplusplus
extern "C" {
@ -279,6 +280,22 @@ WS_DLL_PUBLIC char *int_to_str_back(char *ptr, gint32 value);
*/
WS_DLL_PUBLIC char *int64_to_str_back(char *ptr, gint64 value);
WS_DLL_PUBLIC void guint32_to_str_buf(guint32 u, gchar *buf, int buf_len);
WS_DLL_PUBLIC void guint64_to_str_buf(guint64 u, gchar *buf, int buf_len);
WS_DLL_PUBLIC void ip_to_str_buf(const guint8 *ad, gchar *buf, const int buf_len);
/* Returns length of the result. */
WS_DLL_PUBLIC int ip6_to_str_buf(const ws_in6_addr *ad, gchar *buf, int buf_size);
/* Returns length of the result. Takes a prefix to be inserted before the address. */
WS_DLL_PUBLIC int ip6_to_str_buf_with_pfx(const ws_in6_addr *ad, gchar *buf, int buf_size, const char *prefix);
WS_DLL_PUBLIC gchar *ipxnet_to_str_punct(wmem_allocator_t *scope, const guint32 ad, const char punct);
WS_DLL_PUBLIC gchar *eui64_to_str(wmem_allocator_t *scope, const guint64 ad);
#ifdef __cplusplus
}
#endif /* __cplusplus */