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>
27 #include "gdbusutils.h"
28 #include "gdbusmessage.h"
29 #include "gdbuserror.h"
30 #include "gioenumtypes.h"
31 #include "ginputstream.h"
32 #include "gdatainputstream.h"
33 #include "gmemoryinputstream.h"
34 #include "goutputstream.h"
35 #include "gdataoutputstream.h"
36 #include "gmemoryoutputstream.h"
37 #include "gseekable.h"
41 #include "gunixfdlist.h"
43 #include <sys/types.h>
53 * SECTION:gdbusmessage
54 * @short_description: D-Bus Message
57 * A type for representing D-Bus messages that can be sent or received
58 * on a #GDBusConnection.
61 struct _GDBusMessagePrivate
63 GDBusMessageType type;
64 GDBusMessageFlags flags;
65 guchar major_protocol_version;
74 G_DEFINE_TYPE (GDBusMessage, g_dbus_message, G_TYPE_OBJECT);
77 g_dbus_message_finalize (GObject *object)
79 GDBusMessage *message = G_DBUS_MESSAGE (object);
81 if (message->priv->headers != NULL)
82 g_hash_table_unref (message->priv->headers);
83 if (message->priv->body != NULL)
84 g_variant_unref (message->priv->body);
86 if (message->priv->fd_list != NULL)
87 g_object_unref (message->priv->fd_list);
90 if (G_OBJECT_CLASS (g_dbus_message_parent_class)->finalize != NULL)
91 G_OBJECT_CLASS (g_dbus_message_parent_class)->finalize (object);
95 g_dbus_message_class_init (GDBusMessageClass *klass)
97 GObjectClass *gobject_class;
99 g_type_class_add_private (klass, sizeof (GDBusMessagePrivate));
101 gobject_class = G_OBJECT_CLASS (klass);
103 gobject_class->finalize = g_dbus_message_finalize;
107 g_dbus_message_init (GDBusMessage *message)
109 message->priv = G_TYPE_INSTANCE_GET_PRIVATE (message, G_TYPE_DBUS_MESSAGE, GDBusMessagePrivate);
111 message->priv->headers = g_hash_table_new_full (g_direct_hash,
114 (GDestroyNotify) g_variant_unref);
118 * g_dbus_message_new:
120 * Creates a new empty #GDBusMessage.
122 * Returns: A #GDBusMessage. Free with g_object_unref().
127 g_dbus_message_new (void)
129 return g_object_new (G_TYPE_DBUS_MESSAGE, NULL);
133 * g_dbus_message_new_method_call:
134 * @name: A valid D-Bus name or %NULL.
135 * @path: A valid object path.
136 * @interface: A valid D-Bus interface name or %NULL.
137 * @method: A valid method name.
139 * Creates a new #GDBusMessage for a method call.
141 * Returns: A #GDBusMessage. Free with g_object_unref().
146 g_dbus_message_new_method_call (const gchar *name,
148 const gchar *interface,
151 GDBusMessage *message;
153 g_return_val_if_fail (name == NULL || g_dbus_is_name (name), NULL);
154 g_return_val_if_fail (g_variant_is_object_path (path), NULL);
155 g_return_val_if_fail (g_dbus_is_member_name (method), NULL);
156 g_return_val_if_fail (interface == NULL || g_dbus_is_interface_name (interface), NULL);
158 message = g_dbus_message_new ();
159 message->priv->type = G_DBUS_MESSAGE_TYPE_METHOD_CALL;
162 g_dbus_message_set_destination (message, name);
163 g_dbus_message_set_path (message, path);
164 g_dbus_message_set_member (message, method);
165 if (interface != NULL)
166 g_dbus_message_set_interface (message, interface);
172 * g_dbus_message_new_signal:
173 * @path: A valid object path.
174 * @interface: A valid D-Bus interface name or %NULL.
175 * @signal: A valid signal name.
177 * Creates a new #GDBusMessage for a signal emission.
179 * Returns: A #GDBusMessage. Free with g_object_unref().
184 g_dbus_message_new_signal (const gchar *path,
185 const gchar *interface,
188 GDBusMessage *message;
190 g_return_val_if_fail (g_variant_is_object_path (path), NULL);
191 g_return_val_if_fail (g_dbus_is_member_name (signal), NULL);
192 g_return_val_if_fail (interface == NULL || g_dbus_is_interface_name (interface), NULL);
194 message = g_dbus_message_new ();
195 message->priv->type = G_DBUS_MESSAGE_TYPE_SIGNAL;
196 message->priv->flags = G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED;
198 g_dbus_message_set_path (message, path);
199 g_dbus_message_set_member (message, signal);
201 if (interface != NULL)
202 g_dbus_message_set_interface (message, interface);
209 * g_dbus_message_new_method_reply:
210 * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to
211 * create a reply message to.
213 * Creates a new #GDBusMessage that is a reply to @method_call_message.
215 * Returns: A #GDBusMessage. Free with g_object_unref().
220 g_dbus_message_new_method_reply (GDBusMessage *method_call_message)
222 GDBusMessage *message;
225 g_return_val_if_fail (G_IS_DBUS_MESSAGE (method_call_message), NULL);
226 g_return_val_if_fail (g_dbus_message_get_message_type (method_call_message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL, NULL);
227 g_return_val_if_fail (g_dbus_message_get_serial (method_call_message) != 0, NULL);
229 message = g_dbus_message_new ();
230 message->priv->type = G_DBUS_MESSAGE_TYPE_METHOD_RETURN;
231 message->priv->flags = G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED;
233 g_dbus_message_set_reply_serial (message, g_dbus_message_get_serial (method_call_message));
234 sender = g_dbus_message_get_sender (method_call_message);
236 g_dbus_message_set_destination (message, sender);
242 * g_dbus_message_new_method_error:
243 * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to
244 * create a reply message to.
245 * @error_name: A valid D-Bus error name.
246 * @error_message_format: The D-Bus error message in a printf() format.
247 * @...: Arguments for @error_message_format.
249 * Creates a new #GDBusMessage that is an error reply to @method_call_message.
251 * Returns: A #GDBusMessage. Free with g_object_unref().
256 g_dbus_message_new_method_error (GDBusMessage *method_call_message,
257 const gchar *error_name,
258 const gchar *error_message_format,
264 va_start (var_args, error_message_format);
265 ret = g_dbus_message_new_method_error_valist (method_call_message,
267 error_message_format,
275 * g_dbus_message_new_method_error_literal:
276 * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to
277 * create a reply message to.
278 * @error_name: A valid D-Bus error name.
279 * @error_message: The D-Bus error message.
281 * Creates a new #GDBusMessage that is an error reply to @method_call_message.
283 * Returns: A #GDBusMessage. Free with g_object_unref().
288 g_dbus_message_new_method_error_literal (GDBusMessage *method_call_message,
289 const gchar *error_name,
290 const gchar *error_message)
292 GDBusMessage *message;
295 g_return_val_if_fail (G_IS_DBUS_MESSAGE (method_call_message), NULL);
296 g_return_val_if_fail (g_dbus_message_get_message_type (method_call_message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL, NULL);
297 g_return_val_if_fail (g_dbus_message_get_serial (method_call_message) != 0, NULL);
298 g_return_val_if_fail (g_dbus_is_name (error_name), NULL);
299 g_return_val_if_fail (error_message != NULL, NULL);
301 message = g_dbus_message_new ();
302 message->priv->type = G_DBUS_MESSAGE_TYPE_ERROR;
303 message->priv->flags = G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED;
305 g_dbus_message_set_reply_serial (message, g_dbus_message_get_serial (method_call_message));
306 g_dbus_message_set_error_name (message, error_name);
307 g_dbus_message_set_body (message, g_variant_new ("(s)", error_message));
309 sender = g_dbus_message_get_sender (method_call_message);
311 g_dbus_message_set_destination (message, sender);
317 * g_dbus_message_new_method_error_valist:
318 * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to
319 * create a reply message to.
320 * @error_name: A valid D-Bus error name.
321 * @error_message_format: The D-Bus error message in a printf() format.
322 * @var_args: Arguments for @error_message_format.
324 * Like g_dbus_message_new_method_error() but intended for language bindings.
326 * Returns: A #GDBusMessage. Free with g_object_unref().
331 g_dbus_message_new_method_error_valist (GDBusMessage *method_call_message,
332 const gchar *error_name,
333 const gchar *error_message_format,
337 gchar *error_message;
338 error_message = g_strdup_vprintf (error_message_format, var_args);
339 ret = g_dbus_message_new_method_error_literal (method_call_message,
342 g_free (error_message);
346 /* ---------------------------------------------------------------------------------------------------- */
348 /* TODO: need GI annotations to specify that any guchar value goes for the type */
351 * g_dbus_message_get_message_type:
352 * @message: A #GDBusMessage.
354 * Gets the type of @message.
356 * Returns: A 8-bit unsigned integer (typically a value from the #GDBusMessageType enumeration).
361 g_dbus_message_get_message_type (GDBusMessage *message)
363 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), G_DBUS_MESSAGE_TYPE_INVALID);
364 return message->priv->type;
368 * g_dbus_message_set_message_type:
369 * @message: A #GDBusMessage.
370 * @type: A 8-bit unsigned integer (typically a value from the #GDBusMessageType enumeration).
372 * Sets @message to be of @type.
377 g_dbus_message_set_message_type (GDBusMessage *message,
378 GDBusMessageType type)
380 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
381 g_return_if_fail (type >=0 && type < 256);
382 message->priv->type = type;
385 /* ---------------------------------------------------------------------------------------------------- */
387 /* TODO: need GI annotations to specify that any guchar value goes for flags */
390 * g_dbus_message_get_flags:
391 * @message: A #GDBusMessage.
393 * Gets the flags for @message.
395 * Returns: Flags that are set (typically values from the #GDBusMessageFlags enumeration bitwise ORed together).
400 g_dbus_message_get_flags (GDBusMessage *message)
402 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), G_DBUS_MESSAGE_FLAGS_NONE);
403 return message->priv->flags;
407 * g_dbus_message_set_flags:
408 * @message: A #GDBusMessage.
409 * @flags: Flags for @message that are set (typically values from the #GDBusMessageFlags
410 * enumeration bitwise ORed together).
412 * Sets the flags to set on @message.
417 g_dbus_message_set_flags (GDBusMessage *message,
418 GDBusMessageFlags flags)
420 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
421 g_return_if_fail (flags >=0 && flags < 256);
422 message->priv->flags = flags;
425 /* ---------------------------------------------------------------------------------------------------- */
428 * g_dbus_message_get_serial:
429 * @message: A #GDBusMessage.
431 * Gets the serial for @message.
433 * Returns: A #guint32.
438 g_dbus_message_get_serial (GDBusMessage *message)
440 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), 0);
441 return message->priv->serial;
445 * g_dbus_message_set_serial:
446 * @message: A #GDBusMessage.
447 * @serial: A #guint32.
449 * Sets the serial for @message.
454 g_dbus_message_set_serial (GDBusMessage *message,
457 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
458 message->priv->serial = serial;
461 /* ---------------------------------------------------------------------------------------------------- */
463 /* TODO: need GI annotations to specify that any guchar value goes for header_field */
466 * g_dbus_message_get_header:
467 * @message: A #GDBusMessage.
468 * @header_field: A 8-bit unsigned integer (typically a value from the #GDBusMessageHeaderField enumeration)
470 * Gets a header field on @message.
472 * Returns: A #GVariant with the value if the header was found, %NULL
473 * otherwise. Do not free, it is owned by @message.
478 g_dbus_message_get_header (GDBusMessage *message,
479 GDBusMessageHeaderField header_field)
481 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
482 g_return_val_if_fail (header_field >=0 && header_field < 256, NULL);
483 return g_hash_table_lookup (message->priv->headers, GUINT_TO_POINTER (header_field));
487 * g_dbus_message_set_header:
488 * @message: A #GDBusMessage.
489 * @header_field: A 8-bit unsigned integer (typically a value from the #GDBusMessageHeaderField enumeration)
490 * @value: A #GVariant to set the header field or %NULL to clear the header field.
492 * Sets a header field on @message.
494 * If @value is floating, @message assumes ownership of @value.
499 g_dbus_message_set_header (GDBusMessage *message,
500 GDBusMessageHeaderField header_field,
503 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
504 g_return_if_fail (header_field >=0 && header_field < 256);
507 g_hash_table_remove (message->priv->headers, GUINT_TO_POINTER (header_field));
511 g_hash_table_insert (message->priv->headers, GUINT_TO_POINTER (header_field), g_variant_ref_sink (value));
516 * g_dbus_message_get_header_fields:
517 * @message: A #GDBusMessage.
519 * Gets an array of all header fields on @message that are set.
521 * Returns: An array of header fields terminated by
522 * %G_DBUS_MESSAGE_HEADER_FIELD_INVALID. Each element is a
523 * #guchar. Free with g_free().
528 g_dbus_message_get_header_fields (GDBusMessage *message)
536 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
538 keys = g_hash_table_get_keys (message->priv->headers);
539 num_keys = g_list_length (keys);
540 ret = g_new (guchar, num_keys + 1);
541 for (l = keys, n = 0; l != NULL; l = l->next, n++)
542 ret[n] = GPOINTER_TO_UINT (l->data);
543 g_assert (n == num_keys);
544 ret[n] = G_DBUS_MESSAGE_HEADER_FIELD_INVALID;
550 /* ---------------------------------------------------------------------------------------------------- */
553 * g_dbus_message_get_body:
554 * @message: A #GDBusMessage.
556 * Gets the body of a message.
558 * Returns: A #GVariant or %NULL if the body is empty. Do not free, it is owned by @message.
563 g_dbus_message_get_body (GDBusMessage *message)
565 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
566 return message->priv->body;
570 * g_dbus_message_set_body:
571 * @message: A #GDBusMessage.
572 * @body: Either %NULL or a #GVariant that is a tuple.
574 * Sets the body @message. As a side-effect the
575 * %G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE header field is set to the
576 * type string of @body (or cleared if @body is %NULL).
578 * If @body is floating, @message assumes ownership of @body.
583 g_dbus_message_set_body (GDBusMessage *message,
586 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
587 g_return_if_fail ((body == NULL) || g_variant_is_of_type (body, G_VARIANT_TYPE_TUPLE));
589 if (message->priv->body != NULL)
590 g_variant_unref (message->priv->body);
593 message->priv->body = NULL;
594 g_dbus_message_set_signature (message, NULL);
598 const gchar *type_string;
599 gsize type_string_len;
602 message->priv->body = g_variant_ref_sink (body);
604 type_string = g_variant_get_type_string (body);
605 type_string_len = strlen (type_string);
606 g_assert (type_string_len >= 2);
607 signature = g_strndup (type_string + 1, type_string_len - 2);
608 g_dbus_message_set_signature (message, signature);
613 /* ---------------------------------------------------------------------------------------------------- */
617 * g_dbus_message_get_unix_fd_list:
618 * @message: A #GDBusMessage.
620 * Gets the UNIX file descriptors associated with @message, if any.
622 * This method is only available on UNIX.
624 * Returns: A #GUnixFDList or %NULL if no file descriptors are
625 * associated. Do not free, this object is owned by @message.
630 g_dbus_message_get_unix_fd_list (GDBusMessage *message)
632 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
633 return message->priv->fd_list;
637 * g_dbus_message_set_unix_fd_list:
638 * @message: A #GDBusMessage.
639 * @fd_list: A #GUnixFDList or %NULL.
641 * Sets the UNIX file descriptors associated with @message. As a
642 * side-effect the %G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS header
643 * field is set to the number of fds in @fd_list (or cleared if
644 * @fd_list is %NULL).
646 * This method is only available on UNIX.
651 g_dbus_message_set_unix_fd_list (GDBusMessage *message,
652 GUnixFDList *fd_list)
654 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
655 g_return_if_fail (fd_list == NULL || G_IS_UNIX_FD_LIST (fd_list));
656 if (message->priv->fd_list != NULL)
657 g_object_unref (message->priv->fd_list);
660 message->priv->fd_list = g_object_ref (fd_list);
661 g_dbus_message_set_num_unix_fds (message, g_unix_fd_list_get_length (fd_list));
665 message->priv->fd_list = NULL;
666 g_dbus_message_set_num_unix_fds (message, 0);
671 /* ---------------------------------------------------------------------------------------------------- */
674 ensure_input_padding (GMemoryInputStream *mis,
681 offset = g_seekable_tell (G_SEEKABLE (mis));
682 wanted_offset = ((offset + padding_size - 1) / padding_size) * padding_size;
684 return g_seekable_seek (G_SEEKABLE (mis), wanted_offset, G_SEEK_SET, NULL, error);
688 read_string (GMemoryInputStream *mis,
689 GDataInputStream *dis,
699 s = g_string_new (NULL);
702 while (remaining > 0)
707 to_read = MIN (remaining, sizeof (buf));
708 num_read = g_input_stream_read (G_INPUT_STREAM (mis),
719 G_IO_ERROR_INVALID_ARGUMENT,
720 _("Wanted to read %" G_GSIZE_FORMAT " bytes but got EOF"),
725 remaining -= num_read;
726 g_string_append_len (s, buf, num_read);
730 nul = g_data_input_stream_read_byte (dis, NULL, &local_error);
731 if (local_error != NULL)
733 g_propagate_error (error, local_error);
740 G_IO_ERROR_INVALID_ARGUMENT,
741 _("Expected NUL byte after the string `%s' but found `%c' (%d)"),
746 return g_string_free (s, FALSE);
749 g_string_free (s, TRUE);
754 parse_value_from_blob (GMemoryInputStream *mis,
755 GDataInputStream *dis,
756 const GVariantType *type,
763 if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
766 if (!ensure_input_padding (mis, 4, &local_error))
768 v = g_data_input_stream_read_uint32 (dis, NULL, &local_error);
769 if (local_error != NULL)
771 ret = g_variant_new_boolean (v);
773 else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
776 v = g_data_input_stream_read_byte (dis, NULL, &local_error);
777 if (local_error != NULL)
779 ret = g_variant_new_byte (v);
781 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
784 if (!ensure_input_padding (mis, 2, &local_error))
786 v = g_data_input_stream_read_int16 (dis, NULL, &local_error);
787 if (local_error != NULL)
789 ret = g_variant_new_int16 (v);
791 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
794 if (!ensure_input_padding (mis, 2, &local_error))
796 v = g_data_input_stream_read_uint16 (dis, NULL, &local_error);
797 if (local_error != NULL)
799 ret = g_variant_new_uint16 (v);
801 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
804 if (!ensure_input_padding (mis, 4, &local_error))
806 v = g_data_input_stream_read_int32 (dis, NULL, &local_error);
807 if (local_error != NULL)
809 ret = g_variant_new_int32 (v);
811 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
814 if (!ensure_input_padding (mis, 4, &local_error))
816 v = g_data_input_stream_read_uint32 (dis, NULL, &local_error);
817 if (local_error != NULL)
819 ret = g_variant_new_uint32 (v);
821 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
824 if (!ensure_input_padding (mis, 8, &local_error))
826 v = g_data_input_stream_read_int64 (dis, NULL, &local_error);
827 if (local_error != NULL)
829 ret = g_variant_new_int64 (v);
831 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
834 if (!ensure_input_padding (mis, 8, &local_error))
836 v = g_data_input_stream_read_uint64 (dis, NULL, &local_error);
837 if (local_error != NULL)
839 ret = g_variant_new_uint64 (v);
841 else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
845 if (!ensure_input_padding (mis, 8, &local_error))
847 v = g_data_input_stream_read_uint64 (dis, NULL, &local_error);
848 if (local_error != NULL)
851 encoded = (gdouble *) &v;
852 ret = g_variant_new_double (*encoded);
854 else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
858 if (!ensure_input_padding (mis, 4, &local_error))
860 len = g_data_input_stream_read_uint32 (dis, NULL, &local_error);
861 if (local_error != NULL)
863 v = read_string (mis, dis, (gsize) len, &local_error);
866 ret = g_variant_new_string (v);
868 else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
872 if (!ensure_input_padding (mis, 4, &local_error))
874 len = g_data_input_stream_read_uint32 (dis, NULL, &local_error);
875 if (local_error != NULL)
877 v = read_string (mis, dis, (gsize) len, &local_error);
880 if (!g_variant_is_object_path (v))
882 g_set_error (&local_error,
884 G_IO_ERROR_INVALID_ARGUMENT,
885 _("Parsed value `%s' is not a valid D-Bus object path"),
889 ret = g_variant_new_object_path (v);
891 else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
895 len = g_data_input_stream_read_byte (dis, NULL, &local_error);
896 if (local_error != NULL)
898 v = read_string (mis, dis, (gsize) len, &local_error);
901 if (!g_variant_is_signature (v))
903 g_set_error (&local_error,
905 G_IO_ERROR_INVALID_ARGUMENT,
906 _("Parsed value `%s' is not a valid D-Bus signature"),
910 ret = g_variant_new_signature (v);
912 else if (g_variant_type_is_array (type))
917 const GVariantType *element_type;
918 GVariantBuilder *builder;
920 if (!ensure_input_padding (mis, 4, &local_error))
922 array_len = g_data_input_stream_read_uint32 (dis, NULL, &local_error);
924 if (array_len > (2<<26))
926 g_set_error (&local_error,
928 G_IO_ERROR_INVALID_ARGUMENT,
929 _("Encountered array of length %" G_GUINT32_FORMAT " bytes. Maximum length is 2<<26 bytes."),
934 builder = g_variant_builder_new (type);
935 element_type = g_variant_type_element (type);
937 /* TODO: optimize array of primitive types */
939 offset = g_seekable_tell (G_SEEKABLE (mis));
940 target = offset + array_len;
941 while (offset < target)
944 item = parse_value_from_blob (mis, dis, element_type, &local_error);
947 g_variant_builder_unref (builder);
950 g_variant_builder_add_value (builder, item);
951 offset = g_seekable_tell (G_SEEKABLE (mis));
954 ret = g_variant_builder_end (builder);
956 else if (g_variant_type_is_dict_entry (type))
958 const GVariantType *key_type;
959 const GVariantType *value_type;
963 if (!ensure_input_padding (mis, 8, &local_error))
966 key_type = g_variant_type_key (type);
967 key = parse_value_from_blob (mis, dis, key_type, &local_error);
971 value_type = g_variant_type_value (type);
972 value = parse_value_from_blob (mis, dis, value_type, &local_error);
975 g_variant_unref (key);
978 ret = g_variant_new_dict_entry (key, value);
980 else if (g_variant_type_is_tuple (type))
982 const GVariantType *element_type;
983 GVariantBuilder *builder;
985 if (!ensure_input_padding (mis, 8, &local_error))
988 builder = g_variant_builder_new (type);
989 element_type = g_variant_type_first (type);
990 while (element_type != NULL)
993 item = parse_value_from_blob (mis, dis, element_type, &local_error);
996 g_variant_builder_unref (builder);
999 g_variant_builder_add_value (builder, item);
1001 element_type = g_variant_type_next (element_type);
1003 ret = g_variant_builder_end (builder);
1005 else if (g_variant_type_is_variant (type))
1009 GVariantType *variant_type;
1012 siglen = g_data_input_stream_read_byte (dis, NULL, &local_error);
1013 if (local_error != NULL)
1015 sig = read_string (mis, dis, (gsize) siglen, &local_error);
1018 if (!g_variant_is_signature (sig))
1020 g_set_error (&local_error,
1022 G_IO_ERROR_INVALID_ARGUMENT,
1023 _("Parsed value `%s' for variant is not a valid D-Bus signature"),
1027 variant_type = g_variant_type_new (sig);
1028 value = parse_value_from_blob (mis, dis, variant_type, &local_error);
1029 g_variant_type_free (variant_type);
1032 ret = g_variant_new_variant (value);
1037 s = g_variant_type_dup_string (type);
1038 g_set_error (&local_error,
1040 G_IO_ERROR_INVALID_ARGUMENT,
1041 _("Error deserializing GVariant with type-string `%s' from the D-Bus wire format"),
1047 g_assert (ret != NULL);
1051 g_propagate_error (error, local_error);
1055 /* ---------------------------------------------------------------------------------------------------- */
1057 /* message_header must be at least 16 bytes */
1060 * g_dbus_message_bytes_needed:
1061 * @blob: A blob represent a binary D-Bus message.
1062 * @blob_len: The length of @blob (must be at least 16).
1063 * @error: Return location for error or %NULL.
1065 * Utility function to calculate how many bytes are needed to
1066 * completely deserialize the D-Bus message stored at @blob.
1068 * Returns: Number of bytes needed or -1 if @error is set (e.g. if
1069 * @blob contains invalid data or not enough data is available to
1070 * determine the size).
1075 g_dbus_message_bytes_needed (guchar *blob,
1083 g_return_val_if_fail (blob != NULL, -1);
1084 g_return_val_if_fail (error == NULL || *error == NULL, -1);
1085 g_return_val_if_fail (blob_len >= 16, -1);
1089 /* core header (12 bytes) + ARRAY of STRUCT of (BYTE,VARIANT) */
1090 ret = 12 + 4 + GUINT32_FROM_LE (((guint32 *) blob)[3]);
1091 /* round up so it's a multiple of 8 */
1092 ret = 8 * ((ret + 7)/8);
1093 /* finally add the body size */
1094 ret += GUINT32_FROM_LE (((guint32 *) blob)[1]);
1096 else if (blob[0] == 'B')
1099 g_assert_not_reached ();
1105 G_IO_ERROR_INVALID_ARGUMENT,
1106 "Unable to determine message blob length - given blob is malformed");
1113 G_IO_ERROR_INVALID_ARGUMENT,
1114 "Blob indicates that message exceeds maximum message length (128MiB)");
1121 /* ---------------------------------------------------------------------------------------------------- */
1124 * g_dbus_message_new_from_blob:
1125 * @blob: A blob represent a binary D-Bus message.
1126 * @blob_len: The length of @blob.
1127 * @capabilities: A #GDBusCapabilityFlags describing what protocol features are supported.
1128 * @error: Return location for error or %NULL.
1130 * Creates a new #GDBusMessage from the data stored at @blob.
1132 * Returns: A new #GDBusMessage or %NULL if @error is set. Free with
1138 g_dbus_message_new_from_blob (guchar *blob,
1140 GDBusCapabilityFlags capabilities,
1144 GMemoryInputStream *mis;
1145 GDataInputStream *dis;
1146 GDBusMessage *message;
1148 guchar major_protocol_version;
1149 GDataStreamByteOrder byte_order;
1150 guint32 message_body_len;
1154 GVariant *signature;
1156 /* TODO: check against @capabilities */
1160 g_return_val_if_fail (blob != NULL, NULL);
1161 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1162 g_return_val_if_fail (blob_len >= 12, NULL);
1164 message = g_dbus_message_new ();
1166 mis = G_MEMORY_INPUT_STREAM (g_memory_input_stream_new_from_data (blob, blob_len, NULL));
1167 dis = g_data_input_stream_new (G_INPUT_STREAM (mis));
1169 endianness = g_data_input_stream_read_byte (dis, NULL, NULL);
1173 byte_order = G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN;
1176 byte_order = G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN;
1181 G_IO_ERROR_INVALID_ARGUMENT,
1182 _("Invalid endianness value. Expected 'l' or 'B' but found '%c' (%d)"),
1183 endianness, endianness);
1186 g_data_input_stream_set_byte_order (dis, byte_order);
1188 message->priv->type = g_data_input_stream_read_byte (dis, NULL, NULL);
1189 message->priv->flags = g_data_input_stream_read_byte (dis, NULL, NULL);
1190 major_protocol_version = g_data_input_stream_read_byte (dis, NULL, NULL);
1191 if (major_protocol_version != 1)
1195 G_IO_ERROR_INVALID_ARGUMENT,
1196 _("Invalid major protocol version. Expected 1 but found %d"),
1197 major_protocol_version);
1200 message_body_len = g_data_input_stream_read_uint32 (dis, NULL, NULL);
1201 message->priv->serial = g_data_input_stream_read_uint32 (dis, NULL, NULL);
1203 headers = parse_value_from_blob (mis,
1205 G_VARIANT_TYPE ("a{yv}"),
1207 if (headers == NULL)
1209 g_variant_ref_sink (headers);
1210 g_variant_iter_init (&iter, headers);
1211 while ((item = g_variant_iter_next_value (&iter)))
1213 guchar header_field;
1215 g_variant_get (item,
1219 g_dbus_message_set_header (message, header_field, value);
1221 g_variant_unref (headers);
1223 signature = g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE);
1224 if (signature != NULL)
1226 const gchar *signature_str;
1227 gsize signature_str_len;
1229 signature_str = g_variant_get_string (signature, NULL);
1230 signature_str_len = strlen (signature_str);
1232 /* signature but no body */
1233 if (message_body_len == 0 && signature_str_len > 0)
1237 G_IO_ERROR_INVALID_ARGUMENT,
1238 _("Signature header with signature `%s' found but message body is empty"),
1242 else if (signature_str_len > 0)
1244 GVariantType *variant_type;
1245 gchar *tupled_signature_str;
1247 if (!g_variant_is_signature (signature_str))
1251 G_IO_ERROR_INVALID_ARGUMENT,
1252 _("Parsed value `%s' is not a valid D-Bus signature (for body)"),
1256 tupled_signature_str = g_strdup_printf ("(%s)", signature_str);
1257 variant_type = g_variant_type_new (tupled_signature_str);
1258 g_free (tupled_signature_str);
1259 message->priv->body = parse_value_from_blob (mis,
1263 if (message->priv->body == NULL)
1265 g_variant_type_free (variant_type);
1268 g_variant_ref_sink (message->priv->body);
1269 g_variant_type_free (variant_type);
1274 /* no signature, this is only OK if the body is empty */
1275 if (message_body_len != 0)
1279 G_IO_ERROR_INVALID_ARGUMENT,
1280 _("No signature header in message but the message body is %" G_GUINT32_FORMAT " bytes"),
1290 g_object_unref (dis);
1291 g_object_unref (mis);
1299 if (message != NULL)
1300 g_object_unref (message);
1305 /* ---------------------------------------------------------------------------------------------------- */
1308 ensure_output_padding (GMemoryOutputStream *mos,
1309 GDataOutputStream *dos,
1313 gsize wanted_offset;
1314 gsize padding_needed;
1317 offset = g_memory_output_stream_get_data_size (mos);
1318 wanted_offset = ((offset + padding_size - 1) / padding_size) * padding_size;
1319 padding_needed = wanted_offset - offset;
1321 for (n = 0; n < padding_needed; n++)
1322 g_data_output_stream_put_byte (dos, '\0', NULL, NULL);
1324 return padding_needed;
1328 append_value_to_blob (GVariant *value,
1329 GMemoryOutputStream *mos,
1330 GDataOutputStream *dos,
1331 gsize *out_padding_added,
1334 const GVariantType *type;
1335 gsize padding_added;
1339 type = g_variant_get_type (value);
1340 if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
1342 gboolean v = g_variant_get_boolean (value);
1343 padding_added = ensure_output_padding (mos, dos, 4);
1344 g_data_output_stream_put_uint32 (dos, v, NULL, NULL);
1346 else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
1348 guint8 v = g_variant_get_byte (value);
1349 g_data_output_stream_put_byte (dos, v, NULL, NULL);
1351 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
1353 gint16 v = g_variant_get_int16 (value);
1354 padding_added = ensure_output_padding (mos, dos, 2);
1355 g_data_output_stream_put_int16 (dos, v, NULL, NULL);
1357 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
1359 guint16 v = g_variant_get_uint16 (value);
1360 padding_added = ensure_output_padding (mos, dos, 2);
1361 g_data_output_stream_put_uint16 (dos, v, NULL, NULL);
1363 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
1365 gint32 v = g_variant_get_int32 (value);
1366 padding_added = ensure_output_padding (mos, dos, 4);
1367 g_data_output_stream_put_int32 (dos, v, NULL, NULL);
1369 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
1371 guint32 v = g_variant_get_uint32 (value);
1372 padding_added = ensure_output_padding (mos, dos, 4);
1373 g_data_output_stream_put_uint32 (dos, v, NULL, NULL);
1375 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
1377 gint64 v = g_variant_get_int64 (value);
1378 padding_added = ensure_output_padding (mos, dos, 8);
1379 g_data_output_stream_put_int64 (dos, v, NULL, NULL);
1381 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
1383 guint64 v = g_variant_get_uint64 (value);
1384 padding_added = ensure_output_padding (mos, dos, 8);
1385 g_data_output_stream_put_uint64 (dos, v, NULL, NULL);
1387 else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
1390 gdouble v = g_variant_get_double (value);
1391 padding_added = ensure_output_padding (mos, dos, 8);
1393 encoded = (guint64 *) &v;
1394 g_data_output_stream_put_uint64 (dos, *encoded, NULL, NULL);
1396 else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
1398 const gchar *v = g_variant_get_string (value, NULL);
1400 padding_added = ensure_output_padding (mos, dos, 4);
1402 g_data_output_stream_put_uint32 (dos, len, NULL, NULL);
1403 g_data_output_stream_put_string (dos, v, NULL, NULL);
1404 g_data_output_stream_put_byte (dos, '\0', NULL, NULL);
1406 else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
1408 /* TODO: validate object path */
1409 const gchar *v = g_variant_get_string (value, NULL);
1411 padding_added = ensure_output_padding (mos, dos, 4);
1413 g_data_output_stream_put_uint32 (dos, len, NULL, NULL);
1414 g_data_output_stream_put_string (dos, v, NULL, NULL);
1415 g_data_output_stream_put_byte (dos, '\0', NULL, NULL);
1417 else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
1419 /* TODO: validate signature (including max len being 255) */
1420 const gchar *v = g_variant_get_string (value, NULL);
1423 g_data_output_stream_put_byte (dos, len, NULL, NULL);
1424 g_data_output_stream_put_string (dos, v, NULL, NULL);
1425 g_data_output_stream_put_byte (dos, '\0', NULL, NULL);
1427 else if (g_variant_type_is_array (type))
1431 goffset array_len_offset;
1432 goffset array_payload_begin_offset;
1437 padding_added = ensure_output_padding (mos, dos, 4);
1439 /* array length - will be filled in later */
1440 array_len_offset = g_memory_output_stream_get_data_size (mos);
1441 g_data_output_stream_put_uint32 (dos, 0xF00DFACE, NULL, NULL);
1443 /* From the D-Bus spec:
1445 * "A UINT32 giving the length of the array data in bytes,
1446 * followed by alignment padding to the alignment boundary of
1447 * the array element type, followed by each array element. The
1448 * array length is from the end of the alignment padding to
1449 * the end of the last element, i.e. it does not include the
1450 * padding after the length, or any padding after the last
1453 * Thus, we need to count how much padding the first element
1454 * contributes and subtract that from the array length.
1456 array_payload_begin_offset = g_memory_output_stream_get_data_size (mos);
1458 g_variant_iter_init (&iter, value);
1460 while ((item = g_variant_iter_next_value (&iter)))
1462 gsize padding_added_for_item;
1463 if (!append_value_to_blob (item, mos, dos, &padding_added_for_item, error))
1467 array_payload_begin_offset += padding_added_for_item;
1472 cur_offset = g_memory_output_stream_get_data_size (mos);
1474 array_len = cur_offset - array_payload_begin_offset;
1476 if (!g_seekable_seek (G_SEEKABLE (mos), array_len_offset, G_SEEK_SET, NULL, error))
1479 g_data_output_stream_put_uint32 (dos, array_len, NULL, NULL);
1481 if (!g_seekable_seek (G_SEEKABLE (mos), cur_offset, G_SEEK_SET, NULL, error))
1484 else if (g_variant_type_is_dict_entry (type) || g_variant_type_is_tuple (type))
1489 padding_added = ensure_output_padding (mos, dos, 8);
1491 g_variant_iter_init (&iter, value);
1493 while ((item = g_variant_iter_next_value (&iter)))
1495 if (!append_value_to_blob (item, mos, dos, NULL, error))
1499 else if (g_variant_type_is_variant (type))
1502 const gchar *signature;
1503 child = g_variant_get_child_value (value, 0);
1504 signature = g_variant_get_type_string (child);
1505 /* TODO: validate signature (including max len being 255) */
1506 g_data_output_stream_put_byte (dos, strlen (signature), NULL, NULL);
1507 g_data_output_stream_put_string (dos, signature, NULL, NULL);
1508 g_data_output_stream_put_byte (dos, '\0', NULL, NULL);
1509 if (!append_value_to_blob (child, mos, dos, NULL, error))
1511 g_variant_unref (child);
1514 g_variant_unref (child);
1520 G_IO_ERROR_INVALID_ARGUMENT,
1521 _("Error serializing GVariant with type-string `%s' to the D-Bus wire format"),
1522 g_variant_get_type_string (value));
1526 if (out_padding_added != NULL)
1527 *out_padding_added = padding_added;
1536 append_body_to_blob (GVariant *value,
1537 GMemoryOutputStream *mos,
1538 GDataOutputStream *dos,
1547 if (!g_variant_is_of_type (value, G_VARIANT_TYPE_TUPLE))
1551 G_IO_ERROR_INVALID_ARGUMENT,
1552 "Expected a tuple for the body of the GDBusMessage.");
1556 g_variant_iter_init (&iter, value);
1557 while ((item = g_variant_iter_next_value (&iter)))
1559 if (!append_value_to_blob (item, mos, dos, NULL, error))
1568 /* ---------------------------------------------------------------------------------------------------- */
1571 * g_dbus_message_to_blob:
1572 * @message: A #GDBusMessage.
1573 * @out_size: Return location for size of generated blob.
1574 * @capabilities: A #GDBusCapabilityFlags describing what protocol features are supported.
1575 * @error: Return location for error.
1577 * Serializes @message to a blob.
1579 * Returns: A pointer to a valid binary D-Bus message of @out_size bytes
1580 * generated by @message or %NULL if @error is set. Free with g_free().
1585 g_dbus_message_to_blob (GDBusMessage *message,
1587 GDBusCapabilityFlags capabilities,
1590 GMemoryOutputStream *mos;
1591 GDataOutputStream *dos;
1594 GDataStreamByteOrder byte_order;
1595 goffset body_len_offset;
1596 goffset body_start_offset;
1598 GVariant *header_fields;
1599 GVariantBuilder *builder;
1600 GHashTableIter hash_iter;
1602 GVariant *header_value;
1603 GVariant *signature;
1604 const gchar *signature_str;
1605 gint num_fds_in_message;
1606 gint num_fds_according_to_header;
1608 /* TODO: check against @capabilities */
1612 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
1613 g_return_val_if_fail (out_size != NULL, NULL);
1614 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1616 mos = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new (NULL, 0, g_realloc, g_free));
1617 dos = g_data_output_stream_new (G_OUTPUT_STREAM (mos));
1619 /* TODO: detect endianess... */
1620 byte_order = G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN;
1621 g_data_output_stream_set_byte_order (dos, byte_order);
1624 g_data_output_stream_put_byte (dos, byte_order == G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN ? 'l' : 'B', NULL, NULL);
1625 g_data_output_stream_put_byte (dos, message->priv->type, NULL, NULL);
1626 g_data_output_stream_put_byte (dos, message->priv->flags, NULL, NULL);
1627 g_data_output_stream_put_byte (dos, 1, NULL, NULL); /* major protocol version */
1628 body_len_offset = g_memory_output_stream_get_data_size (mos);
1629 /* body length - will be filled in later */
1630 g_data_output_stream_put_uint32 (dos, 0xF00DFACE, NULL, NULL);
1631 g_data_output_stream_put_uint32 (dos, message->priv->serial, NULL, NULL);
1633 num_fds_in_message = 0;
1635 if (message->priv->fd_list != NULL)
1636 num_fds_in_message = g_unix_fd_list_get_length (message->priv->fd_list);
1638 num_fds_according_to_header = g_dbus_message_get_num_unix_fds (message);
1639 /* TODO: check we have all the right header fields and that they are the correct value etc etc */
1640 if (num_fds_in_message != num_fds_according_to_header)
1644 G_IO_ERROR_INVALID_ARGUMENT,
1645 _("Message has %d fds but the header field indicates %d fds"),
1647 num_fds_according_to_header);
1651 builder = g_variant_builder_new (G_VARIANT_TYPE ("a{yv}"));//G_VARIANT_TYPE_ARRAY);
1652 g_hash_table_iter_init (&hash_iter, message->priv->headers);
1653 while (g_hash_table_iter_next (&hash_iter, &key, (gpointer) &header_value))
1655 g_variant_builder_add (builder,
1657 (guchar) GPOINTER_TO_UINT (key),
1660 header_fields = g_variant_new ("a{yv}", builder);
1662 if (!append_value_to_blob (header_fields, mos, dos, NULL, error))
1664 g_variant_unref (header_fields);
1667 g_variant_unref (header_fields);
1669 /* header size must be a multiple of 8 */
1670 ensure_output_padding (mos, dos, 8);
1672 body_start_offset = g_memory_output_stream_get_data_size (mos);
1674 signature = g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE);
1675 signature_str = NULL;
1676 if (signature != NULL)
1677 signature_str = g_variant_get_string (signature, NULL);
1678 if (message->priv->body != NULL)
1680 gchar *tupled_signature_str;
1681 tupled_signature_str = g_strdup_printf ("(%s)", signature_str);
1682 if (signature == NULL)
1686 G_IO_ERROR_INVALID_ARGUMENT,
1687 _("Message body has signature `%s' but there is no signature header"),
1689 g_free (tupled_signature_str);
1692 else if (g_strcmp0 (tupled_signature_str, g_variant_get_type_string (message->priv->body)) != 0)
1696 G_IO_ERROR_INVALID_ARGUMENT,
1697 _("Message body has type signature `%s' but signature in the header field is `%s'"),
1698 tupled_signature_str, g_variant_get_type_string (message->priv->body));
1699 g_free (tupled_signature_str);
1702 g_free (tupled_signature_str);
1703 if (!append_body_to_blob (message->priv->body, mos, dos, error))
1708 if (signature != NULL)
1712 G_IO_ERROR_INVALID_ARGUMENT,
1713 _("Message body is empty but signature in the header field is `(%s)'"),
1719 /* OK, we're done writing the message - set the body length */
1720 size = g_memory_output_stream_get_data_size (mos);
1721 body_size = size - body_start_offset;
1723 if (!g_seekable_seek (G_SEEKABLE (mos), body_len_offset, G_SEEK_SET, NULL, error))
1726 g_data_output_stream_put_uint32 (dos, body_size, NULL, NULL);
1729 ret = g_memdup (g_memory_output_stream_get_data (mos), size);
1732 g_object_unref (dos);
1733 g_object_unref (mos);
1738 /* ---------------------------------------------------------------------------------------------------- */
1741 get_uint32_header (GDBusMessage *message,
1742 GDBusMessageHeaderField header_field)
1748 value = g_hash_table_lookup (message->priv->headers, GUINT_TO_POINTER (header_field));
1749 if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_UINT32))
1750 ret = g_variant_get_uint32 (value);
1755 static const gchar *
1756 get_string_header (GDBusMessage *message,
1757 GDBusMessageHeaderField header_field)
1763 value = g_hash_table_lookup (message->priv->headers, GUINT_TO_POINTER (header_field));
1764 if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
1765 ret = g_variant_get_string (value, NULL);
1770 static const gchar *
1771 get_object_path_header (GDBusMessage *message,
1772 GDBusMessageHeaderField header_field)
1778 value = g_hash_table_lookup (message->priv->headers, GUINT_TO_POINTER (header_field));
1779 if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_OBJECT_PATH))
1780 ret = g_variant_get_string (value, NULL);
1785 static const gchar *
1786 get_signature_header (GDBusMessage *message,
1787 GDBusMessageHeaderField header_field)
1793 value = g_hash_table_lookup (message->priv->headers, GUINT_TO_POINTER (header_field));
1794 if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_SIGNATURE))
1795 ret = g_variant_get_string (value, NULL);
1800 /* ---------------------------------------------------------------------------------------------------- */
1803 set_uint32_header (GDBusMessage *message,
1804 GDBusMessageHeaderField header_field,
1807 g_dbus_message_set_header (message,
1809 g_variant_new_uint32 (value));
1813 set_string_header (GDBusMessage *message,
1814 GDBusMessageHeaderField header_field,
1817 g_dbus_message_set_header (message,
1819 value == NULL ? NULL : g_variant_new_string (value));
1823 set_object_path_header (GDBusMessage *message,
1824 GDBusMessageHeaderField header_field,
1827 g_dbus_message_set_header (message,
1829 value == NULL ? NULL : g_variant_new_object_path (value));
1833 set_signature_header (GDBusMessage *message,
1834 GDBusMessageHeaderField header_field,
1837 g_dbus_message_set_header (message,
1839 value == NULL ? NULL : g_variant_new_signature (value));
1842 /* ---------------------------------------------------------------------------------------------------- */
1845 * g_dbus_message_get_reply_serial:
1846 * @message: A #GDBusMessage.
1848 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL header field.
1850 * Returns: The value.
1855 g_dbus_message_get_reply_serial (GDBusMessage *message)
1857 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), 0);
1858 return get_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL);
1862 * g_dbus_message_set_reply_serial:
1863 * @message: A #GDBusMessage.
1864 * @value: The value to set.
1866 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL header field.
1871 g_dbus_message_set_reply_serial (GDBusMessage *message,
1874 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
1875 set_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL, value);
1878 /* ---------------------------------------------------------------------------------------------------- */
1881 * g_dbus_message_get_interface:
1882 * @message: A #GDBusMessage.
1884 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE header field.
1886 * Returns: The value.
1891 g_dbus_message_get_interface (GDBusMessage *message)
1893 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
1894 return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE);
1898 * g_dbus_message_set_interface:
1899 * @message: A #GDBusMessage.
1900 * @value: The value to set.
1902 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE header field.
1907 g_dbus_message_set_interface (GDBusMessage *message,
1910 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
1911 g_return_if_fail (value == NULL || g_dbus_is_interface_name (value));
1912 set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE, value);
1915 /* ---------------------------------------------------------------------------------------------------- */
1918 * g_dbus_message_get_member:
1919 * @message: A #GDBusMessage.
1921 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_MEMBER header field.
1923 * Returns: The value.
1928 g_dbus_message_get_member (GDBusMessage *message)
1930 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
1931 return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER);
1935 * g_dbus_message_set_member:
1936 * @message: A #GDBusMessage.
1937 * @value: The value to set.
1939 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_MEMBER header field.
1944 g_dbus_message_set_member (GDBusMessage *message,
1947 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
1948 g_return_if_fail (value == NULL || g_dbus_is_member_name (value));
1949 set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER, value);
1952 /* ---------------------------------------------------------------------------------------------------- */
1955 * g_dbus_message_get_path:
1956 * @message: A #GDBusMessage.
1958 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_PATH header field.
1960 * Returns: The value.
1965 g_dbus_message_get_path (GDBusMessage *message)
1967 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
1968 return get_object_path_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH);
1972 * g_dbus_message_set_path:
1973 * @message: A #GDBusMessage.
1974 * @value: The value to set.
1976 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_PATH header field.
1981 g_dbus_message_set_path (GDBusMessage *message,
1984 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
1985 g_return_if_fail (value == NULL || g_variant_is_object_path (value));
1986 set_object_path_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH, value);
1989 /* ---------------------------------------------------------------------------------------------------- */
1992 * g_dbus_message_get_sender:
1993 * @message: A #GDBusMessage.
1995 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_SENDER header field.
1997 * Returns: The value.
2002 g_dbus_message_get_sender (GDBusMessage *message)
2004 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2005 return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SENDER);
2009 * g_dbus_message_set_sender:
2010 * @message: A #GDBusMessage.
2011 * @value: The value to set.
2013 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_SENDER header field.
2018 g_dbus_message_set_sender (GDBusMessage *message,
2021 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2022 g_return_if_fail (value == NULL || g_dbus_is_name (value));
2023 set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SENDER, value);
2026 /* ---------------------------------------------------------------------------------------------------- */
2029 * g_dbus_message_get_destination:
2030 * @message: A #GDBusMessage.
2032 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION header field.
2034 * Returns: The value.
2039 g_dbus_message_get_destination (GDBusMessage *message)
2041 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2042 return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION);
2046 * g_dbus_message_set_destination:
2047 * @message: A #GDBusMessage.
2048 * @value: The value to set.
2050 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION header field.
2055 g_dbus_message_set_destination (GDBusMessage *message,
2058 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2059 g_return_if_fail (value == NULL || g_dbus_is_name (value));
2060 set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION, value);
2063 /* ---------------------------------------------------------------------------------------------------- */
2066 * g_dbus_message_get_error_name:
2067 * @message: A #GDBusMessage.
2069 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME header field.
2071 * Returns: The value.
2076 g_dbus_message_get_error_name (GDBusMessage *message)
2078 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2079 return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME);
2083 * g_dbus_message_set_error_name:
2084 * @message: A #GDBusMessage.
2085 * @value: The value to set.
2087 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME header field.
2092 g_dbus_message_set_error_name (GDBusMessage *message,
2095 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2096 g_return_if_fail (value == NULL || g_dbus_is_interface_name (value));
2097 set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME, value);
2100 /* ---------------------------------------------------------------------------------------------------- */
2103 * g_dbus_message_get_signature:
2104 * @message: A #GDBusMessage.
2106 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE header field.
2108 * Returns: The value.
2113 g_dbus_message_get_signature (GDBusMessage *message)
2116 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2117 ret = get_signature_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE);
2124 * g_dbus_message_set_signature:
2125 * @message: A #GDBusMessage.
2126 * @value: The value to set.
2128 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE header field.
2133 g_dbus_message_set_signature (GDBusMessage *message,
2136 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2137 g_return_if_fail (value == NULL || g_variant_is_signature (value));
2138 set_signature_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE, value);
2141 /* ---------------------------------------------------------------------------------------------------- */
2144 * g_dbus_message_get_arg0:
2145 * @message: A #GDBusMessage.
2147 * Convenience to get the first item in the body of @message.
2149 * Returns: The string item or %NULL if the first item in the body of
2150 * @message is not a string.
2155 g_dbus_message_get_arg0 (GDBusMessage *message)
2159 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2163 if (message->priv->body != NULL && g_variant_is_of_type (message->priv->body, G_VARIANT_TYPE_TUPLE))
2166 item = g_variant_get_child_value (message->priv->body, 0);
2167 if (g_variant_is_of_type (item, G_VARIANT_TYPE_STRING))
2168 ret = g_variant_get_string (item, NULL);
2174 /* ---------------------------------------------------------------------------------------------------- */
2177 * g_dbus_message_get_num_unix_fds:
2178 * @message: A #GDBusMessage.
2180 * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS header field.
2182 * Returns: The value.
2187 g_dbus_message_get_num_unix_fds (GDBusMessage *message)
2189 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), 0);
2190 return get_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS);
2194 * g_dbus_message_set_num_unix_fds:
2195 * @message: A #GDBusMessage.
2196 * @value: The value to set.
2198 * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS header field.
2203 g_dbus_message_set_num_unix_fds (GDBusMessage *message,
2206 g_return_if_fail (G_IS_DBUS_MESSAGE (message));
2207 set_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS, value);
2210 /* ---------------------------------------------------------------------------------------------------- */
2213 * g_dbus_message_to_gerror:
2214 * @message: A #GDBusMessage.
2215 * @error: The #GError to set.
2217 * If @message is not of type %G_DBUS_MESSAGE_TYPE_ERROR does
2218 * nothing and returns %FALSE.
2220 * Otherwise this method encodes the error in @message as a #GError
2221 * using g_dbus_error_set_dbus_error() using the information in the
2222 * %G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME header field of @message as
2223 * well as the first string item in @message's body.
2225 * Returns: %TRUE if @error was set, %FALSE otherwise.
2230 g_dbus_message_to_gerror (GDBusMessage *message,
2234 const gchar *error_name;
2236 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), FALSE);
2239 if (message->priv->type != G_DBUS_MESSAGE_TYPE_ERROR)
2242 error_name = g_dbus_message_get_error_name (message);
2243 if (error_name != NULL)
2247 body = g_dbus_message_get_body (message);
2249 if (body != NULL && g_variant_is_of_type (body, G_VARIANT_TYPE ("(s)")))
2251 const gchar *error_message;
2252 g_variant_get (body, "(&s)", &error_message);
2253 g_dbus_error_set_dbus_error (error,
2260 /* these two situations are valid, yet pretty rare */
2263 g_dbus_error_set_dbus_error (error,
2266 _("Error return with body of type `%s'"),
2267 g_variant_get_type_string (body));
2271 g_dbus_error_set_dbus_error (error,
2274 _("Error return with empty body"));
2280 /* TOOD: this shouldn't happen - should check this at message serialization
2281 * time and disconnect the peer.
2286 "Error return without error-name header!");
2295 /* ---------------------------------------------------------------------------------------------------- */
2298 enum_to_string (GType enum_type, gint value)
2302 GEnumValue *enum_value;
2304 klass = g_type_class_ref (enum_type);
2305 enum_value = g_enum_get_value (klass, value);
2306 if (enum_value != NULL)
2307 ret = g_strdup (enum_value->value_nick);
2309 ret = g_strdup_printf ("unknown (value %d)", value);
2310 g_type_class_unref (klass);
2315 flags_to_string (GType flags_type, guint value)
2321 klass = g_type_class_ref (flags_type);
2322 s = g_string_new (NULL);
2323 for (n = 0; n < 32; n++)
2325 if ((value & (1<<n)) != 0)
2327 GFlagsValue *flags_value;
2328 flags_value = g_flags_get_first_value (klass, (1<<n));
2330 g_string_append_c (s, ',');
2331 if (flags_value != NULL)
2332 g_string_append (s, flags_value->value_nick);
2334 g_string_append_printf (s, "unknown (bit %d)", n);
2338 g_string_append (s, "none");
2339 g_type_class_unref (klass);
2340 return g_string_free (s, FALSE);;
2344 _sort_keys_func (gconstpointer a,
2350 ia = GPOINTER_TO_INT (a);
2351 ib = GPOINTER_TO_INT (b);
2357 * g_dbus_message_print:
2358 * @message: A #GDBusMessage.
2359 * @indent: Indentation level.
2361 * Produces a human-readable multi-line description of @message.
2363 * The contents of the description has no ABI guarantees, the contents
2364 * and formatting is subject to change at any time. Typical output
2365 * looks something like this:
2372 * path -> objectpath '/org/gtk/GDBus/TestObject'
2373 * interface -> 'org.gtk.GDBus.TestInterface'
2374 * member -> 'GimmeStdout'
2375 * destination -> ':1.146'
2377 * UNIX File Descriptors:
2382 * Type: method-return
2383 * Flags: no-reply-expected
2387 * reply-serial -> uint32 4
2388 * destination -> ':1.159'
2389 * sender -> ':1.146'
2390 * num-unix-fds -> uint32 1
2392 * UNIX File Descriptors:
2393 * fd 12: dev=0:10,mode=020620,ino=5,uid=500,gid=5,rdev=136:2,size=0,atime=1273085037,mtime=1273085851,ctime=1272982635
2396 * Returns: A string that should be freed with g_free().
2401 g_dbus_message_print (GDBusMessage *message,
2409 g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
2411 str = g_string_new (NULL);
2413 s = enum_to_string (G_TYPE_DBUS_MESSAGE_TYPE, message->priv->type);
2414 g_string_append_printf (str, "%*sType: %s\n", indent, "", s);
2416 s = flags_to_string (G_TYPE_DBUS_MESSAGE_FLAGS, message->priv->flags);
2417 g_string_append_printf (str, "%*sFlags: %s\n", indent, "", s);
2419 g_string_append_printf (str, "%*sVersion: %d\n", indent, "", message->priv->major_protocol_version);
2420 g_string_append_printf (str, "%*sSerial: %d\n", indent, "", message->priv->serial);
2422 g_string_append_printf (str, "%*sHeaders:\n", indent, "");
2423 keys = g_hash_table_get_keys (message->priv->headers);
2424 keys = g_list_sort (keys, _sort_keys_func);
2427 for (l = keys; l != NULL; l = l->next)
2429 gint key = GPOINTER_TO_INT (l->data);
2433 value = g_hash_table_lookup (message->priv->headers, l->data);
2434 g_assert (value != NULL);
2436 s = enum_to_string (G_TYPE_DBUS_MESSAGE_HEADER_FIELD, key);
2437 value_str = g_variant_print (value, TRUE);
2438 g_string_append_printf (str, "%*s %s -> %s\n", indent, "", s, value_str);
2445 g_string_append_printf (str, "%*s (none)\n", indent, "");
2447 g_string_append_printf (str, "%*sBody: ", indent, "");
2448 if (message->priv->body != NULL)
2450 g_variant_print_string (message->priv->body,
2456 g_string_append (str, "()");
2458 g_string_append (str, "\n");
2460 g_string_append_printf (str, "%*sUNIX File Descriptors:\n", indent, "");
2461 if (message->priv->fd_list != NULL)
2467 fds = g_unix_fd_list_peek_fds (message->priv->fd_list, &num_fds);
2470 for (n = 0; n < num_fds; n++)
2473 struct stat statbuf;
2474 fs = g_string_new (NULL);
2475 if (fstat (fds[n], &statbuf) == 0)
2477 g_string_append_printf (fs, "%s" "dev=%d:%d", fs->len > 0 ? "," : "",
2478 major (statbuf.st_dev), minor (statbuf.st_dev));
2479 g_string_append_printf (fs, "%s" "mode=0%o", fs->len > 0 ? "," : "",
2481 g_string_append_printf (fs, "%s" "ino=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
2482 (guint64) statbuf.st_ino);
2483 g_string_append_printf (fs, "%s" "uid=%d", fs->len > 0 ? "," : "",
2485 g_string_append_printf (fs, "%s" "gid=%d", fs->len > 0 ? "," : "",
2487 g_string_append_printf (fs, "%s" "rdev=%d:%d", fs->len > 0 ? "," : "",
2488 major (statbuf.st_rdev), minor (statbuf.st_rdev));
2489 g_string_append_printf (fs, "%s" "size=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
2490 (guint64) statbuf.st_size);
2491 g_string_append_printf (fs, "%s" "atime=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
2492 (guint64) statbuf.st_atime);
2493 g_string_append_printf (fs, "%s" "mtime=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
2494 (guint64) statbuf.st_mtime);
2495 g_string_append_printf (fs, "%s" "ctime=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "",
2496 (guint64) statbuf.st_ctime);
2500 g_string_append_printf (fs, "(fstat failed: %s)", strerror (errno));
2502 g_string_append_printf (str, "%*s fd %d: %s\n", indent, "", fds[n], fs->str);
2503 g_string_free (fs, TRUE);
2508 g_string_append_printf (str, "%*s (empty)\n", indent, "");
2513 g_string_append_printf (str, "%*s (none)\n", indent, "");
2517 return g_string_free (str, FALSE);
2521 #define __G_DBUS_MESSAGE_C__
2522 #include "gioaliasdef.c"