Print byte arrays as nicely-formatted hex.
[platform/upstream/dbus.git] / tools / dbus-print-message.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-print-message.h  Utility function to print out a message
3  *
4  * Copyright (C) 2003 Philip Blundell <philb@gnu.org>
5  * Copyright (C) 2003 Red Hat, Inc.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20  *
21  */
22 #include "dbus-print-message.h"
23
24 static const char*
25 type_to_name (int message_type)
26 {
27   switch (message_type)
28     {
29     case DBUS_MESSAGE_TYPE_SIGNAL:
30       return "signal";
31     case DBUS_MESSAGE_TYPE_METHOD_CALL:
32       return "method call";
33     case DBUS_MESSAGE_TYPE_METHOD_RETURN:
34       return "method return";
35     case DBUS_MESSAGE_TYPE_ERROR:
36       return "error";
37     default:
38       return "(unknown message type)";
39     }
40 }
41
42 #define INDENT 3
43
44 static void
45 indent (int depth)
46 {
47   while (depth-- > 0)
48     printf ("   "); /* INDENT spaces. */
49 }
50
51 static void
52 print_ay (DBusMessageIter *iter, int depth)
53 {
54   int current_type;
55   int n = 0;
56   int columns;
57
58   printf ("array of bytes [\n");
59
60   indent (depth + 1);
61
62   /* Each byte takes 3 cells (two hexits, and a space), except the last one. */
63   columns = (80 - ((depth + 1) * INDENT)) / 3;
64
65   if (columns < 8)
66     columns = 8;
67
68   current_type = dbus_message_iter_get_arg_type (iter);
69
70   while (current_type != DBUS_TYPE_INVALID)
71     {
72       unsigned char val;
73       dbus_message_iter_get_basic (iter, &val);
74       printf ("%02x", val);
75
76       n++;
77
78       dbus_message_iter_next (iter);
79       current_type = dbus_message_iter_get_arg_type (iter);
80
81       if (current_type != DBUS_TYPE_INVALID)
82         {
83           if (n == columns)
84             {
85               printf ("\n");
86               indent (depth + 1);
87               n = 0;
88             }
89           else
90             {
91               printf (" ");
92             }
93         }
94     }
95
96   printf ("\n");
97   indent (depth);
98   printf ("]\n");
99 }
100
101 static void
102 print_iter (DBusMessageIter *iter, dbus_bool_t literal, int depth)
103 {
104   do
105     {
106       int type = dbus_message_iter_get_arg_type (iter);
107
108       if (type == DBUS_TYPE_INVALID)
109         break;
110       
111       indent(depth);
112
113       switch (type)
114         {
115         case DBUS_TYPE_STRING:
116           {
117             char *val;
118             dbus_message_iter_get_basic (iter, &val);
119             if (!literal)
120               printf ("string \"");
121             printf ("%s", val);
122             if (!literal)
123               printf ("\"\n");
124             break;
125           }
126
127         case DBUS_TYPE_SIGNATURE:
128           {
129             char *val;
130             dbus_message_iter_get_basic (iter, &val);
131             if (!literal)
132               printf ("signature \"");
133             printf ("%s", val);
134             if (!literal)
135               printf ("\"\n");
136             break;
137           }
138
139         case DBUS_TYPE_OBJECT_PATH:
140           {
141             char *val;
142             dbus_message_iter_get_basic (iter, &val);
143             if (!literal)
144               printf ("object path \"");
145             printf ("%s", val);
146             if (!literal)
147               printf ("\"\n");
148             break;
149           }
150
151         case DBUS_TYPE_INT16:
152           {
153             dbus_int16_t val;
154             dbus_message_iter_get_basic (iter, &val);
155             printf ("int16 %d\n", val);
156             break;
157           }
158
159         case DBUS_TYPE_UINT16:
160           {
161             dbus_uint16_t val;
162             dbus_message_iter_get_basic (iter, &val);
163             printf ("uint16 %u\n", val);
164             break;
165           }
166
167         case DBUS_TYPE_INT32:
168           {
169             dbus_int32_t val;
170             dbus_message_iter_get_basic (iter, &val);
171             printf ("int32 %d\n", val);
172             break;
173           }
174
175         case DBUS_TYPE_UINT32:
176           {
177             dbus_uint32_t val;
178             dbus_message_iter_get_basic (iter, &val);
179             printf ("uint32 %u\n", val);
180             break;
181           }
182
183         case DBUS_TYPE_INT64:
184           {
185             dbus_int64_t val;
186             dbus_message_iter_get_basic (iter, &val);
187             printf ("int64 %lld\n", val);
188             break;
189           }
190
191         case DBUS_TYPE_UINT64:
192           {
193             dbus_uint64_t val;
194             dbus_message_iter_get_basic (iter, &val);
195             printf ("uint64 %llu\n", val);
196             break;
197           }
198
199         case DBUS_TYPE_DOUBLE:
200           {
201             double val;
202             dbus_message_iter_get_basic (iter, &val);
203             printf ("double %g\n", val);
204             break;
205           }
206
207         case DBUS_TYPE_BYTE:
208           {
209             unsigned char val;
210             dbus_message_iter_get_basic (iter, &val);
211             printf ("byte %d\n", val);
212             break;
213           }
214
215         case DBUS_TYPE_BOOLEAN:
216           {
217             dbus_bool_t val;
218             dbus_message_iter_get_basic (iter, &val);
219             printf ("boolean %s\n", val ? "true" : "false");
220             break;
221           }
222
223         case DBUS_TYPE_VARIANT:
224           {
225             DBusMessageIter subiter;
226
227             dbus_message_iter_recurse (iter, &subiter);
228
229             printf ("variant ");
230             print_iter (&subiter, literal, depth+1);
231             break;
232           }
233         case DBUS_TYPE_ARRAY:
234           {
235             int current_type;
236             DBusMessageIter subiter;
237
238             dbus_message_iter_recurse (iter, &subiter);
239
240             current_type = dbus_message_iter_get_arg_type (&subiter);
241
242             if (current_type == DBUS_TYPE_BYTE)
243               {
244                 print_ay (&subiter, depth);
245                 break;
246               }
247
248             printf("array [\n");
249             while (current_type != DBUS_TYPE_INVALID)
250               {
251                 print_iter (&subiter, literal, depth+1);
252
253                 dbus_message_iter_next (&subiter);
254                 current_type = dbus_message_iter_get_arg_type (&subiter);
255
256                 if (current_type != DBUS_TYPE_INVALID)
257                   printf (",");
258               }
259             indent(depth);
260             printf("]\n");
261             break;
262           }
263         case DBUS_TYPE_DICT_ENTRY:
264           {
265             DBusMessageIter subiter;
266
267             dbus_message_iter_recurse (iter, &subiter);
268
269             printf("dict entry(\n");
270             print_iter (&subiter, literal, depth+1);
271             dbus_message_iter_next (&subiter);
272             print_iter (&subiter, literal, depth+1);
273             indent(depth);
274             printf(")\n");
275             break;
276           }
277             
278         case DBUS_TYPE_STRUCT:
279           {
280             int current_type;
281             DBusMessageIter subiter;
282
283             dbus_message_iter_recurse (iter, &subiter);
284
285             printf("struct {\n");
286             while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
287               {
288                 print_iter (&subiter, literal, depth+1);
289                 dbus_message_iter_next (&subiter);
290                 if (dbus_message_iter_get_arg_type (&subiter) != DBUS_TYPE_INVALID)
291                   printf (",");
292               }
293             indent(depth);
294             printf("}\n");
295             break;
296           }
297             
298         default:
299           printf (" (dbus-monitor too dumb to decipher arg type '%c')\n", type);
300           break;
301         }
302     } while (dbus_message_iter_next (iter));
303 }
304
305 void
306 print_message (DBusMessage *message, dbus_bool_t literal)
307 {
308   DBusMessageIter iter;
309   const char *sender;
310   const char *destination;
311   int message_type;
312
313   message_type = dbus_message_get_type (message);
314   sender = dbus_message_get_sender (message);
315   destination = dbus_message_get_destination (message);
316   
317   if (!literal)
318     {
319       printf ("%s sender=%s -> dest=%s",
320               type_to_name (message_type),
321               sender ? sender : "(null sender)",
322               destination ? destination : "(null destination)");
323   
324       switch (message_type)
325         {
326         case DBUS_MESSAGE_TYPE_METHOD_CALL:
327         case DBUS_MESSAGE_TYPE_SIGNAL:
328           printf (" serial=%u path=%s; interface=%s; member=%s\n",
329                   dbus_message_get_serial (message),
330                   dbus_message_get_path (message),
331                   dbus_message_get_interface (message),
332                   dbus_message_get_member (message));
333           break;
334       
335         case DBUS_MESSAGE_TYPE_METHOD_RETURN:
336           printf (" reply_serial=%u\n",
337           dbus_message_get_reply_serial (message));
338           break;
339
340         case DBUS_MESSAGE_TYPE_ERROR:
341           printf (" error_name=%s reply_serial=%u\n",
342                   dbus_message_get_error_name (message),
343           dbus_message_get_reply_serial (message));
344           break;
345
346         default:
347           printf ("\n");
348           break;
349         }
350     }
351
352   dbus_message_iter_init (message, &iter);
353   print_iter (&iter, literal, 1);
354   fflush (stdout);
355   
356 }
357