From 1e14e409a48a96e0599c8f675604735ca132fc0f Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Wed, 9 Sep 2009 20:35:13 +0100 Subject: [PATCH 1/3] Make array-printing code easier to follow Previously dbus_message_iter_get_arg_type() was called twice: once in the loop condition to update 'current_type', and once to check if the loop will run again. This patch moves updating current_type to the end of the loop body. --- tools/dbus-print-message.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tools/dbus-print-message.c b/tools/dbus-print-message.c index 335aa3dc..749fca68 100644 --- a/tools/dbus-print-message.c +++ b/tools/dbus-print-message.c @@ -186,12 +186,17 @@ print_iter (DBusMessageIter *iter, dbus_bool_t literal, int depth) dbus_message_iter_recurse (iter, &subiter); + current_type = dbus_message_iter_get_arg_type (&subiter); + printf("array [\n"); - while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID) + while (current_type != DBUS_TYPE_INVALID) { print_iter (&subiter, literal, depth+1); + dbus_message_iter_next (&subiter); - if (dbus_message_iter_get_arg_type (&subiter) != DBUS_TYPE_INVALID) + current_type = dbus_message_iter_get_arg_type (&subiter); + + if (current_type != DBUS_TYPE_INVALID) printf (","); } indent(depth); From 4d7968c06f30926a793a305288bd0c2a16bf90dd Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Wed, 9 Sep 2009 20:58:53 +0100 Subject: [PATCH 2/3] Print byte arrays as nicely-formatted hex. --- tools/dbus-print-message.c | 59 +++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/tools/dbus-print-message.c b/tools/dbus-print-message.c index 749fca68..f934c7d1 100644 --- a/tools/dbus-print-message.c +++ b/tools/dbus-print-message.c @@ -39,12 +39,63 @@ type_to_name (int message_type) } } +#define INDENT 3 static void indent (int depth) { while (depth-- > 0) - printf (" "); + printf (" "); /* INDENT spaces. */ +} + +static void +print_ay (DBusMessageIter *iter, int depth) +{ + int current_type; + int n = 0; + int columns; + + printf ("array of bytes [\n"); + + indent (depth + 1); + + /* Each byte takes 3 cells (two hexits, and a space), except the last one. */ + columns = (80 - ((depth + 1) * INDENT)) / 3; + + if (columns < 8) + columns = 8; + + current_type = dbus_message_iter_get_arg_type (iter); + + while (current_type != DBUS_TYPE_INVALID) + { + unsigned char val; + dbus_message_iter_get_basic (iter, &val); + printf ("%02x", val); + + n++; + + dbus_message_iter_next (iter); + current_type = dbus_message_iter_get_arg_type (iter); + + if (current_type != DBUS_TYPE_INVALID) + { + if (n == columns) + { + printf ("\n"); + indent (depth + 1); + n = 0; + } + else + { + printf (" "); + } + } + } + + printf ("\n"); + indent (depth); + printf ("]\n"); } static void @@ -188,6 +239,12 @@ print_iter (DBusMessageIter *iter, dbus_bool_t literal, int depth) current_type = dbus_message_iter_get_arg_type (&subiter); + if (current_type == DBUS_TYPE_BYTE) + { + print_ay (&subiter, depth); + break; + } + printf("array [\n"); while (current_type != DBUS_TYPE_INVALID) { From 80f6ebfef5b51290b26b968ae0ceff9b322efd67 Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Wed, 28 Oct 2009 19:40:38 +0000 Subject: [PATCH 3/3] Print all-printable-ASCII byte arrays as strings In practice, ay seems to be used mostly for binary data (in which case, hex output is fine) or for Unix file paths (because they may be non-UTF-8) and similar human-readable strings. So let's print the latter similarly to strings. --- tools/dbus-print-message.c | 75 +++++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 17 deletions(-) diff --git a/tools/dbus-print-message.c b/tools/dbus-print-message.c index f934c7d1..8a8e351d 100644 --- a/tools/dbus-print-message.c +++ b/tools/dbus-print-message.c @@ -21,6 +21,8 @@ */ #include "dbus-print-message.h" +#include + static const char* type_to_name (int message_type) { @@ -49,11 +51,9 @@ indent (int depth) } static void -print_ay (DBusMessageIter *iter, int depth) +print_hex (unsigned char *bytes, unsigned int len, int depth) { - int current_type; - int n = 0; - int columns; + int i, columns; printf ("array of bytes [\n"); @@ -65,26 +65,19 @@ print_ay (DBusMessageIter *iter, int depth) if (columns < 8) columns = 8; - current_type = dbus_message_iter_get_arg_type (iter); + i = 0; - while (current_type != DBUS_TYPE_INVALID) + while (i < len) { - unsigned char val; - dbus_message_iter_get_basic (iter, &val); - printf ("%02x", val); + printf ("%02x", bytes[i]); + i++; - n++; - - dbus_message_iter_next (iter); - current_type = dbus_message_iter_get_arg_type (iter); - - if (current_type != DBUS_TYPE_INVALID) + if (i != len) { - if (n == columns) + if (i % columns == 0) { printf ("\n"); indent (depth + 1); - n = 0; } else { @@ -98,6 +91,54 @@ print_ay (DBusMessageIter *iter, int depth) printf ("]\n"); } +#define DEFAULT_SIZE 100 + +static void +print_ay (DBusMessageIter *iter, int depth) +{ + /* Not using DBusString because it's not public API. It's 2009, and I'm + * manually growing a string chunk by chunk. + */ + unsigned char *bytes = malloc (DEFAULT_SIZE + 1); + unsigned int len = 0; + unsigned int max = DEFAULT_SIZE; + dbus_bool_t all_ascii = TRUE; + int current_type; + + while ((current_type = dbus_message_iter_get_arg_type (iter)) + != DBUS_TYPE_INVALID) + { + unsigned char val; + + dbus_message_iter_get_basic (iter, &val); + bytes[len] = val; + len++; + + if (val < 32 || val > 126) + all_ascii = FALSE; + + if (len == max) + { + max *= 2; + bytes = realloc (bytes, max + 1); + } + + dbus_message_iter_next (iter); + } + + if (all_ascii) + { + bytes[len] = '\0'; + printf ("array of bytes \"%s\"\n", bytes); + } + else + { + print_hex (bytes, len, depth); + } + + free (bytes); +} + static void print_iter (DBusMessageIter *iter, dbus_bool_t literal, int depth) {