Move bytes_to_str() to wsutil

This utility function is useful outside of epan. Move it to wsutil
and export the interface.

The move isn't completely clean as it requires duplicating two small
inline functions but that was necessary to avoiding moving too much at
once.
This commit is contained in:
João Valverde 2021-07-25 22:53:03 +01:00 committed by Wireshark GitLab Utility
parent d34d1a1e13
commit c3bd5c9d91
9 changed files with 268 additions and 165 deletions

View File

@ -75,11 +75,8 @@ libwireshark.so.0 libwireshark0 #MINVER#
build_column_format_array@Base 1.9.1
byte_array_dup@Base 1.9.1
byte_array_equal@Base 1.9.1
bytes_to_hexstr@Base 2.1.0
bytes_to_str@Base 1.99.2
bytesprefix_to_str@Base 2.3.0
bytesval_to_str@Base 2.3.0
bytestring_to_str@Base 1.9.1
call_ber_oid_callback@Base 1.9.1
call_capture_dissector@Base 2.3.0
call_data_dissector@Base 2.1.0

View File

@ -8,6 +8,10 @@ libwsutil.so.0 libwsutil0 #MINVER#
ascii_strdown_inplace@Base 1.10.0
ascii_strup_inplace@Base 1.10.0
bitswap_buf_inplace@Base 1.12.0~rc1
bytes_to_hexstr@Base 3.5.0
bytes_to_hexstr_punct@Base 3.5.0
bytes_to_str@Base 3.5.0
bytestring_to_str@Base 3.5.0
codec_decode@Base 3.1.0
codec_get_channels@Base 3.1.0
codec_get_frequency@Base 3.1.0

View File

@ -10,7 +10,7 @@
#include <ftypes-int.h>
#include <epan/strutil.h>
#include <epan/to_str-int.h>
#include <wsutil/to_str.h>
#include <string.h>
#include <wsutil/glib-compat.h>

View File

