diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2015-08-22 09:30:08 +0200 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2015-08-22 09:30:08 +0200 |
commit | 951d1f91a4595500d50af52245eb0dbeff829aca (patch) | |
tree | 1bafff9fc29544d5045b8fca90aee6836c8c416d /src/core | |
parent | 8b47243516dab4462eb57fca2e3ce79b34b5c146 (diff) | |
download | weechat-951d1f91a4595500d50af52245eb0dbeff829aca.zip |
api: add function string_hex_dump()
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/wee-string.c | 105 | ||||
-rw-r--r-- | src/core/wee-string.h | 3 |
2 files changed, 108 insertions, 0 deletions
diff --git a/src/core/wee-string.c b/src/core/wee-string.c index 2f1adb7d9..389d12c62 100644 --- a/src/core/wee-string.c +++ b/src/core/wee-string.c @@ -2669,6 +2669,111 @@ string_decode_base64 (const char *from, char *to) } /* + * Dumps a data buffer as hexadecimal + ascii. + * + * Note: result must be freed after use. + */ + +char * +string_hex_dump (const char *data, int data_size, int bytes_per_line, + const char *prefix, const char *suffix) +{ + char *buf, *str_hexa, *str_ascii, str_format_line[64], *str_line; + int length_hexa, length_ascii, length_prefix, length_suffix, length_line; + int hexa_pos, ascii_pos, i; + + if (!data || (data_size < 1) || (bytes_per_line < 1)) + return NULL; + + str_hexa = NULL; + str_ascii = NULL; + str_line = NULL; + buf = NULL; + + length_hexa = bytes_per_line * 3; + str_hexa = malloc (length_hexa + 1); + if (!str_hexa) + goto end; + + length_ascii = bytes_per_line * 2; + str_ascii = malloc (length_ascii + 1); + if (!str_ascii) + goto end; + + length_prefix = (prefix) ? strlen (prefix) : 0; + length_suffix = (suffix) ? strlen (suffix) : 0; + + length_line = length_prefix + (bytes_per_line * 3) + 2 + length_ascii + + length_suffix; + str_line = malloc (length_line + 1); + if (!str_line) + goto end; + + buf = malloc ((((data_size / bytes_per_line) + 1) * (length_line + 1)) + 1); + if (!buf) + goto end; + buf[0] = '\0'; + + snprintf (str_format_line, sizeof (str_format_line), + "%%s%%-%ds %%-%ds%%s", + length_hexa, + length_ascii); + + hexa_pos = 0; + ascii_pos = 0; + for (i = 0; i < data_size; i++) + { + snprintf (str_hexa + hexa_pos, 4, + "%02X ", (unsigned char)(data[i])); + hexa_pos += 3; + snprintf (str_ascii + ascii_pos, 3, "%c ", + ((((unsigned char)data[i]) < 32) + || (((unsigned char)data[i]) > 127)) ? + '.' : (unsigned char)(data[i])); + ascii_pos += 2; + if (ascii_pos == bytes_per_line * 2) + { + if (buf[0]) + strcat (buf, "\n"); + str_ascii[ascii_pos - 1] = '\0'; + snprintf (str_line, length_line + 1, + str_format_line, + (prefix) ? prefix : "", + str_hexa, + str_ascii, + (suffix) ? suffix : ""); + strcat (buf, str_line); + hexa_pos = 0; + ascii_pos = 0; + } + } + if (ascii_pos > 0) + { + if (buf[0]) + strcat (buf, "\n"); + str_ascii[ascii_pos - 1] = '\0'; + str_ascii[ascii_pos] = '\0'; + snprintf (str_line, length_line + 1, + str_format_line, + (prefix) ? prefix : "", + str_hexa, + str_ascii, + (suffix) ? suffix : ""); + strcat (buf, str_line); + } + +end: + if (str_hexa) + free (str_hexa); + if (str_ascii) + free (str_ascii); + if (str_line) + free (str_line); + + return buf; +} + +/* * Checks if a string is a command. * * Returns: diff --git a/src/core/wee-string.h b/src/core/wee-string.h index 45df857b5..55899dead 100644 --- a/src/core/wee-string.h +++ b/src/core/wee-string.h @@ -91,6 +91,9 @@ extern void string_encode_base16 (const char *from, int length, char *to); extern int string_decode_base16 (const char *from, char *to); extern void string_encode_base64 (const char *from, int length, char *to); extern int string_decode_base64 (const char *from, char *to); +extern char *string_hex_dump (const char *data, int data_size, + int bytes_per_line, + const char *prefix, const char *suffix); extern int string_is_command_char (const char *string); extern const char *string_input_for_buffer (const char *string); extern char *string_replace_with_callback (const char *string, |