Make array-printing code easier to follow
[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
43 static void
44 indent (int depth)
45 {
46   while (depth-- > 0)
47     printf ("   ");
48 }
49
50 static void
51 print_iter (DBusMessageIter *iter, dbus_bool_t literal, int depth)
52 {
53   do
54     {
55       int type = dbus_message_iter_get_arg_type (iter);
56
57       if (type == DBUS_TYPE_INVALID)
58         break;
59       
60       indent(depth);
61
62       switch (type)
63         {
64         case DBUS_TYPE_STRING:
65           {
66             char *val;
67             dbus_message_iter_get_basic (iter, &val);
68             if (!literal)
69               printf ("string \"");
70             printf ("%s", val);
71             if (!literal)
72               printf ("\"\n");
73             break;
74           }
75
76         case DBUS_TYPE_SIGNATURE:
77           {
78             char *val;
79             dbus_message_iter_get_basic (iter, &val);
80             if (!literal)
81               printf ("signature \"");
82             printf ("%s", val);
83             if (!literal)
84               printf ("\"\n");
85             break;
86           }
87
88         case DBUS_TYPE_OBJECT_PATH:
89           {
90             char *val;
91             dbus_message_iter_get_basic (iter, &val);
92             if (!literal)
93               printf ("object path \"");
94             printf ("%s", val);
95             if (!literal)
96               printf ("\"\n");
97             break;
98           }
99
100         case DBUS_TYPE_INT16:
101           {
102             dbus_int16_t val;
103             dbus_message_iter_get_basic (iter, &val);
104             printf ("int16 %d\n", val);
105             break;
106           }
107
108         case DBUS_TYPE_UINT16:
109           {
110             dbus_uint16_t val;
111             dbus_message_iter_get_basic (iter, &val);
112             printf ("uint16 %u\n", val);
113             break;
114           }
115
116         case DBUS_TYPE_INT32:
117           {
118             dbus_int32_t val;
119             dbus_message_iter_get_basic (iter, &val);
120             printf ("int32 %d\n", val);
121             break;
122           }
123
124         case DBUS_TYPE_UINT32:
125           {
126             dbus_uint32_t val;
127             dbus_message_iter_get_basic (iter, &val);
128             printf ("uint32 %u\n", val);
129             break;
130           }
131
132         case DBUS_TYPE_INT64:
133           {
134             dbus_int64_t val;
135             dbus_message_iter_get_basic (iter, &val);
136             printf ("int64 %lld\n", val);
137             break;
138           }
139
140         case DBUS_TYPE_UINT64:
141           {
142             dbus_uint64_t val;
143             dbus_message_iter_get_basic (iter, &val);
144             printf ("uint64 %llu\n", val);
145             break;
146           }
147
148         case DBUS_TYPE_DOUBLE:
149           {
150             double val;
151             dbus_message_iter_get_basic (iter, &val);
152             printf ("double %g\n", val);
153             break;
154           }
155
156         case DBUS_TYPE_BYTE:
157           {
158             unsigned char val;
159             dbus_message_iter_get_basic (iter, &val);
160             printf ("byte %d\n", val);
161             break;
162           }
163
164         case DBUS_TYPE_BOOLEAN:
165           {
166             dbus_bool_t val;
167             dbus_message_iter_get_basic (iter, &val);
168             printf ("boolean %s\n", val ? "true" : "false");
169             break;
170           }
171
172         case DBUS_TYPE_VARIANT:
173           {
174             DBusMessageIter subiter;
175
176             dbus_message_iter_recurse (iter, &subiter);
177
178             printf ("variant ");
179             print_iter (&subiter, literal, depth+1);
180             break;
181           }
182         case DBUS_TYPE_ARRAY:
183           {
184             int current_type;
185             DBusMessageIter subiter;
186
187             dbus_message_iter_recurse (iter, &subiter);
188
189             current_type = dbus_message_iter_get_arg_type (&subiter);
190
191             printf("array [\n");
192             while (current_type != DBUS_TYPE_INVALID)
193               {
194                 print_iter (&subiter, literal, depth+1);
195
196                 dbus_message_iter_next (&subiter);
197                 current_type = dbus_message_iter_get_arg_type (&subiter);
198
199                 if (current_type != DBUS_TYPE_INVALID)
200                   printf (",");
201               }
202             indent(depth);
203             printf("]\n");
204             break;
205           }
206         case DBUS_TYPE_DICT_ENTRY:
207           {
208             DBusMessageIter subiter;
209
210             dbus_message_iter_recurse (iter, &subiter);
211
212             printf("dict entry(\n");
213             print_iter (&subiter, literal, depth+1);
214             dbus_message_iter_next (&subiter);
215             print_iter (&subiter, literal, depth+1);
216             indent(depth);
217             printf(")\n");
218             break;
219           }
220             
221         case DBUS_TYPE_STRUCT:
222           {
223             int current_type;
224             DBusMessageIter subiter;
225
226             dbus_message_iter_recurse (iter, &subiter);
227
228             printf("struct {\n");
229             while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
230               {
231                 print_iter (&subiter, literal, depth+1);
232                 dbus_message_iter_next (&subiter);
233                 if (dbus_message_iter_get_arg_type (&subiter) != DBUS_TYPE_INVALID)
234                   printf (",");
235               }
236             indent(depth);
237             printf("}\n");
238             break;
239           }
240             
241         default:
242           printf (" (dbus-monitor too dumb to decipher arg type '%c')\n", type);
243           break;
244         }
245     } while (dbus_message_iter_next (iter));
246 }
247
248 void
249 print_message (DBusMessage *message, dbus_bool_t literal)
250 {
251   DBusMessageIter iter;
252   const char *sender;
253   const char *destination;
254   int message_type;
255
256   message_type = dbus_message_get_type (message);
257   sender = dbus_message_get_sender (message);
258   destination = dbus_message_get_destination (message);
259   
260   if (!literal)
261     {
262       printf ("%s sender=%s -> dest=%s",
263               type_to_name (message_type),
264               sender ? sender : "(null sender)",
265               destination ? destination : "(null destination)");
266   
267       switch (message_type)
268         {
269         case DBUS_MESSAGE_TYPE_METHOD_CALL:
270         case DBUS_MESSAGE_TYPE_SIGNAL:
271           printf (" serial=%u path=%s; interface=%s; member=%s\n",
272                   dbus_message_get_serial (message),
273                   dbus_message_get_path (message),
274                   dbus_message_get_interface (message),
275                   dbus_message_get_member (message));
276           break;
277       
278         case DBUS_MESSAGE_TYPE_METHOD_RETURN:
279           printf (" reply_serial=%u\n",
280           dbus_message_get_reply_serial (message));
281           break;
282
283         case DBUS_MESSAGE_TYPE_ERROR:
284           printf (" error_name=%s reply_serial=%u\n",
285                   dbus_message_get_error_name (message),
286           dbus_message_get_reply_serial (message));
287           break;
288
289         default:
290           printf ("\n");
291           break;
292         }
293     }
294
295   dbus_message_iter_init (message, &iter);
296   print_iter (&iter, literal, 1);
297   fflush (stdout);
298   
299 }
300