Add some more test about gdbus_error apis
[glib.git] / gio / gdbusutils.c
blob6ac9dfcda2bcf64dfc896790361311fc6ae40c9e
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 #include "config.h"
25 #include <stdlib.h>
26 #include <string.h>
28 #include "gdbusutils.h"
30 #include "glibintl.h"
32 /**
33 * SECTION:gdbusutils
34 * @title: D-Bus Utilities
35 * @short_description: Various utilities related to D-Bus.
36 * @include: gio/gio.h
38 * Various utility routines related to D-Bus.
41 static gboolean
42 is_valid_bus_name_character (gint c,
43 gboolean allow_hyphen)
45 return
46 (c >= '0' && c <= '9') ||
47 (c >= 'A' && c <= 'Z') ||
48 (c >= 'a' && c <= 'z') ||
49 (c == '_') ||
50 (allow_hyphen && c == '-');
53 static gboolean
54 is_valid_initial_bus_name_character (gint c,
55 gboolean allow_initial_digit,
56 gboolean allow_hyphen)
58 if (allow_initial_digit)
59 return is_valid_bus_name_character (c, allow_hyphen);
60 else
61 return
62 (c >= 'A' && c <= 'Z') ||
63 (c >= 'a' && c <= 'z') ||
64 (c == '_') ||
65 (allow_hyphen && c == '-');
68 static gboolean
69 is_valid_name (const gchar *start,
70 guint len,
71 gboolean allow_initial_digit,
72 gboolean allow_hyphen)
74 gboolean ret;
75 const gchar *s;
76 const gchar *end;
77 gboolean has_dot;
79 ret = FALSE;
81 if (len == 0)
82 goto out;
84 s = start;
85 end = s + len;
86 has_dot = FALSE;
87 while (s != end)
89 if (*s == '.')
91 s += 1;
92 if (G_UNLIKELY (!is_valid_initial_bus_name_character (*s, allow_initial_digit, allow_hyphen)))
93 goto out;
94 has_dot = TRUE;
96 else if (G_UNLIKELY (!is_valid_bus_name_character (*s, allow_hyphen)))
98 goto out;
100 s += 1;
103 if (G_UNLIKELY (!has_dot))
104 goto out;
106 ret = TRUE;
108 out:
109 return ret;
113 * g_dbus_is_name:
114 * @string: The string to check.
116 * Checks if @string is a valid D-Bus bus name (either unique or well-known).
118 * Returns: %TRUE if valid, %FALSE otherwise.
120 * Since: 2.26
122 gboolean
123 g_dbus_is_name (const gchar *string)
125 guint len;
126 gboolean ret;
127 const gchar *s;
128 const gchar *end;
130 g_return_val_if_fail (string != NULL, FALSE);
132 ret = FALSE;
134 len = strlen (string);
135 if (G_UNLIKELY (len == 0 || len > 255))
136 goto out;
138 s = string;
139 end = s + len;
140 if (*s == ':')
142 /* handle unique name */
143 if (!is_valid_name (s + 1, len - 1, TRUE, TRUE))
144 goto out;
145 ret = TRUE;
146 goto out;
148 else if (G_UNLIKELY (*s == '.'))
150 /* can't start with a . */
151 goto out;
153 else if (G_UNLIKELY (!is_valid_initial_bus_name_character (*s, FALSE, TRUE)))
154 goto out;
156 ret = is_valid_name (s + 1, len - 1, FALSE, TRUE);
158 out:
159 return ret;
163 * g_dbus_is_unique_name:
164 * @string: The string to check.
166 * Checks if @string is a valid D-Bus unique bus name.
168 * Returns: %TRUE if valid, %FALSE otherwise.
170 * Since: 2.26
172 gboolean
173 g_dbus_is_unique_name (const gchar *string)
175 gboolean ret;
176 guint len;
178 g_return_val_if_fail (string != NULL, FALSE);
180 ret = FALSE;
182 len = strlen (string);
183 if (G_UNLIKELY (len == 0 || len > 255))
184 goto out;
186 if (G_UNLIKELY (*string != ':'))
187 goto out;
189 if (G_UNLIKELY (!is_valid_name (string + 1, len - 1, TRUE, TRUE)))
190 goto out;
192 ret = TRUE;
194 out:
195 return ret;
199 * g_dbus_is_member_name:
200 * @string: The string to check.
202 * Checks if @string is a valid D-Bus member (e.g. signal or method) name.
204 * Returns: %TRUE if valid, %FALSE otherwise.
206 * Since: 2.26
208 gboolean
209 g_dbus_is_member_name (const gchar *string)
211 gboolean ret;
212 guint n;
214 ret = FALSE;
215 if (G_UNLIKELY (string == NULL))
216 goto out;
218 if (G_UNLIKELY (!is_valid_initial_bus_name_character (string[0], FALSE, FALSE)))
219 goto out;
221 for (n = 1; string[n] != '\0'; n++)
223 if (G_UNLIKELY (!is_valid_bus_name_character (string[n], FALSE)))
225 goto out;
229 ret = TRUE;
231 out:
232 return ret;
236 * g_dbus_is_interface_name:
237 * @string: The string to check.
239 * Checks if @string is a valid D-Bus interface name.
241 * Returns: %TRUE if valid, %FALSE otherwise.
243 * Since: 2.26
245 gboolean
246 g_dbus_is_interface_name (const gchar *string)
248 guint len;
249 gboolean ret;
250 const gchar *s;
251 const gchar *end;
253 g_return_val_if_fail (string != NULL, FALSE);
255 ret = FALSE;
257 len = strlen (string);
258 if (G_UNLIKELY (len == 0 || len > 255))
259 goto out;
261 s = string;
262 end = s + len;
263 if (G_UNLIKELY (*s == '.'))
265 /* can't start with a . */
266 goto out;
268 else if (G_UNLIKELY (!is_valid_initial_bus_name_character (*s, FALSE, FALSE)))
269 goto out;
271 ret = is_valid_name (s + 1, len - 1, FALSE, FALSE);
273 out:
274 return ret;
277 /* ---------------------------------------------------------------------------------------------------- */
279 /* TODO: maybe move to glib? if so, it should conform to http://en.wikipedia.org/wiki/Guid and/or
280 * http://tools.ietf.org/html/rfc4122 - specifically it should have hyphens then.
284 * g_dbus_generate_guid:
286 * Generate a D-Bus GUID that can be used with
287 * e.g. g_dbus_connection_new().
289 * See the D-Bus specification regarding what strings are valid D-Bus
290 * GUID (for example, D-Bus GUIDs are not RFC-4122 compliant).
292 * Returns: A valid D-Bus GUID. Free with g_free().
294 * Since: 2.26
296 gchar *
297 g_dbus_generate_guid (void)
299 GString *s;
300 GTimeVal now;
301 guint32 r1;
302 guint32 r2;
303 guint32 r3;
305 s = g_string_new (NULL);
307 r1 = g_random_int ();
308 r2 = g_random_int ();
309 r3 = g_random_int ();
310 g_get_current_time (&now);
312 g_string_append_printf (s, "%08x", r1);
313 g_string_append_printf (s, "%08x", r2);
314 g_string_append_printf (s, "%08x", r3);
315 g_string_append_printf (s, "%08x", (guint32) now.tv_sec);
317 return g_string_free (s, FALSE);
321 * g_dbus_is_guid:
322 * @string: The string to check.
324 * Checks if @string is a D-Bus GUID.
326 * See the D-Bus specification regarding what strings are valid D-Bus
327 * GUID (for example, D-Bus GUIDs are not RFC-4122 compliant).
329 * Returns: %TRUE if @string is a guid, %FALSE otherwise.
331 * Since: 2.26
333 gboolean
334 g_dbus_is_guid (const gchar *string)
336 gboolean ret;
337 guint n;
339 g_return_val_if_fail (string != NULL, FALSE);
341 ret = FALSE;
343 for (n = 0; n < 32; n++)
345 if (!g_ascii_isxdigit (string[n]))
346 goto out;
348 if (string[32] != '\0')
349 goto out;
351 ret = TRUE;
353 out:
354 return ret;
357 /* ---------------------------------------------------------------------------------------------------- */