1 /* GDBus - GLib D-Bus Library
3 * Copyright (C) 2008-2010 Red Hat, Inc.
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.
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.
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.
20 * Author: David Zeuthen <davidz@redhat.com>
23 /* Uncomment to debug serializer code */
24 /* #define DEBUG_SERIALIZER */
30 #include <sys/types.h>
36 #include "gdbusutils.h"
37 #include "gdbusmessage.h"
38 #include "gdbuserror.h"
39 #include "gioenumtypes.h"
40 #include "ginputstream.h"
41 #include "gdatainputstream.h"
42 #include "gmemoryinputstream.h"
43 #include "goutputstream.h"
44 #include "gdataoutputstream.h"
45 #include "gmemoryoutputstream.h"
46 #include "gseekable.h"
48 #include "gdbusprivate.h"
51 #include "gunixfdlist.h"
58 * SECTION:gdbusmessage
59 * @short_description: D-Bus Message
62 * A type for representing D-Bus messages that can be sent or received
63 * on a #GDBusConnection.
66 struct _GDBusMessagePrivate
68 GDBusMessageType type;
69 GDBusMessageFlags flags;
70 guchar major_protocol_version;
79 G_DEFINE_TYPE (GDBusMessage, g_dbus_message, G_TYPE_OBJECT);
82 g_dbus_message_finalize (GObject *object)
84 GDBusMessage *message = G_DBUS_MESSAGE (object);
86 if (message->priv->headers != NULL)
87 g_hash_table_unref (message->priv->headers);
88 if (message->priv->body != NULL)
89 g_variant_unref (message->priv->body);
91 if (message->priv->fd_list != NULL)
92 g_object_unref (message->priv->fd_list);
95 if (G_OBJECT_CLASS (g_dbus_message_parent_class)->finalize != NULL)
96 G_OBJECT_CLASS (g_dbus_message_parent_class)->finalize (object);
100 g_dbus_message_class_init (GDBusMessageClass *klass)
102 GObjectClass *gobject_class;
104 g_type_class_add_private (klass, sizeof (GDBusMessagePrivate));
106 gobject_class = G_OBJECT_CLASS (klass);
108 gobject_class->finalize = g_dbus_message_finalize;
112 g_dbus_message_init (GDBusMessage *message)
114 message->priv = G_TYPE_INSTANCE_GET_PRIVATE (message, G_TYPE_DBUS_MESSAGE, GDBusMessagePrivate);
116 message->priv->headers = g_hash_table_new_full (g_direct_hash,
119 (GDestroyNotify) g_variant_unref);
123 * g_dbus_message_new:
125 * Creates a new empty #GDBusMessage.
127 * Returns: A #GDBusMessage. Free with g_object_unref().
132 g_dbus_message_new (void)
134 return g_object_new (G_TYPE_DBUS_MESSAGE, NULL);
138 * g_dbus_message_new_method_call:
139 * @name: A valid D-Bus name or %NULL.
140 * @path: A valid object path.
141 * @interface_: A valid D-Bus interface name or %NULL.
142 * @method: A valid method name.
144 * Creates a new #GDBusMessage for a method call.
146 * Returns: A #GDBusMessage. Free with g_object_unref().
151 g_dbus_message_new_method_call (const gchar *name,
153 const gchar *interface_,
156 GDBusMessage *message;
158 g_return_val_if_fail (name == NULL || g_dbus_is_name (name), NULL);
159 g_return_val_if_fail (g_variant_is_object_path (path), NULL);
160 g_return_val_if_fail (g_dbus_is_member_name (method), NULL);
161 g_return_val_if_fail (interface_ == NULL || g_dbus_is_interface_name (interface_), NULL);
163 message = g_dbus_message_new ();
164 message->priv->type = G_DBUS_MESSAGE_TYPE_METHOD_CALL;
167 g_dbus_message_set_destination (message, name);
168 g_dbus_message_set_path (message, path);
169 g_dbus_message_set_member (message, method);
170 if (interface_ != NULL)
171 g_dbus_message_set_interface (message, interface_);
177 * g_dbus_message_new_signal:
178 * @path: A valid object path.
179 * @interface_: A valid D-Bus interface name or %NULL.
180 * @signal: A valid signal name.
182 * Creates a new #GDBusMessage for a signal emission.
184 * Returns: A #GDBusMessage. Free with g_object_unref().
189 g_dbus_message_new_signal (const gchar *path,
190 const gchar *interface_,
193 GDBusMessage *message;
195 g_return_val_if_fail (g_variant_is_object_path (path), NULL);
196 g_return_val_if_fail (g_dbus_is_member_name (signal), NULL);
197 g_return_val_if_fail (interface_ == NULL || g_dbus_is_interface_name (interface_), NULL);
199 message = g_dbus_message_new ();
200 message->priv->type = G_DBUS_MESSAGE_TYPE_SIGNAL;
201 message->priv->flags = G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED;
203 g_dbus_message_set_path (message, path);
204 g_dbus_message_set_member (message, signal);
206 if (interface_ != NULL)
207 g_dbus_message_set_interface (message, interface_);
214 * g_dbus_message_new_method_reply:
215 * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to
216 * create a reply message to.
218 * Creates a new #GDBusMessage that is a reply to @method_call_message.
220 * Returns: A #GDBusMessage. Free with g_object_unref().
225 g_dbus_message_new_method_reply (GDBusMessage *method_call_message)
227 GDBusMessage *message;
230 g_return_val_if_fail (G_IS_DBUS_MESSAGE (method_call_message), NULL);
231 g_return_val_if_fail (g_dbus_message_get_message_type (method_call_message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL, NULL);
232 g_return_val_if_fail (g_dbus_message_get_serial (method_call_message) != 0, NULL);
234 message = g_dbus_message_new ();
235 message->priv->type = G_DBUS_MESSAGE_TYPE_METHOD_RETURN;
236 message->priv->flags = G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED;
238 g_dbus_message_set_reply_serial (message, g_dbus_message_get_serial (method_call_message));
239 sender = g_dbus_message_get_sender (method_call_message);
241 g_dbus_message_set_destination (message, sender);
247 * g_dbus_message_new_method_error:
248 * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to
249 * create a reply message to.
250 * @error_name: A valid D-Bus error name.
251 * @error_message_format: The D-Bus error message in a printf() format.
252 * @...: Arguments for @error_message_format.
254 * Creates a new #GDBusMessage that is an error reply to @method_call_message.
256 * Returns: A #GDBusMessage. Free with g_object_unref().
261 g_dbus_message_new_method_error (GDBusMessage *method_call_message,
262 const gchar *error_name,
263 const gchar *error_message_format,
269 va_start (var_args, error_message_format);
270 ret = g_dbus_message_new_method_error_valist (method_call_message,
272 error_message_format,
280 * g_dbus_message_new_method_error_literal:
281 * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to
282 * create a reply message to.
283 * @error_name: A valid D-Bus error name.
284 * @error_message: The D-Bus error message.
286 * Creates a new #GDBusMessage that is an error reply to @method_call_message.
288 * Returns: A #GDBusMessage. Free with g_object_unref().
293 g_dbus_message_new_method_error_literal (GDBusMessage *method_call_message,
294 const gchar *error_name,
295 const gchar *error_message)
297 GDBusMessage *message;
300 g_return_val_if_fail (G_IS_DBUS_MESSAGE (method_call_message), NULL);
301 g_return_val_if_fail (g_dbus_message_get_message_type (method_call_message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL, NULL);
302 g_return_val_if_fail (g_dbus_message_get_serial (method_call_message) != 0, NULL);
303 g_return_val_if_fail (g_dbus_is_name (error_name), NULL);
304 g_return_val_if_fail (error_message != NULL, NULL);
306 message = g_dbus_message_new ();
307 message->priv->type = G_DBUS_MESSAGE_TYPE_ERROR;
308 message->priv->flags = G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED;
310 g_dbus_message_set_reply_serial (message, g_dbus_message_get_serial (method_call_message));
311 g_dbus_message_set_error_name (message, error_name);
312 g_dbus_message_set_body (message, g_variant_new ("(s)", error_message));
314 sender = g_dbus_message_get_sender (method_call_message);
316 g_dbus_message_set_destination (message, sender);
322 * g_dbus_message_new_method_error_valist:
323 * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to
324 * create a reply message to.
325 * @error_name: A valid D-Bus error name.
326 * @error_message_format: The D-Bus error message in a printf() format.
327 * @var_args: Arguments for @error_message_format.
329 * Like g_dbus_message_new_method_error() but intended for language bindings.
331 * Returns: A #GDBusMessage. Free with g_object_unref().
336 g_dbus_message_new_method_error_valist (GDBusMessage *method_call_message,
337 const gchar *error_name,
338 const gchar *error_message_format,
342 gchar *error_message;
343 error_message = g_strdup_vprintf (error_message_format, var_args);
344 ret = g_dbus_message_new_method_error_literal (method_call_message,
347 g_free (error_message);
351 /* ---------------------------------------------------------------------------------------------------- */
353 /* TODO: need GI annotations to specify that any guchar value goes for the type */
356 * g_dbus_message_get_message_type:
357 * @message: A #GDBusMessage.
359 * Gets the type of @message.
361 * Returns: A 8-bit unsigned integer (typically a value from the #GDBusMessageType enumeration).
366 g_dbus_message_get_message_type (GDBusMessage *message)
368 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), G_DBUS_MESSAGE_TYPE_INVALID);
369 return message->priv->type;
373 * g_dbus_message_set_message_type:
374 * @message: A #GDBusMessage.
375 * @type: A 8-bit unsigned integer (typically a value from the #GDBusMessageType enumeration).
377 * Sets @message to be of @type.
382 g_dbus_message_set_message_type (GDBusMessage *message,
383 GDBusMessageType type)
385 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
386 g_return_if_fail (type >=0 && type < 256);
387 message->priv->type = type;
390 /* ---------------------------------------------------------------------------------------------------- */
392 /* TODO: need GI annotations to specify that any guchar value goes for flags */
395 * g_dbus_message_get_flags:
396 * @message: A #GDBusMessage.
398 * Gets the flags for @message.
400 * Returns: Flags that are set (typically values from the #GDBusMessageFlags enumeration bitwise ORed together).
405 g_dbus_message_get_flags (GDBusMessage *message)
407 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), G_DBUS_MESSAGE_FLAGS_NONE);
408 return message->priv->flags;
412 * g_dbus_message_set_flags:
413 * @message: A #GDBusMessage.
414 * @flags: Flags for @message that are set (typically values from the #GDBusMessageFlags
415 * enumeration bitwise ORed together).
417 * Sets the flags to set on @message.
422 g_dbus_message_set_flags (GDBusMessage *message,
423 GDBusMessageFlags flags)
425 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
426 g_return_if_fail (flags >=0 && flags < 256);
427 message->priv->flags = flags;
430 /* ---------------------------------------------------------------------------------------------------- */
433 * g_dbus_message_get_serial:
434 * @message: A #GDBusMessage.
436 * Gets the serial for @message.
438 * Returns: A #guint32.
443 g_dbus_message_get_serial (GDBusMessage *message)
445 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), 0);
446 return message->priv->serial;
450 * g_dbus_message_set_serial:
451 * @message: A #GDBusMessage.
452 * @serial: A #guint32.
454 * Sets the serial for @message.
459 g_dbus_message_set_serial (GDBusMessage *message,
462 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
463 message->priv->serial = serial;
466 /* ---------------------------------------------------------------------------------------------------- */
468 /* TODO: need GI annotations to specify that any guchar value goes for header_field */
471 * g_dbus_message_get_header:
472 * @message: A #GDBusMessage.
473 * @header_field: A 8-bit unsigned integer (typically a value from the #GDBusMessageHeaderField enumeration)
475 * Gets a header field on @message.
477 * Returns: A #GVariant with the value if the header was found, %NULL
478 * otherwise. Do not free, it is owned by @message.
483 g_dbus_message_get_header (GDBusMessage *message,
484 GDBusMessageHeaderField header_field)
486 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
487 g_return_val_if_fail (header_field >=0 && header_field < 256, NULL);
488 return g_hash_table_lookup (message->priv->headers, GUINT_TO_POINTER (header_field));
492 * g_dbus_message_set_header:
493 * @message: A #GDBusMessage.
494 * @header_field: A 8-bit unsigned integer (typically a value from the #GDBusMessageHeaderField enumeration)
495 * @value: A #GVariant to set the header field or %NULL to clear the header field.
497 * Sets a header field on @message.
499 * If @value is floating, @message assumes ownership of @value.
504 g_dbus_message_set_header (GDBusMessage *message,
505 GDBusMessageHeaderField header_field,
508 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
509 g_return_if_fail (header_field >=0 && header_field < 256);
512 g_hash_table_remove (message->priv->headers, GUINT_TO_POINTER (header_field));
516 g_hash_table_insert (message->priv->headers, GUINT_TO_POINTER (header_field), g_variant_ref_sink (value));
521 * g_dbus_message_get_header_fields:
522 * @message: A #GDBusMessage.
524 * Gets an array of all header fields on @message that are set.
526 * Returns: An array of header fields terminated by
527 * %G_DBUS_MESSAGE_HEADER_FIELD_INVALID. Each element is a
528 * #guchar. Free with g_free().
533 g_dbus_message_get_header_fields (GDBusMessage *message)
541 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
543 keys = g_hash_table_get_keys (message->priv->headers);
544 num_keys = g_list_length (keys);
545 ret = g_new (guchar, num_keys + 1);
546 for (l = keys, n = 0; l != NULL; l = l->next, n++)
547 ret[n] = GPOINTER_TO_UINT (l->data);
548 g_assert (n == num_keys);
549 ret[n] = G_DBUS_MESSAGE_HEADER_FIELD_INVALID;
555 /* ---------------------------------------------------------------------------------------------------- */
558 * g_dbus_message_get_body:
559 * @message: A #GDBusMessage.
561 * Gets the body of a message.
563 * Returns: A #GVariant or %NULL if the body is empty. Do not free, it is owned by @message.
568 g_dbus_message_get_body (GDBusMessage *message)
570 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
571 return message->priv->body;
575 * g_dbus_message_set_body:
576 * @message: A #GDBusMessage.
577 * @body: Either %NULL or a #GVariant that is a tuple.
579 * Sets the body @message. As a side-effect the
580 * %G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE header field is set to the
581 * type string of @body (or cleared if @body is %NULL).
583 * If @body is floating, @message assumes ownership of @body.
588 g_dbus_message_set_body (GDBusMessage *message,
591 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
592 g_return_if_fail ((body == NULL) || g_variant_is_of_type (body, G_VARIANT_TYPE_TUPLE));
594 if (message->priv->body != NULL)
595 g_variant_unref (message->priv->body);
598 message->priv->body = NULL;
599 g_dbus_message_set_signature (message, NULL);
603 const gchar *type_string;
604 gsize type_string_len;
607 message->priv->body = g_variant_ref_sink (body);
609 type_string = g_variant_get_type_string (body);
610 type_string_len = strlen (type_string);
611 g_assert (type_string_len >= 2);
612 signature = g_strndup (type_string + 1, type_string_len - 2);
613 g_dbus_message_set_signature (message, signature);
618 /* ---------------------------------------------------------------------------------------------------- */
622 * g_dbus_message_get_unix_fd_list:
623 * @message: A #GDBusMessage.
625 * Gets the UNIX file descriptors associated with @message, if any.
627 * This method is only available on UNIX.
629 * Returns: A #GUnixFDList or %NULL if no file descriptors are
630 * associated. Do not free, this object is owned by @message.
635 g_dbus_message_get_unix_fd_list (GDBusMessage *message)
637 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
638 return message->priv->fd_list;
642 * g_dbus_message_set_unix_fd_list:
643 * @message: A #GDBusMessage.
644 * @fd_list: A #GUnixFDList or %NULL.
646 * Sets the UNIX file descriptors associated with @message. As a
647 * side-effect the %G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS header
648 * field is set to the number of fds in @fd_list (or cleared if
649 * @fd_list is %NULL).
651 * This method is only available on UNIX.
656 g_dbus_message_set_unix_fd_list (GDBusMessage *message,
657 GUnixFDList *fd_list)
659 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
660 g_return_if_fail (fd_list == NULL || G_IS_UNIX_FD_LIST (fd_list));
661 if (message->priv->fd_list != NULL)
662 g_object_unref (message->priv->fd_list);
665 message->priv->fd_list = g_object_ref (fd_list);
666 g_dbus_message_set_num_unix_fds (message, g_unix_fd_list_get_length (fd_list));
670 message->priv->fd_list = NULL;
671 g_dbus_message_set_num_unix_fds (message, 0);
676 /* ---------------------------------------------------------------------------------------------------- */
679 ensure_input_padding (GMemoryInputStream *mis,
686 offset = g_seekable_tell (G_SEEKABLE (mis));
687 wanted_offset = ((offset + padding_size - 1) / padding_size) * padding_size;
689 if (offset != wanted_offset)
691 return g_seekable_seek (G_SEEKABLE (mis), wanted_offset, G_SEEK_SET, NULL, error);
700 read_string (GMemoryInputStream *mis,
701 GDataInputStream *dis,
711 s = g_string_new (NULL);
714 while (remaining > 0)
719 to_read = MIN (remaining, sizeof (buf));
720 num_read = g_input_stream_read (G_INPUT_STREAM (mis),
729 /* G_GSIZE_FORMAT doesn't work with gettext, so we use %lu */
732 G_IO_ERROR_INVALID_ARGUMENT,
733 _("Wanted to read %lu bytes but got EOF"),
738 remaining -= num_read;
739 g_string_append_len (s, buf, num_read);
743 nul = g_data_input_stream_read_byte (dis, NULL, &local_error);
744 if (local_error != NULL)
746 g_propagate_error (error, local_error);
753 G_IO_ERROR_INVALID_ARGUMENT,
754 _("Expected NUL byte after the string `%s' but found `%c' (%d)"),
759 return g_string_free (s, FALSE);
762 g_string_free (s, TRUE);
766 /* if just_align==TRUE, don't read a value, just align the input stream wrt padding */
768 /* returns a non-floating GVariant! */
770 parse_value_from_blob (GMemoryInputStream *mis,
771 GDataInputStream *dis,
772 const GVariantType *type,
781 #ifdef DEBUG_SERIALIZER
785 s = g_variant_type_dup_string (type);
786 g_print ("%*sReading type %s from offset 0x%04x",
789 (gint) g_seekable_tell (G_SEEKABLE (mis)));
792 #endif /* DEBUG_SERIALIZER */
798 if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
800 if (!ensure_input_padding (mis, 4, &local_error))
805 v = g_data_input_stream_read_uint32 (dis, NULL, &local_error);
806 if (local_error != NULL)
808 ret = g_variant_new_boolean (v);
811 else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
816 v = g_data_input_stream_read_byte (dis, NULL, &local_error);
817 if (local_error != NULL)
819 ret = g_variant_new_byte (v);
822 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
824 if (!ensure_input_padding (mis, 2, &local_error))
829 v = g_data_input_stream_read_int16 (dis, NULL, &local_error);
830 if (local_error != NULL)
832 ret = g_variant_new_int16 (v);
835 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
837 if (!ensure_input_padding (mis, 2, &local_error))
842 v = g_data_input_stream_read_uint16 (dis, NULL, &local_error);
843 if (local_error != NULL)
845 ret = g_variant_new_uint16 (v);
848 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
850 if (!ensure_input_padding (mis, 4, &local_error))
855 v = g_data_input_stream_read_int32 (dis, NULL, &local_error);
856 if (local_error != NULL)
858 ret = g_variant_new_int32 (v);
861 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
863 if (!ensure_input_padding (mis, 4, &local_error))
868 v = g_data_input_stream_read_uint32 (dis, NULL, &local_error);
869 if (local_error != NULL)
871 ret = g_variant_new_uint32 (v);
874 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
876 if (!ensure_input_padding (mis, 8, &local_error))
881 v = g_data_input_stream_read_int64 (dis, NULL, &local_error);
882 if (local_error != NULL)
884 ret = g_variant_new_int64 (v);
887 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
889 if (!ensure_input_padding (mis, 8, &local_error))
894 v = g_data_input_stream_read_uint64 (dis, NULL, &local_error);
895 if (local_error != NULL)
897 ret = g_variant_new_uint64 (v);
900 else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
902 if (!ensure_input_padding (mis, 8, &local_error))
908 v = g_data_input_stream_read_uint64 (dis, NULL, &local_error);
909 if (local_error != NULL)
912 encoded = (gdouble *) &v;
913 ret = g_variant_new_double (*encoded);
916 else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
918 if (!ensure_input_padding (mis, 4, &local_error))
924 len = g_data_input_stream_read_uint32 (dis, NULL, &local_error);
925 if (local_error != NULL)
927 v = read_string (mis, dis, (gsize) len, &local_error);
930 ret = g_variant_new_string (v);
934 else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
936 if (!ensure_input_padding (mis, 4, &local_error))
942 len = g_data_input_stream_read_uint32 (dis, NULL, &local_error);
943 if (local_error != NULL)
945 v = read_string (mis, dis, (gsize) len, &local_error);
948 if (!g_variant_is_object_path (v))
950 g_set_error (&local_error,
952 G_IO_ERROR_INVALID_ARGUMENT,
953 _("Parsed value `%s' is not a valid D-Bus object path"),
958 ret = g_variant_new_object_path (v);
962 else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
968 len = g_data_input_stream_read_byte (dis, NULL, &local_error);
969 if (local_error != NULL)
971 v = read_string (mis, dis, (gsize) len, &local_error);
974 if (!g_variant_is_signature (v))
976 g_set_error (&local_error,
978 G_IO_ERROR_INVALID_ARGUMENT,
979 _("Parsed value `%s' is not a valid D-Bus signature"),
984 ret = g_variant_new_signature (v);
988 else if (g_variant_type_is_array (type))
993 const GVariantType *element_type;
994 GVariantBuilder builder;
996 if (!ensure_input_padding (mis, 4, &local_error))
1005 array_len = g_data_input_stream_read_uint32 (dis, NULL, &local_error);
1006 if (local_error != NULL)
1010 #ifdef DEBUG_SERIALIZER
1011 g_print (": array spans 0x%04x bytes\n", array_len);
1012 #endif /* DEBUG_SERIALIZER */
1014 if (array_len > (2<<26))
1016 /* G_GUINT32_FORMAT doesn't work with gettext, so use u */
1017 g_set_error (&local_error,
1019 G_IO_ERROR_INVALID_ARGUMENT,
1020 _("Encountered array of length %u bytes. Maximum length is 2<<26 bytes."),
1026 g_variant_builder_init (&builder, type);
1027 element_type = g_variant_type_element (type);
1032 item = parse_value_from_blob (mis,
1038 g_assert (item == NULL);
1042 /* TODO: optimize array of primitive types */
1043 offset = g_seekable_tell (G_SEEKABLE (mis));
1044 target = offset + array_len;
1045 while (offset < target)
1048 item = parse_value_from_blob (mis,
1056 g_variant_builder_clear (&builder);
1059 g_variant_builder_add_value (&builder, item);
1060 g_variant_unref (item);
1061 offset = g_seekable_tell (G_SEEKABLE (mis));
1067 ret = g_variant_builder_end (&builder);
1071 g_variant_builder_clear (&builder);
1074 else if (g_variant_type_is_dict_entry (type))
1076 const GVariantType *key_type;
1077 const GVariantType *value_type;
1081 if (!ensure_input_padding (mis, 8, &local_error))
1085 #ifdef DEBUG_SERIALIZER
1087 #endif /* DEBUG_SERIALIZER */
1091 key_type = g_variant_type_key (type);
1092 key = parse_value_from_blob (mis,
1100 value_type = g_variant_type_value (type);
1101 value = parse_value_from_blob (mis,
1109 g_variant_unref (key);
1112 ret = g_variant_new_dict_entry (key, value);
1113 g_variant_unref (key);
1114 g_variant_unref (value);
1117 else if (g_variant_type_is_tuple (type))
1119 if (!ensure_input_padding (mis, 8, &local_error))
1123 #ifdef DEBUG_SERIALIZER
1125 #endif /* DEBUG_SERIALIZER */
1129 const GVariantType *element_type;
1130 GVariantBuilder builder;
1132 g_variant_builder_init (&builder, type);
1133 element_type = g_variant_type_first (type);
1134 while (element_type != NULL)
1137 item = parse_value_from_blob (mis,
1145 g_variant_builder_clear (&builder);
1148 g_variant_builder_add_value (&builder, item);
1149 g_variant_unref (item);
1151 element_type = g_variant_type_next (element_type);
1153 ret = g_variant_builder_end (&builder);
1156 else if (g_variant_type_is_variant (type))
1159 #ifdef DEBUG_SERIALIZER
1161 #endif /* DEBUG_SERIALIZER */
1167 GVariantType *variant_type;
1170 siglen = g_data_input_stream_read_byte (dis, NULL, &local_error);
1171 if (local_error != NULL)
1173 sig = read_string (mis, dis, (gsize) siglen, &local_error);
1176 if (!g_variant_is_signature (sig))
1178 g_set_error (&local_error,
1180 G_IO_ERROR_INVALID_ARGUMENT,
1181 _("Parsed value `%s' for variant is not a valid D-Bus signature"),
1186 variant_type = g_variant_type_new (sig);
1188 value = parse_value_from_blob (mis,
1194 g_variant_type_free (variant_type);
1197 ret = g_variant_new_variant (value);
1198 g_variant_unref (value);
1204 s = g_variant_type_dup_string (type);
1205 g_set_error (&local_error,
1207 G_IO_ERROR_INVALID_ARGUMENT,
1208 _("Error deserializing GVariant with type-string `%s' from the D-Bus wire format"),
1214 g_assert ((just_align && ret == NULL) || (!just_align && ret != NULL));
1216 #ifdef DEBUG_SERIALIZER
1222 if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
1224 s = g_strdup_printf ("0x%02x '%c'", g_variant_get_byte (ret), g_variant_get_byte (ret));
1228 s = g_variant_print (ret, FALSE);
1230 g_print (": %s\n", s);
1234 #endif /* DEBUG_SERIALIZER */
1236 /* sink the reference */
1239 g_assert (g_variant_is_floating (ret));
1240 g_variant_ref_sink (ret);
1245 #ifdef DEBUG_SERIALIZER
1247 "%*sFAILURE: %s (%s, %d)\n",
1249 local_error->message,
1250 g_quark_to_string (local_error->domain),
1252 #endif /* DEBUG_SERIALIZER */
1253 g_propagate_error (error, local_error);
1257 /* ---------------------------------------------------------------------------------------------------- */
1259 /* message_header must be at least 16 bytes */
1262 * g_dbus_message_bytes_needed:
1263 * @blob: A blob represent a binary D-Bus message.
1264 * @blob_len: The length of @blob (must be at least 16).
1265 * @error: Return location for error or %NULL.
1267 * Utility function to calculate how many bytes are needed to
1268 * completely deserialize the D-Bus message stored at @blob.
1270 * Returns: Number of bytes needed or -1 if @error is set (e.g. if
1271 * @blob contains invalid data or not enough data is available to
1272 * determine the size).
1277 g_dbus_message_bytes_needed (guchar *blob,
1285 g_return_val_if_fail (blob != NULL, -1);
1286 g_return_val_if_fail (error == NULL || *error == NULL, -1);
1287 g_return_val_if_fail (blob_len >= 16, -1);
1291 /* core header (12 bytes) + ARRAY of STRUCT of (BYTE,VARIANT) */
1292 ret = 12 + 4 + GUINT32_FROM_LE (((guint32 *) blob)[3]);
1293 /* round up so it's a multiple of 8 */
1294 ret = 8 * ((ret + 7)/8);
1295 /* finally add the body size */
1296 ret += GUINT32_FROM_LE (((guint32 *) blob)[1]);
1298 else if (blob[0] == 'B')
1300 /* core header (12 bytes) + ARRAY of STRUCT of (BYTE,VARIANT) */
1301 ret = 12 + 4 + GUINT32_FROM_BE (((guint32 *) blob)[3]);
1302 /* round up so it's a multiple of 8 */
1303 ret = 8 * ((ret + 7)/8);
1304 /* finally add the body size */
1305 ret += GUINT32_FROM_BE (((guint32 *) blob)[1]);
1311 G_IO_ERROR_INVALID_ARGUMENT,
1312 "Unable to determine message blob length - given blob is malformed");
1319 G_IO_ERROR_INVALID_ARGUMENT,
1320 "Blob indicates that message exceeds maximum message length (128MiB)");
1327 /* ---------------------------------------------------------------------------------------------------- */
1330 * g_dbus_message_new_from_blob:
1331 * @blob: A blob represent a binary D-Bus message.
1332 * @blob_len: The length of @blob.
1333 * @capabilities: A #GDBusCapabilityFlags describing what protocol features are supported.
1334 * @error: Return location for error or %NULL.
1336 * Creates a new #GDBusMessage from the data stored at @blob.
1338 * Returns: A new #GDBusMessage or %NULL if @error is set. Free with
1344 g_dbus_message_new_from_blob (guchar *blob,
1346 GDBusCapabilityFlags capabilities,
1350 GMemoryInputStream *mis;
1351 GDataInputStream *dis;
1352 GDBusMessage *message;
1354 guchar major_protocol_version;
1355 GDataStreamByteOrder byte_order;
1356 guint32 message_body_len;
1360 GVariant *signature;
1362 /* TODO: check against @capabilities */
1366 g_return_val_if_fail (blob != NULL, NULL);
1367 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1368 g_return_val_if_fail (blob_len >= 12, NULL);
1370 message = g_dbus_message_new ();
1372 mis = G_MEMORY_INPUT_STREAM (g_memory_input_stream_new_from_data (blob, blob_len, NULL));
1373 dis = g_data_input_stream_new (G_INPUT_STREAM (mis));
1375 endianness = g_data_input_stream_read_byte (dis, NULL, NULL);
1379 byte_order = G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN;
1382 byte_order = G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN;
1387 G_IO_ERROR_INVALID_ARGUMENT,
1388 _("Invalid endianness value. Expected 'l' or 'B' but found '%c' (%d)"),
1389 endianness, endianness);
1392 g_data_input_stream_set_byte_order (dis, byte_order);
1394 message->priv->type = g_data_input_stream_read_byte (dis, NULL, NULL);
1395 message->priv->flags = g_data_input_stream_read_byte (dis, NULL, NULL);
1396 major_protocol_version = g_data_input_stream_read_byte (dis, NULL, NULL);
1397 if (major_protocol_version != 1)
1401 G_IO_ERROR_INVALID_ARGUMENT,
1402 _("Invalid major protocol version. Expected 1 but found %d"),
1403 major_protocol_version);
1406 message_body_len = g_data_input_stream_read_uint32 (dis, NULL, NULL);
1407 message->priv->serial = g_data_input_stream_read_uint32 (dis, NULL, NULL);
1409 #ifdef DEBUG_SERIALIZER
1410 g_print ("Parsing blob (blob_len = 0x%04x bytes)\n", (gint) blob_len);
1413 s = _g_dbus_hexdump ((const gchar *) blob, blob_len, 2);
1414 g_print ("%s\n", s);
1417 #endif /* DEBUG_SERIALIZER */
1419 #ifdef DEBUG_SERIALIZER
1420 g_print ("Parsing headers (blob_len = 0x%04x bytes)\n", (gint) blob_len);
1421 #endif /* DEBUG_SERIALIZER */
1422 headers = parse_value_from_blob (mis,
1424 G_VARIANT_TYPE ("a{yv}"),
1428 if (headers == NULL)
1430 g_variant_iter_init (&iter, headers);
1431 while ((item = g_variant_iter_next_value (&iter)) != NULL)
1433 guchar header_field;
1435 g_variant_get (item,
1439 g_dbus_message_set_header (message, header_field, value);
1440 g_variant_unref (value);
1441 g_variant_unref (item);
1443 g_variant_unref (headers);
1445 signature = g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE);
1446 if (signature != NULL)
1448 const gchar *signature_str;
1449 gsize signature_str_len;
1451 signature_str = g_variant_get_string (signature, &signature_str_len);
1453 /* signature but no body */
1454 if (message_body_len == 0 && signature_str_len > 0)
1458 G_IO_ERROR_INVALID_ARGUMENT,
1459 _("Signature header with signature `%s' found but message body is empty"),
1463 else if (signature_str_len > 0)
1465 GVariantType *variant_type;
1466 gchar *tupled_signature_str;
1468 if (!g_variant_is_signature (signature_str))
1472 G_IO_ERROR_INVALID_ARGUMENT,
1473 _("Parsed value `%s' is not a valid D-Bus signature (for body)"),
1477 tupled_signature_str = g_strdup_printf ("(%s)", signature_str);
1478 variant_type = g_variant_type_new (tupled_signature_str);
1479 g_free (tupled_signature_str);
1480 #ifdef DEBUG_SERIALIZER
1481 g_print ("Parsing body (blob_len = 0x%04x bytes)\n", (gint) blob_len);
1482 #endif /* DEBUG_SERIALIZER */
1483 message->priv->body = parse_value_from_blob (mis,
1489 g_variant_type_free (variant_type);
1490 if (message->priv->body == NULL)
1496 /* no signature, this is only OK if the body is empty */
1497 if (message_body_len != 0)
1499 /* G_GUINT32_FORMAT doesn't work with gettext, just use %u */
1502 G_IO_ERROR_INVALID_ARGUMENT,
1503 _("No signature header in message but the message body is %u bytes"),
1513 g_object_unref (dis);
1514 g_object_unref (mis);
1522 if (message != NULL)
1523 g_object_unref (message);
1528 /* ---------------------------------------------------------------------------------------------------- */
1531 ensure_output_padding (GMemoryOutputStream *mos,
1532 GDataOutputStream *dos,
1536 gsize wanted_offset;
1537 gsize padding_needed;
1540 offset = g_memory_output_stream_get_data_size (mos);
1541 wanted_offset = ((offset + padding_size - 1) / padding_size) * padding_size;
1542 padding_needed = wanted_offset - offset;
1544 for (n = 0; n < padding_needed; n++)
1545 g_data_output_stream_put_byte (dos, '\0', NULL, NULL);
1547 return padding_needed;
1550 /* note that value can be NULL for e.g. empty arrays - type is never NULL */
1552 append_value_to_blob (GVariant *value,
1553 const GVariantType *type,
1554 GMemoryOutputStream *mos,
1555 GDataOutputStream *dos,
1556 gsize *out_padding_added,
1559 gsize padding_added;
1563 if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
1565 padding_added = ensure_output_padding (mos, dos, 4);
1568 gboolean v = g_variant_get_boolean (value);
1569 g_data_output_stream_put_uint32 (dos, v, NULL, NULL);
1572 else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
1576 guint8 v = g_variant_get_byte (value);
1577 g_data_output_stream_put_byte (dos, v, NULL, NULL);
1580 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
1582 padding_added = ensure_output_padding (mos, dos, 2);
1585 gint16 v = g_variant_get_int16 (value);
1586 g_data_output_stream_put_int16 (dos, v, NULL, NULL);
1589 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
1591 padding_added = ensure_output_padding (mos, dos, 2);
1594 guint16 v = g_variant_get_uint16 (value);
1595 g_data_output_stream_put_uint16 (dos, v, NULL, NULL);
1598 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
1600 padding_added = ensure_output_padding (mos, dos, 4);
1603 gint32 v = g_variant_get_int32 (value);
1604 g_data_output_stream_put_int32 (dos, v, NULL, NULL);
1607 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
1609 padding_added = ensure_output_padding (mos, dos, 4);
1612 guint32 v = g_variant_get_uint32 (value);
1613 g_data_output_stream_put_uint32 (dos, v, NULL, NULL);
1616 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
1618 padding_added = ensure_output_padding (mos, dos, 8);
1621 gint64 v = g_variant_get_int64 (value);
1622 g_data_output_stream_put_int64 (dos, v, NULL, NULL);
1625 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
1627 padding_added = ensure_output_padding (mos, dos, 8);
1630 guint64 v = g_variant_get_uint64 (value);
1631 g_data_output_stream_put_uint64 (dos, v, NULL, NULL);
1634 else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
1636 padding_added = ensure_output_padding (mos, dos, 8);
1640 gdouble v = g_variant_get_double (value);
1642 encoded = (guint64 *) &v;
1643 g_data_output_stream_put_uint64 (dos, *encoded, NULL, NULL);
1646 else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
1648 padding_added = ensure_output_padding (mos, dos, 4);
1652 const gchar *v = g_variant_get_string (value, &len);
1653 g_data_output_stream_put_uint32 (dos, len, NULL, NULL);
1654 g_data_output_stream_put_string (dos, v, NULL, NULL);
1655 g_data_output_stream_put_byte (dos, '\0', NULL, NULL);
1658 else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
1660 padding_added = ensure_output_padding (mos, dos, 4);
1663 /* TODO: validate object path */
1665 const gchar *v = g_variant_get_string (value, &len);
1666 g_data_output_stream_put_uint32 (dos, len, NULL, NULL);
1667 g_data_output_stream_put_string (dos, v, NULL, NULL);
1668 g_data_output_stream_put_byte (dos, '\0', NULL, NULL);
1671 else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
1675 /* TODO: validate signature (including max len being 255) */
1677 const gchar *v = g_variant_get_string (value, &len);
1678 g_data_output_stream_put_byte (dos, len, NULL, NULL);
1679 g_data_output_stream_put_string (dos, v, NULL, NULL);
1680 g_data_output_stream_put_byte (dos, '\0', NULL, NULL);
1683 else if (g_variant_type_is_array (type))
1687 goffset array_len_offset;
1688 goffset array_payload_begin_offset;
1692 padding_added = ensure_output_padding (mos, dos, 4);
1695 /* array length - will be filled in later */
1696 array_len_offset = g_memory_output_stream_get_data_size (mos);
1697 g_data_output_stream_put_uint32 (dos, 0xF00DFACE, NULL, NULL);
1699 /* From the D-Bus spec:
1701 * "A UINT32 giving the length of the array data in bytes,
1702 * followed by alignment padding to the alignment boundary of
1703 * the array element type, followed by each array element. The
1704 * array length is from the end of the alignment padding to
1705 * the end of the last element, i.e. it does not include the
1706 * padding after the length, or any padding after the last
1709 * Thus, we need to count how much padding the first element
1710 * contributes and subtract that from the array length.
1712 array_payload_begin_offset = g_memory_output_stream_get_data_size (mos);
1714 if (g_variant_n_children (value) == 0)
1716 gsize padding_added_for_item;
1717 if (!append_value_to_blob (NULL,
1718 g_variant_type_element (type),
1721 &padding_added_for_item,
1724 array_payload_begin_offset += padding_added_for_item;
1730 g_variant_iter_init (&iter, value);
1731 while ((item = g_variant_iter_next_value (&iter)) != NULL)
1733 gsize padding_added_for_item;
1734 if (!append_value_to_blob (item,
1735 g_variant_get_type (item),
1738 &padding_added_for_item,
1741 g_variant_unref (item);
1744 g_variant_unref (item);
1747 array_payload_begin_offset += padding_added_for_item;
1753 cur_offset = g_memory_output_stream_get_data_size (mos);
1755 array_len = cur_offset - array_payload_begin_offset;
1757 if (!g_seekable_seek (G_SEEKABLE (mos), array_len_offset, G_SEEK_SET, NULL, error))
1760 g_data_output_stream_put_uint32 (dos, array_len, NULL, NULL);
1762 if (!g_seekable_seek (G_SEEKABLE (mos), cur_offset, G_SEEK_SET, NULL, error))
1766 else if (g_variant_type_is_dict_entry (type) || g_variant_type_is_tuple (type))
1768 padding_added = ensure_output_padding (mos, dos, 8);
1773 g_variant_iter_init (&iter, value);
1774 while ((item = g_variant_iter_next_value (&iter)) != NULL)
1776 if (!append_value_to_blob (item,
1777 g_variant_get_type (item),
1783 g_variant_unref (item);
1786 g_variant_unref (item);
1790 else if (g_variant_type_is_variant (type))
1795 const gchar *signature;
1796 child = g_variant_get_child_value (value, 0);
1797 signature = g_variant_get_type_string (child);
1798 /* TODO: validate signature (including max len being 255) */
1799 g_data_output_stream_put_byte (dos, strlen (signature), NULL, NULL);
1800 g_data_output_stream_put_string (dos, signature, NULL, NULL);
1801 g_data_output_stream_put_byte (dos, '\0', NULL, NULL);
1802 if (!append_value_to_blob (child,
1803 g_variant_get_type (child),
1809 g_variant_unref (child);
1812 g_variant_unref (child);
1819 G_IO_ERROR_INVALID_ARGUMENT,
1820 _("Error serializing GVariant with type-string `%s' to the D-Bus wire format"),
1821 g_variant_get_type_string (value));
1825 if (out_padding_added != NULL)
1826 *out_padding_added = padding_added;
1835 append_body_to_blob (GVariant *value,
1836 GMemoryOutputStream *mos,
1837 GDataOutputStream *dos,
1846 if (!g_variant_is_of_type (value, G_VARIANT_TYPE_TUPLE))
1850 G_IO_ERROR_INVALID_ARGUMENT,
1851 "Expected a tuple for the body of the GDBusMessage.");
1855 g_variant_iter_init (&iter, value);
1856 while ((item = g_variant_iter_next_value (&iter)) != NULL)
1858 if (!append_value_to_blob (item,
1859 g_variant_get_type (item),
1865 g_variant_unref (item);
1868 g_variant_unref (item);
1876 /* ---------------------------------------------------------------------------------------------------- */
1879 * g_dbus_message_to_blob:
1880 * @message: A #GDBusMessage.
1881 * @out_size: Return location for size of generated blob.
1882 * @capabilities: A #GDBusCapabilityFlags describing what protocol features are supported.
1883 * @error: Return location for error.
1885 * Serializes @message to a blob.
1887 * Returns: A pointer to a valid binary D-Bus message of @out_size bytes
1888 * generated by @message or %NULL if @error is set. Free with g_free().
1893 g_dbus_message_to_blob (GDBusMessage *message,
1895 GDBusCapabilityFlags capabilities,
1898 GMemoryOutputStream *mos;
1899 GDataOutputStream *dos;
1902 GDataStreamByteOrder byte_order;
1903 goffset body_len_offset;
1904 goffset body_start_offset;
1906 GVariant *header_fields;
1907 GVariantBuilder builder;
1908 GHashTableIter hash_iter;
1910 GVariant *header_value;
1911 GVariant *signature;
1912 const gchar *signature_str;
1913 gint num_fds_in_message;
1914 gint num_fds_according_to_header;
1916 /* TODO: check against @capabilities */
1920 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
1921 g_return_val_if_fail (out_size != NULL, NULL);
1922 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1924 mos = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new (NULL, 0, g_realloc, g_free));
1925 dos = g_data_output_stream_new (G_OUTPUT_STREAM (mos));
1927 /* TODO: detect endianess... */
1928 byte_order = G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN;
1929 g_data_output_stream_set_byte_order (dos, byte_order);
1932 g_data_output_stream_put_byte (dos, byte_order == G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN ? 'l' : 'B', NULL, NULL);
1933 g_data_output_stream_put_byte (dos, message->priv->type, NULL, NULL);
1934 g_data_output_stream_put_byte (dos, message->priv->flags, NULL, NULL);
1935 g_data_output_stream_put_byte (dos, 1, NULL, NULL); /* major protocol version */
1936 body_len_offset = g_memory_output_stream_get_data_size (mos);
1937 /* body length - will be filled in later */
1938 g_data_output_stream_put_uint32 (dos, 0xF00DFACE, NULL, NULL);
1939 g_data_output_stream_put_uint32 (dos, message->priv->serial, NULL, NULL);
1941 num_fds_in_message = 0;
1943 if (message->priv->fd_list != NULL)
1944 num_fds_in_message = g_unix_fd_list_get_length (message->priv->fd_list);
1946 num_fds_according_to_header = g_dbus_message_get_num_unix_fds (message);
1947 /* TODO: check we have all the right header fields and that they are the correct value etc etc */
1948 if (num_fds_in_message != num_fds_according_to_header)
1952 G_IO_ERROR_INVALID_ARGUMENT,
1953 _("Message has %d fds but the header field indicates %d fds"),
1955 num_fds_according_to_header);
1959 g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{yv}"));
1960 g_hash_table_iter_init (&hash_iter, message->priv->headers);
1961 while (g_hash_table_iter_next (&hash_iter, &key, (gpointer) &header_value))
1963 g_variant_builder_add (&builder,
1965 (guchar) GPOINTER_TO_UINT (key),
1968 header_fields = g_variant_builder_end (&builder);
1970 if (!append_value_to_blob (header_fields,
1971 g_variant_get_type (header_fields),
1976 g_variant_unref (header_fields);
1979 g_variant_unref (header_fields);
1981 /* header size must be a multiple of 8 */
1982 ensure_output_padding (mos, dos, 8);
1984 body_start_offset = g_memory_output_stream_get_data_size (mos);
1986 signature = g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE);
1987 signature_str = NULL;
1988 if (signature != NULL)
1989 signature_str = g_variant_get_string (signature, NULL);
1990 if (message->priv->body != NULL)
1992 gchar *tupled_signature_str;
1993 tupled_signature_str = g_strdup_printf ("(%s)", signature_str);
1994 if (signature == NULL)
1998 G_IO_ERROR_INVALID_ARGUMENT,
1999 _("Message body has signature `%s' but there is no signature header"),
2001 g_free (tupled_signature_str);
2004 else if (g_strcmp0 (tupled_signature_str, g_variant_get_type_string (message->priv->body)) != 0)
2008 G_IO_ERROR_INVALID_ARGUMENT,
2009 _("Message body has type signature `%s' but signature in the header field is `%s'"),
2010 tupled_signature_str, g_variant_get_type_string (message->priv->body));
2011 g_free (tupled_signature_str);
2014 g_free (tupled_signature_str);
2015 if (!append_body_to_blob (message->priv->body, mos, dos, error))
2020 if (signature != NULL)
2024 G_IO_ERROR_INVALID_ARGUMENT,
2025 _("Message body is empty but signature in the header field is `(%s)'"),
2031 /* OK, we're done writing the message - set the body length */
2032 size = g_memory_output_stream_get_data_size (mos);
2033 body_size = size - body_start_offset;
2035 if (!g_seekable_seek (G_SEEKABLE (mos), body_len_offset, G_SEEK_SET, NULL, error))
2038 g_data_output_stream_put_uint32 (dos, body_size, NULL, NULL);
2041 ret = g_memdup (g_memory_output_stream_get_data (mos), size);
2044 g_object_unref (dos);
2045 g_object_unref (mos);
2050 /* ---------------------------------------------------------------------------------------------------- */
2053 get_uint32_header (GDBusMessage *message,
2054 GDBusMessageHeaderField header_field)
2060 value = g_hash_table_lookup (message->priv->headers, GUINT_TO_POINTER (header_field));
2061 if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_UINT32))
2062 ret = g_variant_get_uint32 (value);
2067 static const gchar *
2068 get_string_header (GDBusMessage *message,
2069 GDBusMessageHeaderField header_field)
2075 value = g_hash_table_lookup (message->priv->headers, GUINT_TO_POINTER (header_field));
2076 if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
2077 ret = g_variant_get_string (value, NULL);
2082 static const gchar *
2083 get_object_path_header (GDBusMessage *message,
2084 GDBusMessageHeaderField header_field)
2090 value = g_hash_table_lookup (message->priv->headers, GUINT_TO_POINTER (header_field));
2091 if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_OBJECT_PATH))
2092 ret = g_variant_get_string (value, NULL);
2097 static const gchar *
2098 get_signature_header (GDBusMessage *message,
2099 GDBusMessageHeaderField header_field)
2105 value = g_hash_table_lookup (message->priv->headers, GUINT_TO_POINTER (header_field));
2106 if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_SIGNATURE))
2107 ret = g_variant_get_string (value, NULL);
2112 /* ---------------------------------------------------------------------------------------------------- */
2115 set_uint32_header (GDBusMessage *message,
2116 GDBusMessageHeaderField header_field,
2119 g_dbus_message_set_header (message,
2121 g_variant_new_uint32 (value));
2125 set_string_header (GDBusMessage *message,
2126 GDBusMessageHeaderField header_field,
2129 g_dbus_message_set_header (message,
2131 value == NULL ? NULL : g_variant_new_string (value));
2135 set_object_path_header (GDBusMessage *message,
2136 GDBusMessageHeaderField header_field,
2139 g_dbus_message_set_header (message,
2141 value == NULL ? NULL : g_variant_new_object_path (value));
2145 set_signature_header (GDBusMessage *message,
2146 GDBusMessageHeaderField header_field,
2149 g_dbus_message_set_header (message,
2151 value == NULL ? NULL : g_variant_new_signature (value));
2154 /* ---------------------------------------------------------------------------------------------------- */
2157 * g_dbus_message_get_reply_serial:
2158 * @message: A #GDBusMessage.
2160 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL header field.
2162 * Returns: The value.
2167 g_dbus_message_get_reply_serial (GDBusMessage *message)
2169 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), 0);
2170 return get_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL);
2174 * g_dbus_message_set_reply_serial:
2175 * @message: A #GDBusMessage.
2176 * @value: The value to set.
2178 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL header field.
2183 g_dbus_message_set_reply_serial (GDBusMessage *message,
2186 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2187 set_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL, value);
2190 /* ---------------------------------------------------------------------------------------------------- */
2193 * g_dbus_message_get_interface:
2194 * @message: A #GDBusMessage.
2196 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE header field.
2198 * Returns: The value.
2203 g_dbus_message_get_interface (GDBusMessage *message)
2205 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2206 return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE);
2210 * g_dbus_message_set_interface:
2211 * @message: A #GDBusMessage.
2212 * @value: The value to set.
2214 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE header field.
2219 g_dbus_message_set_interface (GDBusMessage *message,
2222 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2223 g_return_if_fail (value == NULL || g_dbus_is_interface_name (value));
2224 set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE, value);
2227 /* ---------------------------------------------------------------------------------------------------- */
2230 * g_dbus_message_get_member:
2231 * @message: A #GDBusMessage.
2233 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_MEMBER header field.
2235 * Returns: The value.
2240 g_dbus_message_get_member (GDBusMessage *message)
2242 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2243 return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER);
2247 * g_dbus_message_set_member:
2248 * @message: A #GDBusMessage.
2249 * @value: The value to set.
2251 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_MEMBER header field.
2256 g_dbus_message_set_member (GDBusMessage *message,
2259 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2260 g_return_if_fail (value == NULL || g_dbus_is_member_name (value));
2261 set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER, value);
2264 /* ---------------------------------------------------------------------------------------------------- */
2267 * g_dbus_message_get_path:
2268 * @message: A #GDBusMessage.
2270 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_PATH header field.
2272 * Returns: The value.
2277 g_dbus_message_get_path (GDBusMessage *message)
2279 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2280 return get_object_path_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH);
2284 * g_dbus_message_set_path:
2285 * @message: A #GDBusMessage.
2286 * @value: The value to set.
2288 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_PATH header field.
2293 g_dbus_message_set_path (GDBusMessage *message,
2296 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2297 g_return_if_fail (value == NULL || g_variant_is_object_path (value));
2298 set_object_path_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH, value);
2301 /* ---------------------------------------------------------------------------------------------------- */
2304 * g_dbus_message_get_sender:
2305 * @message: A #GDBusMessage.
2307 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_SENDER header field.
2309 * Returns: The value.
2314 g_dbus_message_get_sender (GDBusMessage *message)
2316 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2317 return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SENDER);
2321 * g_dbus_message_set_sender:
2322 * @message: A #GDBusMessage.
2323 * @value: The value to set.
2325 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_SENDER header field.
2330 g_dbus_message_set_sender (GDBusMessage *message,
2333 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2334 g_return_if_fail (value == NULL || g_dbus_is_name (value));
2335 set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SENDER, value);
2338 /* ---------------------------------------------------------------------------------------------------- */
2341 * g_dbus_message_get_destination:
2342 * @message: A #GDBusMessage.
2344 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION header field.
2346 * Returns: The value.
2351 g_dbus_message_get_destination (GDBusMessage *message)
2353 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2354 return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION);
2358 * g_dbus_message_set_destination:
2359 * @message: A #GDBusMessage.
2360 * @value: The value to set.
2362 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION header field.
2367 g_dbus_message_set_destination (GDBusMessage *message,
2370 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2371 g_return_if_fail (value == NULL || g_dbus_is_name (value));
2372 set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION, value);
2375 /* ---------------------------------------------------------------------------------------------------- */
2378 * g_dbus_message_get_error_name:
2379 * @message: A #GDBusMessage.
2381 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME header field.
2383 * Returns: The value.
2388 g_dbus_message_get_error_name (GDBusMessage *message)
2390 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2391 return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME);
2395 * g_dbus_message_set_error_name:
2396 * @message: A #GDBusMessage.
2397 * @value: The value to set.
2399 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME header field.
2404 g_dbus_message_set_error_name (GDBusMessage *message,
2407 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2408 g_return_if_fail (value == NULL || g_dbus_is_interface_name (value));
2409 set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME, value);
2412 /* ---------------------------------------------------------------------------------------------------- */
2415 * g_dbus_message_get_signature:
2416 * @message: A #GDBusMessage.
2418 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE header field.
2420 * Returns: The value.
2425 g_dbus_message_get_signature (GDBusMessage *message)
2428 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2429 ret = get_signature_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE);
2436 * g_dbus_message_set_signature:
2437 * @message: A #GDBusMessage.
2438 * @value: The value to set.
2440 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE header field.
2445 g_dbus_message_set_signature (GDBusMessage *message,
2448 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2449 g_return_if_fail (value == NULL || g_variant_is_signature (value));
2450 set_signature_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE, value);
2453 /* ---------------------------------------------------------------------------------------------------- */
2456 * g_dbus_message_get_arg0:
2457 * @message: A #GDBusMessage.
2459 * Convenience to get the first item in the body of @message.
2461 * Returns: The string item or %NULL if the first item in the body of
2462 * @message is not a string.
2467 g_dbus_message_get_arg0 (GDBusMessage *message)
2471 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2475 if (message->priv->body != NULL && g_variant_is_of_type (message->priv->body, G_VARIANT_TYPE_TUPLE))
2478 item = g_variant_get_child_value (message->priv->body, 0);
2479 if (g_variant_is_of_type (item, G_VARIANT_TYPE_STRING))
2480 ret = g_variant_get_string (item, NULL);
2481 g_variant_unref (item);
2487 /* ---------------------------------------------------------------------------------------------------- */
2490 * g_dbus_message_get_num_unix_fds:
2491 * @message: A #GDBusMessage.
2493 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS header field.
2495 * Returns: The value.
2500 g_dbus_message_get_num_unix_fds (GDBusMessage *message)
2502 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), 0);
2503 return get_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS);
2507 * g_dbus_message_set_num_unix_fds:
2508 * @message: A #GDBusMessage.
2509 * @value: The value to set.
2511 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS header field.
2516 g_dbus_message_set_num_unix_fds (GDBusMessage *message,
2519 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2520 set_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS, value);
2523 /* ---------------------------------------------------------------------------------------------------- */
2526 * g_dbus_message_to_gerror:
2527 * @message: A #GDBusMessage.
2528 * @error: The #GError to set.
2530 * If @message is not of type %G_DBUS_MESSAGE_TYPE_ERROR does
2531 * nothing and returns %FALSE.
2533 * Otherwise this method encodes the error in @message as a #GError
2534 * using g_dbus_error_set_dbus_error() using the information in the
2535 * %G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME header field of @message as
2536 * well as the first string item in @message's body.
2538 * Returns: %TRUE if @error was set, %FALSE otherwise.
2543 g_dbus_message_to_gerror (GDBusMessage *message,
2547 const gchar *error_name;
2549 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), FALSE);
2552 if (message->priv->type != G_DBUS_MESSAGE_TYPE_ERROR)
2555 error_name = g_dbus_message_get_error_name (message);
2556 if (error_name != NULL)
2560 body = g_dbus_message_get_body (message);
2562 if (body != NULL && g_variant_is_of_type (body, G_VARIANT_TYPE ("(s)")))
2564 const gchar *error_message;
2565 g_variant_get (body, "(&s)", &error_message);
2566 g_dbus_error_set_dbus_error (error,
2573 /* these two situations are valid, yet pretty rare */
2576 g_dbus_error_set_dbus_error (error,
2579 _("Error return with body of type `%s'"),
2580 g_variant_get_type_string (body));
2584 g_dbus_error_set_dbus_error (error,
2587 _("Error return with empty body"));
2593 /* TOOD: this shouldn't happen - should check this at message serialization
2594 * time and disconnect the peer.
2599 "Error return without error-name header!");
2608 /* ---------------------------------------------------------------------------------------------------- */
2611 flags_to_string (GType flags_type, guint value)
2617 klass = g_type_class_ref (flags_type);
2618 s = g_string_new (NULL);
2619 for (n = 0; n < 32; n++)
2621 if ((value & (1<<n)) != 0)
2623 GFlagsValue *flags_value;
2624 flags_value = g_flags_get_first_value (klass, (1<<n));
2626 g_string_append_c (s, ',');
2627 if (flags_value != NULL)
2628 g_string_append (s, flags_value->value_nick);
2630 g_string_append_printf (s, "unknown (bit %d)", n);
2634 g_string_append (s, "none");
2635 g_type_class_unref (klass);
2636 return g_string_free (s, FALSE);
2640 _sort_keys_func (gconstpointer a,
2646 ia = GPOINTER_TO_INT (a);
2647 ib = GPOINTER_TO_INT (b);
2653 * g_dbus_message_print:
2654 * @message: A #GDBusMessage.
2655 * @indent: Indentation level.
2657 * Produces a human-readable multi-line description of @message.
2659 * The contents of the description has no ABI guarantees, the contents
2660 * and formatting is subject to change at any time. Typical output
2661 * looks something like this:
2668 * path -> objectpath '/org/gtk/GDBus/TestObject'
2669 * interface -> 'org.gtk.GDBus.TestInterface'
2670 * member -> 'GimmeStdout'
2671 * destination -> ':1.146'
2673 * UNIX File Descriptors:
2678 * Type: method-return
2679 * Flags: no-reply-expected
2683 * reply-serial -> uint32 4
2684 * destination -> ':1.159'
2685 * sender -> ':1.146'
2686 * num-unix-fds -> uint32 1
2688 * UNIX File Descriptors:
2689 * fd 12: dev=0:10,mode=020620,ino=5,uid=500,gid=5,rdev=136:2,size=0,atime=1273085037,mtime=1273085851,ctime=1272982635
2692 * Returns: A string that should be freed with g_free().
2697 g_dbus_message_print (GDBusMessage *message,
2705 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2707 str = g_string_new (NULL);
2709 s = _g_dbus_enum_to_string (G_TYPE_DBUS_MESSAGE_TYPE, message->priv->type);
2710 g_string_append_printf (str, "%*sType: %s\n", indent, "", s);
2712 s = flags_to_string (G_TYPE_DBUS_MESSAGE_FLAGS, message->priv->flags);
2713 g_string_append_printf (str, "%*sFlags: %s\n", indent, "", s);
2715 g_string_append_printf (str, "%*sVersion: %d\n", indent, "", message->priv->major_protocol_version);
2716 g_string_append_printf (str, "%*sSerial: %d\n", indent, "", message->priv->serial);
2718 g_string_append_printf (str, "%*sHeaders:\n", indent, "");
2719 keys = g_hash_table_get_keys (message->priv->headers);
2720 keys = g_list_sort (keys, _sort_keys_func);
2723 for (l = keys; l != NULL; l = l->next)
2725 gint key = GPOINTER_TO_INT (l->data);
2729 value = g_hash_table_lookup (message->priv->headers, l->data);
2730 g_assert (value != NULL);
2732 s = _g_dbus_enum_to_string (G_TYPE_DBUS_MESSAGE_HEADER_FIELD, key);
2733 value_str = g_variant_print (value, TRUE);
2734 g_string_append_printf (str, "%*s %s -> %s\n", indent, "", s, value_str);
2741 g_string_append_printf (str, "%*s (none)\n", indent, "");
2743 g_string_append_printf (str, "%*sBody: ", indent, "");
2744 if (message->priv->body != NULL)
2746 g_variant_print_string (message->priv->body,
2752 g_string_append (str, "()");
2754 g_string_append (str, "\n");
2756 g_string_append_printf (str, "%*sUNIX File Descriptors:\n", indent, "");
2757 if (message->priv->fd_list != NULL)
2763 fds = g_unix_fd_list_peek_fds (message->priv->fd_list, &num_fds);
2766 for (n = 0; n < num_fds; n++)
2769 struct stat statbuf;
2770 fs = g_string_new (NULL);
2771 if (fstat (fds[n], &statbuf) == 0)
2773 g_string_append_printf (fs, "%s" "dev=%d:%d", fs->len > 0 ? "," : "",
2774 major (statbuf.st_dev), minor (statbuf.st_dev));
2775 g_string_append_printf (fs, "%s" "mode=0%o", fs->len > 0 ? "," : "",
2777 g_string_append_printf (fs, "%s" "ino=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
2778 (guint64) statbuf.st_ino);
2779 g_string_append_printf (fs, "%s" "uid=%d", fs->len > 0 ? "," : "",
2781 g_string_append_printf (fs, "%s" "gid=%d", fs->len > 0 ? "," : "",
2783 g_string_append_printf (fs, "%s" "rdev=%d:%d", fs->len > 0 ? "," : "",
2784 major (statbuf.st_rdev), minor (statbuf.st_rdev));
2785 g_string_append_printf (fs, "%s" "size=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
2786 (guint64) statbuf.st_size);
2787 g_string_append_printf (fs, "%s" "atime=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
2788 (guint64) statbuf.st_atime);
2789 g_string_append_printf (fs, "%s" "mtime=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
2790 (guint64) statbuf.st_mtime);
2791 g_string_append_printf (fs, "%s" "ctime=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
2792 (guint64) statbuf.st_ctime);
2796 g_string_append_printf (fs, "(fstat failed: %s)", strerror (errno));
2798 g_string_append_printf (str, "%*s fd %d: %s\n", indent, "", fds[n], fs->str);
2799 g_string_free (fs, TRUE);
2804 g_string_append_printf (str, "%*s (empty)\n", indent, "");
2809 g_string_append_printf (str, "%*s (none)\n", indent, "");
2813 return g_string_free (str, FALSE);
2817 #define __G_DBUS_MESSAGE_C__
2818 #include "gioaliasdef.c"