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>
32 #ifdef HAVE_SYS_MKDEV_H
33 #include <sys/mkdev.h>
39 #include "gdbusutils.h"
40 #include "gdbusmessage.h"
41 #include "gdbuserror.h"
42 #include "gioenumtypes.h"
43 #include "ginputstream.h"
44 #include "gdatainputstream.h"
45 #include "gmemoryinputstream.h"
46 #include "goutputstream.h"
47 #include "gdataoutputstream.h"
48 #include "gmemoryoutputstream.h"
49 #include "gseekable.h"
51 #include "gdbusprivate.h"
54 #include "gunixfdlist.h"
59 typedef struct _GMemoryBuffer GMemoryBuffer;
66 GDataStreamByteOrder byte_order;
70 g_memory_buffer_read (GMemoryBuffer *mbuf,
77 if (((gssize) count) < 0)
79 g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
80 _("Too large count value passed to %s"), G_STRFUNC);
84 res = MIN (count, mbuf->valid_len - mbuf->pos);
85 *buffer = mbuf->data + mbuf->pos;
91 g_memory_buffer_read_byte (GMemoryBuffer *mbuf,
94 if (mbuf->pos >= mbuf->valid_len)
96 return mbuf->data [mbuf->pos++];
100 g_memory_buffer_read_int16 (GMemoryBuffer *mbuf,
105 if (mbuf->pos > mbuf->valid_len - 2)
107 mbuf->pos = mbuf->valid_len;
111 memcpy (&v, mbuf->data + mbuf->pos, 2);
113 switch (mbuf->byte_order)
115 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
116 v = GINT16_FROM_BE (v);
118 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
119 v = GINT16_FROM_LE (v);
121 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
129 g_memory_buffer_read_uint16 (GMemoryBuffer *mbuf,
134 if (mbuf->pos > mbuf->valid_len - 2)
136 mbuf->pos = mbuf->valid_len;
140 memcpy (&v, mbuf->data + mbuf->pos, 2);
142 switch (mbuf->byte_order)
144 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
145 v = GINT16_FROM_BE (v);
147 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
148 v = GINT16_FROM_LE (v);
150 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
158 g_memory_buffer_read_int32 (GMemoryBuffer *mbuf,
163 if (mbuf->pos > mbuf->valid_len - 4)
165 mbuf->pos = mbuf->valid_len;
169 memcpy (&v, mbuf->data + mbuf->pos, 4);
171 switch (mbuf->byte_order)
173 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
174 v = GINT32_FROM_BE (v);
176 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
177 v = GINT32_FROM_LE (v);
179 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
187 g_memory_buffer_read_uint32 (GMemoryBuffer *mbuf,
192 if (mbuf->pos > mbuf->valid_len - 4)
194 mbuf->pos = mbuf->valid_len;
198 memcpy (&v, mbuf->data + mbuf->pos, 4);
200 switch (mbuf->byte_order)
202 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
203 v = GUINT32_FROM_BE (v);
205 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
206 v = GUINT32_FROM_LE (v);
208 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
216 g_memory_buffer_read_int64 (GMemoryBuffer *mbuf,
221 if (mbuf->pos > mbuf->valid_len - 8)
223 mbuf->pos = mbuf->valid_len;
227 memcpy (&v, mbuf->data + mbuf->pos, 8);
229 switch (mbuf->byte_order)
231 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
232 v = GINT64_FROM_BE (v);
234 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
235 v = GINT64_FROM_LE (v);
237 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
245 g_memory_buffer_read_uint64 (GMemoryBuffer *mbuf,
250 if (mbuf->pos > mbuf->valid_len - 8)
252 mbuf->pos = mbuf->valid_len;
256 memcpy (&v, mbuf->data + mbuf->pos, 8);
258 switch (mbuf->byte_order)
260 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
261 v = GUINT64_FROM_BE (v);
263 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
264 v = GUINT64_FROM_LE (v);
266 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
273 #define MIN_ARRAY_SIZE 128
276 g_nearest_pow (gint num)
287 array_resize (GMemoryBuffer *mbuf,
293 if (mbuf->len == size)
297 data = g_realloc (mbuf->data, size);
300 memset ((guint8 *)data + len, 0, size - len);
305 if (mbuf->len < mbuf->valid_len)
306 mbuf->valid_len = mbuf->len;
310 g_memory_buffer_write (GMemoryBuffer *mbuf,
320 /* Check for address space overflow, but only if the buffer is resizable.
321 Otherwise we just do a short write and don't worry. */
322 if (mbuf->pos + count < mbuf->pos)
325 if (mbuf->pos + count > mbuf->len)
327 /* At least enought to fit the write, rounded up
328 for greater than linear growth.
329 TODO: This wastes a lot of memory at large buffer sizes.
330 Figure out a more rational allocation strategy. */
331 new_size = g_nearest_pow (mbuf->pos + count);
332 /* Check for overflow again. We have only checked if
333 pos + count > G_MAXSIZE, but it only catches the case of writing
334 more than 4GiB total on a 32-bit system. There's still the problem
335 of g_nearest_pow overflowing above 0x7fffffff, so we're
336 effectively limited to 2GiB. */
337 if (new_size < mbuf->len)
340 new_size = MAX (new_size, MIN_ARRAY_SIZE);
341 array_resize (mbuf, new_size);
344 dest = (guint8 *)mbuf->data + mbuf->pos;
345 memcpy (dest, buffer, count);
348 if (mbuf->pos > mbuf->valid_len)
349 mbuf->valid_len = mbuf->pos;
355 g_memory_buffer_put_byte (GMemoryBuffer *mbuf,
358 return g_memory_buffer_write (mbuf, &data, 1);
362 g_memory_buffer_put_int16 (GMemoryBuffer *mbuf,
365 switch (mbuf->byte_order)
367 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
368 data = GINT16_TO_BE (data);
370 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
371 data = GINT16_TO_LE (data);
373 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
378 return g_memory_buffer_write (mbuf, &data, 2);
382 g_memory_buffer_put_uint16 (GMemoryBuffer *mbuf,
385 switch (mbuf->byte_order)
387 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
388 data = GUINT16_TO_BE (data);
390 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
391 data = GUINT16_TO_LE (data);
393 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
398 return g_memory_buffer_write (mbuf, &data, 2);
402 g_memory_buffer_put_int32 (GMemoryBuffer *mbuf,
405 switch (mbuf->byte_order)
407 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
408 data = GINT32_TO_BE (data);
410 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
411 data = GINT32_TO_LE (data);
413 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
418 return g_memory_buffer_write (mbuf, &data, 4);
422 g_memory_buffer_put_uint32 (GMemoryBuffer *mbuf,
425 switch (mbuf->byte_order)
427 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
428 data = GUINT32_TO_BE (data);
430 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
431 data = GUINT32_TO_LE (data);
433 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
438 return g_memory_buffer_write (mbuf, &data, 4);
442 g_memory_buffer_put_int64 (GMemoryBuffer *mbuf,
445 switch (mbuf->byte_order)
447 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
448 data = GINT64_TO_BE (data);
450 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
451 data = GINT64_TO_LE (data);
453 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
458 return g_memory_buffer_write (mbuf, &data, 8);
462 g_memory_buffer_put_uint64 (GMemoryBuffer *mbuf,
465 switch (mbuf->byte_order)
467 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
468 data = GUINT64_TO_BE (data);
470 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
471 data = GUINT64_TO_LE (data);
473 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
478 return g_memory_buffer_write (mbuf, &data, 8);
482 g_memory_buffer_put_string (GMemoryBuffer *mbuf,
485 g_return_val_if_fail (str != NULL, FALSE);
487 return g_memory_buffer_write (mbuf, str, strlen (str));
492 * SECTION:gdbusmessage
493 * @short_description: D-Bus Message
494 * @include: gio/gio.h
496 * A type for representing D-Bus messages that can be sent or received
497 * on a #GDBusConnection.
500 typedef struct _GDBusMessageClass GDBusMessageClass;
505 * Class structure for #GDBusMessage.
509 struct _GDBusMessageClass
512 GObjectClass parent_class;
518 * The #GDBusMessage structure contains only private data and should
519 * only be accessed using the provided API.
526 GObject parent_instance;
528 GDBusMessageType type;
529 GDBusMessageFlags flags;
531 GDBusMessageByteOrder byte_order;
532 guchar major_protocol_version;
537 GUnixFDList *fd_list;
547 G_DEFINE_TYPE (GDBusMessage, g_dbus_message, G_TYPE_OBJECT);
550 g_dbus_message_finalize (GObject *object)
552 GDBusMessage *message = G_DBUS_MESSAGE (object);
554 if (message->headers != NULL)
555 g_hash_table_unref (message->headers);
556 if (message->body != NULL)
557 g_variant_unref (message->body);
559 if (message->fd_list != NULL)
560 g_object_unref (message->fd_list);
563 if (G_OBJECT_CLASS (g_dbus_message_parent_class)->finalize != NULL)
564 G_OBJECT_CLASS (g_dbus_message_parent_class)->finalize (object);
568 g_dbus_message_get_property (GObject *object,
573 GDBusMessage *message = G_DBUS_MESSAGE (object);
578 g_value_set_boolean (value, g_dbus_message_get_locked (message));
582 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
588 g_dbus_message_class_init (GDBusMessageClass *klass)
590 GObjectClass *gobject_class;
592 gobject_class = G_OBJECT_CLASS (klass);
593 gobject_class->finalize = g_dbus_message_finalize;
594 gobject_class->get_property = g_dbus_message_get_property;
597 * GDBusConnection:locked:
599 * A boolean specifying whether the message is locked.
603 g_object_class_install_property (gobject_class,
605 g_param_spec_boolean ("locked",
607 P_("Whether the message is locked"),
610 G_PARAM_STATIC_NAME |
611 G_PARAM_STATIC_BLURB |
612 G_PARAM_STATIC_NICK));
616 g_dbus_message_init (GDBusMessage *message)
618 /* Any D-Bus implementation is supposed to handle both Big and
619 * Little Endian encodings and the Endianness is part of the D-Bus
620 * message - we prefer to use Big Endian (since it's Network Byte
621 * Order and just easier to read for humans) but if the machine is
622 * Little Endian we use that for performance reasons.
624 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
625 message->byte_order = G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN;
627 /* this could also be G_PDP_ENDIAN */
628 message->byte_order = G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN;
630 message->headers = g_hash_table_new_full (g_direct_hash,
633 (GDestroyNotify) g_variant_unref);
637 * g_dbus_message_new:
639 * Creates a new empty #GDBusMessage.
641 * Returns: A #GDBusMessage. Free with g_object_unref().
646 g_dbus_message_new (void)
648 return g_object_new (G_TYPE_DBUS_MESSAGE, NULL);
652 * g_dbus_message_new_method_call:
653 * @name: (allow-none): A valid D-Bus name or %NULL.
654 * @path: A valid object path.
655 * @interface_: (allow-none): A valid D-Bus interface name or %NULL.
656 * @method: A valid method name.
658 * Creates a new #GDBusMessage for a method call.
660 * Returns: A #GDBusMessage. Free with g_object_unref().
665 g_dbus_message_new_method_call (const gchar *name,
667 const gchar *interface_,
670 GDBusMessage *message;
672 g_return_val_if_fail (name == NULL || g_dbus_is_name (name), NULL);
673 g_return_val_if_fail (g_variant_is_object_path (path), NULL);
674 g_return_val_if_fail (g_dbus_is_member_name (method), NULL);
675 g_return_val_if_fail (interface_ == NULL || g_dbus_is_interface_name (interface_), NULL);
677 message = g_dbus_message_new ();
678 message->type = G_DBUS_MESSAGE_TYPE_METHOD_CALL;
681 g_dbus_message_set_destination (message, name);
682 g_dbus_message_set_path (message, path);
683 g_dbus_message_set_member (message, method);
684 if (interface_ != NULL)
685 g_dbus_message_set_interface (message, interface_);
691 * g_dbus_message_new_signal:
692 * @path: A valid object path.
693 * @interface_: A valid D-Bus interface name.
694 * @signal: A valid signal name.
696 * Creates a new #GDBusMessage for a signal emission.
698 * Returns: A #GDBusMessage. Free with g_object_unref().
703 g_dbus_message_new_signal (const gchar *path,
704 const gchar *interface_,
707 GDBusMessage *message;
709 g_return_val_if_fail (g_variant_is_object_path (path), NULL);
710 g_return_val_if_fail (g_dbus_is_member_name (signal), NULL);
711 g_return_val_if_fail (g_dbus_is_interface_name (interface_), NULL);
713 message = g_dbus_message_new ();
714 message->type = G_DBUS_MESSAGE_TYPE_SIGNAL;
715 message->flags = G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED;
717 g_dbus_message_set_path (message, path);
718 g_dbus_message_set_member (message, signal);
719 g_dbus_message_set_interface (message, interface_);
726 * g_dbus_message_new_method_reply:
727 * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to
728 * create a reply message to.
730 * Creates a new #GDBusMessage that is a reply to @method_call_message.
732 * Returns: (transfer full): #GDBusMessage. Free with g_object_unref().
737 g_dbus_message_new_method_reply (GDBusMessage *method_call_message)
739 GDBusMessage *message;
742 g_return_val_if_fail (G_IS_DBUS_MESSAGE (method_call_message), NULL);
743 g_return_val_if_fail (g_dbus_message_get_message_type (method_call_message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL, NULL);
744 g_return_val_if_fail (g_dbus_message_get_serial (method_call_message) != 0, NULL);
746 message = g_dbus_message_new ();
747 message->type = G_DBUS_MESSAGE_TYPE_METHOD_RETURN;
748 message->flags = G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED;
749 /* reply with same endianness */
750 message->byte_order = method_call_message->byte_order;
752 g_dbus_message_set_reply_serial (message, g_dbus_message_get_serial (method_call_message));
753 sender = g_dbus_message_get_sender (method_call_message);
755 g_dbus_message_set_destination (message, sender);
761 * g_dbus_message_new_method_error:
762 * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to
763 * create a reply message to.
764 * @error_name: A valid D-Bus error name.
765 * @error_message_format: The D-Bus error message in a printf() format.
766 * @...: Arguments for @error_message_format.
768 * Creates a new #GDBusMessage that is an error reply to @method_call_message.
770 * Returns: (transfer full): A #GDBusMessage. Free with g_object_unref().
775 g_dbus_message_new_method_error (GDBusMessage *method_call_message,
776 const gchar *error_name,
777 const gchar *error_message_format,
783 va_start (var_args, error_message_format);
784 ret = g_dbus_message_new_method_error_valist (method_call_message,
786 error_message_format,
794 * g_dbus_message_new_method_error_literal:
795 * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to
796 * create a reply message to.
797 * @error_name: A valid D-Bus error name.
798 * @error_message: The D-Bus error message.
800 * Creates a new #GDBusMessage that is an error reply to @method_call_message.
802 * Returns: (transfer full): A #GDBusMessage. Free with g_object_unref().
807 g_dbus_message_new_method_error_literal (GDBusMessage *method_call_message,
808 const gchar *error_name,
809 const gchar *error_message)
811 GDBusMessage *message;
814 g_return_val_if_fail (G_IS_DBUS_MESSAGE (method_call_message), NULL);
815 g_return_val_if_fail (g_dbus_message_get_message_type (method_call_message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL, NULL);
816 g_return_val_if_fail (g_dbus_message_get_serial (method_call_message) != 0, NULL);
817 g_return_val_if_fail (g_dbus_is_name (error_name), NULL);
818 g_return_val_if_fail (error_message != NULL, NULL);
820 message = g_dbus_message_new ();
821 message->type = G_DBUS_MESSAGE_TYPE_ERROR;
822 message->flags = G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED;
823 /* reply with same endianness */
824 message->byte_order = method_call_message->byte_order;
826 g_dbus_message_set_reply_serial (message, g_dbus_message_get_serial (method_call_message));
827 g_dbus_message_set_error_name (message, error_name);
828 g_dbus_message_set_body (message, g_variant_new ("(s)", error_message));
830 sender = g_dbus_message_get_sender (method_call_message);
832 g_dbus_message_set_destination (message, sender);
838 * g_dbus_message_new_method_error_valist:
839 * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to
840 * create a reply message to.
841 * @error_name: A valid D-Bus error name.
842 * @error_message_format: The D-Bus error message in a printf() format.
843 * @var_args: Arguments for @error_message_format.
845 * Like g_dbus_message_new_method_error() but intended for language bindings.
847 * Returns: (transfer full): A #GDBusMessage. Free with g_object_unref().
852 g_dbus_message_new_method_error_valist (GDBusMessage *method_call_message,
853 const gchar *error_name,
854 const gchar *error_message_format,
858 gchar *error_message;
859 error_message = g_strdup_vprintf (error_message_format, var_args);
860 ret = g_dbus_message_new_method_error_literal (method_call_message,
863 g_free (error_message);
867 /* ---------------------------------------------------------------------------------------------------- */
870 * g_dbus_message_get_byte_order:
871 * @message: A #GDBusMessage.
873 * Gets the byte order of @message.
875 * Returns: The byte order.
877 GDBusMessageByteOrder
878 g_dbus_message_get_byte_order (GDBusMessage *message)
880 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), (GDBusMessageByteOrder) 0);
881 return message->byte_order;
885 * g_dbus_message_set_byte_order:
886 * @message: A #GDBusMessage.
887 * @byte_order: The byte order.
889 * Sets the byte order of @message.
892 g_dbus_message_set_byte_order (GDBusMessage *message,
893 GDBusMessageByteOrder byte_order)
895 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
899 g_warning ("%s: Attempted to modify a locked message", G_STRFUNC);
903 message->byte_order = byte_order;
906 /* ---------------------------------------------------------------------------------------------------- */
908 /* TODO: need GI annotations to specify that any guchar value goes for the type */
911 * g_dbus_message_get_message_type:
912 * @message: A #GDBusMessage.
914 * Gets the type of @message.
916 * Returns: A 8-bit unsigned integer (typically a value from the #GDBusMessageType enumeration).
921 g_dbus_message_get_message_type (GDBusMessage *message)
923 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), G_DBUS_MESSAGE_TYPE_INVALID);
924 return message->type;
928 * g_dbus_message_set_message_type:
929 * @message: A #GDBusMessage.
930 * @type: A 8-bit unsigned integer (typically a value from the #GDBusMessageType enumeration).
932 * Sets @message to be of @type.
937 g_dbus_message_set_message_type (GDBusMessage *message,
938 GDBusMessageType type)
940 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
941 g_return_if_fail (type >=0 && type < 256);
945 g_warning ("%s: Attempted to modify a locked message", G_STRFUNC);
949 message->type = type;
952 /* ---------------------------------------------------------------------------------------------------- */
954 /* TODO: need GI annotations to specify that any guchar value goes for flags */
957 * g_dbus_message_get_flags:
958 * @message: A #GDBusMessage.
960 * Gets the flags for @message.
962 * Returns: Flags that are set (typically values from the #GDBusMessageFlags enumeration bitwise ORed together).
967 g_dbus_message_get_flags (GDBusMessage *message)
969 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), G_DBUS_MESSAGE_FLAGS_NONE);
970 return message->flags;
974 * g_dbus_message_set_flags:
975 * @message: A #GDBusMessage.
976 * @flags: Flags for @message that are set (typically values from the #GDBusMessageFlags
977 * enumeration bitwise ORed together).
979 * Sets the flags to set on @message.
984 g_dbus_message_set_flags (GDBusMessage *message,
985 GDBusMessageFlags flags)
987 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
988 g_return_if_fail (flags >=0 && flags < 256);
992 g_warning ("%s: Attempted to modify a locked message", G_STRFUNC);
996 message->flags = flags;
999 /* ---------------------------------------------------------------------------------------------------- */
1002 * g_dbus_message_get_serial:
1003 * @message: A #GDBusMessage.
1005 * Gets the serial for @message.
1007 * Returns: A #guint32.
1012 g_dbus_message_get_serial (GDBusMessage *message)
1014 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), 0);
1015 return message->serial;
1019 * g_dbus_message_set_serial:
1020 * @message: A #GDBusMessage.
1021 * @serial: A #guint32.
1023 * Sets the serial for @message.
1028 g_dbus_message_set_serial (GDBusMessage *message,
1031 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
1033 if (message->locked)
1035 g_warning ("%s: Attempted to modify a locked message", G_STRFUNC);
1039 message->serial = serial;
1042 /* ---------------------------------------------------------------------------------------------------- */
1044 /* TODO: need GI annotations to specify that any guchar value goes for header_field */
1047 * g_dbus_message_get_header:
1048 * @message: A #GDBusMessage.
1049 * @header_field: A 8-bit unsigned integer (typically a value from the #GDBusMessageHeaderField enumeration)
1051 * Gets a header field on @message.
1053 * Returns: A #GVariant with the value if the header was found, %NULL
1054 * otherwise. Do not free, it is owned by @message.
1059 g_dbus_message_get_header (GDBusMessage *message,
1060 GDBusMessageHeaderField header_field)
1062 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
1063 g_return_val_if_fail (header_field >=0 && header_field < 256, NULL);
1064 return g_hash_table_lookup (message->headers, GUINT_TO_POINTER (header_field));
1068 * g_dbus_message_set_header:
1069 * @message: A #GDBusMessage.
1070 * @header_field: A 8-bit unsigned integer (typically a value from the #GDBusMessageHeaderField enumeration)
1071 * @value: (allow-none): A #GVariant to set the header field or %NULL to clear the header field.
1073 * Sets a header field on @message.
1075 * If @value is floating, @message assumes ownership of @value.
1080 g_dbus_message_set_header (GDBusMessage *message,
1081 GDBusMessageHeaderField header_field,
1084 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
1085 g_return_if_fail (header_field >=0 && header_field < 256);
1087 if (message->locked)
1089 g_warning ("%s: Attempted to modify a locked message", G_STRFUNC);
1095 g_hash_table_remove (message->headers, GUINT_TO_POINTER (header_field));
1099 g_hash_table_insert (message->headers, GUINT_TO_POINTER (header_field), g_variant_ref_sink (value));
1104 * g_dbus_message_get_header_fields:
1105 * @message: A #GDBusMessage.
1107 * Gets an array of all header fields on @message that are set.
1109 * Returns: (array zero-terminated=1): An array of header fields
1110 * terminated by %G_DBUS_MESSAGE_HEADER_FIELD_INVALID. Each element
1111 * is a #guchar. Free with g_free().
1116 g_dbus_message_get_header_fields (GDBusMessage *message)
1124 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
1126 keys = g_hash_table_get_keys (message->headers);
1127 num_keys = g_list_length (keys);
1128 ret = g_new (guchar, num_keys + 1);
1129 for (l = keys, n = 0; l != NULL; l = l->next, n++)
1130 ret[n] = GPOINTER_TO_UINT (l->data);
1131 g_assert (n == num_keys);
1132 ret[n] = G_DBUS_MESSAGE_HEADER_FIELD_INVALID;
1138 /* ---------------------------------------------------------------------------------------------------- */
1141 * g_dbus_message_get_body:
1142 * @message: A #GDBusMessage.
1144 * Gets the body of a message.
1146 * Returns: A #GVariant or %NULL if the body is empty. Do not free, it is owned by @message.
1151 g_dbus_message_get_body (GDBusMessage *message)
1153 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
1154 return message->body;
1158 * g_dbus_message_set_body:
1159 * @message: A #GDBusMessage.
1160 * @body: Either %NULL or a #GVariant that is a tuple.
1162 * Sets the body @message. As a side-effect the
1163 * %G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE header field is set to the
1164 * type string of @body (or cleared if @body is %NULL).
1166 * If @body is floating, @message assumes ownership of @body.
1171 g_dbus_message_set_body (GDBusMessage *message,
1174 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
1175 g_return_if_fail ((body == NULL) || g_variant_is_of_type (body, G_VARIANT_TYPE_TUPLE));
1177 if (message->locked)
1179 g_warning ("%s: Attempted to modify a locked message", G_STRFUNC);
1183 if (message->body != NULL)
1184 g_variant_unref (message->body);
1187 message->body = NULL;
1188 g_dbus_message_set_signature (message, NULL);
1192 const gchar *type_string;
1193 gsize type_string_len;
1196 message->body = g_variant_ref_sink (body);
1198 type_string = g_variant_get_type_string (body);
1199 type_string_len = strlen (type_string);
1200 g_assert (type_string_len >= 2);
1201 signature = g_strndup (type_string + 1, type_string_len - 2);
1202 g_dbus_message_set_signature (message, signature);
1207 /* ---------------------------------------------------------------------------------------------------- */
1211 * g_dbus_message_get_unix_fd_list:
1212 * @message: A #GDBusMessage.
1214 * Gets the UNIX file descriptors associated with @message, if any.
1216 * This method is only available on UNIX.
1218 * Returns: (transfer none):A #GUnixFDList or %NULL if no file descriptors are
1219 * associated. Do not free, this object is owned by @message.
1224 g_dbus_message_get_unix_fd_list (GDBusMessage *message)
1226 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
1227 return message->fd_list;
1231 * g_dbus_message_set_unix_fd_list:
1232 * @message: A #GDBusMessage.
1233 * @fd_list: (allow-none): A #GUnixFDList or %NULL.
1235 * Sets the UNIX file descriptors associated with @message. As a
1236 * side-effect the %G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS header
1237 * field is set to the number of fds in @fd_list (or cleared if
1238 * @fd_list is %NULL).
1240 * This method is only available on UNIX.
1245 g_dbus_message_set_unix_fd_list (GDBusMessage *message,
1246 GUnixFDList *fd_list)
1248 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
1249 g_return_if_fail (fd_list == NULL || G_IS_UNIX_FD_LIST (fd_list));
1251 if (message->locked)
1253 g_warning ("%s: Attempted to modify a locked message", G_STRFUNC);
1257 if (message->fd_list != NULL)
1258 g_object_unref (message->fd_list);
1259 if (fd_list != NULL)
1261 message->fd_list = g_object_ref (fd_list);
1262 g_dbus_message_set_num_unix_fds (message, g_unix_fd_list_get_length (fd_list));
1266 message->fd_list = NULL;
1267 g_dbus_message_set_num_unix_fds (message, 0);
1272 /* ---------------------------------------------------------------------------------------------------- */
1275 validate_headers (GDBusMessage *message,
1280 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), FALSE);
1281 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1285 switch (message->type)
1287 case G_DBUS_MESSAGE_TYPE_INVALID:
1288 g_set_error_literal (error,
1290 G_IO_ERROR_INVALID_ARGUMENT,
1291 _("type is INVALID"));
1295 case G_DBUS_MESSAGE_TYPE_METHOD_CALL:
1296 if (g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH) == NULL ||
1297 g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER) == NULL)
1299 g_set_error_literal (error,
1301 G_IO_ERROR_INVALID_ARGUMENT,
1302 _("METHOD_CALL message: PATH or MEMBER header field is missing"));
1307 case G_DBUS_MESSAGE_TYPE_METHOD_RETURN:
1308 if (g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL) == NULL)
1310 g_set_error_literal (error,
1312 G_IO_ERROR_INVALID_ARGUMENT,
1313 _("METHOD_RETURN message: REPLY_SERIAL header field is missing"));
1318 case G_DBUS_MESSAGE_TYPE_ERROR:
1319 if (g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME) == NULL ||
1320 g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL) == NULL)
1322 g_set_error_literal (error,
1324 G_IO_ERROR_INVALID_ARGUMENT,
1325 _("ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing"));
1330 case G_DBUS_MESSAGE_TYPE_SIGNAL:
1331 if (g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH) == NULL ||
1332 g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE) == NULL ||
1333 g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER) == NULL)
1335 g_set_error_literal (error,
1337 G_IO_ERROR_INVALID_ARGUMENT,
1338 _("SIGNAL message: PATH, INTERFACE or MEMBER header field is missing"));
1341 if (g_strcmp0 (g_dbus_message_get_path (message), "/org/freedesktop/DBus/Local") == 0)
1343 g_set_error_literal (error,
1345 G_IO_ERROR_INVALID_ARGUMENT,
1346 _("SIGNAL message: The PATH header field is using the reserved value /org/freedesktop/DBus/Local"));
1349 if (g_strcmp0 (g_dbus_message_get_interface (message), "org.freedesktop.DBus.Local") == 0)
1351 g_set_error_literal (error,
1353 G_IO_ERROR_INVALID_ARGUMENT,
1354 _("SIGNAL message: The INTERFACE header field is using the reserved value org.freedesktop.DBus.Local"));
1360 /* hitherto unknown type - nothing to check */
1367 g_assert (ret || (error == NULL || *error != NULL));
1371 /* ---------------------------------------------------------------------------------------------------- */
1374 ensure_input_padding (GMemoryBuffer *buf,
1379 gsize wanted_offset;
1382 wanted_offset = ((offset + padding_size - 1) / padding_size) * padding_size;
1383 buf->pos = wanted_offset;
1388 read_string (GMemoryBuffer *mbuf,
1394 GError *local_error;
1395 const gchar *end_valid;
1399 str = g_malloc (len + 1);
1401 num_read = g_memory_buffer_read (mbuf,
1409 /* G_GSIZE_FORMAT doesn't work with gettext, so we use %lu */
1412 G_IO_ERROR_INVALID_ARGUMENT,
1413 g_dngettext (GETTEXT_PACKAGE,
1414 "Wanted to read %lu bytes but only got %lu",
1415 "Wanted to read %lu byte but only got %lu",
1422 memcpy (str, ptr, len);
1424 nul = g_memory_buffer_read_byte (mbuf, &local_error);
1425 if (local_error != NULL)
1427 g_propagate_error (error, local_error);
1430 str[num_read] = '\0';
1431 if (!g_utf8_validate (str, -1, &end_valid))
1435 offset = (gint) (end_valid - str);
1436 valid_str = g_strndup (str, offset);
1439 G_IO_ERROR_INVALID_ARGUMENT,
1440 _("Expected valid UTF-8 string but found invalid bytes at byte offset %d (length of string is %d). "
1441 "The valid UTF-8 string up until that point was `%s'"),
1452 G_IO_ERROR_INVALID_ARGUMENT,
1453 _("Expected NUL byte after the string `%s' but found byte %d"),
1465 /* if just_align==TRUE, don't read a value, just align the input stream wrt padding */
1467 /* returns a non-floating GVariant! */
1469 parse_value_from_blob (GMemoryBuffer *buf,
1470 const GVariantType *type,
1471 gboolean just_align,
1476 GError *local_error;
1478 const gchar *type_string;
1480 type_string = g_variant_type_peek_string (type);
1482 #ifdef DEBUG_SERIALIZER
1485 s = g_variant_type_dup_string (type);
1486 g_print ("%*s%s type %s from offset 0x%04x",
1488 just_align ? "Aligning" : "Reading",
1490 (gint) g_seekable_tell (G_SEEKABLE (buf)));
1493 #endif /* DEBUG_SERIALIZER */
1499 switch (type_string[0])
1501 case 'b': /* G_VARIANT_TYPE_BOOLEAN */
1502 if (!ensure_input_padding (buf, 4, &local_error))
1507 v = g_memory_buffer_read_uint32 (buf, &local_error);
1508 if (local_error != NULL)
1510 ret = g_variant_new_boolean (v);
1514 case 'y': /* G_VARIANT_TYPE_BYTE */
1518 v = g_memory_buffer_read_byte (buf, &local_error);
1519 if (local_error != NULL)
1521 ret = g_variant_new_byte (v);
1525 case 'n': /* G_VARIANT_TYPE_INT16 */
1526 if (!ensure_input_padding (buf, 2, &local_error))
1531 v = g_memory_buffer_read_int16 (buf, &local_error);
1532 if (local_error != NULL)
1534 ret = g_variant_new_int16 (v);
1538 case 'q': /* G_VARIANT_TYPE_UINT16 */
1539 if (!ensure_input_padding (buf, 2, &local_error))
1544 v = g_memory_buffer_read_uint16 (buf, &local_error);
1545 if (local_error != NULL)
1547 ret = g_variant_new_uint16 (v);
1551 case 'i': /* G_VARIANT_TYPE_INT32 */
1552 if (!ensure_input_padding (buf, 4, &local_error))
1557 v = g_memory_buffer_read_int32 (buf, &local_error);
1558 if (local_error != NULL)
1560 ret = g_variant_new_int32 (v);
1564 case 'u': /* G_VARIANT_TYPE_UINT32 */
1565 if (!ensure_input_padding (buf, 4, &local_error))
1570 v = g_memory_buffer_read_uint32 (buf, &local_error);
1571 if (local_error != NULL)
1573 ret = g_variant_new_uint32 (v);
1577 case 'x': /* G_VARIANT_TYPE_INT64 */
1578 if (!ensure_input_padding (buf, 8, &local_error))
1583 v = g_memory_buffer_read_int64 (buf, &local_error);
1584 if (local_error != NULL)
1586 ret = g_variant_new_int64 (v);
1590 case 't': /* G_VARIANT_TYPE_UINT64 */
1591 if (!ensure_input_padding (buf, 8, &local_error))
1596 v = g_memory_buffer_read_uint64 (buf, &local_error);
1597 if (local_error != NULL)
1599 ret = g_variant_new_uint64 (v);
1603 case 'd': /* G_VARIANT_TYPE_DOUBLE */
1604 if (!ensure_input_padding (buf, 8, &local_error))
1612 G_STATIC_ASSERT (sizeof (gdouble) == sizeof (guint64));
1613 u.v_uint64 = g_memory_buffer_read_uint64 (buf, &local_error);
1614 if (local_error != NULL)
1616 ret = g_variant_new_double (u.v_double);
1620 case 's': /* G_VARIANT_TYPE_STRING */
1621 if (!ensure_input_padding (buf, 4, &local_error))
1627 len = g_memory_buffer_read_uint32 (buf, &local_error);
1628 if (local_error != NULL)
1630 v = read_string (buf, (gsize) len, &local_error);
1633 ret = g_variant_new_string (v);
1638 case 'o': /* G_VARIANT_TYPE_OBJECT_PATH */
1639 if (!ensure_input_padding (buf, 4, &local_error))
1645 len = g_memory_buffer_read_uint32 (buf, &local_error);
1646 if (local_error != NULL)
1648 v = read_string (buf, (gsize) len, &local_error);
1651 if (!g_variant_is_object_path (v))
1653 g_set_error (&local_error,
1655 G_IO_ERROR_INVALID_ARGUMENT,
1656 _("Parsed value `%s' is not a valid D-Bus object path"),
1661 ret = g_variant_new_object_path (v);
1666 case 'g': /* G_VARIANT_TYPE_SIGNATURE */
1671 len = g_memory_buffer_read_byte (buf, &local_error);
1672 if (local_error != NULL)
1674 v = read_string (buf, (gsize) len, &local_error);
1677 if (!g_variant_is_signature (v))
1679 g_set_error (&local_error,
1681 G_IO_ERROR_INVALID_ARGUMENT,
1682 _("Parsed value `%s' is not a valid D-Bus signature"),
1687 ret = g_variant_new_signature (v);
1692 case 'h': /* G_VARIANT_TYPE_HANDLE */
1693 if (!ensure_input_padding (buf, 4, &local_error))
1698 v = g_memory_buffer_read_int32 (buf, &local_error);
1699 if (local_error != NULL)
1701 ret = g_variant_new_handle (v);
1705 case 'a': /* G_VARIANT_TYPE_ARRAY */
1706 if (!ensure_input_padding (buf, 4, &local_error))
1709 /* If we are only aligning for this array type, it is the child type of
1710 * another array, which is empty. So, we do not need to add padding for
1711 * this nonexistent array's elements: we only need to align for this
1712 * array itself (4 bytes). See
1713 * <https://bugzilla.gnome.org/show_bug.cgi?id=673612>.
1720 const GVariantType *element_type;
1721 GVariantBuilder builder;
1723 array_len = g_memory_buffer_read_uint32 (buf, &local_error);
1724 if (local_error != NULL)
1728 #ifdef DEBUG_SERIALIZER
1729 g_print (": array spans 0x%04x bytes\n", array_len);
1730 #endif /* DEBUG_SERIALIZER */
1732 if (array_len > (2<<26))
1734 /* G_GUINT32_FORMAT doesn't work with gettext, so use u */
1735 g_set_error (&local_error,
1737 G_IO_ERROR_INVALID_ARGUMENT,
1738 g_dngettext (GETTEXT_PACKAGE,
1739 "Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB).",
1740 "Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB).",
1746 g_variant_builder_init (&builder, type);
1747 element_type = g_variant_type_element (type);
1752 item = parse_value_from_blob (buf,
1757 g_assert (item == NULL);
1761 /* TODO: optimize array of primitive types */
1763 target = offset + array_len;
1764 while (offset < target)
1767 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);
1788 if (g_variant_type_is_dict_entry (type))
1790 const GVariantType *key_type;
1791 const GVariantType *value_type;
1795 if (!ensure_input_padding (buf, 8, &local_error))
1799 #ifdef DEBUG_SERIALIZER
1801 #endif /* DEBUG_SERIALIZER */
1805 key_type = g_variant_type_key (type);
1806 key = parse_value_from_blob (buf,
1813 value_type = g_variant_type_value (type);
1814 value = parse_value_from_blob (buf,
1821 g_variant_unref (key);
1824 ret = g_variant_new_dict_entry (key, value);
1825 g_variant_unref (key);
1826 g_variant_unref (value);
1829 else if (g_variant_type_is_tuple (type))
1831 if (!ensure_input_padding (buf, 8, &local_error))
1835 #ifdef DEBUG_SERIALIZER
1837 #endif /* DEBUG_SERIALIZER */
1841 const GVariantType *element_type;
1842 GVariantBuilder builder;
1844 g_variant_builder_init (&builder, type);
1845 element_type = g_variant_type_first (type);
1846 while (element_type != NULL)
1849 item = parse_value_from_blob (buf,
1856 g_variant_builder_clear (&builder);
1859 g_variant_builder_add_value (&builder, item);
1860 g_variant_unref (item);
1862 element_type = g_variant_type_next (element_type);
1864 ret = g_variant_builder_end (&builder);
1867 else if (g_variant_type_is_variant (type))
1870 #ifdef DEBUG_SERIALIZER
1872 #endif /* DEBUG_SERIALIZER */
1878 GVariantType *variant_type;
1881 siglen = g_memory_buffer_read_byte (buf, &local_error);
1882 if (local_error != NULL)
1884 sig = read_string (buf, (gsize) siglen, &local_error);
1887 if (!g_variant_is_signature (sig))
1889 g_set_error (&local_error,
1891 G_IO_ERROR_INVALID_ARGUMENT,
1892 _("Parsed value `%s' for variant is not a valid D-Bus signature"),
1897 variant_type = g_variant_type_new (sig);
1899 value = parse_value_from_blob (buf,
1904 g_variant_type_free (variant_type);
1907 ret = g_variant_new_variant (value);
1908 g_variant_unref (value);
1914 s = g_variant_type_dup_string (type);
1915 g_set_error (&local_error,
1917 G_IO_ERROR_INVALID_ARGUMENT,
1918 _("Error deserializing GVariant with type string `%s' from the D-Bus wire format"),
1926 g_assert ((just_align && ret == NULL) || (!just_align && ret != NULL));
1928 #ifdef DEBUG_SERIALIZER
1934 if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
1936 s = g_strdup_printf ("0x%02x '%c'", g_variant_get_byte (ret), g_variant_get_byte (ret));
1940 s = g_variant_print (ret, FALSE);
1942 g_print (": %s\n", s);
1947 is_leaf = is_leaf; /* To avoid -Wunused-but-set-variable */
1948 #endif /* DEBUG_SERIALIZER */
1950 /* sink the reference */
1953 g_assert (g_variant_is_floating (ret));
1954 g_variant_ref_sink (ret);
1959 #ifdef DEBUG_SERIALIZER
1961 "%*sFAILURE: %s (%s, %d)\n",
1963 local_error->message,
1964 g_quark_to_string (local_error->domain),
1966 #endif /* DEBUG_SERIALIZER */
1967 g_propagate_error (error, local_error);
1971 /* ---------------------------------------------------------------------------------------------------- */
1973 /* message_header must be at least 16 bytes */
1976 * g_dbus_message_bytes_needed:
1977 * @blob: (array length=blob_len) (element-type guint8): A blob represent a binary D-Bus message.
1978 * @blob_len: The length of @blob (must be at least 16).
1979 * @error: Return location for error or %NULL.
1981 * Utility function to calculate how many bytes are needed to
1982 * completely deserialize the D-Bus message stored at @blob.
1984 * Returns: Number of bytes needed or -1 if @error is set (e.g. if
1985 * @blob contains invalid data or not enough data is available to
1986 * determine the size).
1991 g_dbus_message_bytes_needed (guchar *blob,
1999 g_return_val_if_fail (blob != NULL, -1);
2000 g_return_val_if_fail (error == NULL || *error == NULL, -1);
2001 g_return_val_if_fail (blob_len >= 16, -1);
2005 /* core header (12 bytes) + ARRAY of STRUCT of (BYTE,VARIANT) */
2006 ret = 12 + 4 + GUINT32_FROM_LE (((guint32 *) blob)[3]);
2007 /* round up so it's a multiple of 8 */
2008 ret = 8 * ((ret + 7)/8);
2009 /* finally add the body size */
2010 ret += GUINT32_FROM_LE (((guint32 *) blob)[1]);
2012 else if (blob[0] == 'B')
2014 /* core header (12 bytes) + ARRAY of STRUCT of (BYTE,VARIANT) */
2015 ret = 12 + 4 + GUINT32_FROM_BE (((guint32 *) blob)[3]);
2016 /* round up so it's a multiple of 8 */
2017 ret = 8 * ((ret + 7)/8);
2018 /* finally add the body size */
2019 ret += GUINT32_FROM_BE (((guint32 *) blob)[1]);
2025 G_IO_ERROR_INVALID_ARGUMENT,
2026 "Unable to determine message blob length - given blob is malformed");
2033 G_IO_ERROR_INVALID_ARGUMENT,
2034 "Blob indicates that message exceeds maximum message length (128MiB)");
2041 /* ---------------------------------------------------------------------------------------------------- */
2044 * g_dbus_message_new_from_blob:
2045 * @blob: (array length=blob_len) (element-type guint8): A blob represent a binary D-Bus message.
2046 * @blob_len: The length of @blob.
2047 * @capabilities: A #GDBusCapabilityFlags describing what protocol features are supported.
2048 * @error: Return location for error or %NULL.
2050 * Creates a new #GDBusMessage from the data stored at @blob. The byte
2051 * order that the message was in can be retrieved using
2052 * g_dbus_message_get_byte_order().
2054 * Returns: A new #GDBusMessage or %NULL if @error is set. Free with
2060 g_dbus_message_new_from_blob (guchar *blob,
2062 GDBusCapabilityFlags capabilities,
2067 GDBusMessage *message;
2069 guchar major_protocol_version;
2070 guint32 message_body_len;
2074 GVariant *signature;
2076 /* TODO: check against @capabilities */
2080 g_return_val_if_fail (blob != NULL, NULL);
2081 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
2082 g_return_val_if_fail (blob_len >= 12, NULL);
2084 message = g_dbus_message_new ();
2086 memset (&mbuf, 0, sizeof (mbuf));
2087 mbuf.data = (gchar *)blob;
2088 mbuf.len = mbuf.valid_len = blob_len;
2090 endianness = g_memory_buffer_read_byte (&mbuf, NULL);
2094 mbuf.byte_order = G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN;
2095 message->byte_order = G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN;
2098 mbuf.byte_order = G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN;
2099 message->byte_order = G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN;
2104 G_IO_ERROR_INVALID_ARGUMENT,
2105 _("Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value 0x%02x"),
2110 message->type = g_memory_buffer_read_byte (&mbuf, NULL);
2111 message->flags = g_memory_buffer_read_byte (&mbuf, NULL);
2112 major_protocol_version = g_memory_buffer_read_byte (&mbuf, NULL);
2113 if (major_protocol_version != 1)
2117 G_IO_ERROR_INVALID_ARGUMENT,
2118 _("Invalid major protocol version. Expected 1 but found %d"),
2119 major_protocol_version);
2122 message_body_len = g_memory_buffer_read_uint32 (&mbuf, NULL);
2123 message->serial = g_memory_buffer_read_uint32 (&mbuf, NULL);
2125 #ifdef DEBUG_SERIALIZER
2126 g_print ("Parsing blob (blob_len = 0x%04x bytes)\n", (gint) blob_len);
2129 s = _g_dbus_hexdump ((const gchar *) blob, blob_len, 2);
2130 g_print ("%s\n", s);
2133 #endif /* DEBUG_SERIALIZER */
2135 #ifdef DEBUG_SERIALIZER
2136 g_print ("Parsing headers (blob_len = 0x%04x bytes)\n", (gint) blob_len);
2137 #endif /* DEBUG_SERIALIZER */
2138 headers = parse_value_from_blob (&mbuf,
2139 G_VARIANT_TYPE ("a{yv}"),
2143 if (headers == NULL)
2145 g_variant_iter_init (&iter, headers);
2146 while ((item = g_variant_iter_next_value (&iter)) != NULL)
2148 guchar header_field;
2150 g_variant_get (item,
2154 g_dbus_message_set_header (message, header_field, value);
2155 g_variant_unref (value);
2156 g_variant_unref (item);
2158 g_variant_unref (headers);
2160 signature = g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE);
2161 if (signature != NULL)
2163 const gchar *signature_str;
2164 gsize signature_str_len;
2166 signature_str = g_variant_get_string (signature, &signature_str_len);
2168 /* signature but no body */
2169 if (message_body_len == 0 && signature_str_len > 0)
2173 G_IO_ERROR_INVALID_ARGUMENT,
2174 _("Signature header with signature `%s' found but message body is empty"),
2178 else if (signature_str_len > 0)
2180 GVariantType *variant_type;
2181 gchar *tupled_signature_str;
2183 if (!g_variant_is_signature (signature_str))
2187 G_IO_ERROR_INVALID_ARGUMENT,
2188 _("Parsed value `%s' is not a valid D-Bus signature (for body)"),
2192 tupled_signature_str = g_strdup_printf ("(%s)", signature_str);
2193 variant_type = g_variant_type_new (tupled_signature_str);
2194 g_free (tupled_signature_str);
2195 #ifdef DEBUG_SERIALIZER
2196 g_print ("Parsing body (blob_len = 0x%04x bytes)\n", (gint) blob_len);
2197 #endif /* DEBUG_SERIALIZER */
2198 message->body = parse_value_from_blob (&mbuf,
2203 g_variant_type_free (variant_type);
2204 if (message->body == NULL)
2210 /* no signature, this is only OK if the body is empty */
2211 if (message_body_len != 0)
2213 /* G_GUINT32_FORMAT doesn't work with gettext, just use %u */
2216 G_IO_ERROR_INVALID_ARGUMENT,
2217 g_dngettext (GETTEXT_PACKAGE,
2218 "No signature header in message but the message body is %u byte",
2219 "No signature header in message but the message body is %u bytes",
2226 if (!validate_headers (message, error))
2228 g_prefix_error (error, _("Cannot deserialize message: "));
2241 if (message != NULL)
2242 g_object_unref (message);
2247 /* ---------------------------------------------------------------------------------------------------- */
2250 ensure_output_padding (GMemoryBuffer *mbuf,
2254 gsize wanted_offset;
2255 gsize padding_needed;
2259 wanted_offset = ((offset + padding_size - 1) / padding_size) * padding_size;
2260 padding_needed = wanted_offset - offset;
2262 for (n = 0; n < padding_needed; n++)
2263 g_memory_buffer_put_byte (mbuf, '\0');
2265 return padding_needed;
2268 /* note that value can be NULL for e.g. empty arrays - type is never NULL */
2270 append_value_to_blob (GVariant *value,
2271 const GVariantType *type,
2272 GMemoryBuffer *mbuf,
2273 gsize *out_padding_added,
2276 gsize padding_added;
2277 const gchar *type_string;
2279 type_string = g_variant_type_peek_string (type);
2283 switch (type_string[0])
2285 case 'b': /* G_VARIANT_TYPE_BOOLEAN */
2286 padding_added = ensure_output_padding (mbuf, 4);
2289 gboolean v = g_variant_get_boolean (value);
2290 g_memory_buffer_put_uint32 (mbuf, v);
2294 case 'y': /* G_VARIANT_TYPE_BYTE */
2297 guint8 v = g_variant_get_byte (value);
2298 g_memory_buffer_put_byte (mbuf, v);
2302 case 'n': /* G_VARIANT_TYPE_INT16 */
2303 padding_added = ensure_output_padding (mbuf, 2);
2306 gint16 v = g_variant_get_int16 (value);
2307 g_memory_buffer_put_int16 (mbuf, v);
2311 case 'q': /* G_VARIANT_TYPE_UINT16 */
2312 padding_added = ensure_output_padding (mbuf, 2);
2315 guint16 v = g_variant_get_uint16 (value);
2316 g_memory_buffer_put_uint16 (mbuf, v);
2320 case 'i': /* G_VARIANT_TYPE_INT32 */
2321 padding_added = ensure_output_padding (mbuf, 4);
2324 gint32 v = g_variant_get_int32 (value);
2325 g_memory_buffer_put_int32 (mbuf, v);
2329 case 'u': /* G_VARIANT_TYPE_UINT32 */
2330 padding_added = ensure_output_padding (mbuf, 4);
2333 guint32 v = g_variant_get_uint32 (value);
2334 g_memory_buffer_put_uint32 (mbuf, v);
2338 case 'x': /* G_VARIANT_TYPE_INT64 */
2339 padding_added = ensure_output_padding (mbuf, 8);
2342 gint64 v = g_variant_get_int64 (value);
2343 g_memory_buffer_put_int64 (mbuf, v);
2347 case 't': /* G_VARIANT_TYPE_UINT64 */
2348 padding_added = ensure_output_padding (mbuf, 8);
2351 guint64 v = g_variant_get_uint64 (value);
2352 g_memory_buffer_put_uint64 (mbuf, v);
2356 case 'd': /* G_VARIANT_TYPE_DOUBLE */
2357 padding_added = ensure_output_padding (mbuf, 8);
2364 G_STATIC_ASSERT (sizeof (gdouble) == sizeof (guint64));
2365 u.v_double = g_variant_get_double (value);
2366 g_memory_buffer_put_uint64 (mbuf, u.v_uint64);
2370 case 's': /* G_VARIANT_TYPE_STRING */
2371 padding_added = ensure_output_padding (mbuf, 4);
2377 v = g_variant_get_string (value, &len);
2378 g_assert (g_utf8_validate (v, -1, &end) && (end == v + len));
2379 g_memory_buffer_put_uint32 (mbuf, len);
2380 g_memory_buffer_put_string (mbuf, v);
2381 g_memory_buffer_put_byte (mbuf, '\0');
2385 case 'o': /* G_VARIANT_TYPE_OBJECT_PATH */
2386 padding_added = ensure_output_padding (mbuf, 4);
2390 const gchar *v = g_variant_get_string (value, &len);
2391 g_assert (g_variant_is_object_path (v));
2392 g_memory_buffer_put_uint32 (mbuf, len);
2393 g_memory_buffer_put_string (mbuf, v);
2394 g_memory_buffer_put_byte (mbuf, '\0');
2398 case 'g': /* G_VARIANT_TYPE_SIGNATURE */
2402 const gchar *v = g_variant_get_string (value, &len);
2403 g_assert (g_variant_is_signature (v));
2404 g_memory_buffer_put_byte (mbuf, len);
2405 g_memory_buffer_put_string (mbuf, v);
2406 g_memory_buffer_put_byte (mbuf, '\0');
2410 case 'h': /* G_VARIANT_TYPE_HANDLE */
2411 padding_added = ensure_output_padding (mbuf, 4);
2414 gint32 v = g_variant_get_handle (value);
2415 g_memory_buffer_put_int32 (mbuf, v);
2419 case 'a': /* G_VARIANT_TYPE_ARRAY */
2423 goffset array_len_offset;
2424 goffset array_payload_begin_offset;
2428 padding_added = ensure_output_padding (mbuf, 4);
2431 /* array length - will be filled in later */
2432 array_len_offset = mbuf->valid_len;
2433 g_memory_buffer_put_uint32 (mbuf, 0xF00DFACE);
2435 /* From the D-Bus spec:
2437 * "A UINT32 giving the length of the array data in bytes,
2438 * followed by alignment padding to the alignment boundary of
2439 * the array element type, followed by each array element. The
2440 * array length is from the end of the alignment padding to
2441 * the end of the last element, i.e. it does not include the
2442 * padding after the length, or any padding after the last
2445 * Thus, we need to count how much padding the first element
2446 * contributes and subtract that from the array length.
2448 array_payload_begin_offset = mbuf->valid_len;
2450 if (g_variant_n_children (value) == 0)
2452 gsize padding_added_for_item;
2453 if (!append_value_to_blob (NULL,
2454 g_variant_type_element (type),
2456 &padding_added_for_item,
2459 array_payload_begin_offset += padding_added_for_item;
2465 g_variant_iter_init (&iter, value);
2466 while ((item = g_variant_iter_next_value (&iter)) != NULL)
2468 gsize padding_added_for_item;
2469 if (!append_value_to_blob (item,
2470 g_variant_get_type (item),
2472 &padding_added_for_item,
2475 g_variant_unref (item);
2478 g_variant_unref (item);
2481 array_payload_begin_offset += padding_added_for_item;
2487 cur_offset = mbuf->valid_len;
2488 array_len = cur_offset - array_payload_begin_offset;
2489 mbuf->pos = array_len_offset;
2491 g_memory_buffer_put_uint32 (mbuf, array_len);
2492 mbuf->pos = cur_offset;
2498 if (g_variant_type_is_dict_entry (type) || g_variant_type_is_tuple (type))
2500 padding_added = ensure_output_padding (mbuf, 8);
2505 g_variant_iter_init (&iter, value);
2506 while ((item = g_variant_iter_next_value (&iter)) != NULL)
2508 if (!append_value_to_blob (item,
2509 g_variant_get_type (item),
2514 g_variant_unref (item);
2517 g_variant_unref (item);
2521 else if (g_variant_type_is_variant (type))
2526 const gchar *signature;
2527 child = g_variant_get_child_value (value, 0);
2528 signature = g_variant_get_type_string (child);
2529 g_memory_buffer_put_byte (mbuf, strlen (signature));
2530 g_memory_buffer_put_string (mbuf, signature);
2531 g_memory_buffer_put_byte (mbuf, '\0');
2532 if (!append_value_to_blob (child,
2533 g_variant_get_type (child),
2538 g_variant_unref (child);
2541 g_variant_unref (child);
2548 G_IO_ERROR_INVALID_ARGUMENT,
2549 _("Error serializing GVariant with type string `%s' to the D-Bus wire format"),
2550 g_variant_get_type_string (value));
2556 if (out_padding_added != NULL)
2557 *out_padding_added = padding_added;
2566 append_body_to_blob (GVariant *value,
2567 GMemoryBuffer *mbuf,
2573 if (!g_variant_is_of_type (value, G_VARIANT_TYPE_TUPLE))
2577 G_IO_ERROR_INVALID_ARGUMENT,
2578 "Expected a tuple for the body of the GDBusMessage.");
2582 g_variant_iter_init (&iter, value);
2583 while ((item = g_variant_iter_next_value (&iter)) != NULL)
2585 if (!append_value_to_blob (item,
2586 g_variant_get_type (item),
2591 g_variant_unref (item);
2594 g_variant_unref (item);
2602 /* ---------------------------------------------------------------------------------------------------- */
2605 * g_dbus_message_to_blob:
2606 * @message: A #GDBusMessage.
2607 * @out_size: Return location for size of generated blob.
2608 * @capabilities: A #GDBusCapabilityFlags describing what protocol features are supported.
2609 * @error: Return location for error.
2611 * Serializes @message to a blob. The byte order returned by
2612 * g_dbus_message_get_byte_order() will be used.
2614 * Returns: (array length=out_size) (transfer full): A pointer to a
2615 * valid binary D-Bus message of @out_size bytes generated by @message
2616 * or %NULL if @error is set. Free with g_free().
2621 g_dbus_message_to_blob (GDBusMessage *message,
2623 GDBusCapabilityFlags capabilities,
2629 goffset body_len_offset;
2630 goffset body_start_offset;
2632 GVariant *header_fields;
2633 GVariantBuilder builder;
2634 GHashTableIter hash_iter;
2636 GVariant *header_value;
2637 GVariant *signature;
2638 const gchar *signature_str;
2639 gint num_fds_in_message;
2640 gint num_fds_according_to_header;
2642 /* TODO: check against @capabilities */
2646 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2647 g_return_val_if_fail (out_size != NULL, NULL);
2648 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
2650 memset (&mbuf, 0, sizeof (mbuf));
2651 mbuf.len = MIN_ARRAY_SIZE;
2652 mbuf.data = g_malloc (mbuf.len);
2654 mbuf.byte_order = G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN;
2655 switch (message->byte_order)
2657 case G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN:
2658 mbuf.byte_order = G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN;
2660 case G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN:
2661 mbuf.byte_order = G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN;
2666 g_memory_buffer_put_byte (&mbuf, (guchar) message->byte_order);
2667 g_memory_buffer_put_byte (&mbuf, message->type);
2668 g_memory_buffer_put_byte (&mbuf, message->flags);
2669 g_memory_buffer_put_byte (&mbuf, 1); /* major protocol version */
2670 body_len_offset = mbuf.valid_len;
2671 /* body length - will be filled in later */
2672 g_memory_buffer_put_uint32 (&mbuf, 0xF00DFACE);
2673 g_memory_buffer_put_uint32 (&mbuf, message->serial);
2675 num_fds_in_message = 0;
2677 if (message->fd_list != NULL)
2678 num_fds_in_message = g_unix_fd_list_get_length (message->fd_list);
2680 num_fds_according_to_header = g_dbus_message_get_num_unix_fds (message);
2681 if (num_fds_in_message != num_fds_according_to_header)
2685 G_IO_ERROR_INVALID_ARGUMENT,
2686 _("Message has %d file descriptors but the header field indicates %d file descriptors"),
2688 num_fds_according_to_header);
2692 if (!validate_headers (message, error))
2694 g_prefix_error (error, _("Cannot serialize message: "));
2698 g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{yv}"));
2699 g_hash_table_iter_init (&hash_iter, message->headers);
2700 while (g_hash_table_iter_next (&hash_iter, &key, (gpointer) &header_value))
2702 g_variant_builder_add (&builder,
2704 (guchar) GPOINTER_TO_UINT (key),
2707 header_fields = g_variant_builder_end (&builder);
2709 if (!append_value_to_blob (header_fields,
2710 g_variant_get_type (header_fields),
2715 g_variant_unref (header_fields);
2718 g_variant_unref (header_fields);
2720 /* header size must be a multiple of 8 */
2721 ensure_output_padding (&mbuf, 8);
2723 body_start_offset = mbuf.valid_len;
2725 signature = g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE);
2726 signature_str = NULL;
2727 if (signature != NULL)
2728 signature_str = g_variant_get_string (signature, NULL);
2729 if (message->body != NULL)
2731 gchar *tupled_signature_str;
2732 tupled_signature_str = g_strdup_printf ("(%s)", signature_str);
2733 if (signature == NULL)
2737 G_IO_ERROR_INVALID_ARGUMENT,
2738 _("Message body has signature `%s' but there is no signature header"),
2740 g_free (tupled_signature_str);
2743 else if (g_strcmp0 (tupled_signature_str, g_variant_get_type_string (message->body)) != 0)
2747 G_IO_ERROR_INVALID_ARGUMENT,
2748 _("Message body has type signature `%s' but signature in the header field is `%s'"),
2749 tupled_signature_str, g_variant_get_type_string (message->body));
2750 g_free (tupled_signature_str);
2753 g_free (tupled_signature_str);
2754 if (!append_body_to_blob (message->body, &mbuf, error))
2759 if (signature != NULL && strlen (signature_str) > 0)
2763 G_IO_ERROR_INVALID_ARGUMENT,
2764 _("Message body is empty but signature in the header field is `(%s)'"),
2770 /* OK, we're done writing the message - set the body length */
2771 size = mbuf.valid_len;
2772 body_size = size - body_start_offset;
2774 mbuf.pos = body_len_offset;
2776 g_memory_buffer_put_uint32 (&mbuf, body_size);
2779 ret = (guchar *)mbuf.data;
2785 /* ---------------------------------------------------------------------------------------------------- */
2788 get_uint32_header (GDBusMessage *message,
2789 GDBusMessageHeaderField header_field)
2795 value = g_hash_table_lookup (message->headers, GUINT_TO_POINTER (header_field));
2796 if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_UINT32))
2797 ret = g_variant_get_uint32 (value);
2802 static const gchar *
2803 get_string_header (GDBusMessage *message,
2804 GDBusMessageHeaderField header_field)
2810 value = g_hash_table_lookup (message->headers, GUINT_TO_POINTER (header_field));
2811 if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
2812 ret = g_variant_get_string (value, NULL);
2817 static const gchar *
2818 get_object_path_header (GDBusMessage *message,
2819 GDBusMessageHeaderField header_field)
2825 value = g_hash_table_lookup (message->headers, GUINT_TO_POINTER (header_field));
2826 if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_OBJECT_PATH))
2827 ret = g_variant_get_string (value, NULL);
2832 static const gchar *
2833 get_signature_header (GDBusMessage *message,
2834 GDBusMessageHeaderField header_field)
2840 value = g_hash_table_lookup (message->headers, GUINT_TO_POINTER (header_field));
2841 if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_SIGNATURE))
2842 ret = g_variant_get_string (value, NULL);
2847 /* ---------------------------------------------------------------------------------------------------- */
2850 set_uint32_header (GDBusMessage *message,
2851 GDBusMessageHeaderField header_field,
2854 g_dbus_message_set_header (message,
2856 g_variant_new_uint32 (value));
2860 set_string_header (GDBusMessage *message,
2861 GDBusMessageHeaderField header_field,
2864 g_dbus_message_set_header (message,
2866 value == NULL ? NULL : g_variant_new_string (value));
2870 set_object_path_header (GDBusMessage *message,
2871 GDBusMessageHeaderField header_field,
2874 g_dbus_message_set_header (message,
2876 value == NULL ? NULL : g_variant_new_object_path (value));
2880 set_signature_header (GDBusMessage *message,
2881 GDBusMessageHeaderField header_field,
2884 g_dbus_message_set_header (message,
2886 value == NULL ? NULL : g_variant_new_signature (value));
2889 /* ---------------------------------------------------------------------------------------------------- */
2892 * g_dbus_message_get_reply_serial:
2893 * @message: A #GDBusMessage.
2895 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL header field.
2897 * Returns: The value.
2902 g_dbus_message_get_reply_serial (GDBusMessage *message)
2904 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), 0);
2905 return get_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL);
2909 * g_dbus_message_set_reply_serial:
2910 * @message: A #GDBusMessage.
2911 * @value: The value to set.
2913 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL header field.
2918 g_dbus_message_set_reply_serial (GDBusMessage *message,
2921 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2922 set_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL, value);
2925 /* ---------------------------------------------------------------------------------------------------- */
2928 * g_dbus_message_get_interface:
2929 * @message: A #GDBusMessage.
2931 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE header field.
2933 * Returns: The value.
2938 g_dbus_message_get_interface (GDBusMessage *message)
2940 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2941 return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE);
2945 * g_dbus_message_set_interface:
2946 * @message: A #GDBusMessage.
2947 * @value: The value to set.
2949 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE header field.
2954 g_dbus_message_set_interface (GDBusMessage *message,
2957 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2958 g_return_if_fail (value == NULL || g_dbus_is_interface_name (value));
2959 set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE, value);
2962 /* ---------------------------------------------------------------------------------------------------- */
2965 * g_dbus_message_get_member:
2966 * @message: A #GDBusMessage.
2968 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_MEMBER header field.
2970 * Returns: The value.
2975 g_dbus_message_get_member (GDBusMessage *message)
2977 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2978 return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER);
2982 * g_dbus_message_set_member:
2983 * @message: A #GDBusMessage.
2984 * @value: The value to set.
2986 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_MEMBER header field.
2991 g_dbus_message_set_member (GDBusMessage *message,
2994 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2995 g_return_if_fail (value == NULL || g_dbus_is_member_name (value));
2996 set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER, value);
2999 /* ---------------------------------------------------------------------------------------------------- */
3002 * g_dbus_message_get_path:
3003 * @message: A #GDBusMessage.
3005 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_PATH header field.
3007 * Returns: The value.
3012 g_dbus_message_get_path (GDBusMessage *message)
3014 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
3015 return get_object_path_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH);
3019 * g_dbus_message_set_path:
3020 * @message: A #GDBusMessage.
3021 * @value: The value to set.
3023 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_PATH header field.
3028 g_dbus_message_set_path (GDBusMessage *message,
3031 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
3032 g_return_if_fail (value == NULL || g_variant_is_object_path (value));
3033 set_object_path_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH, value);
3036 /* ---------------------------------------------------------------------------------------------------- */
3039 * g_dbus_message_get_sender:
3040 * @message: A #GDBusMessage.
3042 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_SENDER header field.
3044 * Returns: The value.
3049 g_dbus_message_get_sender (GDBusMessage *message)
3051 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
3052 return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SENDER);
3056 * g_dbus_message_set_sender:
3057 * @message: A #GDBusMessage.
3058 * @value: The value to set.
3060 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_SENDER header field.
3065 g_dbus_message_set_sender (GDBusMessage *message,
3068 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
3069 g_return_if_fail (value == NULL || g_dbus_is_name (value));
3070 set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SENDER, value);
3073 /* ---------------------------------------------------------------------------------------------------- */
3076 * g_dbus_message_get_destination:
3077 * @message: A #GDBusMessage.
3079 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION header field.
3081 * Returns: The value.
3086 g_dbus_message_get_destination (GDBusMessage *message)
3088 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
3089 return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION);
3093 * g_dbus_message_set_destination:
3094 * @message: A #GDBusMessage.
3095 * @value: The value to set.
3097 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION header field.
3102 g_dbus_message_set_destination (GDBusMessage *message,
3105 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
3106 g_return_if_fail (value == NULL || g_dbus_is_name (value));
3107 set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION, value);
3110 /* ---------------------------------------------------------------------------------------------------- */
3113 * g_dbus_message_get_error_name:
3114 * @message: A #GDBusMessage.
3116 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME header field.
3118 * Returns: The value.
3123 g_dbus_message_get_error_name (GDBusMessage *message)
3125 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
3126 return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME);
3130 * g_dbus_message_set_error_name:
3131 * @message: A #GDBusMessage.
3132 * @value: The value to set.
3134 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME header field.
3139 g_dbus_message_set_error_name (GDBusMessage *message,
3142 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
3143 g_return_if_fail (value == NULL || g_dbus_is_interface_name (value));
3144 set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME, value);
3147 /* ---------------------------------------------------------------------------------------------------- */
3150 * g_dbus_message_get_signature:
3151 * @message: A #GDBusMessage.
3153 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE header field.
3155 * Returns: The value.
3160 g_dbus_message_get_signature (GDBusMessage *message)
3163 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
3164 ret = get_signature_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE);
3171 * g_dbus_message_set_signature:
3172 * @message: A #GDBusMessage.
3173 * @value: The value to set.
3175 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE header field.
3180 g_dbus_message_set_signature (GDBusMessage *message,
3183 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
3184 g_return_if_fail (value == NULL || g_variant_is_signature (value));
3185 set_signature_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE, value);
3188 /* ---------------------------------------------------------------------------------------------------- */
3191 * g_dbus_message_get_arg0:
3192 * @message: A #GDBusMessage.
3194 * Convenience to get the first item in the body of @message.
3196 * Returns: The string item or %NULL if the first item in the body of
3197 * @message is not a string.
3202 g_dbus_message_get_arg0 (GDBusMessage *message)
3206 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
3210 if (message->body != NULL && g_variant_is_of_type (message->body, G_VARIANT_TYPE_TUPLE))
3213 item = g_variant_get_child_value (message->body, 0);
3214 if (g_variant_is_of_type (item, G_VARIANT_TYPE_STRING))
3215 ret = g_variant_get_string (item, NULL);
3216 g_variant_unref (item);
3222 /* ---------------------------------------------------------------------------------------------------- */
3225 * g_dbus_message_get_num_unix_fds:
3226 * @message: A #GDBusMessage.
3228 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS header field.
3230 * Returns: The value.
3235 g_dbus_message_get_num_unix_fds (GDBusMessage *message)
3237 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), 0);
3238 return get_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS);
3242 * g_dbus_message_set_num_unix_fds:
3243 * @message: A #GDBusMessage.
3244 * @value: The value to set.
3246 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS header field.
3251 g_dbus_message_set_num_unix_fds (GDBusMessage *message,
3254 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
3255 set_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS, value);
3258 /* ---------------------------------------------------------------------------------------------------- */
3261 * g_dbus_message_to_gerror:
3262 * @message: A #GDBusMessage.
3263 * @error: The #GError to set.
3265 * If @message is not of type %G_DBUS_MESSAGE_TYPE_ERROR does
3266 * nothing and returns %FALSE.
3268 * Otherwise this method encodes the error in @message as a #GError
3269 * using g_dbus_error_set_dbus_error() using the information in the
3270 * %G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME header field of @message as
3271 * well as the first string item in @message's body.
3273 * Returns: %TRUE if @error was set, %FALSE otherwise.
3278 g_dbus_message_to_gerror (GDBusMessage *message,
3282 const gchar *error_name;
3284 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), FALSE);
3287 if (message->type != G_DBUS_MESSAGE_TYPE_ERROR)
3290 error_name = g_dbus_message_get_error_name (message);
3291 if (error_name != NULL)
3295 body = g_dbus_message_get_body (message);
3297 if (body != NULL && g_variant_is_of_type (body, G_VARIANT_TYPE ("(s)")))
3299 const gchar *error_message;
3300 g_variant_get (body, "(&s)", &error_message);
3301 g_dbus_error_set_dbus_error (error,
3308 /* these two situations are valid, yet pretty rare */
3311 g_dbus_error_set_dbus_error (error,
3314 _("Error return with body of type `%s'"),
3315 g_variant_get_type_string (body));
3319 g_dbus_error_set_dbus_error (error,
3322 _("Error return with empty body"));
3328 /* TOOD: this shouldn't happen - should check this at message serialization
3329 * time and disconnect the peer.
3334 "Error return without error-name header!");
3343 /* ---------------------------------------------------------------------------------------------------- */
3346 flags_to_string (GType flags_type, guint value)
3352 klass = g_type_class_ref (flags_type);
3353 s = g_string_new (NULL);
3354 for (n = 0; n < 32; n++)
3356 if ((value & (1<<n)) != 0)
3358 GFlagsValue *flags_value;
3359 flags_value = g_flags_get_first_value (klass, (1<<n));
3361 g_string_append_c (s, ',');
3362 if (flags_value != NULL)
3363 g_string_append (s, flags_value->value_nick);
3365 g_string_append_printf (s, "unknown (bit %d)", n);
3369 g_string_append (s, "none");
3370 g_type_class_unref (klass);
3371 return g_string_free (s, FALSE);
3375 _sort_keys_func (gconstpointer a,
3381 ia = GPOINTER_TO_INT (a);
3382 ib = GPOINTER_TO_INT (b);
3388 * g_dbus_message_print:
3389 * @message: A #GDBusMessage.
3390 * @indent: Indentation level.
3392 * Produces a human-readable multi-line description of @message.
3394 * The contents of the description has no ABI guarantees, the contents
3395 * and formatting is subject to change at any time. Typical output
3396 * looks something like this:
3398 * Type: method-call
3403 * path -> objectpath '/org/gtk/GDBus/TestObject'
3404 * interface -> 'org.gtk.GDBus.TestInterface'
3405 * member -> 'GimmeStdout'
3406 * destination -> ':1.146'
3408 * UNIX File Descriptors:
3413 * Type: method-return
3414 * Flags: no-reply-expected
3418 * reply-serial -> uint32 4
3419 * destination -> ':1.159'
3420 * sender -> ':1.146'
3421 * num-unix-fds -> uint32 1
3423 * UNIX File Descriptors:
3424 * fd 12: dev=0:10,mode=020620,ino=5,uid=500,gid=5,rdev=136:2,size=0,atime=1273085037,mtime=1273085851,ctime=1272982635
3427 * Returns: A string that should be freed with g_free().
3432 g_dbus_message_print (GDBusMessage *message,
3440 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
3442 str = g_string_new (NULL);
3444 s = _g_dbus_enum_to_string (G_TYPE_DBUS_MESSAGE_TYPE, message->type);
3445 g_string_append_printf (str, "%*sType: %s\n", indent, "", s);
3447 s = flags_to_string (G_TYPE_DBUS_MESSAGE_FLAGS, message->flags);
3448 g_string_append_printf (str, "%*sFlags: %s\n", indent, "", s);
3450 g_string_append_printf (str, "%*sVersion: %d\n", indent, "", message->major_protocol_version);
3451 g_string_append_printf (str, "%*sSerial: %d\n", indent, "", message->serial);
3453 g_string_append_printf (str, "%*sHeaders:\n", indent, "");
3454 keys = g_hash_table_get_keys (message->headers);
3455 keys = g_list_sort (keys, _sort_keys_func);
3458 for (l = keys; l != NULL; l = l->next)
3460 gint key = GPOINTER_TO_INT (l->data);
3464 value = g_hash_table_lookup (message->headers, l->data);
3465 g_assert (value != NULL);
3467 s = _g_dbus_enum_to_string (G_TYPE_DBUS_MESSAGE_HEADER_FIELD, key);
3468 value_str = g_variant_print (value, TRUE);
3469 g_string_append_printf (str, "%*s %s -> %s\n", indent, "", s, value_str);
3476 g_string_append_printf (str, "%*s (none)\n", indent, "");
3478 g_string_append_printf (str, "%*sBody: ", indent, "");
3479 if (message->body != NULL)
3481 g_variant_print_string (message->body,
3487 g_string_append (str, "()");
3489 g_string_append (str, "\n");
3491 g_string_append_printf (str, "%*sUNIX File Descriptors:\n", indent, "");
3492 if (message->fd_list != NULL)
3498 fds = g_unix_fd_list_peek_fds (message->fd_list, &num_fds);
3501 for (n = 0; n < num_fds; n++)
3504 struct stat statbuf;
3505 fs = g_string_new (NULL);
3506 if (fstat (fds[n], &statbuf) == 0)
3508 g_string_append_printf (fs, "%s" "dev=%d:%d", fs->len > 0 ? "," : "",
3509 major (statbuf.st_dev), minor (statbuf.st_dev));
3510 g_string_append_printf (fs, "%s" "mode=0%o", fs->len > 0 ? "," : "",
3512 g_string_append_printf (fs, "%s" "ino=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
3513 (guint64) statbuf.st_ino);
3514 g_string_append_printf (fs, "%s" "uid=%d", fs->len > 0 ? "," : "",
3516 g_string_append_printf (fs, "%s" "gid=%d", fs->len > 0 ? "," : "",
3518 g_string_append_printf (fs, "%s" "rdev=%d:%d", fs->len > 0 ? "," : "",
3519 major (statbuf.st_rdev), minor (statbuf.st_rdev));
3520 g_string_append_printf (fs, "%s" "size=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
3521 (guint64) statbuf.st_size);
3522 g_string_append_printf (fs, "%s" "atime=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
3523 (guint64) statbuf.st_atime);
3524 g_string_append_printf (fs, "%s" "mtime=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
3525 (guint64) statbuf.st_mtime);
3526 g_string_append_printf (fs, "%s" "ctime=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
3527 (guint64) statbuf.st_ctime);
3531 g_string_append_printf (fs, "(fstat failed: %s)", strerror (errno));
3533 g_string_append_printf (str, "%*s fd %d: %s\n", indent, "", fds[n], fs->str);
3534 g_string_free (fs, TRUE);
3539 g_string_append_printf (str, "%*s (empty)\n", indent, "");
3544 g_string_append_printf (str, "%*s (none)\n", indent, "");
3548 return g_string_free (str, FALSE);
3552 * g_dbus_message_get_locked:
3553 * @message: A #GDBusMessage.
3555 * Checks whether @message is locked. To monitor changes to this
3556 * value, conncet to the #GObject::notify signal to listen for changes
3557 * on the #GDBusMessage:locked property.
3559 * Returns: %TRUE if @message is locked, %FALSE otherwise.
3564 g_dbus_message_get_locked (GDBusMessage *message)
3566 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), FALSE);
3567 return message->locked;
3571 * g_dbus_message_lock:
3572 * @message: A #GDBusMessage.
3574 * If @message is locked, does nothing. Otherwise locks the message.
3579 g_dbus_message_lock (GDBusMessage *message)
3581 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
3583 if (message->locked)
3586 message->locked = TRUE;
3587 g_object_notify (G_OBJECT (message), "locked");
3594 * g_dbus_message_copy:
3595 * @message: A #GDBusMessage.
3596 * @error: Return location for error or %NULL.
3598 * Copies @message. The copy is a deep copy and the returned
3599 * #GDBusMessage is completely identical except that it is guaranteed
3602 * This operation can fail if e.g. @message contains file descriptors
3603 * and the per-process or system-wide open files limit is reached.
3605 * Returns: (transfer full): A new #GDBusMessage or %NULL if @error is set.
3606 * Free with g_object_unref().
3611 g_dbus_message_copy (GDBusMessage *message,
3615 GHashTableIter iter;
3616 gpointer header_key;
3617 GVariant *header_value;
3619 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
3620 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
3622 ret = g_dbus_message_new ();
3623 ret->type = message->type;
3624 ret->flags = message->flags;
3625 ret->byte_order = message->byte_order;
3626 ret->major_protocol_version = message->major_protocol_version;
3627 ret->serial = message->serial;
3630 if (message->fd_list != NULL)
3636 ret->fd_list = g_unix_fd_list_new ();
3637 fds = g_unix_fd_list_peek_fds (message->fd_list, &num_fds);
3638 for (n = 0; n < num_fds; n++)
3640 if (g_unix_fd_list_append (ret->fd_list,
3644 g_object_unref (ret);
3652 /* see https://bugzilla.gnome.org/show_bug.cgi?id=624546#c8 for why it's fine
3653 * to just ref (as opposed to deep-copying) the GVariant instances
3655 ret->body = message->body != NULL ? g_variant_ref (message->body) : NULL;
3656 g_hash_table_iter_init (&iter, message->headers);
3657 while (g_hash_table_iter_next (&iter, &header_key, (gpointer) &header_value))
3658 g_hash_table_insert (ret->headers, header_key, g_variant_ref (header_value));