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.1 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, see <http://www.gnu.org/licenses/>.
18 * Author: David Zeuthen <davidz@redhat.com>
21 /* Uncomment to debug serializer code */
22 /* #define DEBUG_SERIALIZER */
28 #include <sys/types.h>
32 #include <sys/mkdev.h>
33 #elif MAJOR_IN_SYSMACROS
34 #include <sys/sysmacros.h>
36 #include <sys/types.h>
38 #define MAJOR_MINOR_NOT_FOUND 1
41 #include "gdbusutils.h"
42 #include "gdbusmessage.h"
43 #include "gdbuserror.h"
44 #include "gioenumtypes.h"
45 #include "ginputstream.h"
46 #include "gdatainputstream.h"
47 #include "gmemoryinputstream.h"
48 #include "goutputstream.h"
49 #include "gdataoutputstream.h"
50 #include "gmemoryoutputstream.h"
51 #include "gseekable.h"
53 #include "gdbusprivate.h"
56 #include "gunixfdlist.h"
61 /* See https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-marshaling-signature
62 * This is 64 containers plus 1 value within them. */
63 #define G_DBUS_MAX_TYPE_DEPTH (64 + 1)
65 typedef struct _GMemoryBuffer GMemoryBuffer;
72 GDataStreamByteOrder byte_order;
76 g_memory_buffer_is_byteswapped (GMemoryBuffer *mbuf)
78 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
79 return mbuf->byte_order == G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN;
81 return mbuf->byte_order == G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN;
86 g_memory_buffer_read_byte (GMemoryBuffer *mbuf)
88 if (mbuf->pos >= mbuf->valid_len)
90 return mbuf->data [mbuf->pos++];
94 g_memory_buffer_read_int16 (GMemoryBuffer *mbuf)
98 if (mbuf->pos > mbuf->valid_len - 2)
100 mbuf->pos = mbuf->valid_len;
104 memcpy (&v, mbuf->data + mbuf->pos, 2);
107 if (g_memory_buffer_is_byteswapped (mbuf))
108 v = GUINT16_SWAP_LE_BE (v);
114 g_memory_buffer_read_uint16 (GMemoryBuffer *mbuf)
118 if (mbuf->pos > mbuf->valid_len - 2)
120 mbuf->pos = mbuf->valid_len;
124 memcpy (&v, mbuf->data + mbuf->pos, 2);
127 if (g_memory_buffer_is_byteswapped (mbuf))
128 v = GUINT16_SWAP_LE_BE (v);
134 g_memory_buffer_read_int32 (GMemoryBuffer *mbuf)
138 if (mbuf->pos > mbuf->valid_len - 4)
140 mbuf->pos = mbuf->valid_len;
144 memcpy (&v, mbuf->data + mbuf->pos, 4);
147 if (g_memory_buffer_is_byteswapped (mbuf))
148 v = GUINT32_SWAP_LE_BE (v);
154 g_memory_buffer_read_uint32 (GMemoryBuffer *mbuf)
158 if (mbuf->pos > mbuf->valid_len - 4)
160 mbuf->pos = mbuf->valid_len;
164 memcpy (&v, mbuf->data + mbuf->pos, 4);
167 if (g_memory_buffer_is_byteswapped (mbuf))
168 v = GUINT32_SWAP_LE_BE (v);
174 g_memory_buffer_read_int64 (GMemoryBuffer *mbuf)
178 if (mbuf->pos > mbuf->valid_len - 8)
180 mbuf->pos = mbuf->valid_len;
184 memcpy (&v, mbuf->data + mbuf->pos, 8);
187 if (g_memory_buffer_is_byteswapped (mbuf))
188 v = GUINT64_SWAP_LE_BE (v);
194 g_memory_buffer_read_uint64 (GMemoryBuffer *mbuf)
198 if (mbuf->pos > mbuf->valid_len - 8)
200 mbuf->pos = mbuf->valid_len;
204 memcpy (&v, mbuf->data + mbuf->pos, 8);
207 if (g_memory_buffer_is_byteswapped (mbuf))
208 v = GUINT64_SWAP_LE_BE (v);
213 #define MIN_ARRAY_SIZE 128
216 g_nearest_pow (gsize num)
220 while (n < num && n > 0)
227 array_resize (GMemoryBuffer *mbuf,
233 if (mbuf->len == size)
237 data = g_realloc (mbuf->data, size);
240 memset ((guint8 *)data + len, 0, size - len);
245 if (mbuf->len < mbuf->valid_len)
246 mbuf->valid_len = mbuf->len;
250 g_memory_buffer_write (GMemoryBuffer *mbuf,
260 /* Check for address space overflow, but only if the buffer is resizable.
261 Otherwise we just do a short write and don't worry. */
262 if (mbuf->pos + count < mbuf->pos)
265 if (mbuf->pos + count > mbuf->len)
267 /* At least enough to fit the write, rounded up
268 for greater than linear growth.
269 TODO: This wastes a lot of memory at large buffer sizes.
270 Figure out a more rational allocation strategy. */
271 new_size = g_nearest_pow (mbuf->pos + count);
272 /* Check for overflow again. We have checked if
273 pos + count > G_MAXSIZE, but now check if g_nearest_pow () has
278 new_size = MAX (new_size, MIN_ARRAY_SIZE);
279 array_resize (mbuf, new_size);
282 dest = (guint8 *)mbuf->data + mbuf->pos;
283 memcpy (dest, buffer, count);
286 if (mbuf->pos > mbuf->valid_len)
287 mbuf->valid_len = mbuf->pos;
293 g_memory_buffer_put_byte (GMemoryBuffer *mbuf,
296 return g_memory_buffer_write (mbuf, &data, 1);
300 g_memory_buffer_put_int16 (GMemoryBuffer *mbuf,
303 switch (mbuf->byte_order)
305 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
306 data = GINT16_TO_BE (data);
308 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
309 data = GINT16_TO_LE (data);
311 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
316 return g_memory_buffer_write (mbuf, &data, 2);
320 g_memory_buffer_put_uint16 (GMemoryBuffer *mbuf,
323 switch (mbuf->byte_order)
325 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
326 data = GUINT16_TO_BE (data);
328 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
329 data = GUINT16_TO_LE (data);
331 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
336 return g_memory_buffer_write (mbuf, &data, 2);
340 g_memory_buffer_put_int32 (GMemoryBuffer *mbuf,
343 switch (mbuf->byte_order)
345 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
346 data = GINT32_TO_BE (data);
348 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
349 data = GINT32_TO_LE (data);
351 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
356 return g_memory_buffer_write (mbuf, &data, 4);
360 g_memory_buffer_put_uint32 (GMemoryBuffer *mbuf,
363 switch (mbuf->byte_order)
365 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
366 data = GUINT32_TO_BE (data);
368 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
369 data = GUINT32_TO_LE (data);
371 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
376 return g_memory_buffer_write (mbuf, &data, 4);
380 g_memory_buffer_put_int64 (GMemoryBuffer *mbuf,
383 switch (mbuf->byte_order)
385 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
386 data = GINT64_TO_BE (data);
388 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
389 data = GINT64_TO_LE (data);
391 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
396 return g_memory_buffer_write (mbuf, &data, 8);
400 g_memory_buffer_put_uint64 (GMemoryBuffer *mbuf,
403 switch (mbuf->byte_order)
405 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
406 data = GUINT64_TO_BE (data);
408 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
409 data = GUINT64_TO_LE (data);
411 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
416 return g_memory_buffer_write (mbuf, &data, 8);
420 g_memory_buffer_put_string (GMemoryBuffer *mbuf,
423 g_return_val_if_fail (str != NULL, FALSE);
425 return g_memory_buffer_write (mbuf, str, strlen (str));
430 * SECTION:gdbusmessage
431 * @short_description: D-Bus Message
432 * @include: gio/gio.h
434 * A type for representing D-Bus messages that can be sent or received
435 * on a #GDBusConnection.
438 typedef struct _GDBusMessageClass GDBusMessageClass;
443 * Class structure for #GDBusMessage.
447 struct _GDBusMessageClass
450 GObjectClass parent_class;
456 * The #GDBusMessage structure contains only private data and should
457 * only be accessed using the provided API.
464 GObject parent_instance;
466 GDBusMessageType type;
467 GDBusMessageFlags flags;
469 GDBusMessageByteOrder byte_order;
470 guchar major_protocol_version;
475 GUnixFDList *fd_list;
485 G_DEFINE_TYPE (GDBusMessage, g_dbus_message, G_TYPE_OBJECT)
488 g_dbus_message_finalize (GObject *object)
490 GDBusMessage *message = G_DBUS_MESSAGE (object);
492 if (message->headers != NULL)
493 g_hash_table_unref (message->headers);
494 if (message->body != NULL)
495 g_variant_unref (message->body);
497 if (message->fd_list != NULL)
498 g_object_unref (message->fd_list);
501 if (G_OBJECT_CLASS (g_dbus_message_parent_class)->finalize != NULL)
502 G_OBJECT_CLASS (g_dbus_message_parent_class)->finalize (object);
506 g_dbus_message_get_property (GObject *object,
511 GDBusMessage *message = G_DBUS_MESSAGE (object);
516 g_value_set_boolean (value, g_dbus_message_get_locked (message));
520 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
526 g_dbus_message_class_init (GDBusMessageClass *klass)
528 GObjectClass *gobject_class;
530 gobject_class = G_OBJECT_CLASS (klass);
531 gobject_class->finalize = g_dbus_message_finalize;
532 gobject_class->get_property = g_dbus_message_get_property;
535 * GDBusConnection:locked:
537 * A boolean specifying whether the message is locked.
541 g_object_class_install_property (gobject_class,
543 g_param_spec_boolean ("locked",
545 P_("Whether the message is locked"),
548 G_PARAM_STATIC_NAME |
549 G_PARAM_STATIC_BLURB |
550 G_PARAM_STATIC_NICK));
554 g_dbus_message_init (GDBusMessage *message)
556 /* Any D-Bus implementation is supposed to handle both Big and
557 * Little Endian encodings and the Endianness is part of the D-Bus
558 * message - we prefer to use Big Endian (since it's Network Byte
559 * Order and just easier to read for humans) but if the machine is
560 * Little Endian we use that for performance reasons.
562 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
563 message->byte_order = G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN;
565 /* this could also be G_PDP_ENDIAN */
566 message->byte_order = G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN;
568 message->headers = g_hash_table_new_full (g_direct_hash,
571 (GDestroyNotify) g_variant_unref);
575 * g_dbus_message_new:
577 * Creates a new empty #GDBusMessage.
579 * Returns: A #GDBusMessage. Free with g_object_unref().
584 g_dbus_message_new (void)
586 return g_object_new (G_TYPE_DBUS_MESSAGE, NULL);
590 * g_dbus_message_new_method_call:
591 * @name: (nullable): A valid D-Bus name or %NULL.
592 * @path: A valid object path.
593 * @interface_: (nullable): A valid D-Bus interface name or %NULL.
594 * @method: A valid method name.
596 * Creates a new #GDBusMessage for a method call.
598 * Returns: A #GDBusMessage. Free with g_object_unref().
603 g_dbus_message_new_method_call (const gchar *name,
605 const gchar *interface_,
608 GDBusMessage *message;
610 g_return_val_if_fail (name == NULL || g_dbus_is_name (name), NULL);
611 g_return_val_if_fail (g_variant_is_object_path (path), NULL);
612 g_return_val_if_fail (g_dbus_is_member_name (method), NULL);
613 g_return_val_if_fail (interface_ == NULL || g_dbus_is_interface_name (interface_), NULL);
615 message = g_dbus_message_new ();
616 message->type = G_DBUS_MESSAGE_TYPE_METHOD_CALL;
619 g_dbus_message_set_destination (message, name);
620 g_dbus_message_set_path (message, path);
621 g_dbus_message_set_member (message, method);
622 if (interface_ != NULL)
623 g_dbus_message_set_interface (message, interface_);
629 * g_dbus_message_new_signal:
630 * @path: A valid object path.
631 * @interface_: A valid D-Bus interface name.
632 * @signal: A valid signal name.
634 * Creates a new #GDBusMessage for a signal emission.
636 * Returns: A #GDBusMessage. Free with g_object_unref().
641 g_dbus_message_new_signal (const gchar *path,
642 const gchar *interface_,
645 GDBusMessage *message;
647 g_return_val_if_fail (g_variant_is_object_path (path), NULL);
648 g_return_val_if_fail (g_dbus_is_member_name (signal), NULL);
649 g_return_val_if_fail (g_dbus_is_interface_name (interface_), NULL);
651 message = g_dbus_message_new ();
652 message->type = G_DBUS_MESSAGE_TYPE_SIGNAL;
653 message->flags = G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED;
655 g_dbus_message_set_path (message, path);
656 g_dbus_message_set_member (message, signal);
657 g_dbus_message_set_interface (message, interface_);
664 * g_dbus_message_new_method_reply:
665 * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to
666 * create a reply message to.
668 * Creates a new #GDBusMessage that is a reply to @method_call_message.
670 * Returns: (transfer full): #GDBusMessage. Free with g_object_unref().
675 g_dbus_message_new_method_reply (GDBusMessage *method_call_message)
677 GDBusMessage *message;
680 g_return_val_if_fail (G_IS_DBUS_MESSAGE (method_call_message), NULL);
681 g_return_val_if_fail (g_dbus_message_get_message_type (method_call_message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL, NULL);
682 g_return_val_if_fail (g_dbus_message_get_serial (method_call_message) != 0, NULL);
684 message = g_dbus_message_new ();
685 message->type = G_DBUS_MESSAGE_TYPE_METHOD_RETURN;
686 message->flags = G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED;
687 /* reply with same endianness */
688 message->byte_order = method_call_message->byte_order;
690 g_dbus_message_set_reply_serial (message, g_dbus_message_get_serial (method_call_message));
691 sender = g_dbus_message_get_sender (method_call_message);
693 g_dbus_message_set_destination (message, sender);
699 * g_dbus_message_new_method_error:
700 * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to
701 * create a reply message to.
702 * @error_name: A valid D-Bus error name.
703 * @error_message_format: The D-Bus error message in a printf() format.
704 * @...: Arguments for @error_message_format.
706 * Creates a new #GDBusMessage that is an error reply to @method_call_message.
708 * Returns: (transfer full): A #GDBusMessage. Free with g_object_unref().
713 g_dbus_message_new_method_error (GDBusMessage *method_call_message,
714 const gchar *error_name,
715 const gchar *error_message_format,
721 va_start (var_args, error_message_format);
722 ret = g_dbus_message_new_method_error_valist (method_call_message,
724 error_message_format,
732 * g_dbus_message_new_method_error_literal:
733 * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to
734 * create a reply message to.
735 * @error_name: A valid D-Bus error name.
736 * @error_message: The D-Bus error message.
738 * Creates a new #GDBusMessage that is an error reply to @method_call_message.
740 * Returns: (transfer full): A #GDBusMessage. Free with g_object_unref().
745 g_dbus_message_new_method_error_literal (GDBusMessage *method_call_message,
746 const gchar *error_name,
747 const gchar *error_message)
749 GDBusMessage *message;
752 g_return_val_if_fail (G_IS_DBUS_MESSAGE (method_call_message), NULL);
753 g_return_val_if_fail (g_dbus_message_get_message_type (method_call_message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL, NULL);
754 g_return_val_if_fail (g_dbus_message_get_serial (method_call_message) != 0, NULL);
755 g_return_val_if_fail (g_dbus_is_name (error_name), NULL);
756 g_return_val_if_fail (error_message != NULL, NULL);
758 message = g_dbus_message_new ();
759 message->type = G_DBUS_MESSAGE_TYPE_ERROR;
760 message->flags = G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED;
761 /* reply with same endianness */
762 message->byte_order = method_call_message->byte_order;
764 g_dbus_message_set_reply_serial (message, g_dbus_message_get_serial (method_call_message));
765 g_dbus_message_set_error_name (message, error_name);
766 g_dbus_message_set_body (message, g_variant_new ("(s)", error_message));
768 sender = g_dbus_message_get_sender (method_call_message);
770 g_dbus_message_set_destination (message, sender);
776 * g_dbus_message_new_method_error_valist:
777 * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to
778 * create a reply message to.
779 * @error_name: A valid D-Bus error name.
780 * @error_message_format: The D-Bus error message in a printf() format.
781 * @var_args: Arguments for @error_message_format.
783 * Like g_dbus_message_new_method_error() but intended for language bindings.
785 * Returns: (transfer full): A #GDBusMessage. Free with g_object_unref().
791 g_dbus_message_new_method_error_valist (GDBusMessage *method_call_message,
792 const gchar *error_name,
793 const gchar *error_message_format,
797 gchar *error_message;
798 error_message = g_strdup_vprintf (error_message_format, var_args);
799 ret = g_dbus_message_new_method_error_literal (method_call_message,
802 g_free (error_message);
806 /* ---------------------------------------------------------------------------------------------------- */
809 * g_dbus_message_get_byte_order:
810 * @message: A #GDBusMessage.
812 * Gets the byte order of @message.
814 * Returns: The byte order.
816 GDBusMessageByteOrder
817 g_dbus_message_get_byte_order (GDBusMessage *message)
819 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), (GDBusMessageByteOrder) 0);
820 return message->byte_order;
824 * g_dbus_message_set_byte_order:
825 * @message: A #GDBusMessage.
826 * @byte_order: The byte order.
828 * Sets the byte order of @message.
831 g_dbus_message_set_byte_order (GDBusMessage *message,
832 GDBusMessageByteOrder byte_order)
834 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
838 g_warning ("%s: Attempted to modify a locked message", G_STRFUNC);
842 message->byte_order = byte_order;
845 /* ---------------------------------------------------------------------------------------------------- */
847 /* TODO: need GI annotations to specify that any guchar value goes for the type */
850 * g_dbus_message_get_message_type:
851 * @message: A #GDBusMessage.
853 * Gets the type of @message.
855 * Returns: A 8-bit unsigned integer (typically a value from the #GDBusMessageType enumeration).
860 g_dbus_message_get_message_type (GDBusMessage *message)
862 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), G_DBUS_MESSAGE_TYPE_INVALID);
863 return message->type;
867 * g_dbus_message_set_message_type:
868 * @message: A #GDBusMessage.
869 * @type: A 8-bit unsigned integer (typically a value from the #GDBusMessageType enumeration).
871 * Sets @message to be of @type.
876 g_dbus_message_set_message_type (GDBusMessage *message,
877 GDBusMessageType type)
879 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
880 g_return_if_fail ((guint) type < 256);
884 g_warning ("%s: Attempted to modify a locked message", G_STRFUNC);
888 message->type = type;
891 /* ---------------------------------------------------------------------------------------------------- */
893 /* TODO: need GI annotations to specify that any guchar value goes for flags */
896 * g_dbus_message_get_flags:
897 * @message: A #GDBusMessage.
899 * Gets the flags for @message.
901 * Returns: Flags that are set (typically values from the #GDBusMessageFlags enumeration bitwise ORed together).
906 g_dbus_message_get_flags (GDBusMessage *message)
908 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), G_DBUS_MESSAGE_FLAGS_NONE);
909 return message->flags;
913 * g_dbus_message_set_flags:
914 * @message: A #GDBusMessage.
915 * @flags: Flags for @message that are set (typically values from the #GDBusMessageFlags
916 * enumeration bitwise ORed together).
918 * Sets the flags to set on @message.
923 g_dbus_message_set_flags (GDBusMessage *message,
924 GDBusMessageFlags flags)
926 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
927 g_return_if_fail ((guint) flags < 256);
931 g_warning ("%s: Attempted to modify a locked message", G_STRFUNC);
935 message->flags = flags;
938 /* ---------------------------------------------------------------------------------------------------- */
941 * g_dbus_message_get_serial:
942 * @message: A #GDBusMessage.
944 * Gets the serial for @message.
946 * Returns: A #guint32.
951 g_dbus_message_get_serial (GDBusMessage *message)
953 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), 0);
954 return message->serial;
958 * g_dbus_message_set_serial:
959 * @message: A #GDBusMessage.
960 * @serial: A #guint32.
962 * Sets the serial for @message.
967 g_dbus_message_set_serial (GDBusMessage *message,
970 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
974 g_warning ("%s: Attempted to modify a locked message", G_STRFUNC);
978 message->serial = serial;
981 /* ---------------------------------------------------------------------------------------------------- */
983 /* TODO: need GI annotations to specify that any guchar value goes for header_field */
986 * g_dbus_message_get_header:
987 * @message: A #GDBusMessage.
988 * @header_field: A 8-bit unsigned integer (typically a value from the #GDBusMessageHeaderField enumeration)
990 * Gets a header field on @message.
992 * The caller is responsible for checking the type of the returned #GVariant
993 * matches what is expected.
995 * Returns: (transfer none) (nullable): A #GVariant with the value if the header was found, %NULL
996 * otherwise. Do not free, it is owned by @message.
1001 g_dbus_message_get_header (GDBusMessage *message,
1002 GDBusMessageHeaderField header_field)
1004 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
1005 g_return_val_if_fail ((guint) header_field < 256, NULL);
1006 return g_hash_table_lookup (message->headers, GUINT_TO_POINTER (header_field));
1010 * g_dbus_message_set_header:
1011 * @message: A #GDBusMessage.
1012 * @header_field: A 8-bit unsigned integer (typically a value from the #GDBusMessageHeaderField enumeration)
1013 * @value: (nullable): A #GVariant to set the header field or %NULL to clear the header field.
1015 * Sets a header field on @message.
1017 * If @value is floating, @message assumes ownership of @value.
1022 g_dbus_message_set_header (GDBusMessage *message,
1023 GDBusMessageHeaderField header_field,
1026 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
1027 g_return_if_fail ((guint) header_field < 256);
1029 if (message->locked)
1031 g_warning ("%s: Attempted to modify a locked message", G_STRFUNC);
1037 g_hash_table_remove (message->headers, GUINT_TO_POINTER (header_field));
1041 g_hash_table_insert (message->headers, GUINT_TO_POINTER (header_field), g_variant_ref_sink (value));
1046 * g_dbus_message_get_header_fields:
1047 * @message: A #GDBusMessage.
1049 * Gets an array of all header fields on @message that are set.
1051 * Returns: (array zero-terminated=1): An array of header fields
1052 * terminated by %G_DBUS_MESSAGE_HEADER_FIELD_INVALID. Each element
1053 * is a #guchar. Free with g_free().
1058 g_dbus_message_get_header_fields (GDBusMessage *message)
1066 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
1068 keys = g_hash_table_get_keys (message->headers);
1069 num_keys = g_list_length (keys);
1070 ret = g_new (guchar, num_keys + 1);
1071 for (l = keys, n = 0; l != NULL; l = l->next, n++)
1072 ret[n] = GPOINTER_TO_UINT (l->data);
1073 g_assert (n == num_keys);
1074 ret[n] = G_DBUS_MESSAGE_HEADER_FIELD_INVALID;
1080 /* ---------------------------------------------------------------------------------------------------- */
1083 * g_dbus_message_get_body:
1084 * @message: A #GDBusMessage.
1086 * Gets the body of a message.
1088 * Returns: (nullable) (transfer none): A #GVariant or %NULL if the body is
1089 * empty. Do not free, it is owned by @message.
1094 g_dbus_message_get_body (GDBusMessage *message)
1096 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
1097 return message->body;
1101 * g_dbus_message_set_body:
1102 * @message: A #GDBusMessage.
1103 * @body: Either %NULL or a #GVariant that is a tuple.
1105 * Sets the body @message. As a side-effect the
1106 * %G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE header field is set to the
1107 * type string of @body (or cleared if @body is %NULL).
1109 * If @body is floating, @message assumes ownership of @body.
1114 g_dbus_message_set_body (GDBusMessage *message,
1117 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
1118 g_return_if_fail ((body == NULL) || g_variant_is_of_type (body, G_VARIANT_TYPE_TUPLE));
1120 if (message->locked)
1122 g_warning ("%s: Attempted to modify a locked message", G_STRFUNC);
1126 if (message->body != NULL)
1127 g_variant_unref (message->body);
1130 message->body = NULL;
1131 g_dbus_message_set_signature (message, NULL);
1135 const gchar *type_string;
1136 gsize type_string_len;
1139 message->body = g_variant_ref_sink (body);
1141 type_string = g_variant_get_type_string (body);
1142 type_string_len = strlen (type_string);
1143 g_assert (type_string_len >= 2);
1144 signature = g_strndup (type_string + 1, type_string_len - 2);
1145 g_dbus_message_set_signature (message, signature);
1150 /* ---------------------------------------------------------------------------------------------------- */
1154 * g_dbus_message_get_unix_fd_list:
1155 * @message: A #GDBusMessage.
1157 * Gets the UNIX file descriptors associated with @message, if any.
1159 * This method is only available on UNIX.
1161 * The file descriptors normally correspond to %G_VARIANT_TYPE_HANDLE
1162 * values in the body of the message. For example,
1163 * if g_variant_get_handle() returns 5, that is intended to be a reference
1164 * to the file descriptor that can be accessed by
1165 * `g_unix_fd_list_get (list, 5, ...)`.
1167 * Returns: (nullable) (transfer none): A #GUnixFDList or %NULL if no file descriptors are
1168 * associated. Do not free, this object is owned by @message.
1173 g_dbus_message_get_unix_fd_list (GDBusMessage *message)
1175 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
1176 return message->fd_list;
1180 * g_dbus_message_set_unix_fd_list:
1181 * @message: A #GDBusMessage.
1182 * @fd_list: (nullable): A #GUnixFDList or %NULL.
1184 * Sets the UNIX file descriptors associated with @message. As a
1185 * side-effect the %G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS header
1186 * field is set to the number of fds in @fd_list (or cleared if
1187 * @fd_list is %NULL).
1189 * This method is only available on UNIX.
1191 * When designing D-Bus APIs that are intended to be interoperable,
1192 * please note that non-GDBus implementations of D-Bus can usually only
1193 * access file descriptors if they are referenced by a value of type
1194 * %G_VARIANT_TYPE_HANDLE in the body of the message.
1199 g_dbus_message_set_unix_fd_list (GDBusMessage *message,
1200 GUnixFDList *fd_list)
1202 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
1203 g_return_if_fail (fd_list == NULL || G_IS_UNIX_FD_LIST (fd_list));
1205 if (message->locked)
1207 g_warning ("%s: Attempted to modify a locked message", G_STRFUNC);
1211 if (message->fd_list != NULL)
1212 g_object_unref (message->fd_list);
1213 if (fd_list != NULL)
1215 message->fd_list = g_object_ref (fd_list);
1216 g_dbus_message_set_num_unix_fds (message, g_unix_fd_list_get_length (fd_list));
1220 message->fd_list = NULL;
1221 g_dbus_message_set_num_unix_fds (message, 0);
1226 /* ---------------------------------------------------------------------------------------------------- */
1229 get_type_fixed_size (const GVariantType *type)
1231 /* NB: we do not treat 'b' as fixed-size here because GVariant and
1232 * D-Bus disagree about the size.
1234 switch (*g_variant_type_peek_string (type))
1240 case 'i': case 'u': case 'h':
1242 case 'x': case 't': case 'd':
1250 validate_headers (GDBusMessage *message,
1255 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), FALSE);
1256 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1260 switch (message->type)
1262 case G_DBUS_MESSAGE_TYPE_INVALID:
1263 g_set_error_literal (error,
1265 G_IO_ERROR_INVALID_ARGUMENT,
1266 _("type is INVALID"));
1270 case G_DBUS_MESSAGE_TYPE_METHOD_CALL:
1271 if (g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH) == NULL ||
1272 g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER) == NULL)
1274 g_set_error_literal (error,
1276 G_IO_ERROR_INVALID_ARGUMENT,
1277 _("METHOD_CALL message: PATH or MEMBER header field is missing"));
1282 case G_DBUS_MESSAGE_TYPE_METHOD_RETURN:
1283 if (g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL) == NULL)
1285 g_set_error_literal (error,
1287 G_IO_ERROR_INVALID_ARGUMENT,
1288 _("METHOD_RETURN message: REPLY_SERIAL header field is missing"));
1293 case G_DBUS_MESSAGE_TYPE_ERROR:
1294 if (g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME) == NULL ||
1295 g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL) == NULL)
1297 g_set_error_literal (error,
1299 G_IO_ERROR_INVALID_ARGUMENT,
1300 _("ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing"));
1305 case G_DBUS_MESSAGE_TYPE_SIGNAL:
1306 if (g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH) == NULL ||
1307 g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE) == NULL ||
1308 g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER) == NULL)
1310 g_set_error_literal (error,
1312 G_IO_ERROR_INVALID_ARGUMENT,
1313 _("SIGNAL message: PATH, INTERFACE or MEMBER header field is missing"));
1316 if (g_strcmp0 (g_dbus_message_get_path (message), "/org/freedesktop/DBus/Local") == 0)
1318 g_set_error_literal (error,
1320 G_IO_ERROR_INVALID_ARGUMENT,
1321 _("SIGNAL message: The PATH header field is using the reserved value /org/freedesktop/DBus/Local"));
1324 if (g_strcmp0 (g_dbus_message_get_interface (message), "org.freedesktop.DBus.Local") == 0)
1326 g_set_error_literal (error,
1328 G_IO_ERROR_INVALID_ARGUMENT,
1329 _("SIGNAL message: The INTERFACE header field is using the reserved value org.freedesktop.DBus.Local"));
1335 /* hitherto unknown type - nothing to check */
1342 g_assert (ret || (error == NULL || *error != NULL));
1346 /* ---------------------------------------------------------------------------------------------------- */
1349 ensure_input_padding (GMemoryBuffer *buf,
1353 gsize wanted_offset;
1356 wanted_offset = ((offset + padding_size - 1) / padding_size) * padding_size;
1357 buf->pos = wanted_offset;
1361 static const gchar *
1362 read_string (GMemoryBuffer *mbuf,
1367 const gchar *end_valid;
1369 if G_UNLIKELY (mbuf->pos + len >= mbuf->valid_len || mbuf->pos + len < mbuf->pos)
1371 mbuf->pos = mbuf->valid_len;
1372 /* G_GSIZE_FORMAT doesn't work with gettext, so we use %lu */
1375 G_IO_ERROR_INVALID_ARGUMENT,
1376 g_dngettext (GETTEXT_PACKAGE,
1377 "Wanted to read %lu byte but only got %lu",
1378 "Wanted to read %lu bytes but only got %lu",
1381 (gulong)(mbuf->valid_len - mbuf->pos));
1385 if G_UNLIKELY (mbuf->data[mbuf->pos + len] != '\0')
1387 str = g_strndup (mbuf->data + mbuf->pos, len);
1390 G_IO_ERROR_INVALID_ARGUMENT,
1391 _("Expected NUL byte after the string “%s” but found byte %d"),
1392 str, mbuf->data[mbuf->pos + len]);
1394 mbuf->pos += len + 1;
1398 str = mbuf->data + mbuf->pos;
1399 mbuf->pos += len + 1;
1401 if G_UNLIKELY (!g_utf8_validate (str, -1, &end_valid))
1405 offset = (gint) (end_valid - str);
1406 valid_str = g_strndup (str, offset);
1409 G_IO_ERROR_INVALID_ARGUMENT,
1410 _("Expected valid UTF-8 string but found invalid bytes at byte offset %d (length of string is %d). "
1411 "The valid UTF-8 string up until that point was “%s”"),
1422 static gconstpointer
1423 read_bytes (GMemoryBuffer *mbuf,
1427 gconstpointer result;
1429 if G_UNLIKELY (mbuf->pos + len > mbuf->valid_len || mbuf->pos + len < mbuf->pos)
1431 mbuf->pos = mbuf->valid_len;
1432 /* G_GSIZE_FORMAT doesn't work with gettext, so we use %lu */
1435 G_IO_ERROR_INVALID_ARGUMENT,
1436 g_dngettext (GETTEXT_PACKAGE,
1437 "Wanted to read %lu byte but only got %lu",
1438 "Wanted to read %lu bytes but only got %lu",
1441 (gulong)(mbuf->valid_len - mbuf->pos));
1445 result = mbuf->data + mbuf->pos;
1451 /* if just_align==TRUE, don't read a value, just align the input stream wrt padding */
1453 /* returns a non-floating GVariant! */
1455 parse_value_from_blob (GMemoryBuffer *buf,
1456 const GVariantType *type,
1458 gboolean just_align,
1462 GVariant *ret = NULL;
1463 GError *local_error = NULL;
1464 #ifdef DEBUG_SERIALIZER
1466 #endif /* DEBUG_SERIALIZER */
1467 const gchar *type_string;
1471 g_set_error_literal (&local_error,
1473 G_IO_ERROR_INVALID_ARGUMENT,
1474 _("Value nested too deeply"));
1478 type_string = g_variant_type_peek_string (type);
1480 #ifdef DEBUG_SERIALIZER
1483 s = g_variant_type_dup_string (type);
1484 g_print ("%*s%s type %s from offset 0x%04x",
1486 just_align ? "Aligning" : "Reading",
1491 #endif /* DEBUG_SERIALIZER */
1493 #ifdef DEBUG_SERIALIZER
1495 #endif /* DEBUG_SERIALIZER */
1496 switch (type_string[0])
1498 case 'b': /* G_VARIANT_TYPE_BOOLEAN */
1499 ensure_input_padding (buf, 4);
1503 v = g_memory_buffer_read_uint32 (buf);
1504 ret = g_variant_new_boolean (v);
1508 case 'y': /* G_VARIANT_TYPE_BYTE */
1512 v = g_memory_buffer_read_byte (buf);
1513 ret = g_variant_new_byte (v);
1517 case 'n': /* G_VARIANT_TYPE_INT16 */
1518 ensure_input_padding (buf, 2);
1522 v = g_memory_buffer_read_int16 (buf);
1523 ret = g_variant_new_int16 (v);
1527 case 'q': /* G_VARIANT_TYPE_UINT16 */
1528 ensure_input_padding (buf, 2);
1532 v = g_memory_buffer_read_uint16 (buf);
1533 ret = g_variant_new_uint16 (v);
1537 case 'i': /* G_VARIANT_TYPE_INT32 */
1538 ensure_input_padding (buf, 4);
1542 v = g_memory_buffer_read_int32 (buf);
1543 ret = g_variant_new_int32 (v);
1547 case 'u': /* G_VARIANT_TYPE_UINT32 */
1548 ensure_input_padding (buf, 4);
1552 v = g_memory_buffer_read_uint32 (buf);
1553 ret = g_variant_new_uint32 (v);
1557 case 'x': /* G_VARIANT_TYPE_INT64 */
1558 ensure_input_padding (buf, 8);
1562 v = g_memory_buffer_read_int64 (buf);
1563 ret = g_variant_new_int64 (v);
1567 case 't': /* G_VARIANT_TYPE_UINT64 */
1568 ensure_input_padding (buf, 8);
1572 v = g_memory_buffer_read_uint64 (buf);
1573 ret = g_variant_new_uint64 (v);
1577 case 'd': /* G_VARIANT_TYPE_DOUBLE */
1578 ensure_input_padding (buf, 8);
1585 G_STATIC_ASSERT (sizeof (gdouble) == sizeof (guint64));
1586 u.v_uint64 = g_memory_buffer_read_uint64 (buf);
1587 ret = g_variant_new_double (u.v_double);
1591 case 's': /* G_VARIANT_TYPE_STRING */
1592 ensure_input_padding (buf, 4);
1597 len = g_memory_buffer_read_uint32 (buf);
1598 v = read_string (buf, (gsize) len, &local_error);
1601 ret = g_variant_new_string (v);
1605 case 'o': /* G_VARIANT_TYPE_OBJECT_PATH */
1606 ensure_input_padding (buf, 4);
1611 len = g_memory_buffer_read_uint32 (buf);
1612 v = read_string (buf, (gsize) len, &local_error);
1615 if (!g_variant_is_object_path (v))
1617 g_set_error (&local_error,
1619 G_IO_ERROR_INVALID_ARGUMENT,
1620 _("Parsed value “%s” is not a valid D-Bus object path"),
1624 ret = g_variant_new_object_path (v);
1628 case 'g': /* G_VARIANT_TYPE_SIGNATURE */
1633 len = g_memory_buffer_read_byte (buf);
1634 v = read_string (buf, (gsize) len, &local_error);
1637 if (!g_variant_is_signature (v))
1639 g_set_error (&local_error,
1641 G_IO_ERROR_INVALID_ARGUMENT,
1642 _("Parsed value “%s” is not a valid D-Bus signature"),
1646 ret = g_variant_new_signature (v);
1650 case 'h': /* G_VARIANT_TYPE_HANDLE */
1651 ensure_input_padding (buf, 4);
1655 v = g_memory_buffer_read_int32 (buf);
1656 ret = g_variant_new_handle (v);
1660 case 'a': /* G_VARIANT_TYPE_ARRAY */
1661 ensure_input_padding (buf, 4);
1663 /* If we are only aligning for this array type, it is the child type of
1664 * another array, which is empty. So, we do not need to add padding for
1665 * this nonexistent array's elements: we only need to align for this
1666 * array itself (4 bytes). See
1667 * <https://bugzilla.gnome.org/show_bug.cgi?id=673612>.
1672 const GVariantType *element_type;
1675 array_len = g_memory_buffer_read_uint32 (buf);
1677 #ifdef DEBUG_SERIALIZER
1679 g_print (": array spans 0x%04x bytes\n", array_len);
1680 #endif /* DEBUG_SERIALIZER */
1682 if (array_len > (2<<26))
1684 /* G_GUINT32_FORMAT doesn't work with gettext, so use u */
1685 g_set_error (&local_error,
1687 G_IO_ERROR_INVALID_ARGUMENT,
1688 g_dngettext (GETTEXT_PACKAGE,
1689 "Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB).",
1690 "Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB).",
1696 element_type = g_variant_type_element (type);
1697 fixed_size = get_type_fixed_size (element_type);
1699 /* Fast-path the cases like 'ay', etc. */
1700 if (fixed_size != 0)
1702 gconstpointer array_data;
1704 if (array_len % fixed_size != 0)
1706 g_set_error (&local_error,
1708 G_IO_ERROR_INVALID_ARGUMENT,
1709 _("Encountered array of type “a%c”, expected to have a length a multiple "
1710 "of %u bytes, but found to be %u bytes in length"),
1711 g_variant_type_peek_string (element_type)[0], fixed_size, array_len);
1717 /* If we had recursed into parse_value_from_blob() again to
1718 * parse the array values, this would have been emitted. */
1719 g_set_error_literal (&local_error,
1721 G_IO_ERROR_INVALID_ARGUMENT,
1722 _("Value nested too deeply"));
1726 ensure_input_padding (buf, fixed_size);
1727 array_data = read_bytes (buf, array_len, &local_error);
1728 if (array_data == NULL)
1731 ret = g_variant_new_fixed_array (element_type, array_data, array_len / fixed_size, fixed_size);
1733 if (g_memory_buffer_is_byteswapped (buf))
1735 GVariant *tmp = g_variant_ref_sink (ret);
1736 ret = g_variant_byteswap (tmp);
1737 g_variant_unref (tmp);
1742 GVariantBuilder builder;
1746 g_variant_builder_init (&builder, type);
1750 GVariant *item G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */;
1751 item = parse_value_from_blob (buf,
1757 g_assert (item == NULL);
1762 target = offset + array_len;
1763 while (offset < target)
1766 item = parse_value_from_blob (buf,
1774 g_variant_builder_clear (&builder);
1777 g_variant_builder_add_value (&builder, item);
1778 g_variant_unref (item);
1783 ret = g_variant_builder_end (&builder);
1789 if (g_variant_type_is_dict_entry (type))
1791 const GVariantType *key_type;
1792 const GVariantType *value_type;
1796 ensure_input_padding (buf, 8);
1798 #ifdef DEBUG_SERIALIZER
1801 #endif /* DEBUG_SERIALIZER */
1805 key_type = g_variant_type_key (type);
1806 key = parse_value_from_blob (buf,
1814 value_type = g_variant_type_value (type);
1815 value = parse_value_from_blob (buf,
1823 g_variant_unref (key);
1826 ret = g_variant_new_dict_entry (key, value);
1827 g_variant_unref (key);
1828 g_variant_unref (value);
1831 else if (g_variant_type_is_tuple (type))
1833 ensure_input_padding (buf, 8);
1835 #ifdef DEBUG_SERIALIZER
1838 #endif /* DEBUG_SERIALIZER */
1842 const GVariantType *element_type;
1843 GVariantBuilder builder;
1845 g_variant_builder_init (&builder, type);
1846 element_type = g_variant_type_first (type);
1847 while (element_type != NULL)
1850 item = parse_value_from_blob (buf,
1858 g_variant_builder_clear (&builder);
1861 g_variant_builder_add_value (&builder, item);
1862 g_variant_unref (item);
1864 element_type = g_variant_type_next (element_type);
1866 ret = g_variant_builder_end (&builder);
1869 else if (g_variant_type_is_variant (type))
1871 #ifdef DEBUG_SERIALIZER
1874 #endif /* DEBUG_SERIALIZER */
1880 GVariantType *variant_type;
1883 siglen = g_memory_buffer_read_byte (buf);
1884 sig = read_string (buf, (gsize) siglen, &local_error);
1887 if (!g_variant_is_signature (sig) ||
1888 !g_variant_type_string_is_valid (sig))
1890 /* A D-Bus signature can contain zero or more complete types,
1891 * but a GVariant has to be exactly one complete type. */
1892 g_set_error (&local_error,
1894 G_IO_ERROR_INVALID_ARGUMENT,
1895 _("Parsed value “%s” for variant is not a valid D-Bus signature"),
1900 if (max_depth <= g_variant_type_string_get_depth_ (sig))
1902 /* Catch the type nesting being too deep without having to
1903 * parse the data. We don’t have to check this for static
1904 * container types (like arrays and tuples, above) because
1905 * the g_variant_type_string_is_valid() check performed before
1906 * the initial parse_value_from_blob() call should check the
1907 * static type nesting. */
1908 g_set_error_literal (&local_error,
1910 G_IO_ERROR_INVALID_ARGUMENT,
1911 _("Value nested too deeply"));
1915 variant_type = g_variant_type_new (sig);
1916 value = parse_value_from_blob (buf,
1922 g_variant_type_free (variant_type);
1925 ret = g_variant_new_variant (value);
1926 g_variant_unref (value);
1932 s = g_variant_type_dup_string (type);
1933 g_set_error (&local_error,
1935 G_IO_ERROR_INVALID_ARGUMENT,
1936 _("Error deserializing GVariant with type string “%s” from the D-Bus wire format"),
1944 g_assert ((just_align && ret == NULL) || (!just_align && ret != NULL));
1946 #ifdef DEBUG_SERIALIZER
1952 if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
1954 s = g_strdup_printf ("0x%02x '%c'", g_variant_get_byte (ret), g_variant_get_byte (ret));
1958 s = g_variant_print (ret, FALSE);
1960 g_print (": %s\n", s);
1964 #endif /* DEBUG_SERIALIZER */
1966 /* sink the reference, if floating */
1968 g_variant_take_ref (ret);
1972 #ifdef DEBUG_SERIALIZER
1974 "%*sFAILURE: %s (%s, %d)\n",
1976 local_error->message,
1977 g_quark_to_string (local_error->domain),
1979 #endif /* DEBUG_SERIALIZER */
1980 g_propagate_error (error, local_error);
1984 /* ---------------------------------------------------------------------------------------------------- */
1986 /* message_header must be at least 16 bytes */
1989 * g_dbus_message_bytes_needed:
1990 * @blob: (array length=blob_len) (element-type guint8): A blob representing a binary D-Bus message.
1991 * @blob_len: The length of @blob (must be at least 16).
1992 * @error: Return location for error or %NULL.
1994 * Utility function to calculate how many bytes are needed to
1995 * completely deserialize the D-Bus message stored at @blob.
1997 * Returns: Number of bytes needed or -1 if @error is set (e.g. if
1998 * @blob contains invalid data or not enough data is available to
1999 * determine the size).
2004 g_dbus_message_bytes_needed (guchar *blob,
2012 g_return_val_if_fail (blob != NULL, -1);
2013 g_return_val_if_fail (error == NULL || *error == NULL, -1);
2014 g_return_val_if_fail (blob_len >= 16, -1);
2018 /* core header (12 bytes) + ARRAY of STRUCT of (BYTE,VARIANT) */
2019 ret = 12 + 4 + GUINT32_FROM_LE (((guint32 *) blob)[3]);
2020 /* round up so it's a multiple of 8 */
2021 ret = 8 * ((ret + 7)/8);
2022 /* finally add the body size */
2023 ret += GUINT32_FROM_LE (((guint32 *) blob)[1]);
2025 else if (blob[0] == 'B')
2027 /* core header (12 bytes) + ARRAY of STRUCT of (BYTE,VARIANT) */
2028 ret = 12 + 4 + GUINT32_FROM_BE (((guint32 *) blob)[3]);
2029 /* round up so it's a multiple of 8 */
2030 ret = 8 * ((ret + 7)/8);
2031 /* finally add the body size */
2032 ret += GUINT32_FROM_BE (((guint32 *) blob)[1]);
2038 G_IO_ERROR_INVALID_ARGUMENT,
2039 "Unable to determine message blob length - given blob is malformed");
2046 G_IO_ERROR_INVALID_ARGUMENT,
2047 "Blob indicates that message exceeds maximum message length (128MiB)");
2054 /* ---------------------------------------------------------------------------------------------------- */
2057 * g_dbus_message_new_from_blob:
2058 * @blob: (array length=blob_len) (element-type guint8): A blob representing a binary D-Bus message.
2059 * @blob_len: The length of @blob.
2060 * @capabilities: A #GDBusCapabilityFlags describing what protocol features are supported.
2061 * @error: Return location for error or %NULL.
2063 * Creates a new #GDBusMessage from the data stored at @blob. The byte
2064 * order that the message was in can be retrieved using
2065 * g_dbus_message_get_byte_order().
2067 * If the @blob cannot be parsed, contains invalid fields, or contains invalid
2068 * headers, %G_IO_ERROR_INVALID_ARGUMENT will be returned.
2070 * Returns: A new #GDBusMessage or %NULL if @error is set. Free with
2076 g_dbus_message_new_from_blob (guchar *blob,
2078 GDBusCapabilityFlags capabilities,
2083 GDBusMessage *message;
2085 guchar major_protocol_version;
2086 guint32 message_body_len;
2090 GVariant *signature;
2092 /* TODO: check against @capabilities */
2096 g_return_val_if_fail (blob != NULL, NULL);
2097 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
2098 g_return_val_if_fail (blob_len >= 12, NULL);
2100 message = g_dbus_message_new ();
2102 memset (&mbuf, 0, sizeof (mbuf));
2103 mbuf.data = (gchar *)blob;
2104 mbuf.len = mbuf.valid_len = blob_len;
2106 endianness = g_memory_buffer_read_byte (&mbuf);
2110 mbuf.byte_order = G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN;
2111 message->byte_order = G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN;
2114 mbuf.byte_order = G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN;
2115 message->byte_order = G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN;
2120 G_IO_ERROR_INVALID_ARGUMENT,
2121 _("Invalid endianness value. Expected 0x6c (“l”) or 0x42 (“B”) but found value 0x%02x"),
2126 message->type = g_memory_buffer_read_byte (&mbuf);
2127 message->flags = g_memory_buffer_read_byte (&mbuf);
2128 major_protocol_version = g_memory_buffer_read_byte (&mbuf);
2129 if (major_protocol_version != 1)
2133 G_IO_ERROR_INVALID_ARGUMENT,
2134 _("Invalid major protocol version. Expected 1 but found %d"),
2135 major_protocol_version);
2138 message_body_len = g_memory_buffer_read_uint32 (&mbuf);
2139 message->serial = g_memory_buffer_read_uint32 (&mbuf);
2141 #ifdef DEBUG_SERIALIZER
2142 g_print ("Parsing blob (blob_len = 0x%04x bytes)\n", (gint) blob_len);
2145 s = _g_dbus_hexdump ((const gchar *) blob, blob_len, 2);
2146 g_print ("%s\n", s);
2149 #endif /* DEBUG_SERIALIZER */
2151 #ifdef DEBUG_SERIALIZER
2152 g_print ("Parsing headers (blob_len = 0x%04x bytes)\n", (gint) blob_len);
2153 #endif /* DEBUG_SERIALIZER */
2154 headers = parse_value_from_blob (&mbuf,
2155 G_VARIANT_TYPE ("a{yv}"),
2156 G_DBUS_MAX_TYPE_DEPTH + 2 /* for the a{yv} */,
2160 if (headers == NULL)
2162 g_variant_iter_init (&iter, headers);
2163 while ((item = g_variant_iter_next_value (&iter)) != NULL)
2165 guchar header_field;
2167 g_variant_get (item,
2171 g_dbus_message_set_header (message, header_field, value);
2172 g_variant_unref (value);
2173 g_variant_unref (item);
2175 g_variant_unref (headers);
2177 signature = g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE);
2178 if (signature != NULL)
2180 const gchar *signature_str;
2181 gsize signature_str_len;
2183 if (!g_variant_is_of_type (signature, G_VARIANT_TYPE_SIGNATURE))
2185 g_set_error_literal (error,
2187 G_IO_ERROR_INVALID_ARGUMENT,
2188 _("Signature header found but is not of type signature"));
2192 signature_str = g_variant_get_string (signature, &signature_str_len);
2194 /* signature but no body */
2195 if (message_body_len == 0 && signature_str_len > 0)
2199 G_IO_ERROR_INVALID_ARGUMENT,
2200 _("Signature header with signature “%s” found but message body is empty"),
2204 else if (signature_str_len > 0)
2206 GVariantType *variant_type;
2207 gchar *tupled_signature_str = g_strdup_printf ("(%s)", signature_str);
2209 if (!g_variant_is_signature (signature_str) ||
2210 !g_variant_type_string_is_valid (tupled_signature_str))
2214 G_IO_ERROR_INVALID_ARGUMENT,
2215 _("Parsed value “%s” is not a valid D-Bus signature (for body)"),
2217 g_free (tupled_signature_str);
2221 variant_type = g_variant_type_new (tupled_signature_str);
2222 g_free (tupled_signature_str);
2223 #ifdef DEBUG_SERIALIZER
2224 g_print ("Parsing body (blob_len = 0x%04x bytes)\n", (gint) blob_len);
2225 #endif /* DEBUG_SERIALIZER */
2226 message->body = parse_value_from_blob (&mbuf,
2228 G_DBUS_MAX_TYPE_DEPTH + 1 /* for the surrounding tuple */,
2232 g_variant_type_free (variant_type);
2233 if (message->body == NULL)
2239 /* no signature, this is only OK if the body is empty */
2240 if (message_body_len != 0)
2242 /* G_GUINT32_FORMAT doesn't work with gettext, just use %u */
2245 G_IO_ERROR_INVALID_ARGUMENT,
2246 g_dngettext (GETTEXT_PACKAGE,
2247 "No signature header in message but the message body is %u byte",
2248 "No signature header in message but the message body is %u bytes",
2255 if (!validate_headers (message, error))
2257 g_prefix_error (error, _("Cannot deserialize message: "));
2270 if (message != NULL)
2271 g_object_unref (message);
2276 /* ---------------------------------------------------------------------------------------------------- */
2279 ensure_output_padding (GMemoryBuffer *mbuf,
2283 gsize wanted_offset;
2284 gsize padding_needed;
2288 wanted_offset = ((offset + padding_size - 1) / padding_size) * padding_size;
2289 padding_needed = wanted_offset - offset;
2291 for (n = 0; n < padding_needed; n++)
2292 g_memory_buffer_put_byte (mbuf, '\0');
2294 return padding_needed;
2297 /* note that value can be NULL for e.g. empty arrays - type is never NULL */
2299 append_value_to_blob (GVariant *value,
2300 const GVariantType *type,
2301 GMemoryBuffer *mbuf,
2302 gsize *out_padding_added,
2305 gsize padding_added;
2306 const gchar *type_string;
2308 type_string = g_variant_type_peek_string (type);
2312 switch (type_string[0])
2314 case 'b': /* G_VARIANT_TYPE_BOOLEAN */
2315 padding_added = ensure_output_padding (mbuf, 4);
2318 gboolean v = g_variant_get_boolean (value);
2319 g_memory_buffer_put_uint32 (mbuf, v);
2323 case 'y': /* G_VARIANT_TYPE_BYTE */
2326 guint8 v = g_variant_get_byte (value);
2327 g_memory_buffer_put_byte (mbuf, v);
2331 case 'n': /* G_VARIANT_TYPE_INT16 */
2332 padding_added = ensure_output_padding (mbuf, 2);
2335 gint16 v = g_variant_get_int16 (value);
2336 g_memory_buffer_put_int16 (mbuf, v);
2340 case 'q': /* G_VARIANT_TYPE_UINT16 */
2341 padding_added = ensure_output_padding (mbuf, 2);
2344 guint16 v = g_variant_get_uint16 (value);
2345 g_memory_buffer_put_uint16 (mbuf, v);
2349 case 'i': /* G_VARIANT_TYPE_INT32 */
2350 padding_added = ensure_output_padding (mbuf, 4);
2353 gint32 v = g_variant_get_int32 (value);
2354 g_memory_buffer_put_int32 (mbuf, v);
2358 case 'u': /* G_VARIANT_TYPE_UINT32 */
2359 padding_added = ensure_output_padding (mbuf, 4);
2362 guint32 v = g_variant_get_uint32 (value);
2363 g_memory_buffer_put_uint32 (mbuf, v);
2367 case 'x': /* G_VARIANT_TYPE_INT64 */
2368 padding_added = ensure_output_padding (mbuf, 8);
2371 gint64 v = g_variant_get_int64 (value);
2372 g_memory_buffer_put_int64 (mbuf, v);
2376 case 't': /* G_VARIANT_TYPE_UINT64 */
2377 padding_added = ensure_output_padding (mbuf, 8);
2380 guint64 v = g_variant_get_uint64 (value);
2381 g_memory_buffer_put_uint64 (mbuf, v);
2385 case 'd': /* G_VARIANT_TYPE_DOUBLE */
2386 padding_added = ensure_output_padding (mbuf, 8);
2393 G_STATIC_ASSERT (sizeof (gdouble) == sizeof (guint64));
2394 u.v_double = g_variant_get_double (value);
2395 g_memory_buffer_put_uint64 (mbuf, u.v_uint64);
2399 case 's': /* G_VARIANT_TYPE_STRING */
2400 padding_added = ensure_output_padding (mbuf, 4);
2405 #ifndef G_DISABLE_ASSERT
2409 v = g_variant_get_string (value, &len);
2410 g_assert (g_utf8_validate (v, -1, &end) && (end == v + len));
2411 g_memory_buffer_put_uint32 (mbuf, len);
2412 g_memory_buffer_put_string (mbuf, v);
2413 g_memory_buffer_put_byte (mbuf, '\0');
2417 case 'o': /* G_VARIANT_TYPE_OBJECT_PATH */
2418 padding_added = ensure_output_padding (mbuf, 4);
2422 const gchar *v = g_variant_get_string (value, &len);
2423 g_assert (g_variant_is_object_path (v));
2424 g_memory_buffer_put_uint32 (mbuf, len);
2425 g_memory_buffer_put_string (mbuf, v);
2426 g_memory_buffer_put_byte (mbuf, '\0');
2430 case 'g': /* G_VARIANT_TYPE_SIGNATURE */
2434 const gchar *v = g_variant_get_string (value, &len);
2435 g_assert (g_variant_is_signature (v));
2436 g_memory_buffer_put_byte (mbuf, len);
2437 g_memory_buffer_put_string (mbuf, v);
2438 g_memory_buffer_put_byte (mbuf, '\0');
2442 case 'h': /* G_VARIANT_TYPE_HANDLE */
2443 padding_added = ensure_output_padding (mbuf, 4);
2446 gint32 v = g_variant_get_handle (value);
2447 g_memory_buffer_put_int32 (mbuf, v);
2451 case 'a': /* G_VARIANT_TYPE_ARRAY */
2453 const GVariantType *element_type;
2456 goffset array_len_offset;
2457 goffset array_payload_begin_offset;
2462 padding_added = ensure_output_padding (mbuf, 4);
2465 /* array length - will be filled in later */
2466 array_len_offset = mbuf->valid_len;
2467 g_memory_buffer_put_uint32 (mbuf, 0xF00DFACE);
2469 /* From the D-Bus spec:
2471 * "A UINT32 giving the length of the array data in bytes,
2472 * followed by alignment padding to the alignment boundary of
2473 * the array element type, followed by each array element. The
2474 * array length is from the end of the alignment padding to
2475 * the end of the last element, i.e. it does not include the
2476 * padding after the length, or any padding after the last
2479 * Thus, we need to count how much padding the first element
2480 * contributes and subtract that from the array length.
2482 array_payload_begin_offset = mbuf->valid_len;
2484 element_type = g_variant_type_element (type);
2485 fixed_size = get_type_fixed_size (element_type);
2487 if (g_variant_n_children (value) == 0)
2489 gsize padding_added_for_item;
2490 if (!append_value_to_blob (NULL,
2493 &padding_added_for_item,
2496 array_payload_begin_offset += padding_added_for_item;
2498 else if (fixed_size != 0)
2500 GVariant *use_value;
2502 if (g_memory_buffer_is_byteswapped (mbuf))
2503 use_value = g_variant_byteswap (value);
2505 use_value = g_variant_ref (value);
2507 array_payload_begin_offset += ensure_output_padding (mbuf, fixed_size);
2509 array_len = g_variant_get_size (use_value);
2510 g_memory_buffer_write (mbuf, g_variant_get_data (use_value), array_len);
2511 g_variant_unref (use_value);
2517 g_variant_iter_init (&iter, value);
2518 while ((item = g_variant_iter_next_value (&iter)) != NULL)
2520 gsize padding_added_for_item;
2521 if (!append_value_to_blob (item,
2522 g_variant_get_type (item),
2524 &padding_added_for_item,
2527 g_variant_unref (item);
2530 g_variant_unref (item);
2533 array_payload_begin_offset += padding_added_for_item;
2539 cur_offset = mbuf->valid_len;
2540 array_len = cur_offset - array_payload_begin_offset;
2541 mbuf->pos = array_len_offset;
2543 g_memory_buffer_put_uint32 (mbuf, array_len);
2544 mbuf->pos = cur_offset;
2550 if (g_variant_type_is_dict_entry (type) || g_variant_type_is_tuple (type))
2552 padding_added = ensure_output_padding (mbuf, 8);
2557 g_variant_iter_init (&iter, value);
2558 while ((item = g_variant_iter_next_value (&iter)) != NULL)
2560 if (!append_value_to_blob (item,
2561 g_variant_get_type (item),
2566 g_variant_unref (item);
2569 g_variant_unref (item);
2573 else if (g_variant_type_is_variant (type))
2578 const gchar *signature;
2579 child = g_variant_get_child_value (value, 0);
2580 signature = g_variant_get_type_string (child);
2581 g_memory_buffer_put_byte (mbuf, strlen (signature));
2582 g_memory_buffer_put_string (mbuf, signature);
2583 g_memory_buffer_put_byte (mbuf, '\0');
2584 if (!append_value_to_blob (child,
2585 g_variant_get_type (child),
2590 g_variant_unref (child);
2593 g_variant_unref (child);
2600 G_IO_ERROR_INVALID_ARGUMENT,
2601 _("Error serializing GVariant with type string “%s” to the D-Bus wire format"),
2602 g_variant_get_type_string (value));
2608 if (out_padding_added != NULL)
2609 *out_padding_added = padding_added;
2618 append_body_to_blob (GVariant *value,
2619 GMemoryBuffer *mbuf,
2625 if (!g_variant_is_of_type (value, G_VARIANT_TYPE_TUPLE))
2629 G_IO_ERROR_INVALID_ARGUMENT,
2630 "Expected a tuple for the body of the GDBusMessage.");
2634 g_variant_iter_init (&iter, value);
2635 while ((item = g_variant_iter_next_value (&iter)) != NULL)
2637 if (!append_value_to_blob (item,
2638 g_variant_get_type (item),
2643 g_variant_unref (item);
2646 g_variant_unref (item);
2654 /* ---------------------------------------------------------------------------------------------------- */
2657 * g_dbus_message_to_blob:
2658 * @message: A #GDBusMessage.
2659 * @out_size: Return location for size of generated blob.
2660 * @capabilities: A #GDBusCapabilityFlags describing what protocol features are supported.
2661 * @error: Return location for error.
2663 * Serializes @message to a blob. The byte order returned by
2664 * g_dbus_message_get_byte_order() will be used.
2666 * Returns: (array length=out_size) (transfer full): A pointer to a
2667 * valid binary D-Bus message of @out_size bytes generated by @message
2668 * or %NULL if @error is set. Free with g_free().
2673 g_dbus_message_to_blob (GDBusMessage *message,
2675 GDBusCapabilityFlags capabilities,
2681 goffset body_len_offset;
2682 goffset body_start_offset;
2684 GVariant *header_fields;
2685 GVariantBuilder builder;
2686 GHashTableIter hash_iter;
2688 GVariant *header_value;
2689 GVariant *signature;
2690 const gchar *signature_str;
2691 gint num_fds_in_message;
2692 gint num_fds_according_to_header;
2694 /* TODO: check against @capabilities */
2698 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2699 g_return_val_if_fail (out_size != NULL, NULL);
2700 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
2702 memset (&mbuf, 0, sizeof (mbuf));
2703 mbuf.len = MIN_ARRAY_SIZE;
2704 mbuf.data = g_malloc (mbuf.len);
2706 mbuf.byte_order = G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN;
2707 switch (message->byte_order)
2709 case G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN:
2710 mbuf.byte_order = G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN;
2712 case G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN:
2713 mbuf.byte_order = G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN;
2718 g_memory_buffer_put_byte (&mbuf, (guchar) message->byte_order);
2719 g_memory_buffer_put_byte (&mbuf, message->type);
2720 g_memory_buffer_put_byte (&mbuf, message->flags);
2721 g_memory_buffer_put_byte (&mbuf, 1); /* major protocol version */
2722 body_len_offset = mbuf.valid_len;
2723 /* body length - will be filled in later */
2724 g_memory_buffer_put_uint32 (&mbuf, 0xF00DFACE);
2725 g_memory_buffer_put_uint32 (&mbuf, message->serial);
2727 num_fds_in_message = 0;
2729 if (message->fd_list != NULL)
2730 num_fds_in_message = g_unix_fd_list_get_length (message->fd_list);
2732 num_fds_according_to_header = g_dbus_message_get_num_unix_fds (message);
2733 if (num_fds_in_message != num_fds_according_to_header)
2737 G_IO_ERROR_INVALID_ARGUMENT,
2738 _("Number of file descriptors in message (%d) differs from header field (%d)"),
2740 num_fds_according_to_header);
2744 if (!validate_headers (message, error))
2746 g_prefix_error (error, _("Cannot serialize message: "));
2750 g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{yv}"));
2751 g_hash_table_iter_init (&hash_iter, message->headers);
2752 while (g_hash_table_iter_next (&hash_iter, &key, (gpointer) &header_value))
2754 g_variant_builder_add (&builder,
2756 (guchar) GPOINTER_TO_UINT (key),
2759 header_fields = g_variant_builder_end (&builder);
2761 if (!append_value_to_blob (header_fields,
2762 g_variant_get_type (header_fields),
2767 g_variant_unref (header_fields);
2770 g_variant_unref (header_fields);
2772 /* header size must be a multiple of 8 */
2773 ensure_output_padding (&mbuf, 8);
2775 body_start_offset = mbuf.valid_len;
2777 signature = g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE);
2779 if (signature != NULL && !g_variant_is_of_type (signature, G_VARIANT_TYPE_SIGNATURE))
2781 g_set_error_literal (error,
2783 G_IO_ERROR_INVALID_ARGUMENT,
2784 _("Signature header found but is not of type signature"));
2788 signature_str = NULL;
2789 if (signature != NULL)
2790 signature_str = g_variant_get_string (signature, NULL);
2791 if (message->body != NULL)
2793 gchar *tupled_signature_str;
2794 if (signature == NULL)
2798 G_IO_ERROR_INVALID_ARGUMENT,
2799 _("Message body has signature “%s” but there is no signature header"),
2800 g_variant_get_type_string (message->body));
2803 tupled_signature_str = g_strdup_printf ("(%s)", signature_str);
2804 if (g_strcmp0 (tupled_signature_str, g_variant_get_type_string (message->body)) != 0)
2808 G_IO_ERROR_INVALID_ARGUMENT,
2809 _("Message body has type signature “%s” but signature in the header field is “%s”"),
2810 g_variant_get_type_string (message->body), tupled_signature_str);
2811 g_free (tupled_signature_str);
2814 g_free (tupled_signature_str);
2815 if (!append_body_to_blob (message->body, &mbuf, error))
2820 if (signature != NULL && strlen (signature_str) > 0)
2824 G_IO_ERROR_INVALID_ARGUMENT,
2825 _("Message body is empty but signature in the header field is “(%s)”"),
2831 /* OK, we're done writing the message - set the body length */
2832 size = mbuf.valid_len;
2833 body_size = size - body_start_offset;
2835 mbuf.pos = body_len_offset;
2837 g_memory_buffer_put_uint32 (&mbuf, body_size);
2840 ret = (guchar *)mbuf.data;
2849 /* ---------------------------------------------------------------------------------------------------- */
2852 get_uint32_header (GDBusMessage *message,
2853 GDBusMessageHeaderField header_field)
2859 value = g_hash_table_lookup (message->headers, GUINT_TO_POINTER (header_field));
2860 if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_UINT32))
2861 ret = g_variant_get_uint32 (value);
2866 static const gchar *
2867 get_string_header (GDBusMessage *message,
2868 GDBusMessageHeaderField header_field)
2874 value = g_hash_table_lookup (message->headers, GUINT_TO_POINTER (header_field));
2875 if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
2876 ret = g_variant_get_string (value, NULL);
2881 static const gchar *
2882 get_object_path_header (GDBusMessage *message,
2883 GDBusMessageHeaderField header_field)
2889 value = g_hash_table_lookup (message->headers, GUINT_TO_POINTER (header_field));
2890 if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_OBJECT_PATH))
2891 ret = g_variant_get_string (value, NULL);
2896 static const gchar *
2897 get_signature_header (GDBusMessage *message,
2898 GDBusMessageHeaderField header_field)
2904 value = g_hash_table_lookup (message->headers, GUINT_TO_POINTER (header_field));
2905 if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_SIGNATURE))
2906 ret = g_variant_get_string (value, NULL);
2911 /* ---------------------------------------------------------------------------------------------------- */
2914 set_uint32_header (GDBusMessage *message,
2915 GDBusMessageHeaderField header_field,
2918 g_dbus_message_set_header (message,
2920 g_variant_new_uint32 (value));
2924 set_string_header (GDBusMessage *message,
2925 GDBusMessageHeaderField header_field,
2928 g_dbus_message_set_header (message,
2930 value == NULL ? NULL : g_variant_new_string (value));
2934 set_object_path_header (GDBusMessage *message,
2935 GDBusMessageHeaderField header_field,
2938 g_dbus_message_set_header (message,
2940 value == NULL ? NULL : g_variant_new_object_path (value));
2944 set_signature_header (GDBusMessage *message,
2945 GDBusMessageHeaderField header_field,
2948 g_dbus_message_set_header (message,
2950 value == NULL ? NULL : g_variant_new_signature (value));
2953 /* ---------------------------------------------------------------------------------------------------- */
2956 * g_dbus_message_get_reply_serial:
2957 * @message: A #GDBusMessage.
2959 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL header field.
2961 * Returns: The value.
2966 g_dbus_message_get_reply_serial (GDBusMessage *message)
2968 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), 0);
2969 return get_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL);
2973 * g_dbus_message_set_reply_serial:
2974 * @message: A #GDBusMessage.
2975 * @value: The value to set.
2977 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL header field.
2982 g_dbus_message_set_reply_serial (GDBusMessage *message,
2985 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2986 set_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL, value);
2989 /* ---------------------------------------------------------------------------------------------------- */
2992 * g_dbus_message_get_interface:
2993 * @message: A #GDBusMessage.
2995 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE header field.
2997 * Returns: (nullable): The value.
3002 g_dbus_message_get_interface (GDBusMessage *message)
3004 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
3005 return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE);
3009 * g_dbus_message_set_interface:
3010 * @message: A #GDBusMessage.
3011 * @value: (nullable): The value to set.
3013 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE header field.
3018 g_dbus_message_set_interface (GDBusMessage *message,
3021 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
3022 g_return_if_fail (value == NULL || g_dbus_is_interface_name (value));
3023 set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE, value);
3026 /* ---------------------------------------------------------------------------------------------------- */
3029 * g_dbus_message_get_member:
3030 * @message: A #GDBusMessage.
3032 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_MEMBER header field.
3034 * Returns: (nullable): The value.
3039 g_dbus_message_get_member (GDBusMessage *message)
3041 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
3042 return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER);
3046 * g_dbus_message_set_member:
3047 * @message: A #GDBusMessage.
3048 * @value: (nullable): The value to set.
3050 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_MEMBER header field.
3055 g_dbus_message_set_member (GDBusMessage *message,
3058 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
3059 g_return_if_fail (value == NULL || g_dbus_is_member_name (value));
3060 set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER, value);
3063 /* ---------------------------------------------------------------------------------------------------- */
3066 * g_dbus_message_get_path:
3067 * @message: A #GDBusMessage.
3069 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_PATH header field.
3071 * Returns: (nullable): The value.
3076 g_dbus_message_get_path (GDBusMessage *message)
3078 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
3079 return get_object_path_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH);
3083 * g_dbus_message_set_path:
3084 * @message: A #GDBusMessage.
3085 * @value: (nullable): The value to set.
3087 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_PATH header field.
3092 g_dbus_message_set_path (GDBusMessage *message,
3095 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
3096 g_return_if_fail (value == NULL || g_variant_is_object_path (value));
3097 set_object_path_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH, value);
3100 /* ---------------------------------------------------------------------------------------------------- */
3103 * g_dbus_message_get_sender:
3104 * @message: A #GDBusMessage.
3106 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_SENDER header field.
3108 * Returns: (nullable): The value.
3113 g_dbus_message_get_sender (GDBusMessage *message)
3115 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
3116 return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SENDER);
3120 * g_dbus_message_set_sender:
3121 * @message: A #GDBusMessage.
3122 * @value: (nullable): The value to set.
3124 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_SENDER header field.
3129 g_dbus_message_set_sender (GDBusMessage *message,
3132 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
3133 g_return_if_fail (value == NULL || g_dbus_is_name (value));
3134 set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SENDER, value);
3137 /* ---------------------------------------------------------------------------------------------------- */
3140 * g_dbus_message_get_destination:
3141 * @message: A #GDBusMessage.
3143 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION header field.
3145 * Returns: (nullable): The value.
3150 g_dbus_message_get_destination (GDBusMessage *message)
3152 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
3153 return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION);
3157 * g_dbus_message_set_destination:
3158 * @message: A #GDBusMessage.
3159 * @value: (nullable): The value to set.
3161 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION header field.
3166 g_dbus_message_set_destination (GDBusMessage *message,
3169 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
3170 g_return_if_fail (value == NULL || g_dbus_is_name (value));
3171 set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION, value);
3174 /* ---------------------------------------------------------------------------------------------------- */
3177 * g_dbus_message_get_error_name:
3178 * @message: A #GDBusMessage.
3180 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME header field.
3182 * Returns: (nullable): The value.
3187 g_dbus_message_get_error_name (GDBusMessage *message)
3189 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
3190 return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME);
3194 * g_dbus_message_set_error_name:
3195 * @message: (nullable): A #GDBusMessage.
3196 * @value: The value to set.
3198 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME header field.
3203 g_dbus_message_set_error_name (GDBusMessage *message,
3206 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
3207 g_return_if_fail (value == NULL || g_dbus_is_error_name (value));
3208 set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME, value);
3211 /* ---------------------------------------------------------------------------------------------------- */
3214 * g_dbus_message_get_signature:
3215 * @message: A #GDBusMessage.
3217 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE header field.
3219 * This will always be non-%NULL, but may be an empty string.
3221 * Returns: (not nullable): The value.
3226 g_dbus_message_get_signature (GDBusMessage *message)
3229 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
3230 ret = get_signature_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE);
3237 * g_dbus_message_set_signature:
3238 * @message: A #GDBusMessage.
3239 * @value: (nullable): The value to set.
3241 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE header field.
3246 g_dbus_message_set_signature (GDBusMessage *message,
3249 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
3250 g_return_if_fail (value == NULL || g_variant_is_signature (value));
3251 set_signature_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE, value);
3254 /* ---------------------------------------------------------------------------------------------------- */
3257 * g_dbus_message_get_arg0:
3258 * @message: A #GDBusMessage.
3260 * Convenience to get the first item in the body of @message.
3262 * Returns: (nullable): The string item or %NULL if the first item in the body of
3263 * @message is not a string.
3268 g_dbus_message_get_arg0 (GDBusMessage *message)
3272 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
3276 if (message->body != NULL && g_variant_is_of_type (message->body, G_VARIANT_TYPE_TUPLE))
3279 item = g_variant_get_child_value (message->body, 0);
3280 if (g_variant_is_of_type (item, G_VARIANT_TYPE_STRING))
3281 ret = g_variant_get_string (item, NULL);
3282 g_variant_unref (item);
3288 /* ---------------------------------------------------------------------------------------------------- */
3291 * g_dbus_message_get_num_unix_fds:
3292 * @message: A #GDBusMessage.
3294 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS header field.
3296 * Returns: The value.
3301 g_dbus_message_get_num_unix_fds (GDBusMessage *message)
3303 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), 0);
3304 return get_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS);
3308 * g_dbus_message_set_num_unix_fds:
3309 * @message: A #GDBusMessage.
3310 * @value: The value to set.
3312 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS header field.
3317 g_dbus_message_set_num_unix_fds (GDBusMessage *message,
3320 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
3321 set_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS, value);
3324 /* ---------------------------------------------------------------------------------------------------- */
3327 * g_dbus_message_to_gerror:
3328 * @message: A #GDBusMessage.
3329 * @error: The #GError to set.
3331 * If @message is not of type %G_DBUS_MESSAGE_TYPE_ERROR does
3332 * nothing and returns %FALSE.
3334 * Otherwise this method encodes the error in @message as a #GError
3335 * using g_dbus_error_set_dbus_error() using the information in the
3336 * %G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME header field of @message as
3337 * well as the first string item in @message's body.
3339 * Returns: %TRUE if @error was set, %FALSE otherwise.
3344 g_dbus_message_to_gerror (GDBusMessage *message,
3348 const gchar *error_name;
3350 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), FALSE);
3353 if (message->type != G_DBUS_MESSAGE_TYPE_ERROR)
3356 error_name = g_dbus_message_get_error_name (message);
3357 if (error_name != NULL)
3361 body = g_dbus_message_get_body (message);
3363 if (body != NULL && g_variant_is_of_type (body, G_VARIANT_TYPE ("(s)")))
3365 const gchar *error_message;
3366 g_variant_get (body, "(&s)", &error_message);
3367 g_dbus_error_set_dbus_error (error,
3374 /* these two situations are valid, yet pretty rare */
3377 g_dbus_error_set_dbus_error (error,
3380 _("Error return with body of type “%s”"),
3381 g_variant_get_type_string (body));
3385 g_dbus_error_set_dbus_error (error,
3388 _("Error return with empty body"));
3394 /* TODO: this shouldn't happen - should check this at message serialization
3395 * time and disconnect the peer.
3400 "Error return without error-name header!");
3409 /* ---------------------------------------------------------------------------------------------------- */
3412 flags_to_string (GType flags_type, guint value)
3418 klass = g_type_class_ref (flags_type);
3419 s = g_string_new (NULL);
3420 for (n = 0; n < 32; n++)
3422 if ((value & (1<<n)) != 0)
3424 GFlagsValue *flags_value;
3425 flags_value = g_flags_get_first_value (klass, (1<<n));
3427 g_string_append_c (s, ',');
3428 if (flags_value != NULL)
3429 g_string_append (s, flags_value->value_nick);
3431 g_string_append_printf (s, "unknown (bit %d)", n);
3435 g_string_append (s, "none");
3436 g_type_class_unref (klass);
3437 return g_string_free (s, FALSE);
3441 _sort_keys_func (gconstpointer a,
3447 ia = GPOINTER_TO_INT (a);
3448 ib = GPOINTER_TO_INT (b);
3454 * g_dbus_message_print:
3455 * @message: A #GDBusMessage.
3456 * @indent: Indentation level.
3458 * Produces a human-readable multi-line description of @message.
3460 * The contents of the description has no ABI guarantees, the contents
3461 * and formatting is subject to change at any time. Typical output
3462 * looks something like this:
3469 * path -> objectpath '/org/gtk/GDBus/TestObject'
3470 * interface -> 'org.gtk.GDBus.TestInterface'
3471 * member -> 'GimmeStdout'
3472 * destination -> ':1.146'
3474 * UNIX File Descriptors:
3479 * Type: method-return
3480 * Flags: no-reply-expected
3484 * reply-serial -> uint32 4
3485 * destination -> ':1.159'
3486 * sender -> ':1.146'
3487 * num-unix-fds -> uint32 1
3489 * UNIX File Descriptors:
3490 * fd 12: dev=0:10,mode=020620,ino=5,uid=500,gid=5,rdev=136:2,size=0,atime=1273085037,mtime=1273085851,ctime=1272982635
3493 * Returns: (not nullable): A string that should be freed with g_free().
3498 g_dbus_message_print (GDBusMessage *message,
3506 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
3508 str = g_string_new (NULL);
3510 s = _g_dbus_enum_to_string (G_TYPE_DBUS_MESSAGE_TYPE, message->type);
3511 g_string_append_printf (str, "%*sType: %s\n", indent, "", s);
3513 s = flags_to_string (G_TYPE_DBUS_MESSAGE_FLAGS, message->flags);
3514 g_string_append_printf (str, "%*sFlags: %s\n", indent, "", s);
3516 g_string_append_printf (str, "%*sVersion: %d\n", indent, "", message->major_protocol_version);
3517 g_string_append_printf (str, "%*sSerial: %d\n", indent, "", message->serial);
3519 g_string_append_printf (str, "%*sHeaders:\n", indent, "");
3520 keys = g_hash_table_get_keys (message->headers);
3521 keys = g_list_sort (keys, _sort_keys_func);
3524 for (l = keys; l != NULL; l = l->next)
3526 gint key = GPOINTER_TO_INT (l->data);
3530 value = g_hash_table_lookup (message->headers, l->data);
3531 g_assert (value != NULL);
3533 s = _g_dbus_enum_to_string (G_TYPE_DBUS_MESSAGE_HEADER_FIELD, key);
3534 value_str = g_variant_print (value, TRUE);
3535 g_string_append_printf (str, "%*s %s -> %s\n", indent, "", s, value_str);
3542 g_string_append_printf (str, "%*s (none)\n", indent, "");
3545 g_string_append_printf (str, "%*sBody: ", indent, "");
3546 if (message->body != NULL)
3548 g_variant_print_string (message->body,
3554 g_string_append (str, "()");
3556 g_string_append (str, "\n");
3558 g_string_append_printf (str, "%*sUNIX File Descriptors:\n", indent, "");
3559 if (message->fd_list != NULL)
3565 fds = g_unix_fd_list_peek_fds (message->fd_list, &num_fds);
3568 for (n = 0; n < num_fds; n++)
3571 struct stat statbuf;
3572 fs = g_string_new (NULL);
3573 if (fstat (fds[n], &statbuf) == 0)
3575 #ifndef MAJOR_MINOR_NOT_FOUND
3576 g_string_append_printf (fs, "%s" "dev=%d:%d", fs->len > 0 ? "," : "",
3577 (gint) major (statbuf.st_dev), (gint) minor (statbuf.st_dev));
3579 g_string_append_printf (fs, "%s" "mode=0%o", fs->len > 0 ? "," : "",
3580 (guint) statbuf.st_mode);
3581 g_string_append_printf (fs, "%s" "ino=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
3582 (guint64) statbuf.st_ino);
3583 g_string_append_printf (fs, "%s" "uid=%u", fs->len > 0 ? "," : "",
3584 (guint) statbuf.st_uid);
3585 g_string_append_printf (fs, "%s" "gid=%u", fs->len > 0 ? "," : "",
3586 (guint) statbuf.st_gid);
3587 #ifndef MAJOR_MINOR_NOT_FOUND
3588 g_string_append_printf (fs, "%s" "rdev=%d:%d", fs->len > 0 ? "," : "",
3589 (gint) major (statbuf.st_rdev), (gint) minor (statbuf.st_rdev));
3591 g_string_append_printf (fs, "%s" "size=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
3592 (guint64) statbuf.st_size);
3593 g_string_append_printf (fs, "%s" "atime=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
3594 (guint64) statbuf.st_atime);
3595 g_string_append_printf (fs, "%s" "mtime=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
3596 (guint64) statbuf.st_mtime);
3597 g_string_append_printf (fs, "%s" "ctime=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
3598 (guint64) statbuf.st_ctime);
3603 g_string_append_printf (fs, "(fstat failed: %s)", g_strerror (errsv));
3605 g_string_append_printf (str, "%*s fd %d: %s\n", indent, "", fds[n], fs->str);
3606 g_string_free (fs, TRUE);
3611 g_string_append_printf (str, "%*s (empty)\n", indent, "");
3616 g_string_append_printf (str, "%*s (none)\n", indent, "");
3620 return g_string_free (str, FALSE);
3624 * g_dbus_message_get_locked:
3625 * @message: A #GDBusMessage.
3627 * Checks whether @message is locked. To monitor changes to this
3628 * value, conncet to the #GObject::notify signal to listen for changes
3629 * on the #GDBusMessage:locked property.
3631 * Returns: %TRUE if @message is locked, %FALSE otherwise.
3636 g_dbus_message_get_locked (GDBusMessage *message)
3638 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), FALSE);
3639 return message->locked;
3643 * g_dbus_message_lock:
3644 * @message: A #GDBusMessage.
3646 * If @message is locked, does nothing. Otherwise locks the message.
3651 g_dbus_message_lock (GDBusMessage *message)
3653 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
3655 if (message->locked)
3658 message->locked = TRUE;
3659 g_object_notify (G_OBJECT (message), "locked");
3666 * g_dbus_message_copy:
3667 * @message: A #GDBusMessage.
3668 * @error: Return location for error or %NULL.
3670 * Copies @message. The copy is a deep copy and the returned
3671 * #GDBusMessage is completely identical except that it is guaranteed
3674 * This operation can fail if e.g. @message contains file descriptors
3675 * and the per-process or system-wide open files limit is reached.
3677 * Returns: (transfer full): A new #GDBusMessage or %NULL if @error is set.
3678 * Free with g_object_unref().
3683 g_dbus_message_copy (GDBusMessage *message,
3687 GHashTableIter iter;
3688 gpointer header_key;
3689 GVariant *header_value;
3691 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
3692 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
3694 ret = g_dbus_message_new ();
3695 ret->type = message->type;
3696 ret->flags = message->flags;
3697 ret->byte_order = message->byte_order;
3698 ret->major_protocol_version = message->major_protocol_version;
3699 ret->serial = message->serial;
3702 if (message->fd_list != NULL)
3708 ret->fd_list = g_unix_fd_list_new ();
3709 fds = g_unix_fd_list_peek_fds (message->fd_list, &num_fds);
3710 for (n = 0; n < num_fds; n++)
3712 if (g_unix_fd_list_append (ret->fd_list,
3716 g_object_unref (ret);
3724 /* see https://bugzilla.gnome.org/show_bug.cgi?id=624546#c8 for why it's fine
3725 * to just ref (as opposed to deep-copying) the GVariant instances
3727 ret->body = message->body != NULL ? g_variant_ref (message->body) : NULL;
3728 g_hash_table_iter_init (&iter, message->headers);
3729 while (g_hash_table_iter_next (&iter, &header_key, (gpointer) &header_value))
3730 g_hash_table_insert (ret->headers, header_key, g_variant_ref (header_value));
3739 g_dbus_message_init_header_iter (GDBusMessage *message,
3740 GHashTableIter *iter)
3742 g_hash_table_iter_init (iter, message->headers);