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