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, see <http://www.gnu.org/licenses/>.
18 * Author: David Zeuthen <davidz@redhat.com>
26 #include "gdbusutils.h"
32 * @title: D-Bus Utilities
33 * @short_description: Various utilities related to D-Bus
36 * Various utility routines related to D-Bus.
40 is_valid_bus_name_character (gint c,
41 gboolean allow_hyphen)
44 (c >= '0' && c <= '9') ||
45 (c >= 'A' && c <= 'Z') ||
46 (c >= 'a' && c <= 'z') ||
48 (allow_hyphen && c == '-');
52 is_valid_initial_bus_name_character (gint c,
53 gboolean allow_initial_digit,
54 gboolean allow_hyphen)
56 if (allow_initial_digit)
57 return is_valid_bus_name_character (c, allow_hyphen);
60 (c >= 'A' && c <= 'Z') ||
61 (c >= 'a' && c <= 'z') ||
63 (allow_hyphen && c == '-');
67 is_valid_name (const gchar *start,
69 gboolean allow_initial_digit,
70 gboolean allow_hyphen)
90 if (G_UNLIKELY (!is_valid_initial_bus_name_character (*s, allow_initial_digit, allow_hyphen)))
94 else if (G_UNLIKELY (!is_valid_bus_name_character (*s, allow_hyphen)))
101 if (G_UNLIKELY (!has_dot))
112 * @string: The string to check.
114 * Checks if @string is a valid D-Bus bus name (either unique or well-known).
116 * Returns: %TRUE if valid, %FALSE otherwise.
121 g_dbus_is_name (const gchar *string)
127 g_return_val_if_fail (string != NULL, FALSE);
131 len = strlen (string);
132 if (G_UNLIKELY (len == 0 || len > 255))
138 /* handle unique name */
139 if (!is_valid_name (s + 1, len - 1, TRUE, TRUE))
144 else if (G_UNLIKELY (*s == '.'))
146 /* can't start with a . */
149 else if (G_UNLIKELY (!is_valid_initial_bus_name_character (*s, FALSE, TRUE)))
152 ret = is_valid_name (s + 1, len - 1, FALSE, TRUE);
159 * g_dbus_is_unique_name:
160 * @string: The string to check.
162 * Checks if @string is a valid D-Bus unique bus name.
164 * Returns: %TRUE if valid, %FALSE otherwise.
169 g_dbus_is_unique_name (const gchar *string)
174 g_return_val_if_fail (string != NULL, FALSE);
178 len = strlen (string);
179 if (G_UNLIKELY (len == 0 || len > 255))
182 if (G_UNLIKELY (*string != ':'))
185 if (G_UNLIKELY (!is_valid_name (string + 1, len - 1, TRUE, TRUE)))
195 * g_dbus_is_member_name:
196 * @string: The string to check.
198 * Checks if @string is a valid D-Bus member (e.g. signal or method) name.
200 * Returns: %TRUE if valid, %FALSE otherwise.
205 g_dbus_is_member_name (const gchar *string)
211 if (G_UNLIKELY (string == NULL))
214 if (G_UNLIKELY (!is_valid_initial_bus_name_character (string[0], FALSE, FALSE)))
217 for (n = 1; string[n] != '\0'; n++)
219 if (G_UNLIKELY (!is_valid_bus_name_character (string[n], FALSE)))
232 * g_dbus_is_interface_name:
233 * @string: The string to check.
235 * Checks if @string is a valid D-Bus interface name.
237 * Returns: %TRUE if valid, %FALSE otherwise.
242 g_dbus_is_interface_name (const gchar *string)
248 g_return_val_if_fail (string != NULL, FALSE);
252 len = strlen (string);
253 if (G_UNLIKELY (len == 0 || len > 255))
257 if (G_UNLIKELY (*s == '.'))
259 /* can't start with a . */
262 else if (G_UNLIKELY (!is_valid_initial_bus_name_character (*s, FALSE, FALSE)))
265 ret = is_valid_name (s + 1, len - 1, FALSE, FALSE);
271 /* ---------------------------------------------------------------------------------------------------- */
273 /* TODO: maybe move to glib? if so, it should conform to http://en.wikipedia.org/wiki/Guid and/or
274 * http://tools.ietf.org/html/rfc4122 - specifically it should have hyphens then.
278 * g_dbus_generate_guid:
280 * Generate a D-Bus GUID that can be used with
281 * e.g. g_dbus_connection_new().
283 * See the D-Bus specification regarding what strings are valid D-Bus
284 * GUID (for example, D-Bus GUIDs are not RFC-4122 compliant).
286 * Returns: A valid D-Bus GUID. Free with g_free().
291 g_dbus_generate_guid (void)
299 s = g_string_new (NULL);
301 r1 = g_random_int ();
302 r2 = g_random_int ();
303 r3 = g_random_int ();
304 g_get_current_time (&now);
306 g_string_append_printf (s, "%08x", r1);
307 g_string_append_printf (s, "%08x", r2);
308 g_string_append_printf (s, "%08x", r3);
309 g_string_append_printf (s, "%08x", (guint32) now.tv_sec);
311 return g_string_free (s, FALSE);
316 * @string: The string to check.
318 * Checks if @string is a D-Bus GUID.
320 * See the D-Bus specification regarding what strings are valid D-Bus
321 * GUID (for example, D-Bus GUIDs are not RFC-4122 compliant).
323 * Returns: %TRUE if @string is a guid, %FALSE otherwise.
328 g_dbus_is_guid (const gchar *string)
333 g_return_val_if_fail (string != NULL, FALSE);
337 for (n = 0; n < 32; n++)
339 if (!g_ascii_isxdigit (string[n]))
342 if (string[32] != '\0')
351 /* ---------------------------------------------------------------------------------------------------- */
354 * g_dbus_gvariant_to_gvalue:
355 * @value: A #GVariant.
356 * @out_gvalue: (out): Return location pointing to a zero-filled (uninitialized) #GValue.
358 * Converts a #GVariant to a #GValue. If @value is floating, it is consumed.
360 * The rules specified in the g_dbus_gvalue_to_gvariant() function are
361 * used - this function is essentially its reverse form.
363 * The conversion never fails - a valid #GValue is always returned in
369 g_dbus_gvariant_to_gvalue (GVariant *value,
372 const GVariantType *type;
375 g_return_if_fail (value != NULL);
376 g_return_if_fail (out_gvalue != NULL);
378 memset (out_gvalue, '\0', sizeof (GValue));
380 switch (g_variant_classify (value))
382 case G_VARIANT_CLASS_BOOLEAN:
383 g_value_init (out_gvalue, G_TYPE_BOOLEAN);
384 g_value_set_boolean (out_gvalue, g_variant_get_boolean (value));
387 case G_VARIANT_CLASS_BYTE:
388 g_value_init (out_gvalue, G_TYPE_UCHAR);
389 g_value_set_uchar (out_gvalue, g_variant_get_byte (value));
392 case G_VARIANT_CLASS_INT16:
393 g_value_init (out_gvalue, G_TYPE_INT);
394 g_value_set_int (out_gvalue, g_variant_get_int16 (value));
397 case G_VARIANT_CLASS_UINT16:
398 g_value_init (out_gvalue, G_TYPE_UINT);
399 g_value_set_uint (out_gvalue, g_variant_get_uint16 (value));
402 case G_VARIANT_CLASS_INT32:
403 g_value_init (out_gvalue, G_TYPE_INT);
404 g_value_set_int (out_gvalue, g_variant_get_int32 (value));
407 case G_VARIANT_CLASS_UINT32:
408 g_value_init (out_gvalue, G_TYPE_UINT);
409 g_value_set_uint (out_gvalue, g_variant_get_uint32 (value));
412 case G_VARIANT_CLASS_INT64:
413 g_value_init (out_gvalue, G_TYPE_INT64);
414 g_value_set_int64 (out_gvalue, g_variant_get_int64 (value));
417 case G_VARIANT_CLASS_UINT64:
418 g_value_init (out_gvalue, G_TYPE_UINT64);
419 g_value_set_uint64 (out_gvalue, g_variant_get_uint64 (value));
422 case G_VARIANT_CLASS_DOUBLE:
423 g_value_init (out_gvalue, G_TYPE_DOUBLE);
424 g_value_set_double (out_gvalue, g_variant_get_double (value));
427 case G_VARIANT_CLASS_STRING:
428 g_value_init (out_gvalue, G_TYPE_STRING);
429 g_value_set_string (out_gvalue, g_variant_get_string (value, NULL));
432 case G_VARIANT_CLASS_OBJECT_PATH:
433 g_value_init (out_gvalue, G_TYPE_STRING);
434 g_value_set_string (out_gvalue, g_variant_get_string (value, NULL));
437 case G_VARIANT_CLASS_SIGNATURE:
438 g_value_init (out_gvalue, G_TYPE_STRING);
439 g_value_set_string (out_gvalue, g_variant_get_string (value, NULL));
442 case G_VARIANT_CLASS_ARRAY:
443 type = g_variant_get_type (value);
444 switch (g_variant_type_peek_string (type)[1])
446 case G_VARIANT_CLASS_BYTE:
447 g_value_init (out_gvalue, G_TYPE_STRING);
448 g_value_set_string (out_gvalue, g_variant_get_bytestring (value));
451 case G_VARIANT_CLASS_STRING:
452 g_value_init (out_gvalue, G_TYPE_STRV);
453 array = g_variant_dup_strv (value, NULL);
454 g_value_take_boxed (out_gvalue, array);
457 case G_VARIANT_CLASS_OBJECT_PATH:
458 g_value_init (out_gvalue, G_TYPE_STRV);
459 array = g_variant_dup_objv (value, NULL);
460 g_value_take_boxed (out_gvalue, array);
463 case G_VARIANT_CLASS_ARRAY:
464 switch (g_variant_type_peek_string (type)[2])
466 case G_VARIANT_CLASS_BYTE:
467 g_value_init (out_gvalue, G_TYPE_STRV);
468 array = g_variant_dup_bytestring_array (value, NULL);
469 g_value_take_boxed (out_gvalue, array);
473 g_value_init (out_gvalue, G_TYPE_VARIANT);
474 g_value_set_variant (out_gvalue, value);
480 g_value_init (out_gvalue, G_TYPE_VARIANT);
481 g_value_set_variant (out_gvalue, value);
486 case G_VARIANT_CLASS_HANDLE:
487 case G_VARIANT_CLASS_VARIANT:
488 case G_VARIANT_CLASS_MAYBE:
489 case G_VARIANT_CLASS_TUPLE:
490 case G_VARIANT_CLASS_DICT_ENTRY:
491 g_value_init (out_gvalue, G_TYPE_VARIANT);
492 g_value_set_variant (out_gvalue, value);
499 * g_dbus_gvalue_to_gvariant:
500 * @gvalue: A #GValue to convert to a #GVariant.
501 * @type: A #GVariantType.
503 * Converts a #GValue to a #GVariant of the type indicated by the @type parameter.
505 * The conversion is using the following rules:
506 * <table frame='all'>
507 * <title>#GValue / #GVariant conversion rules</title>
508 * <tgroup cols='2' align='left' colsep='1' rowsep='1'>
511 * <entry>If the #GType for @gvalue is...</entry>
512 * <entry>... then @type must be</entry>
517 * <entry>#G_TYPE_STRING</entry>
519 * ['s'][G-VARIANT-TYPE-STRING:CAPS],
520 * ['o'][G-VARIANT-TYPE-OBJECT-PATH:CAPS],
521 * ['g'][G-VARIANT-TYPE-SIGNATURE:CAPS] or
522 * ['ay'][G-VARIANT-TYPE-BYTESTRING:CAPS]
526 * <entry>#G_TYPE_STRV</entry>
528 * ['as'][G-VARIANT-TYPE-STRING-ARRAY:CAPS],
529 * ['ao'][G-VARIANT-TYPE-OBJECT-PATH-ARRAY:CAPS] or
530 * ['aay'][G-VARIANT-TYPE-BYTESTRING-ARRAY:CAPS]
534 * <entry>#G_TYPE_BOOLEAN</entry>
536 * ['b'][G-VARIANT-TYPE-BOOLEAN:CAPS]
540 * <entry>#G_TYPE_UCHAR</entry>
542 * ['y'][G-VARIANT-TYPE-BYTE:CAPS]
546 * <entry>#G_TYPE_INT</entry>
548 * ['i'][G-VARIANT-TYPE-INT32:CAPS] or
549 * ['n'][G-VARIANT-TYPE-INT16:CAPS]
553 * <entry>#G_TYPE_UINT</entry>
555 * ['u'][G-VARIANT-TYPE-UINT32:CAPS] or
556 * ['q'][G-VARIANT-TYPE-UINT16:CAPS]
560 * <entry>#G_TYPE_INT64</entry>
562 * ['x'][G-VARIANT-TYPE-INT64:CAPS]
566 * <entry>#G_TYPE_UINT64</entry>
568 * ['t'][G-VARIANT-TYPE-UINT64:CAPS]
572 * <entry>#G_TYPE_DOUBLE</entry>
574 * ['d'][G-VARIANT-TYPE-DOUBLE:CAPS]
578 * <entry>#G_TYPE_VARIANT</entry>
579 * <entry>Any #GVariantType</entry>
584 * This can fail if e.g. @gvalue is of type #G_TYPE_STRING and @type
585 * is ['i'][G-VARIANT-TYPE-INT32:CAPS]. It will also fail for any #GType
586 * (including e.g. #G_TYPE_OBJECT and #G_TYPE_BOXED derived-types) not
587 * in the table above.
589 * Note that if @gvalue is of type #G_TYPE_VARIANT and its value is
590 * %NULL, the empty #GVariant instance (never %NULL) for @type is
591 * returned (e.g. 0 for scalar types, the empty string for string types,
592 * '/' for object path types, the empty array for any array type and so on).
594 * See the g_dbus_gvariant_to_gvalue() function for how to convert a
595 * #GVariant to a #GValue.
597 * Returns: A #GVariant (never floating) of #GVariantType
598 * @type holding the data from @gvalue or %NULL in case of
599 * failure. Free with g_variant_unref().
604 g_dbus_gvalue_to_gvariant (const GValue *gvalue,
605 const GVariantType *type)
609 const gchar * const *as;
610 const gchar *empty_strv[1] = {NULL};
612 g_return_val_if_fail (gvalue != NULL, NULL);
613 g_return_val_if_fail (type != NULL, NULL);
617 /* @type can easily be e.g. "s" with the GValue holding a GVariant - for example this
618 * can happen when using the org.gtk.GDBus.C.ForceGVariant annotation with the
619 * gdbus-codegen(1) tool.
621 if (G_VALUE_TYPE (gvalue) == G_TYPE_VARIANT)
623 ret = g_value_dup_variant (gvalue);
627 switch (g_variant_type_peek_string (type)[0])
629 case G_VARIANT_CLASS_BOOLEAN:
630 ret = g_variant_ref_sink (g_variant_new_boolean (g_value_get_boolean (gvalue)));
633 case G_VARIANT_CLASS_BYTE:
634 ret = g_variant_ref_sink (g_variant_new_byte (g_value_get_uchar (gvalue)));
637 case G_VARIANT_CLASS_INT16:
638 ret = g_variant_ref_sink (g_variant_new_int16 (g_value_get_int (gvalue)));
641 case G_VARIANT_CLASS_UINT16:
642 ret = g_variant_ref_sink (g_variant_new_uint16 (g_value_get_uint (gvalue)));
645 case G_VARIANT_CLASS_INT32:
646 ret = g_variant_ref_sink (g_variant_new_int32 (g_value_get_int (gvalue)));
649 case G_VARIANT_CLASS_UINT32:
650 ret = g_variant_ref_sink (g_variant_new_uint32 (g_value_get_uint (gvalue)));
653 case G_VARIANT_CLASS_INT64:
654 ret = g_variant_ref_sink (g_variant_new_int64 (g_value_get_int64 (gvalue)));
657 case G_VARIANT_CLASS_UINT64:
658 ret = g_variant_ref_sink (g_variant_new_uint64 (g_value_get_uint64 (gvalue)));
661 case G_VARIANT_CLASS_DOUBLE:
662 ret = g_variant_ref_sink (g_variant_new_double (g_value_get_double (gvalue)));
665 case G_VARIANT_CLASS_STRING:
666 s = g_value_get_string (gvalue);
669 ret = g_variant_ref_sink (g_variant_new_string (s));
672 case G_VARIANT_CLASS_OBJECT_PATH:
673 s = g_value_get_string (gvalue);
676 ret = g_variant_ref_sink (g_variant_new_object_path (s));
679 case G_VARIANT_CLASS_SIGNATURE:
680 s = g_value_get_string (gvalue);
683 ret = g_variant_ref_sink (g_variant_new_signature (s));
686 case G_VARIANT_CLASS_ARRAY:
687 switch (g_variant_type_peek_string (type)[1])
689 case G_VARIANT_CLASS_BYTE:
690 s = g_value_get_string (gvalue);
693 ret = g_variant_ref_sink (g_variant_new_bytestring (s));
696 case G_VARIANT_CLASS_STRING:
697 as = g_value_get_boxed (gvalue);
700 ret = g_variant_ref_sink (g_variant_new_strv (as, -1));
703 case G_VARIANT_CLASS_OBJECT_PATH:
704 as = g_value_get_boxed (gvalue);
707 ret = g_variant_ref_sink (g_variant_new_objv (as, -1));
710 case G_VARIANT_CLASS_ARRAY:
711 switch (g_variant_type_peek_string (type)[2])
713 case G_VARIANT_CLASS_BYTE:
714 as = g_value_get_boxed (gvalue);
717 ret = g_variant_ref_sink (g_variant_new_bytestring_array (as, -1));
721 ret = g_value_dup_variant (gvalue);
727 ret = g_value_dup_variant (gvalue);
732 case G_VARIANT_CLASS_HANDLE:
733 case G_VARIANT_CLASS_VARIANT:
734 case G_VARIANT_CLASS_MAYBE:
735 case G_VARIANT_CLASS_TUPLE:
736 case G_VARIANT_CLASS_DICT_ENTRY:
737 ret = g_value_dup_variant (gvalue);
742 /* Could be that the GValue is holding a NULL GVariant - in that case,
743 * we return an "empty" GVariant instead of a NULL GVariant
747 GVariant *untrusted_empty;
748 untrusted_empty = g_variant_new_from_data (type, NULL, 0, FALSE, NULL, NULL);
749 ret = g_variant_ref_sink (g_variant_get_normal_form (untrusted_empty));
750 g_variant_unref (untrusted_empty);
753 g_assert (!g_variant_is_floating (ret));