GDBus: Make message serialization routines take capabilities param
[platform/upstream/glib.git] / gio / gdbusmessage.c
1 /* GDBus - GLib D-Bus Library
2  *
3  * Copyright (C) 2008-2010 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: David Zeuthen <davidz@redhat.com>
21  */
22
23 #include "config.h"
24
25 #include <string.h>
26
27 #include "gdbusutils.h"
28 #include "gdbusmessage.h"
29 #include "gdbuserror.h"
30 #include "gioenumtypes.h"
31 #include "ginputstream.h"
32 #include "gdatainputstream.h"
33 #include "gmemoryinputstream.h"
34 #include "goutputstream.h"
35 #include "gdataoutputstream.h"
36 #include "gmemoryoutputstream.h"
37 #include "gseekable.h"
38 #include "gioerror.h"
39
40 #ifdef G_OS_UNIX
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <unistd.h>
44 #include <errno.h>
45 #endif
46
47 #include "glibintl.h"
48 #include "gioalias.h"
49
50 /**
51  * SECTION:gdbusmessage
52  * @short_description: D-Bus Message
53  * @include: gio/gio.h
54  *
55  * A type for representing D-Bus messages that can be sent or received
56  * on a #GDBusConnection.
57  */
58
59 struct _GDBusMessagePrivate
60 {
61   GDBusMessageType type;
62   GDBusMessageFlags flags;
63   guchar major_protocol_version;
64   guint32 serial;
65   GHashTable *headers;
66   GVariant *body;
67 #ifdef G_OS_UNIX
68   GUnixFDList *fd_list;
69 #endif
70 };
71
72 G_DEFINE_TYPE (GDBusMessage, g_dbus_message, G_TYPE_OBJECT);
73
74 static void
75 g_dbus_message_finalize (GObject *object)
76 {
77   GDBusMessage *message = G_DBUS_MESSAGE (object);
78
79   if (message->priv->headers != NULL)
80     g_hash_table_unref (message->priv->headers);
81   if (message->priv->body != NULL)
82     g_variant_unref (message->priv->body);
83 #ifdef G_OS_UNIX
84   if (message->priv->fd_list != NULL)
85     g_object_unref (message->priv->fd_list);
86 #endif
87
88   if (G_OBJECT_CLASS (g_dbus_message_parent_class)->finalize != NULL)
89     G_OBJECT_CLASS (g_dbus_message_parent_class)->finalize (object);
90 }
91
92 static void
93 g_dbus_message_class_init (GDBusMessageClass *klass)
94 {
95   GObjectClass *gobject_class;
96
97   g_type_class_add_private (klass, sizeof (GDBusMessagePrivate));
98
99   gobject_class = G_OBJECT_CLASS (klass);
100
101   gobject_class->finalize     = g_dbus_message_finalize;
102 }
103
104 static void
105 g_dbus_message_init (GDBusMessage *message)
106 {
107   message->priv = G_TYPE_INSTANCE_GET_PRIVATE (message, G_TYPE_DBUS_MESSAGE, GDBusMessagePrivate);
108
109   message->priv->headers = g_hash_table_new_full (g_direct_hash,
110                                                   g_direct_equal,
111                                                   NULL,
112                                                   (GDestroyNotify) g_variant_unref);
113 }
114
115 /**
116  * g_dbus_message_new:
117  *
118  * Creates a new empty #GDBusMessage.
119  *
120  * Returns: A #GDBusMessage. Free with g_object_unref().
121  *
122  * Since: 2.26
123  */
124 GDBusMessage *
125 g_dbus_message_new (void)
126 {
127   return g_object_new (G_TYPE_DBUS_MESSAGE, NULL);
128 }
129
130 /**
131  * g_dbus_message_new_method_call:
132  * @name: A valid D-Bus name or %NULL.
133  * @path: A valid object path.
134  * @interface: A valid D-Bus interface name or %NULL.
135  * @method: A valid method name.
136  *
137  * Creates a new #GDBusMessage for a method call.
138  *
139  * Returns: A #GDBusMessage. Free with g_object_unref().
140  *
141  * Since: 2.26
142  */
143 GDBusMessage *
144 g_dbus_message_new_method_call (const gchar *name,
145                                 const gchar *path,
146                                 const gchar *interface,
147                                 const gchar *method)
148 {
149   GDBusMessage *message;
150
151   g_return_val_if_fail (name == NULL || g_dbus_is_name (name), NULL);
152   g_return_val_if_fail (g_variant_is_object_path (path), NULL);
153   g_return_val_if_fail (g_dbus_is_member_name (method), NULL);
154   g_return_val_if_fail (interface == NULL || g_dbus_is_interface_name (interface), NULL);
155
156   message = g_dbus_message_new ();
157   message->priv->type = G_DBUS_MESSAGE_TYPE_METHOD_CALL;
158
159   if (name != NULL)
160     g_dbus_message_set_destination (message, name);
161   g_dbus_message_set_path (message, path);
162   g_dbus_message_set_member (message, method);
163   if (interface != NULL)
164     g_dbus_message_set_interface (message, interface);
165
166   return message;
167 }
168
169 /**
170  * g_dbus_message_new_signal:
171  * @path: A valid object path.
172  * @interface: A valid D-Bus interface name or %NULL.
173  * @signal: A valid signal name.
174  *
175  * Creates a new #GDBusMessage for a signal emission.
176  *
177  * Returns: A #GDBusMessage. Free with g_object_unref().
178  *
179  * Since: 2.26
180  */
181 GDBusMessage *
182 g_dbus_message_new_signal (const gchar  *path,
183                            const gchar  *interface,
184                            const gchar  *signal)
185 {
186   GDBusMessage *message;
187
188   g_return_val_if_fail (g_variant_is_object_path (path), NULL);
189   g_return_val_if_fail (g_dbus_is_member_name (signal), NULL);
190   g_return_val_if_fail (interface == NULL || g_dbus_is_interface_name (interface), NULL);
191
192   message = g_dbus_message_new ();
193   message->priv->type = G_DBUS_MESSAGE_TYPE_SIGNAL;
194   message->priv->flags = G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED;
195
196   g_dbus_message_set_path (message, path);
197   g_dbus_message_set_member (message, signal);
198
199   if (interface != NULL)
200     g_dbus_message_set_interface (message, interface);
201
202   return message;
203 }
204
205
206 /**
207  * g_dbus_message_new_method_reply:
208  * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to
209  * create a reply message to.
210  *
211  * Creates a new #GDBusMessage that is a reply to @method_call_message.
212  *
213  * Returns: A #GDBusMessage. Free with g_object_unref().
214  *
215  * Since: 2.26
216  */
217 GDBusMessage *
218 g_dbus_message_new_method_reply (GDBusMessage *method_call_message)
219 {
220   GDBusMessage *message;
221   const gchar *sender;
222
223   g_return_val_if_fail (G_IS_DBUS_MESSAGE (method_call_message), NULL);
224   g_return_val_if_fail (g_dbus_message_get_message_type (method_call_message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL, NULL);
225   g_return_val_if_fail (g_dbus_message_get_serial (method_call_message) != 0, NULL);
226
227   message = g_dbus_message_new ();
228   message->priv->type = G_DBUS_MESSAGE_TYPE_METHOD_RETURN;
229   message->priv->flags = G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED;
230
231   g_dbus_message_set_reply_serial (message, g_dbus_message_get_serial (method_call_message));
232   sender = g_dbus_message_get_sender (method_call_message);
233   if (sender != NULL)
234     g_dbus_message_set_destination (message, sender);
235
236   return message;
237 }
238
239 /**
240  * g_dbus_message_new_method_error:
241  * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to
242  * create a reply message to.
243  * @error_name: A valid D-Bus error name.
244  * @error_message_format: The D-Bus error message in a printf() format.
245  * @...: Arguments for @error_message_format.
246  *
247  * Creates a new #GDBusMessage that is an error reply to @method_call_message.
248  *
249  * Returns: A #GDBusMessage. Free with g_object_unref().
250  *
251  * Since: 2.26
252  */
253 GDBusMessage *
254 g_dbus_message_new_method_error (GDBusMessage             *method_call_message,
255                                  const gchar              *error_name,
256                                  const gchar              *error_message_format,
257                                  ...)
258 {
259   GDBusMessage *ret;
260   va_list var_args;
261
262   va_start (var_args, error_message_format);
263   ret = g_dbus_message_new_method_error_valist (method_call_message,
264                                                 error_name,
265                                                 error_message_format,
266                                                 var_args);
267   va_end (var_args);
268
269   return ret;
270 }
271
272 /**
273  * g_dbus_message_new_method_error_literal:
274  * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to
275  * create a reply message to.
276  * @error_name: A valid D-Bus error name.
277  * @error_message: The D-Bus error message.
278  *
279  * Creates a new #GDBusMessage that is an error reply to @method_call_message.
280  *
281  * Returns: A #GDBusMessage. Free with g_object_unref().
282  *
283  * Since: 2.26
284  */
285 GDBusMessage *
286 g_dbus_message_new_method_error_literal (GDBusMessage  *method_call_message,
287                                          const gchar   *error_name,
288                                          const gchar   *error_message)
289 {
290   GDBusMessage *message;
291   const gchar *sender;
292
293   g_return_val_if_fail (G_IS_DBUS_MESSAGE (method_call_message), NULL);
294   g_return_val_if_fail (g_dbus_message_get_message_type (method_call_message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL, NULL);
295   g_return_val_if_fail (g_dbus_message_get_serial (method_call_message) != 0, NULL);
296   g_return_val_if_fail (g_dbus_is_name (error_name), NULL);
297   g_return_val_if_fail (error_message != NULL, NULL);
298
299   message = g_dbus_message_new ();
300   message->priv->type = G_DBUS_MESSAGE_TYPE_ERROR;
301   message->priv->flags = G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED;
302
303   g_dbus_message_set_reply_serial (message, g_dbus_message_get_serial (method_call_message));
304   g_dbus_message_set_error_name (message, error_name);
305   g_dbus_message_set_body (message, g_variant_new ("(s)", error_message));
306
307   sender = g_dbus_message_get_sender (method_call_message);
308   if (sender != NULL)
309     g_dbus_message_set_destination (message, sender);
310
311   return message;
312 }
313
314 /**
315  * g_dbus_message_new_method_error_valist:
316  * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to
317  * create a reply message to.
318  * @error_name: A valid D-Bus error name.
319  * @error_message_format: The D-Bus error message in a printf() format.
320  * @var_args: Arguments for @error_message_format.
321  *
322  * Like g_dbus_message_new_method_error() but intended for language bindings.
323  *
324  * Returns: A #GDBusMessage. Free with g_object_unref().
325  *
326  * Since: 2.26
327  */
328 GDBusMessage *
329 g_dbus_message_new_method_error_valist (GDBusMessage             *method_call_message,
330                                         const gchar              *error_name,
331                                         const gchar              *error_message_format,
332                                         va_list                   var_args)
333 {
334   GDBusMessage *ret;
335   gchar *error_message;
336   error_message = g_strdup_vprintf (error_message_format, var_args);
337   ret = g_dbus_message_new_method_error_literal (method_call_message,
338                                                  error_name,
339                                                  error_message);
340   g_free (error_message);
341   return ret;
342 }
343
344 /* ---------------------------------------------------------------------------------------------------- */
345
346 /* TODO: need GI annotations to specify that any guchar value goes for the type */
347
348 /**
349  * g_dbus_message_get_message_type:
350  * @message: A #GDBusMessage.
351  *
352  * Gets the type of @message.
353  *
354  * Returns: A 8-bit unsigned integer (typically a value from the #GDBusMessageType enumeration).
355  *
356  * Since: 2.26
357  */
358 GDBusMessageType
359 g_dbus_message_get_message_type (GDBusMessage  *message)
360 {
361   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), G_DBUS_MESSAGE_TYPE_INVALID);
362   return message->priv->type;
363 }
364
365 /**
366  * g_dbus_message_set_message_type:
367  * @message: A #GDBusMessage.
368  * @type: A 8-bit unsigned integer (typically a value from the #GDBusMessageType enumeration).
369  *
370  * Sets @message to be of @type.
371  *
372  * Since: 2.26
373  */
374 void
375 g_dbus_message_set_message_type (GDBusMessage      *message,
376                                  GDBusMessageType   type)
377 {
378   g_return_if_fail (G_IS_DBUS_MESSAGE (message));
379   g_return_if_fail (type >=0 && type < 256);
380   message->priv->type = type;
381 }
382
383 /* ---------------------------------------------------------------------------------------------------- */
384
385 /* TODO: need GI annotations to specify that any guchar value goes for flags */
386
387 /**
388  * g_dbus_message_get_flags:
389  * @message: A #GDBusMessage.
390  *
391  * Gets the flags for @message.
392  *
393  * Returns: Flags that are set (typically values from the #GDBusMessageFlags enumeration bitwise ORed together).
394  *
395  * Since: 2.26
396  */
397 GDBusMessageFlags
398 g_dbus_message_get_flags (GDBusMessage  *message)
399 {
400   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), G_DBUS_MESSAGE_FLAGS_NONE);
401   return message->priv->flags;
402 }
403
404 /**
405  * g_dbus_message_set_flags:
406  * @message: A #GDBusMessage.
407  * @flags: Flags for @message that are set (typically values from the #GDBusMessageFlags
408  * enumeration bitwise ORed together).
409  *
410  * Sets the flags to set on @message.
411  *
412  * Since: 2.26
413  */
414 void
415 g_dbus_message_set_flags (GDBusMessage       *message,
416                           GDBusMessageFlags   flags)
417 {
418   g_return_if_fail (G_IS_DBUS_MESSAGE (message));
419   g_return_if_fail (flags >=0 && flags < 256);
420   message->priv->flags = flags;
421 }
422
423 /* ---------------------------------------------------------------------------------------------------- */
424
425 /**
426  * g_dbus_message_get_serial:
427  * @message: A #GDBusMessage.
428  *
429  * Gets the serial for @message.
430  *
431  * Returns: A #guint32.
432  *
433  * Since: 2.26
434  */
435 guint32
436 g_dbus_message_get_serial (GDBusMessage *message)
437 {
438   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), 0);
439   return message->priv->serial;
440 }
441
442 /**
443  * g_dbus_message_set_serial:
444  * @message: A #GDBusMessage.
445  * @serial: A #guint32.
446  *
447  * Sets the serial for @message.
448  *
449  * Since: 2.26
450  */
451 void
452 g_dbus_message_set_serial (GDBusMessage  *message,
453                            guint32        serial)
454 {
455   g_return_if_fail (G_IS_DBUS_MESSAGE (message));
456   message->priv->serial = serial;
457 }
458
459 /* ---------------------------------------------------------------------------------------------------- */
460
461 /* TODO: need GI annotations to specify that any guchar value goes for header_field */
462
463 /**
464  * g_dbus_message_get_header:
465  * @message: A #GDBusMessage.
466  * @header_field: A 8-bit unsigned integer (typically a value from the #GDBusMessageHeaderField enumeration)
467  *
468  * Gets a header field on @message.
469  *
470  * Returns: A #GVariant with the value if the header was found, %NULL
471  * otherwise. Do not free, it is owned by @message.
472  *
473  * Since: 2.26
474  */
475 GVariant *
476 g_dbus_message_get_header (GDBusMessage             *message,
477                            GDBusMessageHeaderField   header_field)
478 {
479   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
480   g_return_val_if_fail (header_field >=0 && header_field < 256, NULL);
481   return g_hash_table_lookup (message->priv->headers, GUINT_TO_POINTER (header_field));
482 }
483
484 /**
485  * g_dbus_message_set_header:
486  * @message: A #GDBusMessage.
487  * @header_field: A 8-bit unsigned integer (typically a value from the #GDBusMessageHeaderField enumeration)
488  * @value: A #GVariant to set the header field or %NULL to clear the header field.
489  *
490  * Sets a header field on @message.
491  *
492  * If @value is floating, @message assumes ownership of @value.
493  *
494  * Since: 2.26
495  */
496 void
497 g_dbus_message_set_header (GDBusMessage             *message,
498                            GDBusMessageHeaderField   header_field,
499                            GVariant                 *value)
500 {
501   g_return_if_fail (G_IS_DBUS_MESSAGE (message));
502   g_return_if_fail (header_field >=0 && header_field < 256);
503   if (value == NULL)
504     {
505       g_hash_table_remove (message->priv->headers, GUINT_TO_POINTER (header_field));
506     }
507   else
508     {
509       g_hash_table_insert (message->priv->headers, GUINT_TO_POINTER (header_field), g_variant_ref_sink (value));
510     }
511 }
512
513 /**
514  * g_dbus_message_get_header_fields:
515  * @message: A #GDBusMessage.
516  *
517  * Gets an array of all header fields on @message that are set.
518  *
519  * Returns: An array of header fields terminated by
520  * %G_DBUS_MESSAGE_HEADER_FIELD_INVALID.  Each element is a
521  * #guchar. Free with g_free().
522  *
523  * Since: 2.26
524  */
525 guchar *
526 g_dbus_message_get_header_fields (GDBusMessage  *message)
527 {
528   GList *keys;
529   guchar *ret;
530   guint num_keys;
531   GList *l;
532   guint n;
533
534   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
535
536   keys = g_hash_table_get_keys (message->priv->headers);
537   num_keys = g_list_length (keys);
538   ret = g_new (guchar, num_keys + 1);
539   for (l = keys, n = 0; l != NULL; l = l->next, n++)
540     ret[n] = GPOINTER_TO_UINT (l->data);
541   g_assert (n == num_keys);
542   ret[n] = G_DBUS_MESSAGE_HEADER_FIELD_INVALID;
543   g_list_free (keys);
544
545   return ret;
546 }
547
548 /* ---------------------------------------------------------------------------------------------------- */
549
550 /**
551  * g_dbus_message_get_body:
552  * @message: A #GDBusMessage.
553  *
554  * Gets the body of a message.
555  *
556  * Returns: A #GVariant or %NULL if the body is empty. Do not free, it is owned by @message.
557  *
558  * Since: 2.26
559  */
560 GVariant *
561 g_dbus_message_get_body (GDBusMessage  *message)
562 {
563   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
564   return message->priv->body;
565 }
566
567 /**
568  * g_dbus_message_set_body:
569  * @message: A #GDBusMessage.
570  * @body: Either %NULL or a #GVariant that is a tuple.
571  *
572  * Sets the body @message. As a side-effect the
573  * %G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE header field is set to the
574  * type string of @body (or cleared if @body is %NULL).
575  *
576  * If @body is floating, @message assumes ownership of @body.
577  *
578  * Since: 2.26
579  */
580 void
581 g_dbus_message_set_body (GDBusMessage  *message,
582                          GVariant      *body)
583 {
584   g_return_if_fail (G_IS_DBUS_MESSAGE (message));
585   g_return_if_fail ((body == NULL) || g_variant_is_of_type (body, G_VARIANT_TYPE_TUPLE));
586
587   if (message->priv->body != NULL)
588     g_variant_unref (message->priv->body);
589   if (body == NULL)
590     {
591       message->priv->body = NULL;
592       g_dbus_message_set_signature (message, NULL);
593     }
594   else
595     {
596       const gchar *type_string;
597       gsize type_string_len;
598       gchar *signature;
599
600       message->priv->body = g_variant_ref_sink (body);
601
602       type_string = g_variant_get_type_string (body);
603       type_string_len = strlen (type_string);
604       g_assert (type_string_len >= 2);
605       signature = g_strndup (type_string + 1, type_string_len - 2);
606       g_dbus_message_set_signature (message, signature);
607       g_free (signature);
608     }
609 }
610
611 /* ---------------------------------------------------------------------------------------------------- */
612
613 #ifdef G_OS_UNIX
614 /**
615  * g_dbus_message_get_unix_fd_list:
616  * @message: A #GDBusMessage.
617  *
618  * Gets the UNIX file descriptors associated with @message, if any.
619  *
620  * This method is only available on UNIX.
621  *
622  * Returns: A #GUnixFDList or %NULL if no file descriptors are
623  * associated. Do not free, this object is owned by @message.
624  *
625  * Since: 2.26
626  */
627 GUnixFDList *
628 g_dbus_message_get_unix_fd_list (GDBusMessage  *message)
629 {
630   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
631   return message->priv->fd_list;
632 }
633
634 /**
635  * g_dbus_message_set_unix_fd_list:
636  * @message: A #GDBusMessage.
637  * @fd_list: A #GUnixFDList or %NULL.
638  *
639  * Sets the UNIX file descriptors associated with @message. As a
640  * side-effect the %G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS header
641  * field is set to the number of fds in @fd_list (or cleared if
642  * @fd_list is %NULL).
643  *
644  * This method is only available on UNIX.
645  *
646  * Since: 2.26
647  */
648 void
649 g_dbus_message_set_unix_fd_list (GDBusMessage  *message,
650                                  GUnixFDList   *fd_list)
651 {
652   g_return_if_fail (G_IS_DBUS_MESSAGE (message));
653   g_return_if_fail (fd_list == NULL || G_IS_UNIX_FD_LIST (fd_list));
654   if (message->priv->fd_list != NULL)
655     g_object_unref (message->priv->fd_list);
656   if (fd_list != NULL)
657     {
658       message->priv->fd_list = g_object_ref (fd_list);
659       g_dbus_message_set_num_unix_fds (message, g_unix_fd_list_get_length (fd_list));
660     }
661   else
662     {
663       message->priv->fd_list = NULL;
664       g_dbus_message_set_num_unix_fds (message, 0);
665     }
666 }
667 #endif
668
669 /* ---------------------------------------------------------------------------------------------------- */
670
671 static gboolean
672 ensure_input_padding (GMemoryInputStream   *mis,
673                       gsize                 padding_size,
674                       GError              **error)
675 {
676   gsize offset;
677   gsize wanted_offset;
678
679   offset = g_seekable_tell (G_SEEKABLE (mis));
680   wanted_offset = ((offset + padding_size - 1) / padding_size) * padding_size;
681
682   return g_seekable_seek (G_SEEKABLE (mis), wanted_offset, G_SEEK_SET, NULL, error);
683 }
684
685 static gchar *
686 read_string (GMemoryInputStream    *mis,
687              GDataInputStream      *dis,
688              gsize                  len,
689              GError               **error)
690 {
691   GString *s;
692   gchar buf[256];
693   gsize remaining;
694   guchar nul;
695   GError *local_error;
696
697   s = g_string_new (NULL);
698
699   remaining = len;
700   while (remaining > 0)
701     {
702       gsize to_read;
703       gssize num_read;
704
705       to_read = MIN (remaining, sizeof (buf));
706       num_read = g_input_stream_read (G_INPUT_STREAM (mis),
707                                       buf,
708                                       to_read,
709                                       NULL,
710                                       error);
711       if (num_read < 0)
712         goto fail;
713       if (num_read == 0)
714         {
715           g_set_error (error,
716                        G_IO_ERROR,
717                        G_IO_ERROR_INVALID_ARGUMENT,
718                        _("Wanted to read %" G_GSIZE_FORMAT " bytes but got EOF"),
719                        to_read);
720           goto fail;
721         }
722
723       remaining -= num_read;
724       g_string_append_len (s, buf, num_read);
725     }
726
727   local_error = NULL;
728   nul = g_data_input_stream_read_byte (dis, NULL, &local_error);
729   if (local_error != NULL)
730     {
731       g_propagate_error (error, local_error);
732       goto fail;
733     }
734   if (nul != '\0')
735     {
736       g_set_error (error,
737                    G_IO_ERROR,
738                    G_IO_ERROR_INVALID_ARGUMENT,
739                    _("Expected NUL byte after the string `%s' but found `%c' (%d)"),
740                    s->str, nul, nul);
741       goto fail;
742     }
743
744   return g_string_free (s, FALSE);
745
746  fail:
747   g_string_free (s, TRUE);
748   return NULL;
749 }
750
751 static GVariant *
752 parse_value_from_blob (GMemoryInputStream    *mis,
753                        GDataInputStream      *dis,
754                        const GVariantType    *type,
755                        GError               **error)
756 {
757   GVariant *ret;
758   GError *local_error;
759
760   local_error = NULL;
761   if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
762     {
763       gboolean v;
764       if (!ensure_input_padding (mis, 4, &local_error))
765         goto fail;
766       v = g_data_input_stream_read_uint32 (dis, NULL, &local_error);
767       if (local_error != NULL)
768         goto fail;
769       ret = g_variant_new_boolean (v);
770     }
771   else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
772     {
773       guchar v;
774       v = g_data_input_stream_read_byte (dis, NULL, &local_error);
775       if (local_error != NULL)
776         goto fail;
777       ret = g_variant_new_byte (v);
778     }
779   else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
780     {
781       gint16 v;
782       if (!ensure_input_padding (mis, 2, &local_error))
783         goto fail;
784       v = g_data_input_stream_read_int16 (dis, NULL, &local_error);
785       if (local_error != NULL)
786         goto fail;
787       ret = g_variant_new_int16 (v);
788     }
789   else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
790     {
791       guint16 v;
792       if (!ensure_input_padding (mis, 2, &local_error))
793         goto fail;
794       v = g_data_input_stream_read_uint16 (dis, NULL, &local_error);
795       if (local_error != NULL)
796         goto fail;
797       ret = g_variant_new_uint16 (v);
798     }
799   else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
800     {
801       gint32 v;
802       if (!ensure_input_padding (mis, 4, &local_error))
803         goto fail;
804       v = g_data_input_stream_read_int32 (dis, NULL, &local_error);
805       if (local_error != NULL)
806         goto fail;
807       ret = g_variant_new_int32 (v);
808     }
809   else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
810     {
811       guint32 v;
812       if (!ensure_input_padding (mis, 4, &local_error))
813         goto fail;
814       v = g_data_input_stream_read_uint32 (dis, NULL, &local_error);
815       if (local_error != NULL)
816         goto fail;
817       ret = g_variant_new_uint32 (v);
818     }
819   else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
820     {
821       gint64 v;
822       if (!ensure_input_padding (mis, 8, &local_error))
823         goto fail;
824       v = g_data_input_stream_read_int64 (dis, NULL, &local_error);
825       if (local_error != NULL)
826         goto fail;
827       ret = g_variant_new_int64 (v);
828     }
829   else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
830     {
831       guint64 v;
832       if (!ensure_input_padding (mis, 8, &local_error))
833         goto fail;
834       v = g_data_input_stream_read_uint64 (dis, NULL, &local_error);
835       if (local_error != NULL)
836         goto fail;
837       ret = g_variant_new_uint64 (v);
838     }
839   else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
840     {
841       guint64 v;
842       gdouble *encoded;
843       if (!ensure_input_padding (mis, 8, &local_error))
844         goto fail;
845       v = g_data_input_stream_read_uint64 (dis, NULL, &local_error);
846       if (local_error != NULL)
847         goto fail;
848       /* TODO: hmm */
849       encoded = (gdouble *) &v;
850       ret = g_variant_new_double (*encoded);
851     }
852   else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
853     {
854       guint32 len;
855       gchar *v;
856       if (!ensure_input_padding (mis, 4, &local_error))
857         goto fail;
858       len = g_data_input_stream_read_uint32 (dis, NULL, &local_error);
859       if (local_error != NULL)
860         goto fail;
861       v = read_string (mis, dis, (gsize) len, &local_error);
862       if (v == NULL)
863         goto fail;
864       ret = g_variant_new_string (v);
865     }
866   else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
867     {
868       guint32 len;
869       gchar *v;
870       if (!ensure_input_padding (mis, 4, &local_error))
871         goto fail;
872       len = g_data_input_stream_read_uint32 (dis, NULL, &local_error);
873       if (local_error != NULL)
874         goto fail;
875       v = read_string (mis, dis, (gsize) len, &local_error);
876       if (v == NULL)
877         goto fail;
878       if (!g_variant_is_object_path (v))
879         {
880           g_set_error (&local_error,
881                        G_IO_ERROR,
882                        G_IO_ERROR_INVALID_ARGUMENT,
883                        _("Parsed value `%s' is not a valid D-Bus object path"),
884                        v);
885           goto fail;
886         }
887       ret = g_variant_new_object_path (v);
888     }
889   else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
890     {
891       guchar len;
892       gchar *v;
893       len = g_data_input_stream_read_byte (dis, NULL, &local_error);
894       if (local_error != NULL)
895         goto fail;
896       v = read_string (mis, dis, (gsize) len, &local_error);
897       if (v == NULL)
898         goto fail;
899       if (!g_variant_is_signature (v))
900         {
901           g_set_error (&local_error,
902                        G_IO_ERROR,
903                        G_IO_ERROR_INVALID_ARGUMENT,
904                        _("Parsed value `%s' is not a valid D-Bus signature"),
905                        v);
906           goto fail;
907         }
908       ret = g_variant_new_signature (v);
909     }
910   else if (g_variant_type_is_array (type))
911     {
912       guint32 array_len;
913       goffset offset;
914       goffset target;
915       const GVariantType *element_type;
916       GVariantBuilder *builder;
917
918       if (!ensure_input_padding (mis, 4, &local_error))
919         goto fail;
920       array_len = g_data_input_stream_read_uint32 (dis, NULL, &local_error);
921
922       if (array_len > (2<<26))
923         {
924           g_set_error (&local_error,
925                        G_IO_ERROR,
926                        G_IO_ERROR_INVALID_ARGUMENT,
927                        _("Encountered array of length %" G_GUINT32_FORMAT " bytes. Maximum length is 2<<26 bytes."),
928                        array_len);
929           goto fail;
930         }
931
932       builder = g_variant_builder_new (type);
933       element_type = g_variant_type_element (type);
934
935       /* TODO: optimize array of primitive types */
936
937       offset = g_seekable_tell (G_SEEKABLE (mis));
938       target = offset + array_len;
939       while (offset < target)
940         {
941           GVariant *item;
942           item = parse_value_from_blob (mis, dis, element_type, &local_error);
943           if (item == NULL)
944             {
945               g_variant_builder_unref (builder);
946               goto fail;
947             }
948           g_variant_builder_add_value (builder, item);
949           offset = g_seekable_tell (G_SEEKABLE (mis));
950         }
951
952       ret = g_variant_builder_end (builder);
953     }
954   else if (g_variant_type_is_dict_entry (type))
955     {
956       const GVariantType *key_type;
957       const GVariantType *value_type;
958       GVariant *key;
959       GVariant *value;
960
961       if (!ensure_input_padding (mis, 8, &local_error))
962         goto fail;
963
964       key_type = g_variant_type_key (type);
965       key = parse_value_from_blob (mis, dis, key_type, &local_error);
966       if (key == NULL)
967         goto fail;
968
969       value_type = g_variant_type_value (type);
970       value = parse_value_from_blob (mis, dis, value_type, &local_error);
971       if (value == NULL)
972         {
973           g_variant_unref (key);
974           goto fail;
975         }
976       ret = g_variant_new_dict_entry (key, value);
977     }
978   else if (g_variant_type_is_tuple (type))
979     {
980       const GVariantType *element_type;
981       GVariantBuilder *builder;
982
983       if (!ensure_input_padding (mis, 8, &local_error))
984         goto fail;
985
986       builder = g_variant_builder_new (type);
987       element_type = g_variant_type_first (type);
988       while (element_type != NULL)
989         {
990           GVariant *item;
991           item = parse_value_from_blob (mis, dis, element_type, &local_error);
992           if (item == NULL)
993             {
994               g_variant_builder_unref (builder);
995               goto fail;
996             }
997           g_variant_builder_add_value (builder, item);
998
999           element_type = g_variant_type_next (element_type);
1000         }
1001       ret = g_variant_builder_end (builder);
1002     }
1003   else if (g_variant_type_is_variant (type))
1004     {
1005       guchar siglen;
1006       gchar *sig;
1007       GVariantType *variant_type;
1008       GVariant *value;
1009
1010       siglen = g_data_input_stream_read_byte (dis, NULL, &local_error);
1011       if (local_error != NULL)
1012         goto fail;
1013       sig = read_string (mis, dis, (gsize) siglen, &local_error);
1014       if (sig == NULL)
1015         goto fail;
1016       if (!g_variant_is_signature (sig))
1017         {
1018           g_set_error (&local_error,
1019                        G_IO_ERROR,
1020                        G_IO_ERROR_INVALID_ARGUMENT,
1021                        _("Parsed value `%s' for variant is not a valid D-Bus signature"),
1022                        sig);
1023           goto fail;
1024         }
1025       variant_type = g_variant_type_new (sig);
1026       value = parse_value_from_blob (mis, dis, variant_type, &local_error);
1027       g_variant_type_free (variant_type);
1028       if (value == NULL)
1029         goto fail;
1030       ret = g_variant_new_variant (value);
1031     }
1032   else
1033     {
1034       gchar *s;
1035       s = g_variant_type_dup_string (type);
1036       g_set_error (&local_error,
1037                    G_IO_ERROR,
1038                    G_IO_ERROR_INVALID_ARGUMENT,
1039                    _("Error deserializing GVariant with type-string `%s' from the D-Bus wire format"),
1040                    s);
1041       g_free (s);
1042       goto fail;
1043     }
1044
1045   g_assert (ret != NULL);
1046   return ret;
1047
1048  fail:
1049   g_propagate_error (error, local_error);
1050   return NULL;
1051 }
1052
1053 /* ---------------------------------------------------------------------------------------------------- */
1054
1055 /* message_header must be at least 16 bytes */
1056
1057 /**
1058  * g_dbus_message_bytes_needed:
1059  * @blob: A blob represent a binary D-Bus message.
1060  * @blob_len: The length of @blob (must be at least 16).
1061  * @error: Return location for error or %NULL.
1062  *
1063  * Utility function to calculate how many bytes are needed to
1064  * completely deserialize the D-Bus message stored at @blob.
1065  *
1066  * Returns: Number of bytes needed or -1 if @error is set (e.g. if
1067  * @blob contains invalid data or not enough data is available to
1068  * determine the size).
1069  *
1070  * Since: 2.26
1071  */
1072 gssize
1073 g_dbus_message_bytes_needed (guchar                *blob,
1074                              gsize                  blob_len,
1075                              GError               **error)
1076 {
1077   gssize ret;
1078
1079   ret = -1;
1080
1081   g_return_val_if_fail (blob != NULL, -1);
1082   g_return_val_if_fail (error == NULL || *error == NULL, -1);
1083   g_return_val_if_fail (blob_len >= 16, -1);
1084
1085   if (blob[0] == 'l')
1086     {
1087       /* core header (12 bytes) + ARRAY of STRUCT of (BYTE,VARIANT) */
1088       ret = 12 + 4 + GUINT32_FROM_LE (((guint32 *) blob)[3]);
1089       /* round up so it's a multiple of 8 */
1090       ret = 8 * ((ret + 7)/8);
1091       /* finally add the body size */
1092       ret += GUINT32_FROM_LE (((guint32 *) blob)[1]);
1093     }
1094   else if (blob[0] == 'B')
1095     {
1096       /* TODO */
1097       g_assert_not_reached ();
1098     }
1099   else
1100     {
1101       g_set_error (error,
1102                    G_IO_ERROR,
1103                    G_IO_ERROR_INVALID_ARGUMENT,
1104                    "Unable to determine message blob length - given blob is malformed");
1105     }
1106
1107   if (ret > (2<<27))
1108     {
1109       g_set_error (error,
1110                    G_IO_ERROR,
1111                    G_IO_ERROR_INVALID_ARGUMENT,
1112                    "Blob indicates that message exceeds maximum message length (128MiB)");
1113       ret = -1;
1114     }
1115
1116   return ret;
1117 }
1118
1119 /* ---------------------------------------------------------------------------------------------------- */
1120
1121 /**
1122  * g_dbus_message_new_from_blob:
1123  * @blob: A blob represent a binary D-Bus message.
1124  * @blob_len: The length of @blob.
1125  * @capabilities: A #GDBusCapabilityFlags describing what protocol features are supported.
1126  * @error: Return location for error or %NULL.
1127  *
1128  * Creates a new #GDBusMessage from the data stored at @blob.
1129  *
1130  * Returns: A new #GDBusMessage or %NULL if @error is set. Free with
1131  * g_object_unref().
1132  *
1133  * Since: 2.26
1134  */
1135 GDBusMessage *
1136 g_dbus_message_new_from_blob (guchar                *blob,
1137                               gsize                  blob_len,
1138                               GDBusCapabilityFlags   capabilities,
1139                               GError               **error)
1140 {
1141   gboolean ret;
1142   GMemoryInputStream *mis;
1143   GDataInputStream *dis;
1144   GDBusMessage *message;
1145   guchar endianness;
1146   guchar major_protocol_version;
1147   GDataStreamByteOrder byte_order;
1148   guint32 message_body_len;
1149   GVariant *headers;
1150   GVariant *item;
1151   GVariantIter iter;
1152   GVariant *signature;
1153
1154   /* TODO: check against @capabilities */
1155
1156   ret = FALSE;
1157
1158   g_return_val_if_fail (blob != NULL, NULL);
1159   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1160   g_return_val_if_fail (blob_len >= 12, NULL);
1161
1162   message = g_dbus_message_new ();
1163
1164   mis = G_MEMORY_INPUT_STREAM (g_memory_input_stream_new_from_data (blob, blob_len, NULL));
1165   dis = g_data_input_stream_new (G_INPUT_STREAM (mis));
1166
1167   endianness = g_data_input_stream_read_byte (dis, NULL, NULL);
1168   switch (endianness)
1169     {
1170     case 'l':
1171       byte_order = G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN;
1172       break;
1173     case 'B':
1174       byte_order = G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN;
1175       break;
1176     default:
1177       g_set_error (error,
1178                    G_IO_ERROR,
1179                    G_IO_ERROR_INVALID_ARGUMENT,
1180                    _("Invalid endianness value. Expected 'l' or 'B' but found '%c' (%d)"),
1181                    endianness, endianness);
1182       goto out;
1183     }
1184   g_data_input_stream_set_byte_order (dis, byte_order);
1185
1186   message->priv->type = g_data_input_stream_read_byte (dis, NULL, NULL);
1187   message->priv->flags = g_data_input_stream_read_byte (dis, NULL, NULL);
1188   major_protocol_version = g_data_input_stream_read_byte (dis, NULL, NULL);
1189   if (major_protocol_version != 1)
1190     {
1191       g_set_error (error,
1192                    G_IO_ERROR,
1193                    G_IO_ERROR_INVALID_ARGUMENT,
1194                    _("Invalid major protocol version. Expected 1 but found %d"),
1195                    major_protocol_version);
1196       goto out;
1197     }
1198   message_body_len = g_data_input_stream_read_uint32 (dis, NULL, NULL);
1199   message->priv->serial = g_data_input_stream_read_uint32 (dis, NULL, NULL);
1200
1201   headers = parse_value_from_blob (mis,
1202                                    dis,
1203                                    G_VARIANT_TYPE ("a{yv}"),
1204                                    error);
1205   if (headers == NULL)
1206     goto out;
1207   g_variant_ref_sink (headers);
1208   g_variant_iter_init (&iter, headers);
1209   while ((item = g_variant_iter_next_value (&iter)))
1210     {
1211       guchar header_field;
1212       GVariant *value;
1213       g_variant_get (item,
1214                      "{yv}",
1215                      &header_field,
1216                      &value);
1217       g_dbus_message_set_header (message, header_field, value);
1218     }
1219   g_variant_unref (headers);
1220
1221   signature = g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE);
1222   if (signature != NULL)
1223     {
1224       const gchar *signature_str;
1225       gsize signature_str_len;
1226
1227       signature_str = g_variant_get_string (signature, NULL);
1228       signature_str_len = strlen (signature_str);
1229
1230       /* signature but no body */
1231       if (message_body_len == 0 && signature_str_len > 0)
1232         {
1233           g_set_error (error,
1234                        G_IO_ERROR,
1235                        G_IO_ERROR_INVALID_ARGUMENT,
1236                        _("Signature header with signature `%s' found but message body is empty"),
1237                        signature_str);
1238           goto out;
1239         }
1240       else if (signature_str_len > 0)
1241         {
1242           GVariantType *variant_type;
1243           gchar *tupled_signature_str;
1244
1245           if (!g_variant_is_signature (signature_str))
1246             {
1247               g_set_error (error,
1248                            G_IO_ERROR,
1249                            G_IO_ERROR_INVALID_ARGUMENT,
1250                            _("Parsed value `%s' is not a valid D-Bus signature (for body)"),
1251                            signature_str);
1252               goto out;
1253             }
1254           tupled_signature_str = g_strdup_printf ("(%s)", signature_str);
1255           variant_type = g_variant_type_new (tupled_signature_str);
1256           g_free (tupled_signature_str);
1257           message->priv->body = parse_value_from_blob (mis,
1258                                                        dis,
1259                                                        variant_type,
1260                                                        error);
1261           if (message->priv->body == NULL)
1262             {
1263               g_variant_type_free (variant_type);
1264               goto out;
1265             }
1266           g_variant_ref_sink (message->priv->body);
1267           g_variant_type_free (variant_type);
1268         }
1269     }
1270   else
1271     {
1272       /* no signature, this is only OK if the body is empty */
1273       if (message_body_len != 0)
1274         {
1275           g_set_error (error,
1276                        G_IO_ERROR,
1277                        G_IO_ERROR_INVALID_ARGUMENT,
1278                        _("No signature header in message but the message body is %" G_GUINT32_FORMAT " bytes"),
1279                        message_body_len);
1280           goto out;
1281         }
1282     }
1283
1284
1285   ret = TRUE;
1286
1287  out:
1288   g_object_unref (dis);
1289   g_object_unref (mis);
1290
1291   if (ret)
1292     {
1293       return message;
1294     }
1295   else
1296     {
1297       if (message != NULL)
1298         g_object_unref (message);
1299       return NULL;
1300     }
1301 }
1302
1303 /* ---------------------------------------------------------------------------------------------------- */
1304
1305 static gsize
1306 ensure_output_padding (GMemoryOutputStream  *mos,
1307                        GDataOutputStream    *dos,
1308                        gsize                 padding_size)
1309 {
1310   gsize offset;
1311   gsize wanted_offset;
1312   gsize padding_needed;
1313   guint n;
1314
1315   offset = g_memory_output_stream_get_data_size (mos);
1316   wanted_offset = ((offset + padding_size - 1) / padding_size) * padding_size;
1317   padding_needed = wanted_offset - offset;
1318
1319   for (n = 0; n < padding_needed; n++)
1320     g_data_output_stream_put_byte (dos, '\0', NULL, NULL);
1321
1322   return padding_needed;
1323 }
1324
1325 static gboolean
1326 append_value_to_blob (GVariant             *value,
1327                       GMemoryOutputStream  *mos,
1328                       GDataOutputStream    *dos,
1329                       gsize                *out_padding_added,
1330                       GError              **error)
1331 {
1332   const GVariantType *type;
1333   gsize padding_added;
1334
1335   padding_added = 0;
1336
1337   type = g_variant_get_type (value);
1338   if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
1339     {
1340       gboolean v = g_variant_get_boolean (value);
1341       padding_added = ensure_output_padding (mos, dos, 4);
1342       g_data_output_stream_put_uint32 (dos, v, NULL, NULL);
1343     }
1344   else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
1345     {
1346       guint8 v = g_variant_get_byte (value);
1347       g_data_output_stream_put_byte (dos, v, NULL, NULL);
1348     }
1349   else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
1350     {
1351       gint16 v = g_variant_get_int16 (value);
1352       padding_added = ensure_output_padding (mos, dos, 2);
1353       g_data_output_stream_put_int16 (dos, v, NULL, NULL);
1354     }
1355   else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
1356     {
1357       guint16 v = g_variant_get_uint16 (value);
1358       padding_added = ensure_output_padding (mos, dos, 2);
1359       g_data_output_stream_put_uint16 (dos, v, NULL, NULL);
1360     }
1361   else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
1362     {
1363       gint32 v = g_variant_get_int32 (value);
1364       padding_added = ensure_output_padding (mos, dos, 4);
1365       g_data_output_stream_put_int32 (dos, v, NULL, NULL);
1366     }
1367   else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
1368     {
1369       guint32 v = g_variant_get_uint32 (value);
1370       padding_added = ensure_output_padding (mos, dos, 4);
1371       g_data_output_stream_put_uint32 (dos, v, NULL, NULL);
1372     }
1373   else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
1374     {
1375       gint64 v = g_variant_get_int64 (value);
1376       padding_added = ensure_output_padding (mos, dos, 8);
1377       g_data_output_stream_put_int64 (dos, v, NULL, NULL);
1378     }
1379   else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
1380     {
1381       guint64 v = g_variant_get_uint64 (value);
1382       padding_added = ensure_output_padding (mos, dos, 8);
1383       g_data_output_stream_put_uint64 (dos, v, NULL, NULL);
1384     }
1385   else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
1386     {
1387       guint64 *encoded;
1388       gdouble v = g_variant_get_double (value);
1389       padding_added = ensure_output_padding (mos, dos, 8);
1390       /* TODO: hmm */
1391       encoded = (guint64 *) &v;
1392       g_data_output_stream_put_uint64 (dos, *encoded, NULL, NULL);
1393     }
1394   else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
1395     {
1396       const gchar *v = g_variant_get_string (value, NULL);
1397       gsize len;
1398       padding_added = ensure_output_padding (mos, dos, 4);
1399       len = strlen (v);
1400       g_data_output_stream_put_uint32 (dos, len, NULL, NULL);
1401       g_data_output_stream_put_string (dos, v, NULL, NULL);
1402       g_data_output_stream_put_byte (dos, '\0', NULL, NULL);
1403     }
1404   else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
1405     {
1406       /* TODO: validate object path */
1407       const gchar *v = g_variant_get_string (value, NULL);
1408       gsize len;
1409       padding_added = ensure_output_padding (mos, dos, 4);
1410       len = strlen (v);
1411       g_data_output_stream_put_uint32 (dos, len, NULL, NULL);
1412       g_data_output_stream_put_string (dos, v, NULL, NULL);
1413       g_data_output_stream_put_byte (dos, '\0', NULL, NULL);
1414     }
1415   else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
1416     {
1417       /* TODO: validate signature (including max len being 255) */
1418       const gchar *v = g_variant_get_string (value, NULL);
1419       gsize len;
1420       len = strlen (v);
1421       g_data_output_stream_put_byte (dos, len, NULL, NULL);
1422       g_data_output_stream_put_string (dos, v, NULL, NULL);
1423       g_data_output_stream_put_byte (dos, '\0', NULL, NULL);
1424     }
1425   else if (g_variant_type_is_array (type))
1426     {
1427       GVariant *item;
1428       GVariantIter iter;
1429       goffset array_len_offset;
1430       goffset array_payload_begin_offset;
1431       goffset cur_offset;
1432       gsize array_len;
1433       guint n;
1434
1435       padding_added = ensure_output_padding (mos, dos, 4);
1436
1437       /* array length - will be filled in later */
1438       array_len_offset = g_memory_output_stream_get_data_size (mos);
1439       g_data_output_stream_put_uint32 (dos, 0xF00DFACE, NULL, NULL);
1440
1441       /* From the D-Bus spec:
1442        *
1443        *   "A UINT32 giving the length of the array data in bytes,
1444        *    followed by alignment padding to the alignment boundary of
1445        *    the array element type, followed by each array element. The
1446        *    array length is from the end of the alignment padding to
1447        *    the end of the last element, i.e. it does not include the
1448        *    padding after the length, or any padding after the last
1449        *    element."
1450        *
1451        * Thus, we need to count how much padding the first element
1452        * contributes and subtract that from the array length.
1453        */
1454       array_payload_begin_offset = g_memory_output_stream_get_data_size (mos);
1455
1456       g_variant_iter_init (&iter, value);
1457       n = 0;
1458       while ((item = g_variant_iter_next_value (&iter)))
1459         {
1460           gsize padding_added_for_item;
1461           if (!append_value_to_blob (item, mos, dos, &padding_added_for_item, error))
1462             goto fail;
1463           if (n == 0)
1464             {
1465               array_payload_begin_offset += padding_added_for_item;
1466             }
1467           n++;
1468         }
1469
1470       cur_offset = g_memory_output_stream_get_data_size (mos);
1471
1472       array_len = cur_offset - array_payload_begin_offset;
1473
1474       if (!g_seekable_seek (G_SEEKABLE (mos), array_len_offset, G_SEEK_SET, NULL, error))
1475         goto fail;
1476
1477       g_data_output_stream_put_uint32 (dos, array_len, NULL, NULL);
1478
1479       if (!g_seekable_seek (G_SEEKABLE (mos), cur_offset, G_SEEK_SET, NULL, error))
1480         goto fail;
1481     }
1482   else if (g_variant_type_is_dict_entry (type) || g_variant_type_is_tuple (type))
1483     {
1484       GVariant *item;
1485       GVariantIter iter;
1486
1487       padding_added = ensure_output_padding (mos, dos, 8);
1488
1489       g_variant_iter_init (&iter, value);
1490
1491       while ((item = g_variant_iter_next_value (&iter)))
1492         {
1493           if (!append_value_to_blob (item, mos, dos, NULL, error))
1494             goto fail;
1495         }
1496     }
1497   else if (g_variant_type_is_variant (type))
1498     {
1499       GVariant *child;
1500       const gchar *signature;
1501       child = g_variant_get_child_value (value, 0);
1502       signature = g_variant_get_type_string (child);
1503       /* TODO: validate signature (including max len being 255) */
1504       g_data_output_stream_put_byte (dos, strlen (signature), NULL, NULL);
1505       g_data_output_stream_put_string (dos, signature, NULL, NULL);
1506       g_data_output_stream_put_byte (dos, '\0', NULL, NULL);
1507       if (!append_value_to_blob (child, mos, dos, NULL, error))
1508         {
1509           g_variant_unref (child);
1510           goto fail;
1511         }
1512       g_variant_unref (child);
1513     }
1514   else
1515     {
1516       g_set_error (error,
1517                    G_IO_ERROR,
1518                    G_IO_ERROR_INVALID_ARGUMENT,
1519                    _("Error serializing GVariant with type-string `%s' to the D-Bus wire format"),
1520                    g_variant_get_type_string (value));
1521       goto fail;
1522     }
1523
1524   if (out_padding_added != NULL)
1525     *out_padding_added = padding_added;
1526
1527   return TRUE;
1528
1529  fail:
1530   return FALSE;
1531 }
1532
1533 static gboolean
1534 append_body_to_blob (GVariant             *value,
1535                      GMemoryOutputStream  *mos,
1536                      GDataOutputStream    *dos,
1537                      GError              **error)
1538 {
1539   gboolean ret;
1540   GVariant *item;
1541   GVariantIter iter;
1542
1543   ret = FALSE;
1544
1545   if (!g_variant_is_of_type (value, G_VARIANT_TYPE_TUPLE))
1546     {
1547       g_set_error (error,
1548                    G_IO_ERROR,
1549                    G_IO_ERROR_INVALID_ARGUMENT,
1550                    "Expected a tuple for the body of the GDBusMessage.");
1551       goto fail;
1552     }
1553
1554   g_variant_iter_init (&iter, value);
1555   while ((item = g_variant_iter_next_value (&iter)))
1556     {
1557       if (!append_value_to_blob (item, mos, dos, NULL, error))
1558         goto fail;
1559     }
1560   return TRUE;
1561
1562  fail:
1563   return FALSE;
1564 }
1565
1566 /* ---------------------------------------------------------------------------------------------------- */
1567
1568 /**
1569  * g_dbus_message_to_blob:
1570  * @message: A #GDBusMessage.
1571  * @out_size: Return location for size of generated blob.
1572  * @capabilities: A #GDBusCapabilityFlags describing what protocol features are supported.
1573  * @error: Return location for error.
1574  *
1575  * Serializes @message to a blob.
1576  *
1577  * Returns: A pointer to a valid binary D-Bus message of @out_size bytes
1578  * generated by @message or %NULL if @error is set. Free with g_free().
1579  *
1580  * Since: 2.26
1581  */
1582 guchar *
1583 g_dbus_message_to_blob (GDBusMessage          *message,
1584                         gsize                 *out_size,
1585                         GDBusCapabilityFlags   capabilities,
1586                         GError               **error)
1587 {
1588   GMemoryOutputStream *mos;
1589   GDataOutputStream *dos;
1590   guchar *ret;
1591   gsize size;
1592   GDataStreamByteOrder byte_order;
1593   goffset body_len_offset;
1594   goffset body_start_offset;
1595   gsize body_size;
1596   GVariant *header_fields;
1597   GVariantBuilder *builder;
1598   GHashTableIter hash_iter;
1599   gpointer key;
1600   GVariant *header_value;
1601   GVariant *signature;
1602   const gchar *signature_str;
1603   gint num_fds_in_message;
1604   gint num_fds_according_to_header;
1605
1606   /* TODO: check against @capabilities */
1607
1608   ret = NULL;
1609
1610   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
1611   g_return_val_if_fail (out_size != NULL, NULL);
1612   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1613
1614   mos = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new (NULL, 0, g_realloc, g_free));
1615   dos = g_data_output_stream_new (G_OUTPUT_STREAM (mos));
1616
1617   /* TODO: detect endianess... */
1618   byte_order = G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN;
1619   g_data_output_stream_set_byte_order (dos, byte_order);
1620
1621   /* Core header */
1622   g_data_output_stream_put_byte (dos, byte_order == G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN ? 'l' : 'B', NULL, NULL);
1623   g_data_output_stream_put_byte (dos, message->priv->type, NULL, NULL);
1624   g_data_output_stream_put_byte (dos, message->priv->flags, NULL, NULL);
1625   g_data_output_stream_put_byte (dos, 1, NULL, NULL); /* major protocol version */
1626   body_len_offset = g_memory_output_stream_get_data_size (mos);
1627   /* body length - will be filled in later */
1628   g_data_output_stream_put_uint32 (dos, 0xF00DFACE, NULL, NULL);
1629   g_data_output_stream_put_uint32 (dos, message->priv->serial, NULL, NULL);
1630
1631   num_fds_in_message = 0;
1632 #ifdef G_OS_UNIX
1633   if (message->priv->fd_list != NULL)
1634     num_fds_in_message = g_unix_fd_list_get_length (message->priv->fd_list);
1635 #endif
1636   num_fds_according_to_header = g_dbus_message_get_num_unix_fds (message);
1637   /* TODO: check we have all the right header fields and that they are the correct value etc etc */
1638   if (num_fds_in_message != num_fds_according_to_header)
1639     {
1640       g_set_error (error,
1641                    G_IO_ERROR,
1642                    G_IO_ERROR_INVALID_ARGUMENT,
1643                    _("Message has %d fds but the header field indicates %d fds"),
1644                    num_fds_in_message,
1645                    num_fds_according_to_header);
1646       goto out;
1647     }
1648
1649   builder = g_variant_builder_new (G_VARIANT_TYPE ("a{yv}"));//G_VARIANT_TYPE_ARRAY);
1650   g_hash_table_iter_init (&hash_iter, message->priv->headers);
1651   while (g_hash_table_iter_next (&hash_iter, &key, (gpointer) &header_value))
1652     {
1653       g_variant_builder_add (builder,
1654                              "{yv}",
1655                              (guchar) GPOINTER_TO_UINT (key),
1656                              header_value);
1657     }
1658   header_fields = g_variant_new ("a{yv}", builder);
1659
1660   if (!append_value_to_blob (header_fields, mos, dos, NULL, error))
1661     {
1662       g_variant_unref (header_fields);
1663       goto out;
1664     }
1665   g_variant_unref (header_fields);
1666
1667   /* header size must be a multiple of 8 */
1668   ensure_output_padding (mos, dos, 8);
1669
1670   body_start_offset = g_memory_output_stream_get_data_size (mos);
1671
1672   signature = g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE);
1673   signature_str = NULL;
1674   if (signature != NULL)
1675       signature_str = g_variant_get_string (signature, NULL);
1676   if (message->priv->body != NULL)
1677     {
1678       gchar *tupled_signature_str;
1679       tupled_signature_str = g_strdup_printf ("(%s)", signature_str);
1680       if (signature == NULL)
1681         {
1682           g_set_error (error,
1683                        G_IO_ERROR,
1684                        G_IO_ERROR_INVALID_ARGUMENT,
1685                        _("Message body has signature `%s' but there is no signature header"),
1686                        signature_str);
1687           g_free (tupled_signature_str);
1688           goto out;
1689         }
1690       else if (g_strcmp0 (tupled_signature_str, g_variant_get_type_string (message->priv->body)) != 0)
1691         {
1692           g_set_error (error,
1693                        G_IO_ERROR,
1694                        G_IO_ERROR_INVALID_ARGUMENT,
1695                        _("Message body has type signature `%s' but signature in the header field is `%s'"),
1696                        tupled_signature_str, g_variant_get_type_string (message->priv->body));
1697           g_free (tupled_signature_str);
1698           goto out;
1699         }
1700       g_free (tupled_signature_str);
1701       if (!append_body_to_blob (message->priv->body, mos, dos, error))
1702         goto out;
1703     }
1704   else
1705     {
1706       if (signature != NULL)
1707         {
1708           g_set_error (error,
1709                        G_IO_ERROR,
1710                        G_IO_ERROR_INVALID_ARGUMENT,
1711                        _("Message body is empty but signature in the header field is `(%s)'"),
1712                        signature_str);
1713           goto out;
1714         }
1715     }
1716
1717   /* OK, we're done writing the message - set the body length */
1718   size = g_memory_output_stream_get_data_size (mos);
1719   body_size = size - body_start_offset;
1720
1721   if (!g_seekable_seek (G_SEEKABLE (mos), body_len_offset, G_SEEK_SET, NULL, error))
1722     goto out;
1723
1724   g_data_output_stream_put_uint32 (dos, body_size, NULL, NULL);
1725
1726   *out_size = size;
1727   ret = g_memdup (g_memory_output_stream_get_data (mos), size);
1728
1729  out:
1730   g_object_unref (dos);
1731   g_object_unref (mos);
1732
1733   return ret;
1734 }
1735
1736 /* ---------------------------------------------------------------------------------------------------- */
1737
1738 static guint32
1739 get_uint32_header (GDBusMessage            *message,
1740                    GDBusMessageHeaderField  header_field)
1741 {
1742   GVariant *value;
1743   guint32 ret;
1744
1745   ret = 0;
1746   value = g_hash_table_lookup (message->priv->headers, GUINT_TO_POINTER (header_field));
1747   if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_UINT32))
1748     ret = g_variant_get_uint32 (value);
1749
1750   return ret;
1751 }
1752
1753 static const gchar *
1754 get_string_header (GDBusMessage            *message,
1755                    GDBusMessageHeaderField  header_field)
1756 {
1757   GVariant *value;
1758   const gchar *ret;
1759
1760   ret = NULL;
1761   value = g_hash_table_lookup (message->priv->headers, GUINT_TO_POINTER (header_field));
1762   if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
1763     ret = g_variant_get_string (value, NULL);
1764
1765   return ret;
1766 }
1767
1768 static const gchar *
1769 get_object_path_header (GDBusMessage            *message,
1770                         GDBusMessageHeaderField  header_field)
1771 {
1772   GVariant *value;
1773   const gchar *ret;
1774
1775   ret = NULL;
1776   value = g_hash_table_lookup (message->priv->headers, GUINT_TO_POINTER (header_field));
1777   if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_OBJECT_PATH))
1778     ret = g_variant_get_string (value, NULL);
1779
1780   return ret;
1781 }
1782
1783 static const gchar *
1784 get_signature_header (GDBusMessage            *message,
1785                       GDBusMessageHeaderField  header_field)
1786 {
1787   GVariant *value;
1788   const gchar *ret;
1789
1790   ret = NULL;
1791   value = g_hash_table_lookup (message->priv->headers, GUINT_TO_POINTER (header_field));
1792   if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_SIGNATURE))
1793     ret = g_variant_get_string (value, NULL);
1794
1795   return ret;
1796 }
1797
1798 /* ---------------------------------------------------------------------------------------------------- */
1799
1800 static void
1801 set_uint32_header (GDBusMessage             *message,
1802                    GDBusMessageHeaderField   header_field,
1803                    guint32                   value)
1804 {
1805   g_dbus_message_set_header (message,
1806                              header_field,
1807                              g_variant_new_uint32 (value));
1808 }
1809
1810 static void
1811 set_string_header (GDBusMessage             *message,
1812                    GDBusMessageHeaderField   header_field,
1813                    const gchar              *value)
1814 {
1815   g_dbus_message_set_header (message,
1816                              header_field,
1817                              value == NULL ? NULL : g_variant_new_string (value));
1818 }
1819
1820 static void
1821 set_object_path_header (GDBusMessage             *message,
1822                         GDBusMessageHeaderField   header_field,
1823                         const gchar              *value)
1824 {
1825   g_dbus_message_set_header (message,
1826                              header_field,
1827                              value == NULL ? NULL : g_variant_new_object_path (value));
1828 }
1829
1830 static void
1831 set_signature_header (GDBusMessage             *message,
1832                       GDBusMessageHeaderField   header_field,
1833                       const gchar              *value)
1834 {
1835   g_dbus_message_set_header (message,
1836                              header_field,
1837                              value == NULL ? NULL : g_variant_new_signature (value));
1838 }
1839
1840 /* ---------------------------------------------------------------------------------------------------- */
1841
1842 /**
1843  * g_dbus_message_get_reply_serial:
1844  * @message: A #GDBusMessage.
1845  *
1846  * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL header field.
1847  *
1848  * Returns: The value.
1849  *
1850  * Since: 2.26
1851  */
1852 guint32
1853 g_dbus_message_get_reply_serial (GDBusMessage  *message)
1854 {
1855   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), 0);
1856   return get_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL);
1857 }
1858
1859 /**
1860  * g_dbus_message_set_reply_serial:
1861  * @message: A #GDBusMessage.
1862  * @value: The value to set.
1863  *
1864  * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL header field.
1865  *
1866  * Since: 2.26
1867  */
1868 void
1869 g_dbus_message_set_reply_serial (GDBusMessage  *message,
1870                                  guint32        value)
1871 {
1872   g_return_if_fail (G_IS_DBUS_MESSAGE (message));
1873   set_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL, value);
1874 }
1875
1876 /* ---------------------------------------------------------------------------------------------------- */
1877
1878 /**
1879  * g_dbus_message_get_interface:
1880  * @message: A #GDBusMessage.
1881  *
1882  * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE header field.
1883  *
1884  * Returns: The value.
1885  *
1886  * Since: 2.26
1887  */
1888 const gchar *
1889 g_dbus_message_get_interface (GDBusMessage  *message)
1890 {
1891   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
1892   return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE);
1893 }
1894
1895 /**
1896  * g_dbus_message_set_interface:
1897  * @message: A #GDBusMessage.
1898  * @value: The value to set.
1899  *
1900  * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE header field.
1901  *
1902  * Since: 2.26
1903  */
1904 void
1905 g_dbus_message_set_interface (GDBusMessage  *message,
1906                               const gchar   *value)
1907 {
1908   g_return_if_fail (G_IS_DBUS_MESSAGE (message));
1909   g_return_if_fail (value == NULL || g_dbus_is_interface_name (value));
1910   set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE, value);
1911 }
1912
1913 /* ---------------------------------------------------------------------------------------------------- */
1914
1915 /**
1916  * g_dbus_message_get_member:
1917  * @message: A #GDBusMessage.
1918  *
1919  * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_MEMBER header field.
1920  *
1921  * Returns: The value.
1922  *
1923  * Since: 2.26
1924  */
1925 const gchar *
1926 g_dbus_message_get_member (GDBusMessage  *message)
1927 {
1928   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
1929   return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER);
1930 }
1931
1932 /**
1933  * g_dbus_message_set_member:
1934  * @message: A #GDBusMessage.
1935  * @value: The value to set.
1936  *
1937  * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_MEMBER header field.
1938  *
1939  * Since: 2.26
1940  */
1941 void
1942 g_dbus_message_set_member (GDBusMessage  *message,
1943                            const gchar   *value)
1944 {
1945   g_return_if_fail (G_IS_DBUS_MESSAGE (message));
1946   g_return_if_fail (value == NULL || g_dbus_is_member_name (value));
1947   set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER, value);
1948 }
1949
1950 /* ---------------------------------------------------------------------------------------------------- */
1951
1952 /**
1953  * g_dbus_message_get_path:
1954  * @message: A #GDBusMessage.
1955  *
1956  * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_PATH header field.
1957  *
1958  * Returns: The value.
1959  *
1960  * Since: 2.26
1961  */
1962 const gchar *
1963 g_dbus_message_get_path (GDBusMessage  *message)
1964 {
1965   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
1966   return get_object_path_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH);
1967 }
1968
1969 /**
1970  * g_dbus_message_set_path:
1971  * @message: A #GDBusMessage.
1972  * @value: The value to set.
1973  *
1974  * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_PATH header field.
1975  *
1976  * Since: 2.26
1977  */
1978 void
1979 g_dbus_message_set_path (GDBusMessage  *message,
1980                          const gchar   *value)
1981 {
1982   g_return_if_fail (G_IS_DBUS_MESSAGE (message));
1983   g_return_if_fail (value == NULL || g_variant_is_object_path (value));
1984   set_object_path_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH, value);
1985 }
1986
1987 /* ---------------------------------------------------------------------------------------------------- */
1988
1989 /**
1990  * g_dbus_message_get_sender:
1991  * @message: A #GDBusMessage.
1992  *
1993  * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_SENDER header field.
1994  *
1995  * Returns: The value.
1996  *
1997  * Since: 2.26
1998  */
1999 const gchar *
2000 g_dbus_message_get_sender (GDBusMessage *message)
2001 {
2002   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2003   return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SENDER);
2004 }
2005
2006 /**
2007  * g_dbus_message_set_sender:
2008  * @message: A #GDBusMessage.
2009  * @value: The value to set.
2010  *
2011  * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_SENDER header field.
2012  *
2013  * Since: 2.26
2014  */
2015 void
2016 g_dbus_message_set_sender (GDBusMessage  *message,
2017                            const gchar   *value)
2018 {
2019   g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2020   g_return_if_fail (value == NULL || g_dbus_is_name (value));
2021   set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SENDER, value);
2022 }
2023
2024 /* ---------------------------------------------------------------------------------------------------- */
2025
2026 /**
2027  * g_dbus_message_get_destination:
2028  * @message: A #GDBusMessage.
2029  *
2030  * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION header field.
2031  *
2032  * Returns: The value.
2033  *
2034  * Since: 2.26
2035  */
2036 const gchar *
2037 g_dbus_message_get_destination (GDBusMessage  *message)
2038 {
2039   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2040   return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION);
2041 }
2042
2043 /**
2044  * g_dbus_message_set_destination:
2045  * @message: A #GDBusMessage.
2046  * @value: The value to set.
2047  *
2048  * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION header field.
2049  *
2050  * Since: 2.26
2051  */
2052 void
2053 g_dbus_message_set_destination (GDBusMessage  *message,
2054                                 const gchar   *value)
2055 {
2056   g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2057   g_return_if_fail (value == NULL || g_dbus_is_name (value));
2058   set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION, value);
2059 }
2060
2061 /* ---------------------------------------------------------------------------------------------------- */
2062
2063 /**
2064  * g_dbus_message_get_error_name:
2065  * @message: A #GDBusMessage.
2066  *
2067  * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME header field.
2068  *
2069  * Returns: The value.
2070  *
2071  * Since: 2.26
2072  */
2073 const gchar *
2074 g_dbus_message_get_error_name (GDBusMessage  *message)
2075 {
2076   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2077   return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME);
2078 }
2079
2080 /**
2081  * g_dbus_message_set_error_name:
2082  * @message: A #GDBusMessage.
2083  * @value: The value to set.
2084  *
2085  * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME header field.
2086  *
2087  * Since: 2.26
2088  */
2089 void
2090 g_dbus_message_set_error_name (GDBusMessage  *message,
2091                                const gchar   *value)
2092 {
2093   g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2094   g_return_if_fail (value == NULL || g_dbus_is_interface_name (value));
2095   set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME, value);
2096 }
2097
2098 /* ---------------------------------------------------------------------------------------------------- */
2099
2100 /**
2101  * g_dbus_message_get_signature:
2102  * @message: A #GDBusMessage.
2103  *
2104  * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE header field.
2105  *
2106  * Returns: The value.
2107  *
2108  * Since: 2.26
2109  */
2110 const gchar *
2111 g_dbus_message_get_signature (GDBusMessage  *message)
2112 {
2113   const gchar *ret;
2114   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2115   ret = get_signature_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE);
2116   if (ret == NULL)
2117     ret = "";
2118   return ret;
2119 }
2120
2121 /**
2122  * g_dbus_message_set_signature:
2123  * @message: A #GDBusMessage.
2124  * @value: The value to set.
2125  *
2126  * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE header field.
2127  *
2128  * Since: 2.26
2129  */
2130 void
2131 g_dbus_message_set_signature (GDBusMessage  *message,
2132                               const gchar   *value)
2133 {
2134   g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2135   g_return_if_fail (value == NULL || g_variant_is_signature (value));
2136   set_signature_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE, value);
2137 }
2138
2139 /* ---------------------------------------------------------------------------------------------------- */
2140
2141 /**
2142  * g_dbus_message_get_arg0:
2143  * @message: A #GDBusMessage.
2144  *
2145  * Convenience to get the first item in the body of @message.
2146  *
2147  * Returns: The string item or %NULL if the first item in the body of
2148  * @message is not a string.
2149  *
2150  * Since: 2.26
2151  */
2152 const gchar *
2153 g_dbus_message_get_arg0 (GDBusMessage  *message)
2154 {
2155   const gchar *ret;
2156
2157   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2158
2159   ret = NULL;
2160
2161   if (message->priv->body != NULL && g_variant_is_of_type (message->priv->body, G_VARIANT_TYPE_TUPLE))
2162     {
2163       GVariant *item;
2164       item = g_variant_get_child_value (message->priv->body, 0);
2165       if (g_variant_is_of_type (item, G_VARIANT_TYPE_STRING))
2166         ret = g_variant_get_string (item, NULL);
2167     }
2168
2169   return ret;
2170 }
2171
2172 /* ---------------------------------------------------------------------------------------------------- */
2173
2174 /**
2175  * g_dbus_message_get_num_unix_fds:
2176  * @message: A #GDBusMessage.
2177  *
2178  * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS header field.
2179  *
2180  * Returns: The value.
2181  *
2182  * Since: 2.26
2183  */
2184 guint32
2185 g_dbus_message_get_num_unix_fds (GDBusMessage *message)
2186 {
2187   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), 0);
2188   return get_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS);
2189 }
2190
2191 /**
2192  * g_dbus_message_set_num_unix_fds:
2193  * @message: A #GDBusMessage.
2194  * @value: The value to set.
2195  *
2196  * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS header field.
2197  *
2198  * Since: 2.26
2199  */
2200 void
2201 g_dbus_message_set_num_unix_fds (GDBusMessage  *message,
2202                                  guint32        value)
2203 {
2204   g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2205   set_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS, value);
2206 }
2207
2208 /* ---------------------------------------------------------------------------------------------------- */
2209
2210 /**
2211  * g_dbus_message_to_gerror:
2212  * @message: A #GDBusMessage.
2213  * @error: The #GError to set.
2214  *
2215  * If @message is not of type %G_DBUS_MESSAGE_TYPE_ERROR does
2216  * nothing and returns %FALSE.
2217  *
2218  * Otherwise this method encodes the error in @message as a #GError
2219  * using g_dbus_error_set_dbus_error() using the information in the
2220  * %G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME header field of @message as
2221  * well as the first string item in @message's body.
2222  *
2223  * Returns: %TRUE if @error was set, %FALSE otherwise.
2224  *
2225  * Since: 2.26
2226  */
2227 gboolean
2228 g_dbus_message_to_gerror (GDBusMessage   *message,
2229                           GError        **error)
2230 {
2231   gboolean ret;
2232   const gchar *error_name;
2233
2234   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), FALSE);
2235
2236   ret = FALSE;
2237   if (message->priv->type != G_DBUS_MESSAGE_TYPE_ERROR)
2238     goto out;
2239
2240   error_name = g_dbus_message_get_error_name (message);
2241   if (error_name != NULL)
2242     {
2243       GVariant *body;
2244
2245       body = g_dbus_message_get_body (message);
2246
2247       if (body != NULL && g_variant_is_of_type (body, G_VARIANT_TYPE ("(s)")))
2248         {
2249           const gchar *error_message;
2250           g_variant_get (body, "(s)", &error_message);
2251           g_dbus_error_set_dbus_error (error,
2252                                        error_name,
2253                                        error_message,
2254                                        NULL);
2255         }
2256       else
2257         {
2258           /* these two situations are valid, yet pretty rare */
2259           if (body != NULL)
2260             {
2261               g_dbus_error_set_dbus_error (error,
2262                                            error_name,
2263                                            "",
2264                                            _("Error return with body of type `%s'"),
2265                                            g_variant_get_type_string (body));
2266             }
2267           else
2268             {
2269               g_dbus_error_set_dbus_error (error,
2270                                            error_name,
2271                                            "",
2272                                            _("Error return with empty body"));
2273             }
2274         }
2275     }
2276   else
2277     {
2278       /* TOOD: this shouldn't happen - should check this at message serialization
2279        * time and disconnect the peer.
2280        */
2281       g_set_error (error,
2282                    G_IO_ERROR,
2283                    G_IO_ERROR_FAILED,
2284                    "Error return without error-name header!");
2285     }
2286
2287   ret = TRUE;
2288
2289  out:
2290   return ret;
2291 }
2292
2293 /* ---------------------------------------------------------------------------------------------------- */
2294
2295 static gchar *
2296 enum_to_string (GType enum_type, gint value)
2297 {
2298   gchar *ret;
2299   GEnumClass *klass;
2300   GEnumValue *enum_value;
2301
2302   klass = g_type_class_ref (enum_type);
2303   enum_value = g_enum_get_value (klass, value);
2304   if (enum_value != NULL)
2305     ret = g_strdup (enum_value->value_nick);
2306   else
2307     ret = g_strdup_printf ("unknown (value %d)", value);
2308   g_type_class_unref (klass);
2309   return ret;
2310 }
2311
2312 static gchar *
2313 flags_to_string (GType flags_type, guint value)
2314 {
2315   GString *s;
2316   GFlagsClass *klass;
2317   guint n;
2318
2319   klass = g_type_class_ref (flags_type);
2320   s = g_string_new (NULL);
2321   for (n = 0; n < 32; n++)
2322     {
2323       if ((value & (1<<n)) != 0)
2324         {
2325           GFlagsValue *flags_value;
2326           flags_value = g_flags_get_first_value (klass, (1<<n));
2327           if (s->len > 0)
2328             g_string_append_c (s, ',');
2329           if (flags_value != NULL)
2330             g_string_append (s, flags_value->value_nick);
2331           else
2332             g_string_append_printf (s, "unknown (bit %d)", n);
2333         }
2334     }
2335   if (s->len == 0)
2336     g_string_append (s, "none");
2337   g_type_class_unref (klass);
2338   return g_string_free (s, FALSE);;
2339 }
2340
2341 static gint
2342 _sort_keys_func (gconstpointer a,
2343                  gconstpointer b)
2344 {
2345   gint ia;
2346   gint ib;
2347
2348   ia = GPOINTER_TO_INT (a);
2349   ib = GPOINTER_TO_INT (b);
2350
2351   return ia - ib;
2352 }
2353
2354 /**
2355  * g_dbus_message_print:
2356  * @message: A #GDBusMessage.
2357  * @indent: Indentation level.
2358  *
2359  * Produces a human-readable multi-line description of @message.
2360  *
2361  * The contents of the description has no ABI guarantees, the contents
2362  * and formatting is subject to change at any time. Typical output
2363  * looks something like this:
2364  * <programlisting>
2365  * Type:    method-call
2366  * Flags:   none
2367  * Version: 0
2368  * Serial:  4
2369  * Headers:
2370  *   path -> objectpath '/org/gtk/GDBus/TestObject'
2371  *   interface -> 'org.gtk.GDBus.TestInterface'
2372  *   member -> 'GimmeStdout'
2373  *   destination -> ':1.146'
2374  * Body: ()
2375  * UNIX File Descriptors:
2376  *   (none)
2377  * </programlisting>
2378  * or
2379  * <programlisting>
2380  * Type:    method-return
2381  * Flags:   no-reply-expected
2382  * Version: 0
2383  * Serial:  477
2384  * Headers:
2385  *   reply-serial -> uint32 4
2386  *   destination -> ':1.159'
2387  *   sender -> ':1.146'
2388  *   num-unix-fds -> uint32 1
2389  * Body: ()
2390  * UNIX File Descriptors:
2391  *   fd 12: dev=0:10,mode=020620,ino=5,uid=500,gid=5,rdev=136:2,size=0,atime=1273085037,mtime=1273085851,ctime=1272982635
2392  * </programlisting>
2393  *
2394  * Returns: A string that should be freed with g_free().
2395  *
2396  * Since: 2.26
2397  */
2398 gchar *
2399 g_dbus_message_print (GDBusMessage *message,
2400                       guint         indent)
2401 {
2402   GString *str;
2403   gchar *s;
2404   GList *keys;
2405   GList *l;
2406
2407   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2408
2409   str = g_string_new (NULL);
2410
2411   s = enum_to_string (G_TYPE_DBUS_MESSAGE_TYPE, message->priv->type);
2412   g_string_append_printf (str, "%*sType:    %s\n", indent, "", s);
2413   g_free (s);
2414   s = flags_to_string (G_TYPE_DBUS_MESSAGE_FLAGS, message->priv->flags);
2415   g_string_append_printf (str, "%*sFlags:   %s\n", indent, "", s);
2416   g_free (s);
2417   g_string_append_printf (str, "%*sVersion: %d\n", indent, "", message->priv->major_protocol_version);
2418   g_string_append_printf (str, "%*sSerial:  %d\n", indent, "", message->priv->serial);
2419
2420   g_string_append_printf (str, "%*sHeaders:\n", indent, "");
2421   keys = g_hash_table_get_keys (message->priv->headers);
2422   keys = g_list_sort (keys, _sort_keys_func);
2423   if (keys != NULL)
2424     {
2425       for (l = keys; l != NULL; l = l->next)
2426         {
2427           gint key = GPOINTER_TO_INT (l->data);
2428           GVariant *value;
2429           gchar *value_str;
2430
2431           value = g_hash_table_lookup (message->priv->headers, l->data);
2432           g_assert (value != NULL);
2433
2434           s = enum_to_string (G_TYPE_DBUS_MESSAGE_HEADER_FIELD, key);
2435           value_str = g_variant_print (value, TRUE);
2436           g_string_append_printf (str, "%*s  %s -> %s\n", indent, "", s, value_str);
2437           g_free (s);
2438           g_free (value_str);
2439         }
2440     }
2441   else
2442     {
2443       g_string_append_printf (str, "%*s  (none)\n", indent, "");
2444     }
2445   g_string_append_printf (str, "%*sBody: ", indent, "");
2446   if (message->priv->body != NULL)
2447     {
2448       g_variant_print_string (message->priv->body,
2449                               str,
2450                               TRUE);
2451     }
2452   else
2453     {
2454       g_string_append (str, "()");
2455     }
2456   g_string_append (str, "\n");
2457 #ifdef G_OS_UNIX
2458   g_string_append_printf (str, "%*sUNIX File Descriptors:\n", indent, "");
2459   if (message->priv->fd_list != NULL)
2460     {
2461       gint num_fds;
2462       const gint *fds;
2463       gint n;
2464
2465       fds = g_unix_fd_list_peek_fds (message->priv->fd_list, &num_fds);
2466       if (num_fds > 0)
2467         {
2468           for (n = 0; n < num_fds; n++)
2469             {
2470               GString *fs;
2471               struct stat statbuf;
2472               fs = g_string_new (NULL);
2473               if (fstat (fds[n], &statbuf) == 0)
2474                 {
2475                   g_string_append_printf (fs, "%s" "dev=%d:%d", fs->len > 0 ? "," : "",
2476                                           major (statbuf.st_dev), minor (statbuf.st_dev));
2477                   g_string_append_printf (fs, "%s" "mode=0%o", fs->len > 0 ? "," : "",
2478                                           statbuf.st_mode);
2479                   g_string_append_printf (fs, "%s" "ino=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
2480                                           (guint64) statbuf.st_ino);
2481                   g_string_append_printf (fs, "%s" "uid=%d", fs->len > 0 ? "," : "",
2482                                           statbuf.st_uid);
2483                   g_string_append_printf (fs, "%s" "gid=%d", fs->len > 0 ? "," : "",
2484                                           statbuf.st_gid);
2485                   g_string_append_printf (fs, "%s" "rdev=%d:%d", fs->len > 0 ? "," : "",
2486                                           major (statbuf.st_rdev), minor (statbuf.st_rdev));
2487                   g_string_append_printf (fs, "%s" "size=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
2488                                           (guint64) statbuf.st_size);
2489                   g_string_append_printf (fs, "%s" "atime=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
2490                                           (guint64) statbuf.st_atime);
2491                   g_string_append_printf (fs, "%s" "mtime=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
2492                                           (guint64) statbuf.st_mtime);
2493                   g_string_append_printf (fs, "%s" "ctime=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
2494                                           (guint64) statbuf.st_ctime);
2495                 }
2496               else
2497                 {
2498                   g_string_append_printf (fs, "(fstat failed: %s)", strerror (errno));
2499                 }
2500               g_string_append_printf (str, "%*s  fd %d: %s\n", indent, "", fds[n], fs->str);
2501               g_string_free (fs, TRUE);
2502             }
2503         }
2504       else
2505         {
2506           g_string_append_printf (str, "%*s  (empty)\n", indent, "");
2507         }
2508     }
2509   else
2510     {
2511       g_string_append_printf (str, "%*s  (none)\n", indent, "");
2512     }
2513 #endif
2514
2515   return g_string_free (str, FALSE);
2516 }
2517
2518
2519 #define __G_DBUS_MESSAGE_C__
2520 #include "gioaliasdef.c"