Print all-printable-ASCII byte arrays as strings
authorWill Thompson <will.thompson@collabora.co.uk>
Wed, 28 Oct 2009 19:40:38 +0000 (19:40 +0000)
committerColin Walters <walters@verbum.org>
Thu, 28 Jan 2010 22:01:24 +0000 (17:01 -0500)
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

index f934c7d..8a8e351 100644 (file)
@@ -21,6 +21,8 @@
  */
 #include "dbus-print-message.h"
 
+#include <stdlib.h>
+
 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)
 {