nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* GDBus - GLib D-Bus Library |
2 | * |
||
3 | * Copyright (C) 2008-2010 Red Hat, Inc. |
||
4 | * |
||
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. |
||
9 | * |
||
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. |
||
14 | * |
||
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/>. |
||
17 | * |
||
18 | * Author: David Zeuthen <davidz@redhat.com> |
||
19 | */ |
||
20 | |||
21 | #include "config.h" |
||
22 | |||
23 | #include <stdlib.h> |
||
24 | #include <string.h> |
||
25 | |||
26 | #include "gdbusutils.h" |
||
27 | |||
28 | #include "glibintl.h" |
||
29 | |||
30 | /** |
||
31 | * SECTION:gdbusutils |
||
32 | * @title: D-Bus Utilities |
||
33 | * @short_description: Various utilities related to D-Bus |
||
34 | * @include: gio/gio.h |
||
35 | * |
||
36 | * Various utility routines related to D-Bus. |
||
37 | */ |
||
38 | |||
39 | static gboolean |
||
40 | is_valid_bus_name_character (gint c, |
||
41 | gboolean allow_hyphen) |
||
42 | { |
||
43 | return |
||
44 | (c >= '0' && c <= '9') || |
||
45 | (c >= 'A' && c <= 'Z') || |
||
46 | (c >= 'a' && c <= 'z') || |
||
47 | (c == '_') || |
||
48 | (allow_hyphen && c == '-'); |
||
49 | } |
||
50 | |||
51 | static gboolean |
||
52 | is_valid_initial_bus_name_character (gint c, |
||
53 | gboolean allow_initial_digit, |
||
54 | gboolean allow_hyphen) |
||
55 | { |
||
56 | if (allow_initial_digit) |
||
57 | return is_valid_bus_name_character (c, allow_hyphen); |
||
58 | else |
||
59 | return |
||
60 | (c >= 'A' && c <= 'Z') || |
||
61 | (c >= 'a' && c <= 'z') || |
||
62 | (c == '_') || |
||
63 | (allow_hyphen && c == '-'); |
||
64 | } |
||
65 | |||
66 | static gboolean |
||
67 | is_valid_name (const gchar *start, |
||
68 | guint len, |
||
69 | gboolean allow_initial_digit, |
||
70 | gboolean allow_hyphen) |
||
71 | { |
||
72 | gboolean ret; |
||
73 | const gchar *s; |
||
74 | const gchar *end; |
||
75 | gboolean has_dot; |
||
76 | |||
77 | ret = FALSE; |
||
78 | |||
79 | if (len == 0) |
||
80 | goto out; |
||
81 | |||
82 | s = start; |
||
83 | end = s + len; |
||
84 | has_dot = FALSE; |
||
85 | while (s != end) |
||
86 | { |
||
87 | if (*s == '.') |
||
88 | { |
||
89 | s += 1; |
||
90 | if (G_UNLIKELY (!is_valid_initial_bus_name_character (*s, allow_initial_digit, allow_hyphen))) |
||
91 | goto out; |
||
92 | has_dot = TRUE; |
||
93 | } |
||
94 | else if (G_UNLIKELY (!is_valid_bus_name_character (*s, allow_hyphen))) |
||
95 | { |
||
96 | goto out; |
||
97 | } |
||
98 | s += 1; |
||
99 | } |
||
100 | |||
101 | if (G_UNLIKELY (!has_dot)) |
||
102 | goto out; |
||
103 | |||
104 | ret = TRUE; |
||
105 | |||
106 | out: |
||
107 | return ret; |
||
108 | } |
||
109 | |||
110 | /** |
||
111 | * g_dbus_is_name: |
||
112 | * @string: The string to check. |
||
113 | * |
||
114 | * Checks if @string is a valid D-Bus bus name (either unique or well-known). |
||
115 | * |
||
116 | * Returns: %TRUE if valid, %FALSE otherwise. |
||
117 | * |
||
118 | * Since: 2.26 |
||
119 | */ |
||
120 | gboolean |
||
121 | g_dbus_is_name (const gchar *string) |
||
122 | { |
||
123 | guint len; |
||
124 | gboolean ret; |
||
125 | const gchar *s; |
||
126 | |||
127 | g_return_val_if_fail (string != NULL, FALSE); |
||
128 | |||
129 | ret = FALSE; |
||
130 | |||
131 | len = strlen (string); |
||
132 | if (G_UNLIKELY (len == 0 || len > 255)) |
||
133 | goto out; |
||
134 | |||
135 | s = string; |
||
136 | if (*s == ':') |
||
137 | { |
||
138 | /* handle unique name */ |
||
139 | if (!is_valid_name (s + 1, len - 1, TRUE, TRUE)) |
||
140 | goto out; |
||
141 | ret = TRUE; |
||
142 | goto out; |
||
143 | } |
||
144 | else if (G_UNLIKELY (*s == '.')) |
||
145 | { |
||
146 | /* can't start with a . */ |
||
147 | goto out; |
||
148 | } |
||
149 | else if (G_UNLIKELY (!is_valid_initial_bus_name_character (*s, FALSE, TRUE))) |
||
150 | goto out; |
||
151 | |||
152 | ret = is_valid_name (s + 1, len - 1, FALSE, TRUE); |
||
153 | |||
154 | out: |
||
155 | return ret; |
||
156 | } |
||
157 | |||
158 | /** |
||
159 | * g_dbus_is_unique_name: |
||
160 | * @string: The string to check. |
||
161 | * |
||
162 | * Checks if @string is a valid D-Bus unique bus name. |
||
163 | * |
||
164 | * Returns: %TRUE if valid, %FALSE otherwise. |
||
165 | * |
||
166 | * Since: 2.26 |
||
167 | */ |
||
168 | gboolean |
||
169 | g_dbus_is_unique_name (const gchar *string) |
||
170 | { |
||
171 | gboolean ret; |
||
172 | guint len; |
||
173 | |||
174 | g_return_val_if_fail (string != NULL, FALSE); |
||
175 | |||
176 | ret = FALSE; |
||
177 | |||
178 | len = strlen (string); |
||
179 | if (G_UNLIKELY (len == 0 || len > 255)) |
||
180 | goto out; |
||
181 | |||
182 | if (G_UNLIKELY (*string != ':')) |
||
183 | goto out; |
||
184 | |||
185 | if (G_UNLIKELY (!is_valid_name (string + 1, len - 1, TRUE, TRUE))) |
||
186 | goto out; |
||
187 | |||
188 | ret = TRUE; |
||
189 | |||
190 | out: |
||
191 | return ret; |
||
192 | } |
||
193 | |||
194 | /** |
||
195 | * g_dbus_is_member_name: |
||
196 | * @string: The string to check. |
||
197 | * |
||
198 | * Checks if @string is a valid D-Bus member (e.g. signal or method) name. |
||
199 | * |
||
200 | * Returns: %TRUE if valid, %FALSE otherwise. |
||
201 | * |
||
202 | * Since: 2.26 |
||
203 | */ |
||
204 | gboolean |
||
205 | g_dbus_is_member_name (const gchar *string) |
||
206 | { |
||
207 | gboolean ret; |
||
208 | guint n; |
||
209 | |||
210 | ret = FALSE; |
||
211 | if (G_UNLIKELY (string == NULL)) |
||
212 | goto out; |
||
213 | |||
214 | if (G_UNLIKELY (!is_valid_initial_bus_name_character (string[0], FALSE, FALSE))) |
||
215 | goto out; |
||
216 | |||
217 | for (n = 1; string[n] != '\0'; n++) |
||
218 | { |
||
219 | if (G_UNLIKELY (!is_valid_bus_name_character (string[n], FALSE))) |
||
220 | { |
||
221 | goto out; |
||
222 | } |
||
223 | } |
||
224 | |||
225 | ret = TRUE; |
||
226 | |||
227 | out: |
||
228 | return ret; |
||
229 | } |
||
230 | |||
231 | /** |
||
232 | * g_dbus_is_interface_name: |
||
233 | * @string: The string to check. |
||
234 | * |
||
235 | * Checks if @string is a valid D-Bus interface name. |
||
236 | * |
||
237 | * Returns: %TRUE if valid, %FALSE otherwise. |
||
238 | * |
||
239 | * Since: 2.26 |
||
240 | */ |
||
241 | gboolean |
||
242 | g_dbus_is_interface_name (const gchar *string) |
||
243 | { |
||
244 | guint len; |
||
245 | gboolean ret; |
||
246 | const gchar *s; |
||
247 | |||
248 | g_return_val_if_fail (string != NULL, FALSE); |
||
249 | |||
250 | ret = FALSE; |
||
251 | |||
252 | len = strlen (string); |
||
253 | if (G_UNLIKELY (len == 0 || len > 255)) |
||
254 | goto out; |
||
255 | |||
256 | s = string; |
||
257 | if (G_UNLIKELY (*s == '.')) |
||
258 | { |
||
259 | /* can't start with a . */ |
||
260 | goto out; |
||
261 | } |
||
262 | else if (G_UNLIKELY (!is_valid_initial_bus_name_character (*s, FALSE, FALSE))) |
||
263 | goto out; |
||
264 | |||
265 | ret = is_valid_name (s + 1, len - 1, FALSE, FALSE); |
||
266 | |||
267 | out: |
||
268 | return ret; |
||
269 | } |
||
270 | |||
271 | /* ---------------------------------------------------------------------------------------------------- */ |
||
272 | |||
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. |
||
275 | */ |
||
276 | |||
277 | /** |
||
278 | * g_dbus_generate_guid: |
||
279 | * |
||
280 | * Generate a D-Bus GUID that can be used with |
||
281 | * e.g. g_dbus_connection_new(). |
||
282 | * |
||
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). |
||
285 | * |
||
286 | * Returns: A valid D-Bus GUID. Free with g_free(). |
||
287 | * |
||
288 | * Since: 2.26 |
||
289 | */ |
||
290 | gchar * |
||
291 | g_dbus_generate_guid (void) |
||
292 | { |
||
293 | GString *s; |
||
294 | GTimeVal now; |
||
295 | guint32 r1; |
||
296 | guint32 r2; |
||
297 | guint32 r3; |
||
298 | |||
299 | s = g_string_new (NULL); |
||
300 | |||
301 | r1 = g_random_int (); |
||
302 | r2 = g_random_int (); |
||
303 | r3 = g_random_int (); |
||
304 | g_get_current_time (&now); |
||
305 | |||
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); |
||
310 | |||
311 | return g_string_free (s, FALSE); |
||
312 | } |
||
313 | |||
314 | /** |
||
315 | * g_dbus_is_guid: |
||
316 | * @string: The string to check. |
||
317 | * |
||
318 | * Checks if @string is a D-Bus GUID. |
||
319 | * |
||
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). |
||
322 | * |
||
323 | * Returns: %TRUE if @string is a guid, %FALSE otherwise. |
||
324 | * |
||
325 | * Since: 2.26 |
||
326 | */ |
||
327 | gboolean |
||
328 | g_dbus_is_guid (const gchar *string) |
||
329 | { |
||
330 | gboolean ret; |
||
331 | guint n; |
||
332 | |||
333 | g_return_val_if_fail (string != NULL, FALSE); |
||
334 | |||
335 | ret = FALSE; |
||
336 | |||
337 | for (n = 0; n < 32; n++) |
||
338 | { |
||
339 | if (!g_ascii_isxdigit (string[n])) |
||
340 | goto out; |
||
341 | } |
||
342 | if (string[32] != '\0') |
||
343 | goto out; |
||
344 | |||
345 | ret = TRUE; |
||
346 | |||
347 | out: |
||
348 | return ret; |
||
349 | } |
||
350 | |||
351 | /* ---------------------------------------------------------------------------------------------------- */ |
||
352 | |||
353 | /** |
||
354 | * g_dbus_gvariant_to_gvalue: |
||
355 | * @value: A #GVariant. |
||
356 | * @out_gvalue: (out): Return location pointing to a zero-filled (uninitialized) #GValue. |
||
357 | * |
||
358 | * Converts a #GVariant to a #GValue. If @value is floating, it is consumed. |
||
359 | * |
||
360 | * The rules specified in the g_dbus_gvalue_to_gvariant() function are |
||
361 | * used - this function is essentially its reverse form. |
||
362 | * |
||
363 | * The conversion never fails - a valid #GValue is always returned in |
||
364 | * @out_gvalue. |
||
365 | * |
||
366 | * Since: 2.30 |
||
367 | */ |
||
368 | void |
||
369 | g_dbus_gvariant_to_gvalue (GVariant *value, |
||
370 | GValue *out_gvalue) |
||
371 | { |
||
372 | const GVariantType *type; |
||
373 | gchar **array; |
||
374 | |||
375 | g_return_if_fail (value != NULL); |
||
376 | g_return_if_fail (out_gvalue != NULL); |
||
377 | |||
378 | memset (out_gvalue, '\0', sizeof (GValue)); |
||
379 | |||
380 | switch (g_variant_classify (value)) |
||
381 | { |
||
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)); |
||
385 | break; |
||
386 | |||
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)); |
||
390 | break; |
||
391 | |||
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)); |
||
395 | break; |
||
396 | |||
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)); |
||
400 | break; |
||
401 | |||
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)); |
||
405 | break; |
||
406 | |||
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)); |
||
410 | break; |
||
411 | |||
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)); |
||
415 | break; |
||
416 | |||
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)); |
||
420 | break; |
||
421 | |||
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)); |
||
425 | break; |
||
426 | |||
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)); |
||
430 | break; |
||
431 | |||
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)); |
||
435 | break; |
||
436 | |||
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)); |
||
440 | break; |
||
441 | |||
442 | case G_VARIANT_CLASS_ARRAY: |
||
443 | type = g_variant_get_type (value); |
||
444 | switch (g_variant_type_peek_string (type)[1]) |
||
445 | { |
||
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)); |
||
449 | break; |
||
450 | |||
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); |
||
455 | break; |
||
456 | |||
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); |
||
461 | break; |
||
462 | |||
463 | case G_VARIANT_CLASS_ARRAY: |
||
464 | switch (g_variant_type_peek_string (type)[2]) |
||
465 | { |
||
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); |
||
470 | break; |
||
471 | |||
472 | default: |
||
473 | g_value_init (out_gvalue, G_TYPE_VARIANT); |
||
474 | g_value_set_variant (out_gvalue, value); |
||
475 | break; |
||
476 | } |
||
477 | break; |
||
478 | |||
479 | default: |
||
480 | g_value_init (out_gvalue, G_TYPE_VARIANT); |
||
481 | g_value_set_variant (out_gvalue, value); |
||
482 | break; |
||
483 | } |
||
484 | break; |
||
485 | |||
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); |
||
493 | break; |
||
494 | } |
||
495 | } |
||
496 | |||
497 | |||
498 | /** |
||
499 | * g_dbus_gvalue_to_gvariant: |
||
500 | * @gvalue: A #GValue to convert to a #GVariant |
||
501 | * @type: A #GVariantType |
||
502 | * |
||
503 | * Converts a #GValue to a #GVariant of the type indicated by the @type |
||
504 | * parameter. |
||
505 | * |
||
506 | * The conversion is using the following rules: |
||
507 | * |
||
508 | * - #G_TYPE_STRING: 's', 'o', 'g' or 'ay' |
||
509 | * - #G_TYPE_STRV: 'as', 'ao' or 'aay' |
||
510 | * - #G_TYPE_BOOLEAN: 'b' |
||
511 | * - #G_TYPE_UCHAR: 'y' |
||
512 | * - #G_TYPE_INT: 'i', 'n' |
||
513 | * - #G_TYPE_UINT: 'u', 'q' |
||
514 | * - #G_TYPE_INT64 'x' |
||
515 | * - #G_TYPE_UINT64: 't' |
||
516 | * - #G_TYPE_DOUBLE: 'd' |
||
517 | * - #G_TYPE_VARIANT: Any #GVariantType |
||
518 | * |
||
519 | * This can fail if e.g. @gvalue is of type #G_TYPE_STRING and @type |
||
520 | * is ['i'][G-VARIANT-TYPE-INT32:CAPS]. It will also fail for any #GType |
||
521 | * (including e.g. #G_TYPE_OBJECT and #G_TYPE_BOXED derived-types) not |
||
522 | * in the table above. |
||
523 | * |
||
524 | * Note that if @gvalue is of type #G_TYPE_VARIANT and its value is |
||
525 | * %NULL, the empty #GVariant instance (never %NULL) for @type is |
||
526 | * returned (e.g. 0 for scalar types, the empty string for string types, |
||
527 | * '/' for object path types, the empty array for any array type and so on). |
||
528 | * |
||
529 | * See the g_dbus_gvariant_to_gvalue() function for how to convert a |
||
530 | * #GVariant to a #GValue. |
||
531 | * |
||
532 | * Returns: A #GVariant (never floating) of #GVariantType @type holding |
||
533 | * the data from @gvalue or %NULL in case of failure. Free with |
||
534 | * g_variant_unref(). |
||
535 | * |
||
536 | * Since: 2.30 |
||
537 | */ |
||
538 | GVariant * |
||
539 | g_dbus_gvalue_to_gvariant (const GValue *gvalue, |
||
540 | const GVariantType *type) |
||
541 | { |
||
542 | GVariant *ret; |
||
543 | const gchar *s; |
||
544 | const gchar * const *as; |
||
545 | const gchar *empty_strv[1] = {NULL}; |
||
546 | |||
547 | g_return_val_if_fail (gvalue != NULL, NULL); |
||
548 | g_return_val_if_fail (type != NULL, NULL); |
||
549 | |||
550 | ret = NULL; |
||
551 | |||
552 | /* @type can easily be e.g. "s" with the GValue holding a GVariant - for example this |
||
553 | * can happen when using the org.gtk.GDBus.C.ForceGVariant annotation with the |
||
554 | * gdbus-codegen(1) tool. |
||
555 | */ |
||
556 | if (G_VALUE_TYPE (gvalue) == G_TYPE_VARIANT) |
||
557 | { |
||
558 | ret = g_value_dup_variant (gvalue); |
||
559 | } |
||
560 | else |
||
561 | { |
||
562 | switch (g_variant_type_peek_string (type)[0]) |
||
563 | { |
||
564 | case G_VARIANT_CLASS_BOOLEAN: |
||
565 | ret = g_variant_ref_sink (g_variant_new_boolean (g_value_get_boolean (gvalue))); |
||
566 | break; |
||
567 | |||
568 | case G_VARIANT_CLASS_BYTE: |
||
569 | ret = g_variant_ref_sink (g_variant_new_byte (g_value_get_uchar (gvalue))); |
||
570 | break; |
||
571 | |||
572 | case G_VARIANT_CLASS_INT16: |
||
573 | ret = g_variant_ref_sink (g_variant_new_int16 (g_value_get_int (gvalue))); |
||
574 | break; |
||
575 | |||
576 | case G_VARIANT_CLASS_UINT16: |
||
577 | ret = g_variant_ref_sink (g_variant_new_uint16 (g_value_get_uint (gvalue))); |
||
578 | break; |
||
579 | |||
580 | case G_VARIANT_CLASS_INT32: |
||
581 | ret = g_variant_ref_sink (g_variant_new_int32 (g_value_get_int (gvalue))); |
||
582 | break; |
||
583 | |||
584 | case G_VARIANT_CLASS_UINT32: |
||
585 | ret = g_variant_ref_sink (g_variant_new_uint32 (g_value_get_uint (gvalue))); |
||
586 | break; |
||
587 | |||
588 | case G_VARIANT_CLASS_INT64: |
||
589 | ret = g_variant_ref_sink (g_variant_new_int64 (g_value_get_int64 (gvalue))); |
||
590 | break; |
||
591 | |||
592 | case G_VARIANT_CLASS_UINT64: |
||
593 | ret = g_variant_ref_sink (g_variant_new_uint64 (g_value_get_uint64 (gvalue))); |
||
594 | break; |
||
595 | |||
596 | case G_VARIANT_CLASS_DOUBLE: |
||
597 | ret = g_variant_ref_sink (g_variant_new_double (g_value_get_double (gvalue))); |
||
598 | break; |
||
599 | |||
600 | case G_VARIANT_CLASS_STRING: |
||
601 | s = g_value_get_string (gvalue); |
||
602 | if (s == NULL) |
||
603 | s = ""; |
||
604 | ret = g_variant_ref_sink (g_variant_new_string (s)); |
||
605 | break; |
||
606 | |||
607 | case G_VARIANT_CLASS_OBJECT_PATH: |
||
608 | s = g_value_get_string (gvalue); |
||
609 | if (s == NULL) |
||
610 | s = "/"; |
||
611 | ret = g_variant_ref_sink (g_variant_new_object_path (s)); |
||
612 | break; |
||
613 | |||
614 | case G_VARIANT_CLASS_SIGNATURE: |
||
615 | s = g_value_get_string (gvalue); |
||
616 | if (s == NULL) |
||
617 | s = ""; |
||
618 | ret = g_variant_ref_sink (g_variant_new_signature (s)); |
||
619 | break; |
||
620 | |||
621 | case G_VARIANT_CLASS_ARRAY: |
||
622 | switch (g_variant_type_peek_string (type)[1]) |
||
623 | { |
||
624 | case G_VARIANT_CLASS_BYTE: |
||
625 | s = g_value_get_string (gvalue); |
||
626 | if (s == NULL) |
||
627 | s = ""; |
||
628 | ret = g_variant_ref_sink (g_variant_new_bytestring (s)); |
||
629 | break; |
||
630 | |||
631 | case G_VARIANT_CLASS_STRING: |
||
632 | as = g_value_get_boxed (gvalue); |
||
633 | if (as == NULL) |
||
634 | as = empty_strv; |
||
635 | ret = g_variant_ref_sink (g_variant_new_strv (as, -1)); |
||
636 | break; |
||
637 | |||
638 | case G_VARIANT_CLASS_OBJECT_PATH: |
||
639 | as = g_value_get_boxed (gvalue); |
||
640 | if (as == NULL) |
||
641 | as = empty_strv; |
||
642 | ret = g_variant_ref_sink (g_variant_new_objv (as, -1)); |
||
643 | break; |
||
644 | |||
645 | case G_VARIANT_CLASS_ARRAY: |
||
646 | switch (g_variant_type_peek_string (type)[2]) |
||
647 | { |
||
648 | case G_VARIANT_CLASS_BYTE: |
||
649 | as = g_value_get_boxed (gvalue); |
||
650 | if (as == NULL) |
||
651 | as = empty_strv; |
||
652 | ret = g_variant_ref_sink (g_variant_new_bytestring_array (as, -1)); |
||
653 | break; |
||
654 | |||
655 | default: |
||
656 | ret = g_value_dup_variant (gvalue); |
||
657 | break; |
||
658 | } |
||
659 | break; |
||
660 | |||
661 | default: |
||
662 | ret = g_value_dup_variant (gvalue); |
||
663 | break; |
||
664 | } |
||
665 | break; |
||
666 | |||
667 | case G_VARIANT_CLASS_HANDLE: |
||
668 | case G_VARIANT_CLASS_VARIANT: |
||
669 | case G_VARIANT_CLASS_MAYBE: |
||
670 | case G_VARIANT_CLASS_TUPLE: |
||
671 | case G_VARIANT_CLASS_DICT_ENTRY: |
||
672 | ret = g_value_dup_variant (gvalue); |
||
673 | break; |
||
674 | } |
||
675 | } |
||
676 | |||
677 | /* Could be that the GValue is holding a NULL GVariant - in that case, |
||
678 | * we return an "empty" GVariant instead of a NULL GVariant |
||
679 | */ |
||
680 | if (ret == NULL) |
||
681 | { |
||
682 | GVariant *untrusted_empty; |
||
683 | untrusted_empty = g_variant_new_from_data (type, NULL, 0, FALSE, NULL, NULL); |
||
684 | ret = g_variant_ref_sink (g_variant_get_normal_form (untrusted_empty)); |
||
685 | g_variant_unref (untrusted_empty); |
||
686 | } |
||
687 | |||
688 | g_assert (!g_variant_is_floating (ret)); |
||
689 | |||
690 | return ret; |
||
691 | } |