Add str_hex_cstyle to print bytes as a C style array

This function converts data to a C style array string presentation.
This commit is contained in:
Robert Müller 2023-01-18 00:09:07 +01:00
parent 64578d4954
commit 0e59b84718
3 changed files with 98 additions and 0 deletions

View file

@ -3078,6 +3078,39 @@ void str_hex(char *dst, int dst_size, const void *data, int data_size)
dst[dst_index] = '\0';
}
void str_hex_cstyle(char *dst, int dst_size, const void *data, int data_size, int bytes_per_line)
{
static const char hex[] = "0123456789ABCDEF";
int data_index;
int dst_index;
int remaining_bytes_per_line = bytes_per_line;
for(data_index = 0, dst_index = 0; data_index < data_size && dst_index < dst_size - 6; data_index++)
{
--remaining_bytes_per_line;
dst[data_index * 6] = '0';
dst[data_index * 6 + 1] = 'x';
dst[data_index * 6 + 2] = hex[((const unsigned char *)data)[data_index] >> 4];
dst[data_index * 6 + 3] = hex[((const unsigned char *)data)[data_index] & 0xf];
dst[data_index * 6 + 4] = ',';
if(remaining_bytes_per_line == 0)
{
dst[data_index * 6 + 5] = '\n';
remaining_bytes_per_line = bytes_per_line;
}
else
{
dst[data_index * 6 + 5] = ' ';
}
dst_index += 6;
}
dst[dst_index] = '\0';
// Remove trailing comma and space/newline
if(dst_index >= 1)
dst[dst_index - 1] = '\0';
if(dst_index >= 2)
dst[dst_index - 2] = '\0';
}
static int hexval(char x)
{
switch(x)

View file

@ -1640,6 +1640,22 @@ int str_countchr(const char *haystack, char needle);
*/
void str_hex(char *dst, int dst_size, const void *data, int data_size);
/**
* Takes a datablock and generates a hex string of it, in the C style array format,
* i.e. with bytes formatted in 0x00-0xFF notation and commas with spaces between the bytes.
* The output can be split over multiple lines by specifying the maximum number of bytes
* that should be printed per line.
*
* @param dst Buffer to fill with hex data.
* @param dst_size Size of the buffer (at least 6 * data_size + 1 to contain all data).
* @param data Data to turn into hex.
* @param data_size Size of the data.
* @param bytes_per_line After this many printed bytes a newline will be printed.
*
* @remark The destination buffer will be zero-terminated.
*/
void str_hex_cstyle(char *dst, int dst_size, const void *data, int data_size, int bytes_per_line = 12);
/*
Function: str_hex_decode
Takes a hex string *without spaces between bytes* and returns a

View file

@ -272,6 +272,7 @@ TEST(Str, HexEncode)
EXPECT_STREQ(aOut, "41 42 43 ");
str_hex(aOut, sizeof(aOut), pData, 4);
EXPECT_STREQ(aOut, "41 42 43 44 ");
str_hex(aOut, 1, pData, 4);
EXPECT_STREQ(aOut, "");
str_hex(aOut, 2, pData, 4);
@ -290,6 +291,54 @@ TEST(Str, HexEncode)
EXPECT_STREQ(aOut, "41 42 ");
}
TEST(Str, HexEncodeCstyle)
{
char aOut[128];
const char *pData = "ABCD";
str_hex_cstyle(aOut, sizeof(aOut), pData, 0);
EXPECT_STREQ(aOut, "");
str_hex_cstyle(aOut, sizeof(aOut), pData, 1);
EXPECT_STREQ(aOut, "0x41");
str_hex_cstyle(aOut, sizeof(aOut), pData, 2);
EXPECT_STREQ(aOut, "0x41, 0x42");
str_hex_cstyle(aOut, sizeof(aOut), pData, 3);
EXPECT_STREQ(aOut, "0x41, 0x42, 0x43");
str_hex_cstyle(aOut, sizeof(aOut), pData, 4);
EXPECT_STREQ(aOut, "0x41, 0x42, 0x43, 0x44");
str_hex_cstyle(aOut, 1, pData, 4);
EXPECT_STREQ(aOut, "");
str_hex_cstyle(aOut, 2, pData, 4);
EXPECT_STREQ(aOut, "");
str_hex_cstyle(aOut, 3, pData, 4);
EXPECT_STREQ(aOut, "");
str_hex_cstyle(aOut, 4, pData, 4);
EXPECT_STREQ(aOut, "");
str_hex_cstyle(aOut, 5, pData, 4);
EXPECT_STREQ(aOut, "");
str_hex_cstyle(aOut, 6, pData, 4);
EXPECT_STREQ(aOut, "");
str_hex_cstyle(aOut, 7, pData, 4);
EXPECT_STREQ(aOut, "0x41");
str_hex_cstyle(aOut, 12, pData, 4);
EXPECT_STREQ(aOut, "0x41");
str_hex_cstyle(aOut, 13, pData, 4);
EXPECT_STREQ(aOut, "0x41, 0x42");
str_hex_cstyle(aOut, 14, pData, 4);
EXPECT_STREQ(aOut, "0x41, 0x42");
str_hex_cstyle(aOut, sizeof(aOut), pData, 4, 1);
EXPECT_STREQ(aOut, "0x41,\n0x42,\n0x43,\n0x44");
str_hex_cstyle(aOut, sizeof(aOut), pData, 4, 2);
EXPECT_STREQ(aOut, "0x41, 0x42,\n0x43, 0x44");
str_hex_cstyle(aOut, sizeof(aOut), pData, 4, 3);
EXPECT_STREQ(aOut, "0x41, 0x42, 0x43,\n0x44");
str_hex_cstyle(aOut, sizeof(aOut), pData, 4, 4);
EXPECT_STREQ(aOut, "0x41, 0x42, 0x43, 0x44");
str_hex_cstyle(aOut, sizeof(aOut), pData, 4, 500);
EXPECT_STREQ(aOut, "0x41, 0x42, 0x43, 0x44");
}
TEST(Str, HexDecode)
{
char aOut[5] = {'a', 'b', 'c', 'd', 0};