@ -71,18 +71,6 @@ char *qword_to_hex(char *out, guint64 qword);
*/
char *qword_to_hex_punct(char *out, guint64 qword, char punct);
/**
* bytes_to_hexstr_punct()
*
* Output hex represetation of guint8 ad array, and return pointer after last character.
* Each byte will be separated with punct character (cannot be NUL).
* It always output full representation (padded with 0).
*
* String is not NUL terminated by this routine.
* There needs to be at least len * 3 - 1 bytes in the buffer.
*/
char *bytes_to_hexstr_punct(char *out, const guint8 *ad, size_t len, char punct);
/**
* oct_to_str_back()
*

View File

@ -125,122 +125,6 @@ qword_to_hex_punct(char *out, guint64 qword, char punct)
return out;
}
/*
* This does *not* null-terminate the string. It returns a pointer
* to the position in the string following the last character it
* puts there, so that the caller can either put the null terminator
* in or can append more stuff to the buffer.
*
* There needs to be at least len * 2 bytes left in the buffer.
*/
char *
bytes_to_hexstr(char *out, const guint8 *ad, size_t len)
{
size_t i;
if (!ad)
REPORT_DISSECTOR_BUG("Null pointer passed to bytes_to_hexstr()");
for (i = 0; i < len; i++)
out = byte_to_hex(out, ad[i]);
return out;
}
/*
* This does *not* null-terminate the string. It returns a pointer
* to the position in the string following the last character it
* puts there, so that the caller can either put the null terminator
* in or can append more stuff to the buffer.
*
* There needs to be at least len * 3 - 1 bytes left in the buffer.
*/
char *
bytes_to_hexstr_punct(char *out, const guint8 *ad, size_t len, char punct)
{
size_t i;
if (!ad)
REPORT_DISSECTOR_BUG("Null pointer passed to bytes_to_hexstr_punct()");
out = byte_to_hex(out, ad[0]);
for (i = 1; i < len; i++) {
*out++ = punct;
out = byte_to_hex(out, ad[i]);
}
return out;
}
/* Max string length for displaying byte string. */
#define MAX_BYTE_STR_LEN 72
/* Routine to convert a sequence of bytes to a hex string, one byte/two hex
* digits at at a time, with a specified punctuation character between
* the bytes.
*
* If punct is '\0', no punctuation is applied (and thus
* the resulting string is (len-1) bytes shorter)
*/
gchar *
bytestring_to_str(wmem_allocator_t *scope, const guint8 *ad, size_t len, const char punct)
{
gchar *buf;
size_t buflen = len;
gchar *buf_ptr;
int truncated = 0;
if (len == 0)
return wmem_strdup(scope, "");
if (!ad)
REPORT_DISSECTOR_BUG("Null pointer passed to bytestring_to_str()");
if (!punct)
return bytes_to_str(scope, ad, len);
buf=(gchar *)wmem_alloc(scope, MAX_BYTE_STR_LEN+3+1);
if (buflen > MAX_BYTE_STR_LEN/3) { /* bd_len > 16 */
truncated = 1;
buflen = MAX_BYTE_STR_LEN/3;
}
buf_ptr = bytes_to_hexstr_punct(buf, ad, buflen, punct); /* max MAX_BYTE_STR_LEN-1 bytes */
if (truncated) {
*buf_ptr++ = punct; /* 1 byte */
buf_ptr = g_stpcpy(buf_ptr, UTF8_HORIZONTAL_ELLIPSIS); /* 3 bytes */
}
*buf_ptr = '\0';
return buf;
}
char *
bytes_to_str(wmem_allocator_t *scope, const guint8 *bd, size_t bd_len)
{
gchar *cur;
gchar *cur_ptr;
int truncated = 0;
if (!bd)
REPORT_DISSECTOR_BUG("Null pointer passed to bytes_to_str()");
cur=(gchar *)wmem_alloc(scope, MAX_BYTE_STR_LEN+3+1);
if (bd_len == 0) { cur[0] = '\0'; return cur; }
if (bd_len > MAX_BYTE_STR_LEN/2) { /* bd_len > 24 */
truncated = 1;
bd_len = MAX_BYTE_STR_LEN/2;
}
cur_ptr = bytes_to_hexstr(cur, bd, bd_len); /* max MAX_BYTE_STR_LEN bytes */
if (truncated)
cur_ptr = g_stpcpy(cur_ptr, UTF8_HORIZONTAL_ELLIPSIS); /* 3 bytes */
*cur_ptr = '\0'; /* 1 byte */
return cur;
}
static int
guint32_to_str_buf_len(const guint32 u)
{

View File

@ -20,6 +20,7 @@
#include <epan/ipv6.h>
#include "ws_symbol_export.h"
#include <epan/wmem_scopes.h>
#include <wsutil/to_str.h>
#define GUID_STR_LEN 37
#define MAX_ADDR_STR_LEN 256
@ -168,39 +169,6 @@ WS_DLL_PUBLIC char *word_to_hex(char *out, guint16 word);
*/
WS_DLL_PUBLIC char *dword_to_hex(char *out, guint32 dword);
/** Turn an array of bytes into a string showing the bytes in hex.
*
* @param scope memory allocation scheme used
* @param bd A pointer to the byte array
* @param bd_len The length of the byte array
* @return A pointer to the formatted string
*/
WS_DLL_PUBLIC char *bytes_to_str(wmem_allocator_t *scope, const guint8 *bd, size_t bd_len);
/** Turn an array of bytes into a string showing the bytes in hex,
* separated by a punctuation character.
*
* @param scope memory allocation scheme used
* @param ad A pointer to the byte array
* @param len The length of the byte array
* @param punct The punctuation character
* @return A pointer to the formatted string
*
* @see bytes_to_str()
*/
WS_DLL_PUBLIC gchar *bytestring_to_str(wmem_allocator_t *scope, const guint8 *ad, size_t len, const char punct);
/**
* bytes_to_hexstr()
*
* Output hex represetation of guint8 ad array, and return pointer after last character.
* It always output full representation (padded with 0).
*
* String is not NUL terminated by this routine.
* There needs to be at least len * 2 bytes in the buffer.
*/
WS_DLL_PUBLIC char *bytes_to_hexstr(char *out, const guint8 *ad, size_t len);
/**
* uint_to_str_back()
*

View File

@ -64,6 +64,7 @@ set(WSUTIL_PUBLIC_HEADERS
strtoi.h
tempfile.h
time_util.h
to_str.h
type_util.h
unicode-utils.h
utf8_entities.h
@ -121,6 +122,7 @@ set(WSUTIL_COMMON_FILES
report_message.c
tempfile.c
time_util.c
to_str.c
type_util.c
unicode-utils.c
glib-compat.c

188
wsutil/to_str.c Normal file
View File

@ -0,0 +1,188 @@
/* wsutil/to_str.c
* Routines for utilities to convert various other types to strings.
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <glib.h>
#include "to_str.h"
#include <wsutil/utf8_entities.h>
#include <wsutil/wslog.h>
static inline char
low_nibble_of_octet_to_hex(guint8 oct)
{
/* At least one version of Apple's C compiler/linker is buggy, causing
a complaint from the linker about the "literal C string section"
not ending with '\0' if we initialize a 16-element "char" array with
a 16-character string, the fact that initializing such an array with
such a string is perfectly legitimate ANSI C nonwithstanding, the 17th
'\0' byte in the string nonwithstanding. */
static const gchar hex_digits[16] =
{ '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
return hex_digits[oct & 0xF];
}
static inline char *
byte_to_hex(char *out, guint32 dword)
{
*out++ = low_nibble_of_octet_to_hex(dword >> 4);
*out++ = low_nibble_of_octet_to_hex(dword);
return out;
}
/*
* This does *not* null-terminate the string. It returns a pointer
* to the position in the string following the last character it
* puts there, so that the caller can either put the null terminator
* in or can append more stuff to the buffer.
*
* There needs to be at least len * 2 bytes left in the buffer.
*/
char *
bytes_to_hexstr(char *out, const guint8 *ad, size_t len)
{
size_t i;
if (!ad) {
ws_warning("Null pointer passed to bytes_to_hexstr()");
return NULL;
}
for (i = 0; i < len; i++)
out = byte_to_hex(out, ad[i]);
return out;
}
/*
* This does *not* null-terminate the string. It returns a pointer
* to the position in the string following the last character it
* puts there, so that the caller can either put the null terminator
* in or can append more stuff to the buffer.
*
* There needs to be at least len * 3 - 1 bytes left in the buffer.
*/
char *
bytes_to_hexstr_punct(char *out, const guint8 *ad, size_t len, char punct)
{
size_t i;
if (!ad) {
ws_warning("Null pointer passed to bytes_to_hexstr_punct()");
return NULL;
}
out = byte_to_hex(out, ad[0]);
for (i = 1; i < len; i++) {
*out++ = punct;
out = byte_to_hex(out, ad[i]);
}
return out;
}
/* Max string length for displaying byte string. */
#define MAX_BYTE_STR_LEN 72
/* Routine to convert a sequence of bytes to a hex string, one byte/two hex
* digits at at a time, with a specified punctuation character between
* the bytes.
*
* If punct is '\0', no punctuation is applied (and thus
* the resulting string is (len-1) bytes shorter)
*/
gchar *
bytestring_to_str(wmem_allocator_t *scope, const guint8 *ad, size_t len, const char punct)
{
gchar *buf;
size_t buflen = len;
gchar *buf_ptr;
int truncated = 0;
if (len == 0) {
ws_warning("Zero length passed to bytestring_to_str()");
return wmem_strdup(scope, "(zero length)");
}
if (!ad) {
ws_warning("Null pointer passed to bytestring_to_str()");
return wmem_strdup(scope, "(null pointer)");
}
if (!punct)
return bytes_to_str(scope, ad, len);
buf=(gchar *)wmem_alloc(scope, MAX_BYTE_STR_LEN+3+1);
if (buflen > MAX_BYTE_STR_LEN/3) { /* bd_len > 16 */
truncated = 1;
buflen = MAX_BYTE_STR_LEN/3;
}
buf_ptr = bytes_to_hexstr_punct(buf, ad, buflen, punct); /* max MAX_BYTE_STR_LEN-1 bytes */
if (truncated) {
*buf_ptr++ = punct; /* 1 byte */
buf_ptr = g_stpcpy(buf_ptr, UTF8_HORIZONTAL_ELLIPSIS); /* 3 bytes */
}
*buf_ptr = '\0';
return buf;
}
char *
bytes_to_str(wmem_allocator_t *scope, const guint8 *bd, size_t bd_len)
{
gchar *cur;
gchar *cur_ptr;
int truncated = 0;
if (bd_len == 0) {
ws_warning("Zero length passed to bytes_to_str()");
return wmem_strdup(scope, "(zero length)");
}
if (!bd) {
ws_warning("Null pointer passed to bytes_to_str()");
return wmem_strdup(scope, "(null pointer)");
}
cur=(gchar *)wmem_alloc(scope, MAX_BYTE_STR_LEN+3+1);
if (bd_len > MAX_BYTE_STR_LEN/2) { /* bd_len > 24 */
truncated = 1;
bd_len = MAX_BYTE_STR_LEN/2;
}
cur_ptr = bytes_to_hexstr(cur, bd, bd_len); /* max MAX_BYTE_STR_LEN bytes */
if (truncated)
cur_ptr = g_stpcpy(cur_ptr, UTF8_HORIZONTAL_ELLIPSIS); /* 3 bytes */
*cur_ptr = '\0'; /* 1 byte */
return cur;
}
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
* :indentSize=8:tabSize=8:noTabs=false:
*/

72
wsutil/to_str.h Normal file
View File

@ -0,0 +1,72 @@
/* wsutil/to_str.h
* Definitions for utilities to convert various other types to strings.
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef __WSUTIL_TO_STR_H__
#define __WSUTIL_TO_STR_H__
#include <glib.h>
#include <ws_symbol_export.h>
#include <wsutil/wmem/wmem.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* bytes_to_hexstr()
*
* Output hex represetation of guint8 ad array, and return pointer after last character.
* It always output full representation (padded with 0).
*
* String is not NUL terminated by this routine.
* There needs to be at least len * 2 bytes in the buffer.
*/
WS_DLL_PUBLIC char *bytes_to_hexstr(char *out, const guint8 *ad, size_t len);
/**
* bytes_to_hexstr_punct()
*
* Output hex represetation of guint8 ad array, and return pointer after last character.
* Each byte will be separated with punct character (cannot be NUL).
* It always output full representation (padded with 0).
*
* String is not NUL terminated by this routine.
* There needs to be at least len * 3 - 1 bytes in the buffer.
*/
WS_DLL_PUBLIC char *bytes_to_hexstr_punct(char *out, const guint8 *ad, size_t len, char punct);
/** Turn an array of bytes into a string showing the bytes in hex,
* separated by a punctuation character.
*
* @param scope memory allocation scheme used
* @param ad A pointer to the byte array
* @param len The length of the byte array
* @param punct The punctuation character
* @return A pointer to the formatted string
*
* @see bytes_to_str()
*/
WS_DLL_PUBLIC gchar *bytestring_to_str(wmem_allocator_t *scope, const guint8 *ad, size_t len, const char punct);
/** Turn an array of bytes into a string showing the bytes in hex.
*
* @param scope memory allocation scheme used
* @param bd A pointer to the byte array
* @param bd_len The length of the byte array
* @return A pointer to the formatted string
*/
WS_DLL_PUBLIC char *bytes_to_str(wmem_allocator_t *scope, const guint8 *bd, size_t bd_len);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __TO_STR_H__ */