1/* -*- mode: C; c-file-style: "gnu" -*- */
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 *
21 */
22#include "dbus-print-message.h"
23
24static const char*
25type_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
43static void
44indent (int depth)
45{
46  while (depth-- > 0)
47    printf ("   ");
48}
49
50static void
51print_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	    printf("array [\n");
190	    while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
191	      {
192		print_iter (&subiter, literal, depth+1);
193		dbus_message_iter_next (&subiter);
194		if (dbus_message_iter_get_arg_type (&subiter) != DBUS_TYPE_INVALID)
195		  printf (",");
196	      }
197	    indent(depth);
198	    printf("]\n");
199	    break;
200	  }
201	case DBUS_TYPE_DICT_ENTRY:
202	  {
203	    DBusMessageIter subiter;
204
205	    dbus_message_iter_recurse (iter, &subiter);
206
207	    printf("dict entry(\n");
208	    print_iter (&subiter, literal, depth+1);
209	    dbus_message_iter_next (&subiter);
210	    print_iter (&subiter, literal, depth+1);
211	    indent(depth);
212	    printf(")\n");
213	    break;
214	  }
215
216	case DBUS_TYPE_STRUCT:
217	  {
218	    int current_type;
219	    DBusMessageIter subiter;
220
221	    dbus_message_iter_recurse (iter, &subiter);
222
223	    printf("struct {\n");
224	    while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
225	      {
226		print_iter (&subiter, literal, depth+1);
227		dbus_message_iter_next (&subiter);
228		if (dbus_message_iter_get_arg_type (&subiter) != DBUS_TYPE_INVALID)
229		  printf (",");
230	      }
231	    indent(depth);
232	    printf("}\n");
233	    break;
234	  }
235
236	default:
237	  printf (" (dbus-monitor too dumb to decipher arg type '%c')\n", type);
238	  break;
239	}
240    } while (dbus_message_iter_next (iter));
241}
242
243void
244print_message (DBusMessage *message, dbus_bool_t literal)
245{
246  DBusMessageIter iter;
247  const char *sender;
248  const char *destination;
249  int message_type;
250
251  message_type = dbus_message_get_type (message);
252  sender = dbus_message_get_sender (message);
253  destination = dbus_message_get_destination (message);
254
255  if (!literal)
256    {
257      printf ("%s sender=%s -> dest=%s",
258	      type_to_name (message_type),
259	      sender ? sender : "(null sender)",
260	      destination ? destination : "(null destination)");
261
262      switch (message_type)
263	{
264	case DBUS_MESSAGE_TYPE_METHOD_CALL:
265	case DBUS_MESSAGE_TYPE_SIGNAL:
266	  printf (" path=%s; interface=%s; member=%s\n",
267		  dbus_message_get_path (message),
268		  dbus_message_get_interface (message),
269		  dbus_message_get_member (message));
270	  break;
271
272	case DBUS_MESSAGE_TYPE_METHOD_RETURN:
273	  printf ("\n");
274	  break;
275
276	case DBUS_MESSAGE_TYPE_ERROR:
277	  printf (" error_name=%s\n",
278		  dbus_message_get_error_name (message));
279	  break;
280
281	default:
282	  printf ("\n");
283	  break;
284	}
285    }
286
287  dbus_message_iter_init (message, &iter);
288  print_iter (&iter, literal, 1);
289  fflush (stdout);
290
291}
292
293