1 /*
2  * util.c - Source for telepathy-glib utility functions
3  * Copyright © 2006-2010 Collabora Ltd. <http://www.collabora.co.uk/>
4  * Copyright © 2006-2008 Nokia Corporation
5  * Copyright © 1999 Tom Tromey
6  * Copyright © 2000 Red Hat, Inc.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22 
23 /**
24  * SECTION:util
25  * @title: Utilities
26  * @short_description: Non-Telepathy utility functions
27  *
28  * Some utility functions used in telepathy-glib which could have been in
29  * GLib, but aren't.
30  */
31 
32 #include "config.h"
33 
34 #include <glib/gstdio.h>
35 #include <gobject/gvaluecollector.h>
36 
37 #ifdef HAVE_GIO_UNIX
38 #include <gio/gunixsocketaddress.h>
39 #include <gio/gunixconnection.h>
40 #endif /* HAVE_GIO_UNIX */
41 
42 #include <telepathy-glib/enums.h>
43 #include <telepathy-glib/errors.h>
44 #include <telepathy-glib/util-internal.h>
45 #include <telepathy-glib/util.h>
46 
47 #include <errno.h>
48 #include <stdio.h>
49 #include <string.h>
50 
51 #define DEBUG_FLAG TP_DEBUG_MISC
52 #include "debug-internal.h"
53 #include "simple-client-factory-internal.h"
54 
55 /**
56  * tp_verify:
57  * @R: a requirement (constant expression) to be checked at compile-time
58  *
59  * Make an assertion at compile time, like C++0x's proposed static_assert
60  * keyword. If @R is determined to be true, there is no overhead at runtime;
61  * if @R is determined to be false, compilation will fail.
62  *
63  * This macro can be used at file scope (it expands to a dummy extern
64  * declaration).
65  *
66  * (This is gnulib's verify macro, written by Paul Eggert, Bruno Haible and
67  * Jim Meyering.)
68  *
69  * This macro will be deprecated in a future telepathy-glib release. Please
70  * use GLib 2.20's G_STATIC_ASSERT() macro in new code.
71  *
72  * Since: 0.7.34
73  */
74 
75 /**
76  * tp_verify_true:
77  * @R: a requirement (constant expression) to be checked at compile-time
78  *
79  * Make an assertion at compile time, like C++0x's proposed static_assert
80  * keyword. If @R is determined to be true, there is no overhead at runtime,
81  * and the macro evaluates to 1 as an integer constant expression;
82  * if @R is determined to be false, compilation will fail.
83  *
84  * This macro can be used anywhere that an integer constant expression would
85  * be allowed.
86  *
87  * (This is gnulib's verify_true macro, written by Paul Eggert, Bruno Haible
88  * and Jim Meyering.)
89  *
90  * This macro will be deprecated in a future telepathy-glib release. Please
91  * use GLib 2.20's G_STATIC_ASSERT() macro in new code.
92  *
93  * Returns: 1
94  *
95  * Since: 0.7.34
96  */
97 
98 /**
99  * tp_verify_statement:
100  * @R: a requirement (constant expression) to be checked at compile-time
101  *
102  * Make an assertion at compile time, like C++0x's proposed static_assert
103  * keyword. If @R is determined to be true, there is no overhead at runtime;
104  * if @R is determined to be false, compilation will fail.
105  *
106  * This macro can be used anywhere that a statement would be allowed; it
107  * is equivalent to ((void) tp_verify_true (R)).
108  *
109  * This macro will be deprecated in a future telepathy-glib release. Please
110  * use GLib 2.20's G_STATIC_ASSERT() macro in new code.
111  *
112  * Since: 0.7.34
113  */
114 
115 /**
116  * tp_g_ptr_array_contains: (skip)
117  * @haystack: The pointer array to be searched
118  * @needle: The pointer to look for
119  *
120  * <!--no further documentation needed-->
121  *
122  * Returns: %TRUE if @needle is one of the elements of @haystack
123  */
124 
125 gboolean
tp_g_ptr_array_contains(GPtrArray * haystack,gpointer needle)126 tp_g_ptr_array_contains (GPtrArray *haystack, gpointer needle)
127 {
128   guint i;
129 
130   g_return_val_if_fail (haystack != NULL, FALSE);
131 
132   for (i = 0; i < haystack->len; i++)
133     {
134       if (g_ptr_array_index (haystack, i) == needle)
135         return TRUE;
136     }
137 
138   return FALSE;
139 }
140 
141 static void
add_to_array(gpointer data,gpointer user_data)142 add_to_array (gpointer data,
143     gpointer user_data)
144 {
145   g_ptr_array_add (user_data, data);
146 }
147 
148 /**
149  * tp_g_ptr_array_extend: (skip)
150  * @target: a #GPtrArray to copy items to
151  * @source: a #GPtrArray to copy items from
152  *
153  * Appends all elements of @source to @target. Note that this only copies the
154  * pointers from @source; any duplication or reference-incrementing must be
155  * performed by the caller.
156  *
157  * After this function has been called, it is safe to call
158  * g_ptr_array_free() on @source and also free the actual pointer array,
159  * as long as doing so does not free the data pointed to by the new
160  * items in @target.
161  *
162  * Since: 0.14.3
163  */
164 void
tp_g_ptr_array_extend(GPtrArray * target,GPtrArray * source)165 tp_g_ptr_array_extend (GPtrArray *target,
166     GPtrArray *source)
167 {
168   g_return_if_fail (source != NULL);
169   g_return_if_fail (target != NULL);
170 
171   g_ptr_array_foreach (source, add_to_array, target);
172 }
173 
174 /**
175  * tp_g_value_slice_new: (skip)
176  * @type: The type desired for the new GValue
177  *
178  * Slice-allocate an empty #GValue. tp_g_value_slice_new_boolean() and similar
179  * functions are likely to be more convenient to use for the types supported.
180  *
181  * Returns: a newly allocated, newly initialized #GValue, to be freed with
182  * tp_g_value_slice_free() or g_slice_free().
183  * Since: 0.5.14
184  */
185 GValue *
tp_g_value_slice_new(GType type)186 tp_g_value_slice_new (GType type)
187 {
188   GValue *ret = g_slice_new0 (GValue);
189 
190   g_value_init (ret, type);
191   return ret;
192 }
193 
194 /**
195  * tp_g_value_slice_new_boolean: (skip)
196  * @b: a boolean value
197  *
198  * Slice-allocate and initialize a #GValue. This function is convenient to
199  * use when constructing hash tables from string to #GValue, for example.
200  *
201  * Returns: a #GValue of type %G_TYPE_BOOLEAN with value @b, to be freed with
202  * tp_g_value_slice_free() or g_slice_free()
203  *
204  * Since: 0.7.27
205  */
206 GValue *
tp_g_value_slice_new_boolean(gboolean b)207 tp_g_value_slice_new_boolean (gboolean b)
208 {
209   GValue *v = tp_g_value_slice_new (G_TYPE_BOOLEAN);
210 
211   g_value_set_boolean (v, b);
212   return v;
213 }
214 
215 /**
216  * tp_g_value_slice_new_int: (skip)
217  * @n: an integer
218  *
219  * Slice-allocate and initialize a #GValue. This function is convenient to
220  * use when constructing hash tables from string to #GValue, for example.
221  *
222  * Returns: a #GValue of type %G_TYPE_INT with value @n, to be freed with
223  * tp_g_value_slice_free() or g_slice_free()
224  *
225  * Since: 0.7.27
226  */
227 GValue *
tp_g_value_slice_new_int(gint n)228 tp_g_value_slice_new_int (gint n)
229 {
230   GValue *v = tp_g_value_slice_new (G_TYPE_INT);
231 
232   g_value_set_int (v, n);
233   return v;
234 }
235 
236 /**
237  * tp_g_value_slice_new_int64: (skip)
238  * @n: a 64-bit integer
239  *
240  * Slice-allocate and initialize a #GValue. This function is convenient to
241  * use when constructing hash tables from string to #GValue, for example.
242  *
243  * Returns: a #GValue of type %G_TYPE_INT64 with value @n, to be freed with
244  * tp_g_value_slice_free() or g_slice_free()
245  *
246  * Since: 0.7.27
247  */
248 GValue *
tp_g_value_slice_new_int64(gint64 n)249 tp_g_value_slice_new_int64 (gint64 n)
250 {
251   GValue *v = tp_g_value_slice_new (G_TYPE_INT64);
252 
253   g_value_set_int64 (v, n);
254   return v;
255 }
256 
257 /**
258  * tp_g_value_slice_new_byte: (skip)
259  * @n: an unsigned integer
260  *
261  * Slice-allocate and initialize a #GValue. This function is convenient to
262  * use when constructing hash tables from string to #GValue, for example.
263  *
264  * Returns: a #GValue of type %G_TYPE_UCHAR with value @n, to be freed with
265  * tp_g_value_slice_free() or g_slice_free()
266  *
267  * Since: 0.11.0
268  */
269 GValue *
tp_g_value_slice_new_byte(guchar n)270 tp_g_value_slice_new_byte (guchar n)
271 {
272   GValue *v = tp_g_value_slice_new (G_TYPE_UCHAR);
273 
274   g_value_set_uchar (v, n);
275   return v;
276 }
277 
278 /**
279  * tp_g_value_slice_new_uint: (skip)
280  * @n: an unsigned integer
281  *
282  * Slice-allocate and initialize a #GValue. This function is convenient to
283  * use when constructing hash tables from string to #GValue, for example.
284  *
285  * Returns: a #GValue of type %G_TYPE_UINT with value @n, to be freed with
286  * tp_g_value_slice_free() or g_slice_free()
287  *
288  * Since: 0.7.27
289  */
290 GValue *
tp_g_value_slice_new_uint(guint n)291 tp_g_value_slice_new_uint (guint n)
292 {
293   GValue *v = tp_g_value_slice_new (G_TYPE_UINT);
294 
295   g_value_set_uint (v, n);
296   return v;
297 }
298 
299 /**
300  * tp_g_value_slice_new_uint64: (skip)
301  * @n: a 64-bit unsigned integer
302  *
303  * Slice-allocate and initialize a #GValue. This function is convenient to
304  * use when constructing hash tables from string to #GValue, for example.
305  *
306  * Returns: a #GValue of type %G_TYPE_UINT64 with value @n, to be freed with
307  * tp_g_value_slice_free() or g_slice_free()
308  *
309  * Since: 0.7.27
310  */
311 GValue *
tp_g_value_slice_new_uint64(guint64 n)312 tp_g_value_slice_new_uint64 (guint64 n)
313 {
314   GValue *v = tp_g_value_slice_new (G_TYPE_UINT64);
315 
316   g_value_set_uint64 (v, n);
317   return v;
318 }
319 
320 /**
321  * tp_g_value_slice_new_double: (skip)
322  * @d: a number
323  *
324  * Slice-allocate and initialize a #GValue. This function is convenient to
325  * use when constructing hash tables from string to #GValue, for example.
326  *
327  * Returns: a #GValue of type %G_TYPE_DOUBLE with value @n, to be freed with
328  * tp_g_value_slice_free() or g_slice_free()
329  *
330  * Since: 0.7.27
331  */
332 GValue *
tp_g_value_slice_new_double(double n)333 tp_g_value_slice_new_double (double n)
334 {
335   GValue *v = tp_g_value_slice_new (G_TYPE_DOUBLE);
336 
337   g_value_set_double (v, n);
338   return v;
339 }
340 
341 /**
342  * tp_g_value_slice_new_string: (skip)
343  * @string: a string to be copied into the value
344  *
345  * Slice-allocate and initialize a #GValue. This function is convenient to
346  * use when constructing hash tables from string to #GValue, for example.
347  *
348  * Returns: a #GValue of type %G_TYPE_STRING whose value is a copy of @string,
349  * to be freed with tp_g_value_slice_free() or g_slice_free()
350  *
351  * Since: 0.7.27
352  */
353 GValue *
tp_g_value_slice_new_string(const gchar * string)354 tp_g_value_slice_new_string (const gchar *string)
355 {
356   GValue *v = tp_g_value_slice_new (G_TYPE_STRING);
357 
358   g_value_set_string (v, string);
359   return v;
360 }
361 
362 /**
363  * tp_g_value_slice_new_static_string: (skip)
364  * @string: a static string which must remain valid forever, to be pointed to
365  *  by the value
366  *
367  * Slice-allocate and initialize a #GValue. This function is convenient to
368  * use when constructing hash tables from string to #GValue, for example.
369  *
370  * Returns: a #GValue of type %G_TYPE_STRING whose value is @string,
371  * to be freed with tp_g_value_slice_free() or g_slice_free()
372  *
373  * Since: 0.7.27
374  */
375 GValue *
tp_g_value_slice_new_static_string(const gchar * string)376 tp_g_value_slice_new_static_string (const gchar *string)
377 {
378   GValue *v = tp_g_value_slice_new (G_TYPE_STRING);
379 
380   g_value_set_static_string (v, string);
381   return v;
382 }
383 
384 /**
385  * tp_g_value_slice_new_take_string: (skip)
386  * @string: a string which will be freed with g_free() by the returned #GValue
387  *  (the caller must own it before calling this function, but no longer owns
388  *  it after this function returns)
389  *
390  * Slice-allocate and initialize a #GValue. This function is convenient to
391  * use when constructing hash tables from string to #GValue, for example.
392  *
393  * Returns: a #GValue of type %G_TYPE_STRING whose value is @string,
394  * to be freed with tp_g_value_slice_free() or g_slice_free()
395  *
396  * Since: 0.7.27
397  */
398 GValue *
tp_g_value_slice_new_take_string(gchar * string)399 tp_g_value_slice_new_take_string (gchar *string)
400 {
401   GValue *v = tp_g_value_slice_new (G_TYPE_STRING);
402 
403   g_value_take_string (v, string);
404   return v;
405 }
406 
407 /**
408  * tp_g_value_slice_new_boxed: (skip)
409  * @type: a boxed type
410  * @p: a pointer of type @type, which will be copied
411  *
412  * Slice-allocate and initialize a #GValue. This function is convenient to
413  * use when constructing hash tables from string to #GValue, for example.
414  *
415  * Returns: a #GValue of type @type whose value is a copy of @p,
416  * to be freed with tp_g_value_slice_free() or g_slice_free()
417  *
418  * Since: 0.7.27
419  */
420 GValue *
tp_g_value_slice_new_boxed(GType type,gconstpointer p)421 tp_g_value_slice_new_boxed (GType type,
422                             gconstpointer p)
423 {
424   GValue *v;
425 
426   g_return_val_if_fail (G_TYPE_FUNDAMENTAL (type) == G_TYPE_BOXED, NULL);
427   v = tp_g_value_slice_new (type);
428   g_value_set_boxed (v, p);
429   return v;
430 }
431 
432 /**
433  * tp_g_value_slice_new_static_boxed: (skip)
434  * @type: a boxed type
435  * @p: a pointer of type @type, which must remain valid forever
436  *
437  * Slice-allocate and initialize a #GValue. This function is convenient to
438  * use when constructing hash tables from string to #GValue, for example.
439  *
440  * Returns: a #GValue of type @type whose value is @p,
441  * to be freed with tp_g_value_slice_free() or g_slice_free()
442  *
443  * Since: 0.7.27
444  */
445 GValue *
tp_g_value_slice_new_static_boxed(GType type,gconstpointer p)446 tp_g_value_slice_new_static_boxed (GType type,
447                                    gconstpointer p)
448 {
449   GValue *v;
450 
451   g_return_val_if_fail (G_TYPE_FUNDAMENTAL (type) == G_TYPE_BOXED, NULL);
452   v = tp_g_value_slice_new (type);
453   g_value_set_static_boxed (v, p);
454   return v;
455 }
456 
457 /**
458  * tp_g_value_slice_new_take_boxed: (skip)
459  * @type: a boxed type
460  * @p: a pointer of type @type which will be freed with g_boxed_free() by the
461  *  returned #GValue (the caller must own it before calling this function, but
462  *  no longer owns it after this function returns)
463  *
464  * Slice-allocate and initialize a #GValue. This function is convenient to
465  * use when constructing hash tables from string to #GValue, for example.
466  *
467  * Returns: a #GValue of type @type whose value is @p,
468  * to be freed with tp_g_value_slice_free() or g_slice_free()
469  *
470  * Since: 0.7.27
471  */
472 GValue *
tp_g_value_slice_new_take_boxed(GType type,gpointer p)473 tp_g_value_slice_new_take_boxed (GType type,
474                                  gpointer p)
475 {
476   GValue *v;
477 
478   g_return_val_if_fail (G_TYPE_FUNDAMENTAL (type) == G_TYPE_BOXED, NULL);
479   v = tp_g_value_slice_new (type);
480   g_value_take_boxed (v, p);
481   return v;
482 }
483 
484 /**
485  * tp_g_value_slice_free: (skip)
486  * @value: A GValue which was allocated with the g_slice API
487  *
488  * Unset and free a slice-allocated GValue.
489  *
490  * <literal>(GDestroyNotify) tp_g_value_slice_free</literal> can be used
491  * as a destructor for values in a #GHashTable, for example.
492  */
493 
494 void
tp_g_value_slice_free(GValue * value)495 tp_g_value_slice_free (GValue *value)
496 {
497   g_value_unset (value);
498   g_slice_free (GValue, value);
499 }
500 
501 
502 /**
503  * tp_g_value_slice_dup: (skip)
504  * @value: A GValue
505  *
506  * <!-- 'Returns' says it all -->
507  *
508  * Returns: a newly allocated copy of @value, to be freed with
509  * tp_g_value_slice_free() or g_slice_free().
510  * Since: 0.5.14
511  */
512 GValue *
tp_g_value_slice_dup(const GValue * value)513 tp_g_value_slice_dup (const GValue *value)
514 {
515   GValue *ret = tp_g_value_slice_new (G_VALUE_TYPE (value));
516 
517   g_value_copy (value, ret);
518   return ret;
519 }
520 
521 
522 struct _tp_g_hash_table_update
523 {
524   GHashTable *target;
525   GBoxedCopyFunc key_dup, value_dup;
526 };
527 
528 static void
_tp_g_hash_table_update_helper(gpointer key,gpointer value,gpointer user_data)529 _tp_g_hash_table_update_helper (gpointer key,
530                                 gpointer value,
531                                 gpointer user_data)
532 {
533   struct _tp_g_hash_table_update *data = user_data;
534   gpointer new_key = (data->key_dup != NULL) ? (data->key_dup) (key) : key;
535   gpointer new_value = (data->value_dup != NULL) ? (data->value_dup) (value)
536                                                  : value;
537 
538   g_hash_table_replace (data->target, new_key, new_value);
539 }
540 
541 /**
542  * tp_g_hash_table_update: (skip)
543  * @target: The hash table to be updated
544  * @source: The hash table to update it with (read-only)
545  * @key_dup: function to duplicate a key from @source so it can be be stored
546  *           in @target. If NULL, the key is not copied, but is used as-is
547  * @value_dup: function to duplicate a value from @source so it can be stored
548  *             in @target. If NULL, the value is not copied, but is used as-is
549  *
550  * Add each item in @source to @target, replacing any existing item with the
551  * same key. @key_dup and @value_dup are used to duplicate the items; in
552  * principle they could also be used to convert between types.
553  *
554  * Since: 0.7.0
555  */
556 void
tp_g_hash_table_update(GHashTable * target,GHashTable * source,GBoxedCopyFunc key_dup,GBoxedCopyFunc value_dup)557 tp_g_hash_table_update (GHashTable *target,
558                         GHashTable *source,
559                         GBoxedCopyFunc key_dup,
560                         GBoxedCopyFunc value_dup)
561 {
562   struct _tp_g_hash_table_update data = { target, key_dup,
563       value_dup };
564 
565   g_return_if_fail (target != NULL);
566   g_return_if_fail (source != NULL);
567   g_return_if_fail (target != source);
568 
569   g_hash_table_foreach (source, _tp_g_hash_table_update_helper, &data);
570 }
571 
572 /**
573  * tp_str_empty: (skip)
574  * @s: (type utf8) (transfer none): a string
575  *
576  * Return %TRUE if @s is empty, counting %NULL as empty.
577  *
578  * Returns: (type boolean): %TRUE if @s is either %NULL or ""
579  *
580  * Since: 0.11.1
581  */
582 /* no definition here - it's inlined */
583 
584 /**
585  * tp_strdiff: (skip)
586  * @left: The first string to compare (may be NULL)
587  * @right: The second string to compare (may be NULL)
588  *
589  * Return %TRUE if the given strings are different. Unlike #strcmp this
590  * function will handle null pointers, treating them as distinct from any
591  * string.
592  *
593  * Returns: %FALSE if @left and @right are both %NULL, or if
594  *          neither is %NULL and both have the same contents; %TRUE otherwise
595  */
596 
597 gboolean
tp_strdiff(const gchar * left,const gchar * right)598 tp_strdiff (const gchar *left, const gchar *right)
599 {
600   return g_strcmp0 (left, right) != 0;
601 }
602 
603 
604 
605 /**
606  * tp_mixin_offset_cast: (skip)
607  * @instance: A pointer to a structure
608  * @offset: The offset of a structure member in bytes, which must not be 0
609  *
610  * Extend a pointer by an offset, provided the offset is not 0.
611  * This is used to cast from an object instance to one of the telepathy-glib
612  * mixin classes.
613  *
614  * Returns: a pointer @offset bytes beyond @instance
615  */
616 gpointer
tp_mixin_offset_cast(gpointer instance,guint offset)617 tp_mixin_offset_cast (gpointer instance, guint offset)
618 {
619   g_return_val_if_fail (offset != 0, NULL);
620 
621   return ((guchar *) instance + offset);
622 }
623 
624 
625 /**
626  * tp_mixin_instance_get_offset: (skip)
627  * @instance: A pointer to a GObject-derived instance structure
628  * @quark: A quark that was used to store the offset with g_type_set_qdata()
629  *
630  * If the type of @instance, or any of its ancestor types, has had an offset
631  * attached using qdata with the given @quark, return that offset. If not,
632  * return 0.
633  *
634  * In older telepathy-glib versions, calling this function on an instance that
635  * did not have the mixin was considered to be a programming error. Since
636  * version 0.13.9, 0 is returned, without error.
637  *
638  * This is used to implement the telepathy-glib mixin classes.
639  *
640  * Returns: the offset of the mixin
641  */
642 guint
tp_mixin_instance_get_offset(gpointer instance,GQuark quark)643 tp_mixin_instance_get_offset (gpointer instance,
644                               GQuark quark)
645 {
646   GType t;
647 
648   for (t = G_OBJECT_TYPE (instance);
649        t != 0;
650        t = g_type_parent (t))
651     {
652       gpointer qdata = g_type_get_qdata (t, quark);
653 
654       if (qdata != NULL)
655         return GPOINTER_TO_UINT (qdata);
656     }
657 
658   return 0;
659 }
660 
661 
662 /**
663  * tp_mixin_class_get_offset: (skip)
664  * @klass: A pointer to a GObjectClass-derived class structure
665  * @quark: A quark that was used to store the offset with g_type_set_qdata()
666  *
667  * If the type of @klass, or any of its ancestor types, has had an offset
668  * attached using qdata with the given @quark, return that offset; if not,
669  * return 0.
670  *
671  * In older telepathy-glib versions, calling this function on an instance that
672  * did not have the mixin was considered to be a programming error. Since
673  * version 0.13.9, 0 is returned, without error.
674  *
675  * This is used to implement the telepathy-glib mixin classes.
676  *
677  * Returns: the offset of the mixin class
678  */
679 guint
tp_mixin_class_get_offset(gpointer klass,GQuark quark)680 tp_mixin_class_get_offset (gpointer klass,
681                            GQuark quark)
682 {
683   GType t;
684 
685   for (t = G_OBJECT_CLASS_TYPE (klass);
686        t != 0;
687        t = g_type_parent (t))
688     {
689       gpointer qdata = g_type_get_qdata (t, quark);
690 
691       if (qdata != NULL)
692         return GPOINTER_TO_UINT (qdata);
693     }
694 
695   return 0;
696 }
697 
698 
699 static inline gboolean
_esc_ident_bad(gchar c,gboolean is_first)700 _esc_ident_bad (gchar c, gboolean is_first)
701 {
702   return ((c < 'a' || c > 'z') &&
703           (c < 'A' || c > 'Z') &&
704           (c < '0' || c > '9' || is_first));
705 }
706 
707 
708 /**
709  * tp_escape_as_identifier:
710  * @name: The string to be escaped
711  *
712  * Escape an arbitrary string so it follows the rules for a C identifier,
713  * and hence an object path component, interface element component,
714  * bus name component or member name in D-Bus.
715  *
716  * Unlike g_strcanon this is a reversible encoding, so it preserves
717  * distinctness.
718  *
719  * The escaping consists of replacing all non-alphanumerics, and the first
720  * character if it's a digit, with an underscore and two lower-case hex
721  * digits:
722  *
723  *    "0123abc_xyz\x01\xff" -> _30123abc_5fxyz_01_ff
724  *
725  * i.e. similar to URI encoding, but with _ taking the role of %, and a
726  * smaller allowed set. As a special case, "" is escaped to "_" (just for
727  * completeness, really).
728  *
729  * Returns: (transfer full): the escaped string, which must be freed by
730  *  the caller with #g_free
731  */
732 gchar *
tp_escape_as_identifier(const gchar * name)733 tp_escape_as_identifier (const gchar *name)
734 {
735   gboolean bad = FALSE;
736   size_t len = 0;
737   GString *op;
738   const gchar *ptr, *first_ok;
739 
740   g_return_val_if_fail (name != NULL, NULL);
741 
742   /* fast path for empty name */
743   if (name[0] == '\0')
744     return g_strdup ("_");
745 
746   for (ptr = name; *ptr; ptr++)
747     {
748       if (_esc_ident_bad (*ptr, ptr == name))
749         {
750           bad = TRUE;
751           len += 3;
752         }
753       else
754         len++;
755     }
756 
757   /* fast path if it's clean */
758   if (!bad)
759     return g_strdup (name);
760 
761   /* If strictly less than ptr, first_ok is the first uncopied safe character.
762    */
763   first_ok = name;
764   op = g_string_sized_new (len);
765   for (ptr = name; *ptr; ptr++)
766     {
767       if (_esc_ident_bad (*ptr, ptr == name))
768         {
769           /* copy preceding safe characters if any */
770           if (first_ok < ptr)
771             {
772               g_string_append_len (op, first_ok, ptr - first_ok);
773             }
774           /* escape the unsafe character */
775           g_string_append_printf (op, "_%02x", (unsigned char)(*ptr));
776           /* restart after it */
777           first_ok = ptr + 1;
778         }
779     }
780   /* copy trailing safe characters if any */
781   if (first_ok < ptr)
782     {
783       g_string_append_len (op, first_ok, ptr - first_ok);
784     }
785   return g_string_free (op, FALSE);
786 }
787 
788 
789 /**
790  * tp_strv_contains: (skip)
791  * @strv: a NULL-terminated array of strings, or %NULL (which is treated as an
792  *        empty strv)
793  * @str: a non-NULL string
794  *
795  * <!-- -->
796  * Returns: TRUE if @str is an element of @strv, according to strcmp().
797  *
798  * Since: 0.7.15
799  */
800 gboolean
tp_strv_contains(const gchar * const * strv,const gchar * str)801 tp_strv_contains (const gchar * const *strv,
802                   const gchar *str)
803 {
804   g_return_val_if_fail (str != NULL, FALSE);
805 
806   if (strv == NULL)
807     return FALSE;
808 
809   while (*strv != NULL)
810     {
811       if (!tp_strdiff (str, *strv))
812         return TRUE;
813       strv++;
814     }
815 
816   return FALSE;
817 }
818 
819 /**
820  * tp_g_key_file_get_int64: (skip)
821  * @key_file: a non-%NULL #GKeyFile
822  * @group_name: a non-%NULL group name
823  * @key: a non-%NULL key
824  * @error: return location for a #GError
825  *
826  * Returns the value associated with @key under @group_name as a signed
827  * 64-bit integer. This is similar to g_key_file_get_integer() but can return
828  * 64-bit results without truncation.
829  *
830  * Returns: the value associated with the key as a signed 64-bit integer, or
831  * 0 if the key was not found or could not be parsed.
832  *
833  * Since: 0.7.31
834  * Deprecated: Since 0.21.0. Use g_key_file_get_int64() instead.
835  */
836 gint64
tp_g_key_file_get_int64(GKeyFile * key_file,const gchar * group_name,const gchar * key,GError ** error)837 tp_g_key_file_get_int64 (GKeyFile *key_file,
838                          const gchar *group_name,
839                          const gchar *key,
840                          GError **error)
841 {
842   gchar *s, *end;
843   gint64 v;
844 
845   g_return_val_if_fail (key_file != NULL, -1);
846   g_return_val_if_fail (group_name != NULL, -1);
847   g_return_val_if_fail (key != NULL, -1);
848 
849   s = g_key_file_get_value (key_file, group_name, key, error);
850 
851   if (s == NULL)
852     return 0;
853 
854   v = g_ascii_strtoll (s, &end, 10);
855 
856   if (*s == '\0' || *end != '\0')
857     {
858       g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE,
859           "Key '%s' in group '%s' has value '%s' where int64 was expected",
860           key, group_name, s);
861       return 0;
862     }
863 
864   g_free (s);
865   return v;
866 }
867 
868 /**
869  * tp_g_key_file_get_uint64: (skip)
870  * @key_file: a non-%NULL #GKeyFile
871  * @group_name: a non-%NULL group name
872  * @key: a non-%NULL key
873  * @error: return location for a #GError
874  *
875  * Returns the value associated with @key under @group_name as an unsigned
876  * 64-bit integer. This is similar to g_key_file_get_integer() but can return
877  * large positive results without truncation.
878  *
879  * Returns: the value associated with the key as an unsigned 64-bit integer,
880  * or 0 if the key was not found or could not be parsed.
881  *
882  * Since: 0.7.31
883  * Deprecated: Since 0.21.0. Use g_key_file_get_uint64() instead.
884  */
885 guint64
tp_g_key_file_get_uint64(GKeyFile * key_file,const gchar * group_name,const gchar * key,GError ** error)886 tp_g_key_file_get_uint64 (GKeyFile *key_file,
887                           const gchar *group_name,
888                           const gchar *key,
889                           GError **error)
890 {
891   gchar *s, *end;
892   guint64 v;
893 
894   g_return_val_if_fail (key_file != NULL, -1);
895   g_return_val_if_fail (group_name != NULL, -1);
896   g_return_val_if_fail (key != NULL, -1);
897 
898   s = g_key_file_get_value (key_file, group_name, key, error);
899 
900   if (s == NULL)
901     return 0;
902 
903   v = g_ascii_strtoull (s, &end, 10);
904 
905   if (*s == '\0' || *end != '\0')
906     {
907       g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE,
908           "Key '%s' in group '%s' has value '%s' where uint64 was expected",
909           key, group_name, s);
910       return 0;
911     }
912 
913   g_free (s);
914   return v;
915 }
916 
917 typedef struct {
918     GObject *instance;
919     GObject *observer;
920     GClosure *closure;
921     gulong handler_id;
922 } WeakHandlerCtx;
923 
924 static WeakHandlerCtx *
whc_new(GObject * instance,GObject * observer)925 whc_new (GObject *instance,
926          GObject *observer)
927 {
928   WeakHandlerCtx *ctx = g_slice_new0 (WeakHandlerCtx);
929 
930   ctx->instance = instance;
931   ctx->observer = observer;
932 
933   return ctx;
934 }
935 
936 static void
whc_free(WeakHandlerCtx * ctx)937 whc_free (WeakHandlerCtx *ctx)
938 {
939   g_slice_free (WeakHandlerCtx, ctx);
940 }
941 
942 static void observer_destroyed_cb (gpointer, GObject *);
943 static void closure_invalidated_cb (gpointer, GClosure *);
944 
945 /*
946  * If signal handlers are removed before the object is destroyed, this
947  * callback will never get triggered.
948  */
949 static void
instance_destroyed_cb(gpointer ctx_,GObject * where_the_instance_was)950 instance_destroyed_cb (gpointer ctx_,
951     GObject *where_the_instance_was)
952 {
953   WeakHandlerCtx *ctx = ctx_;
954 
955   /* No need to disconnect the signal here, the instance has gone away. */
956   g_object_weak_unref (ctx->observer, observer_destroyed_cb, ctx);
957   g_closure_remove_invalidate_notifier (ctx->closure, ctx,
958       closure_invalidated_cb);
959   whc_free (ctx);
960 }
961 
962 /* Triggered when the observer is destroyed. */
963 static void
observer_destroyed_cb(gpointer ctx_,GObject * where_the_observer_was)964 observer_destroyed_cb (gpointer ctx_,
965     GObject *where_the_observer_was)
966 {
967   WeakHandlerCtx *ctx = ctx_;
968 
969   g_closure_remove_invalidate_notifier (ctx->closure, ctx,
970       closure_invalidated_cb);
971   g_signal_handler_disconnect (ctx->instance, ctx->handler_id);
972   g_object_weak_unref (ctx->instance, instance_destroyed_cb, ctx);
973   whc_free (ctx);
974 }
975 
976 /* Triggered when either object is destroyed or the handler is disconnected. */
977 static void
closure_invalidated_cb(gpointer ctx_,GClosure * where_the_closure_was)978 closure_invalidated_cb (gpointer ctx_,
979     GClosure *where_the_closure_was)
980 {
981   WeakHandlerCtx *ctx = ctx_;
982 
983   g_object_weak_unref (ctx->instance, instance_destroyed_cb, ctx);
984   g_object_weak_unref (ctx->observer, observer_destroyed_cb, ctx);
985   whc_free (ctx);
986 }
987 
988 /**
989  * tp_g_signal_connect_object: (skip)
990  * @instance: the instance to connect to.
991  * @detailed_signal: a string of the form "signal-name::detail".
992  * @c_handler: the #GCallback to connect.
993  * @gobject: the object to pass as data to @c_handler.
994  * @connect_flags: a combination of #GConnectFlags. Only
995  *  %G_CONNECT_AFTER and %G_CONNECT_SWAPPED are supported by this function.
996  *
997  * Connects a #GCallback function to a signal for a particular object, as if
998  * with g_signal_connect(). Additionally, arranges for the signal handler to be
999  * disconnected if @gobject is destroyed.
1000  *
1001  * This is similar to g_signal_connect_data(), but uses a closure which
1002  * ensures that the @gobject stays alive during the call to @c_handler
1003  * by temporarily adding a reference count to @gobject.
1004  *
1005  * This is similar to g_signal_connect_object(), but doesn't have the
1006  * documented bug that everyone is too scared to fix. Also, it does not allow
1007  * you to pass in NULL as @gobject
1008  *
1009  * This is intended to be a convenient way for objects to use themselves as
1010  * user_data for callbacks without having to explicitly disconnect all the
1011  * handlers in their finalizers.
1012  *
1013  * Changed in 0.10.4 and 0.11.3: %G_CONNECT_AFTER is now respected.
1014  *
1015  * Returns: the handler id
1016  *
1017  * Since: 0.9.2
1018  */
1019 gulong
tp_g_signal_connect_object(gpointer instance,const gchar * detailed_signal,GCallback c_handler,gpointer gobject,GConnectFlags connect_flags)1020 tp_g_signal_connect_object (gpointer instance,
1021     const gchar *detailed_signal,
1022     GCallback c_handler,
1023     gpointer gobject,
1024     GConnectFlags connect_flags)
1025 {
1026   GObject *instance_obj = G_OBJECT (instance);
1027   WeakHandlerCtx *ctx = whc_new (instance_obj, gobject);
1028 
1029   g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
1030   g_return_val_if_fail (detailed_signal != NULL, 0);
1031   g_return_val_if_fail (c_handler != NULL, 0);
1032   g_return_val_if_fail (G_IS_OBJECT (gobject), 0);
1033   g_return_val_if_fail (
1034       (connect_flags & ~(G_CONNECT_AFTER|G_CONNECT_SWAPPED)) == 0, 0);
1035 
1036   if (connect_flags & G_CONNECT_SWAPPED)
1037     ctx->closure = g_cclosure_new_object_swap (c_handler, gobject);
1038   else
1039     ctx->closure = g_cclosure_new_object (c_handler, gobject);
1040 
1041   ctx->handler_id = g_signal_connect_closure (instance, detailed_signal,
1042       ctx->closure, (connect_flags & G_CONNECT_AFTER) ? TRUE : FALSE);
1043 
1044   g_object_weak_ref (instance_obj, instance_destroyed_cb, ctx);
1045   g_object_weak_ref (gobject, observer_destroyed_cb, ctx);
1046   g_closure_add_invalidate_notifier (ctx->closure, ctx,
1047       closure_invalidated_cb);
1048 
1049   return ctx->handler_id;
1050 }
1051 
1052 /*
1053  * _tp_quark_array_copy:
1054  * @quarks: A 0-terminated list of quarks to copy
1055  *
1056  * Copy a zero-terminated array into a GArray. The trailing
1057  * 0 is not counted in the @len member of the returned
1058  * array, but the @data member is guaranteed to be
1059  * zero-terminated.
1060  *
1061  * Returns: A new GArray containing a copy of @quarks.
1062  */
1063 GArray *
_tp_quark_array_copy(const GQuark * quarks)1064 _tp_quark_array_copy (const GQuark *quarks)
1065 {
1066   GArray *array;
1067   const GQuark *q;
1068 
1069   array = g_array_new (TRUE, TRUE, sizeof (GQuark));
1070 
1071   for (q = quarks; q != NULL && *q != 0; q++)
1072     {
1073       g_array_append_val (array, *q);
1074     }
1075 
1076   return array;
1077 }
1078 
1079 /**
1080  * tp_value_array_build: (skip)
1081  * @length: The number of elements that should be in the array
1082  * @type: The type of the first argument.
1083  * @...: The value of the first item in the struct followed by a list of type,
1084  * value pairs terminated by G_TYPE_INVALID.
1085  *
1086  * Creates a new #GValueArray for use with structs, containing the values
1087  * passed in as parameters. The values are copied or reffed as appropriate for
1088  * their type.
1089  *
1090  * <example>
1091  *   <title> using tp_value_array_build</title>
1092  *    <programlisting>
1093  * GValueArray *array = tp_value_array_build (2,
1094  *    G_TYPE_STRING, host,
1095  *    G_TYPE_UINT, port,
1096  *    G_TYPE_INVALID);
1097  *    </programlisting>
1098  * </example>
1099  *
1100  * Returns: a newly created #GValueArray, free with tp_value_array_free()
1101  *
1102  * Since: 0.9.2
1103  */
1104 GValueArray *
tp_value_array_build(gsize length,GType type,...)1105 tp_value_array_build (gsize length,
1106   GType type,
1107   ...)
1108 {
1109   GValueArray *arr;
1110   GType t;
1111   va_list var_args;
1112   char *error = NULL;
1113 
1114   G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1115   arr = g_value_array_new (length);
1116   G_GNUC_END_IGNORE_DEPRECATIONS
1117 
1118   va_start (var_args, type);
1119 
1120   for (t = type; t != G_TYPE_INVALID; t = va_arg (var_args, GType))
1121     {
1122       GValue *v = arr->values + arr->n_values;
1123 
1124       G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1125       g_value_array_append (arr, NULL);
1126       G_GNUC_END_IGNORE_DEPRECATIONS
1127 
1128       g_value_init (v, t);
1129 
1130       G_VALUE_COLLECT (v, var_args, 0, &error);
1131 
1132       if (error != NULL)
1133         {
1134           CRITICAL ("%s", error);
1135           g_free (error);
1136 
1137           tp_value_array_free (arr);
1138           va_end (var_args);
1139           return NULL;
1140         }
1141     }
1142 
1143   g_warn_if_fail (arr->n_values == length);
1144 
1145   va_end (var_args);
1146   return arr;
1147 }
1148 
1149 /**
1150  * tp_value_array_unpack: (skip)
1151  * @array: the array to unpack
1152  * @len: The number of elements that should be in the array
1153  * @...: a list of correctly typed pointers to store the values in
1154  *
1155  * Unpacks a #GValueArray into separate variables.
1156  *
1157  * The contents of the values aren't copied into the variables, and so become
1158  * invalid when @array is freed.
1159  *
1160  * <example>
1161  *   <title>using tp_value_array_unpack</title>
1162  *    <programlisting>
1163  * const gchar *host;
1164  * guint port;
1165  *
1166  * tp_value_array_unpack (array, 2,
1167  *    &host,
1168  *    &port);
1169  *    </programlisting>
1170  * </example>
1171  *
1172  * Since: 0.11.0
1173  */
1174 void
tp_value_array_unpack(GValueArray * array,gsize len,...)1175 tp_value_array_unpack (GValueArray *array,
1176     gsize len,
1177     ...)
1178 {
1179   va_list var_args;
1180   guint i;
1181 
1182   va_start (var_args, len);
1183 
1184   for (i = 0; i < len; i++)
1185     {
1186       GValue *value;
1187       char *error = NULL;
1188 
1189       if (G_UNLIKELY (i > array->n_values))
1190         {
1191           WARNING ("More parameters than entries in the struct!");
1192           break;
1193         }
1194 
1195       G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1196       value = g_value_array_get_nth (array, i);
1197       G_GNUC_END_IGNORE_DEPRECATIONS
1198 
1199       G_VALUE_LCOPY (value, var_args, G_VALUE_NOCOPY_CONTENTS, &error);
1200       if (error != NULL)
1201         {
1202           WARNING ("%s", error);
1203           g_free (error);
1204           break;
1205         }
1206     }
1207 
1208   va_end (var_args);
1209 }
1210 
1211 /**
1212  * TpWeakRef:
1213  *
1214  * A simple wrapper for a weak reference to a #GObject, suitable for use in
1215  * asynchronous calls which should only affect the object if it hasn't already
1216  * been freed.
1217  *
1218  * As well as wrapping a weak reference to an object, this structure can
1219  * contain an extra pointer to arbitrary data. This is useful for asynchronous
1220  * calls which act on an object and some second piece of data, which are quite
1221  * common in practice.
1222  *
1223  * If more than one piece of auxiliary data is required, the @user_data
1224  * argument to the constructor can be a struct or a #GValueArray.
1225  *
1226  * Since: 0.11.3
1227  */
1228 struct _TpWeakRef {
1229     /*<private>*/
1230     gpointer object;
1231     gpointer user_data;
1232     GDestroyNotify destroy;
1233 };
1234 
1235 /**
1236  * tp_weak_ref_new: (skip)
1237  * @object: (type GObject.Object): an object to which to take a weak reference
1238  * @user_data: optional additional data to store alongside the weak ref
1239  * @destroy: destructor for @user_data, called when the weak ref
1240  *  is freed
1241  *
1242  * Return a new weak reference wrapper for @object.
1243  *
1244  * Returns: (transfer full): a new weak-reference wrapper
1245  *
1246  * Free-function: tp_weak_ref_destroy()
1247  *
1248  * Since: 0.11.3
1249  */
1250 TpWeakRef *
tp_weak_ref_new(gpointer object,gpointer user_data,GDestroyNotify destroy)1251 tp_weak_ref_new (gpointer object,
1252     gpointer user_data,
1253     GDestroyNotify destroy)
1254 {
1255   TpWeakRef *self;
1256 
1257   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1258 
1259   self = g_slice_new (TpWeakRef);
1260   self->object = object;
1261   g_object_add_weak_pointer (self->object, &self->object);
1262   self->user_data = user_data;
1263   self->destroy = destroy;
1264   return self;
1265 }
1266 
1267 /**
1268  * tp_weak_ref_get_user_data: (skip)
1269  * @self: a weak reference
1270  *
1271  * Return the additional data that was passed to tp_weak_ref_new().
1272  *
1273  * Returns: the additional data supplied in tp_weak_ref_new(), which may be
1274  *  %NULL
1275  *
1276  * Since: 0.11.3
1277  */
1278 gpointer
tp_weak_ref_get_user_data(TpWeakRef * self)1279 tp_weak_ref_get_user_data (TpWeakRef *self)
1280 {
1281   return self->user_data;
1282 }
1283 
1284 /**
1285  * tp_weak_ref_dup_object: (skip)
1286  * @self: a weak reference
1287  *
1288  * If the weakly referenced object still exists, return a new reference to
1289  * it. Otherwise, return %NULL.
1290  *
1291  * Returns: (type GObject.Object) (transfer full): a new reference, or %NULL
1292  *
1293  * Since: 0.11.3
1294  */
1295 gpointer
tp_weak_ref_dup_object(TpWeakRef * self)1296 tp_weak_ref_dup_object (TpWeakRef *self)
1297 {
1298   if (self->object != NULL)
1299     return g_object_ref (self->object);
1300 
1301   return NULL;
1302 }
1303 
1304 /**
1305  * tp_weak_ref_destroy: (skip)
1306  * @self: (transfer full): a weak reference
1307  *
1308  * Free a weak reference wrapper. This drops the weak reference to the
1309  * object (if it still exists), and frees the user data with the user-supplied
1310  * destructor function if one was provided.
1311  *
1312  * Since: 0.11.3
1313  */
1314 void
tp_weak_ref_destroy(TpWeakRef * self)1315 tp_weak_ref_destroy (TpWeakRef *self)
1316 {
1317   if (self->object != NULL)
1318     g_object_remove_weak_pointer (self->object, &self->object);
1319 
1320   if (self->destroy != NULL)
1321     (self->destroy) (self->user_data);
1322 
1323   g_slice_free (TpWeakRef, self);
1324 }
1325 
1326 /**
1327  * tp_clear_object: (skip)
1328  * @op: a pointer to a variable, struct member etc. holding a #GObject
1329  *
1330  * Set a variable holding a #GObject to %NULL. If it was not already %NULL,
1331  * unref the object it previously pointed to.
1332  *
1333  * This is exactly equivalent to calling tp_clear_pointer() on @op,
1334  * with @destroy = g_object_unref(). See tp_clear_pointer() for example usage.
1335  *
1336  * Since: 0.11.7
1337  */
1338 
1339 /**
1340  * tp_clear_pointer: (skip)
1341  * @pp: a pointer to a variable, struct member etc. holding a pointer
1342  * @destroy: a function to which a gpointer can be passed, to destroy *@pp
1343  *  (if calling this macro from C++, explicitly casting the function to
1344  *  #GDestroyNotify may be necessary)
1345  *
1346  * Set a variable holding a pointer to %NULL. If it was not already %NULL,
1347  * unref or destroy the object it previously pointed to with @destroy.
1348  *
1349  * More precisely, if *@pp is non-%NULL, set *@pp to %NULL, then
1350  * call @destroy on the object that *@pp previously pointed to.
1351  *
1352  * This is analogous to g_clear_error() for non-error objects, but also
1353  * ensures that @pp is already %NULL before the destructor is run.
1354  *
1355  * Typical usage is something like this:
1356  *
1357  * |[
1358  * typedef struct {
1359  *   TpConnection *conn;
1360  *   GError *error;
1361  *   GHashTable *table;
1362  *   MyStruct *misc;
1363  * } Foo;
1364  * Foo *foo;
1365  *
1366  * ...
1367  *
1368  * tp_clear_object (&amp;foo->conn);
1369  * g_clear_error (&amp;foo->error);
1370  * tp_clear_boxed (G_TYPE_HASH_TABLE, &amp;foo->table);
1371  * tp_clear_pointer (&amp;foo->misc, my_struct_destroy);
1372  * ]|
1373  *
1374  * Since: 0.11.7
1375  */
1376 
1377 /**
1378  * tp_clear_boxed: (skip)
1379  * @gtype: (type GObject.Type): the #GType of *@pp, e.g. %G_TYPE_HASH_TABLE
1380  * @pp: a pointer to a variable, struct member etc. holding a boxed object
1381  *
1382  * Set a variable holding a boxed object to %NULL. If it was not already %NULL,
1383  * destroy the boxed object it previously pointed to, as appropriate for
1384  * @gtype.
1385  *
1386  * More precisely, if *@pp is non-%NULL, set *@pp to %NULL, then
1387  * call g_boxed_free() on the object that *@pp previously pointed to.
1388  *
1389  * This is similar to tp_clear_pointer(); see that function's documentation
1390  * for typical usage.
1391  *
1392  * Since: 0.11.7
1393  */
1394 
1395 /**
1396  * tp_simple_async_report_success_in_idle:
1397  * @source: (allow-none): the source object
1398  * @callback: (scope async): the callback
1399  * @user_data: (closure): user data for @callback
1400  * @source_tag: the source tag for the #GSimpleAsyncResult
1401  *
1402  * Create a new #GSimpleAsyncResult with no operation result, and call
1403  * g_simple_async_result_complete_in_idle() on it.
1404  *
1405  * This is like a successful version of g_simple_async_report_error_in_idle(),
1406  * suitable for asynchronous functions that (conceptually) either succeed and
1407  * return nothing, or raise an error, such as tp_proxy_prepare_async().
1408  *
1409  * The corresponding finish function should not call a function that attempts
1410  * to get a result, such as g_simple_async_result_get_op_res_gpointer().
1411  *
1412  * Since: 0.11.9
1413  */
1414 void
tp_simple_async_report_success_in_idle(GObject * source,GAsyncReadyCallback callback,gpointer user_data,gpointer source_tag)1415 tp_simple_async_report_success_in_idle (GObject *source,
1416     GAsyncReadyCallback callback,
1417     gpointer user_data,
1418     gpointer source_tag)
1419 {
1420   GSimpleAsyncResult *simple;
1421 
1422   simple = g_simple_async_result_new (source, callback, user_data, source_tag);
1423   g_simple_async_result_complete_in_idle (simple);
1424   g_object_unref (simple);
1425 }
1426 
1427 /**
1428  * tp_user_action_time_from_x11:
1429  * @x11_time: an X11 timestamp, or 0 to indicate the current time
1430  *
1431  * Convert an X11 timestamp into a user action time as used in Telepathy.
1432  *
1433  * This also works for the timestamps used by GDK 2, GDK 3 and Clutter 1.0;
1434  * it may or may not work with other toolkits or versions.
1435  *
1436  * Returns: a nonzero Telepathy user action time, or
1437  *  %TP_USER_ACTION_TIME_CURRENT_TIME
1438  *
1439  * Since: 0.11.13
1440  */
1441 gint64
tp_user_action_time_from_x11(guint32 x11_time)1442 tp_user_action_time_from_x11 (guint32 x11_time)
1443 {
1444   if (x11_time == 0)
1445     {
1446       return TP_USER_ACTION_TIME_CURRENT_TIME;
1447     }
1448 
1449   return x11_time;
1450 }
1451 
1452 /**
1453  * tp_user_action_time_should_present:
1454  * @user_action_time: (type gint64): the Telepathy user action time
1455  * @x11_time: (out) (allow-none): a pointer to guint32 used to
1456  *  return an X11 timestamp, or 0 to indicate the current time; if
1457  *  %FALSE is returned, the value placed here is not meaningful
1458  *
1459  * Interpret a Telepathy user action time to decide whether a Handler should
1460  * attempt to gain focus. If %TRUE is returned, it would be appropriate to
1461  * call gtk_window_present_with_time() using @x11_time as input, for instance.
1462  *
1463  * @x11_time is used to return a timestamp in the right format for X11,
1464  * GDK 2, GDK 3 and Clutter 1.0; it may or may not work with other
1465  * toolkits or versions.
1466  *
1467  * Returns: %TRUE if it would be appropriate to present a window
1468  *
1469  * Since: 0.11.13
1470  */
1471 
1472 gboolean
tp_user_action_time_should_present(gint64 user_action_time,guint32 * x11_time)1473 tp_user_action_time_should_present (gint64 user_action_time,
1474     guint32 *x11_time)
1475 {
1476   guint32 when = 0;
1477   gboolean ret;
1478 
1479   if (user_action_time > 0 && user_action_time <= G_MAXUINT32)
1480     {
1481       when = (guint32) user_action_time;
1482       ret = TRUE;
1483     }
1484   else if (user_action_time == TP_USER_ACTION_TIME_CURRENT_TIME)
1485     {
1486       ret = TRUE;
1487     }
1488   else
1489     {
1490       ret = FALSE;
1491     }
1492 
1493   if (ret && x11_time != NULL)
1494     *x11_time = when;
1495 
1496   return ret;
1497 }
1498 
1499 /* Add each of @quarks to @array if it isn't already present.
1500  *
1501  * There are @n quarks, or if @n == -1, the array is 0-terminated. */
1502 void
_tp_quark_array_merge(GArray * array,const GQuark * quarks,gssize n)1503 _tp_quark_array_merge (GArray *array,
1504     const GQuark *quarks,
1505     gssize n)
1506 {
1507   gssize i;
1508   guint j;
1509 
1510   g_return_if_fail (array != NULL);
1511   g_return_if_fail (g_array_get_element_size (array) == sizeof (GQuark));
1512   g_return_if_fail (n >= -1);
1513   g_return_if_fail (n <= 0 || quarks != NULL);
1514 
1515   if (quarks == NULL || n == 0)
1516     return;
1517 
1518   if (n < 0)
1519     {
1520       n = 0;
1521 
1522       for (i = 0; quarks[i] != 0; i++)
1523         n++;
1524     }
1525   else
1526     {
1527       for (i = 0; i < n; i++)
1528         g_return_if_fail (quarks[i] != 0);
1529     }
1530 
1531   if (array->len == 0)
1532     {
1533       /* fast-path for the common case: there's nothing to merge with */
1534       g_array_append_vals (array, quarks, n);
1535       return;
1536     }
1537 
1538   for (i = 0; i < n; i++)
1539     {
1540       for (j = 0; j < array->len; j++)
1541         {
1542           if (g_array_index (array, GQuark, j) == quarks[i])
1543             goto next_i;
1544         }
1545 
1546       g_array_append_val (array, quarks[i]);
1547 next_i:
1548       continue;
1549     }
1550 }
1551 
1552 /* Helper to implement functions with 0-terminated list of features in args */
1553 void
_tp_quark_array_merge_valist(GArray * array,GQuark feature,va_list var_args)1554 _tp_quark_array_merge_valist (GArray *array,
1555     GQuark feature,
1556     va_list var_args)
1557 {
1558   GArray *features;
1559   GQuark f;
1560 
1561   features = g_array_new (FALSE, FALSE, sizeof (GQuark));
1562 
1563   for (f = feature; f != 0; f = va_arg (var_args, GQuark))
1564     g_array_append_val (features, f);
1565 
1566   _tp_quark_array_merge (array, (GQuark *) features->data, features->len);
1567 
1568   g_array_unref (features);
1569 }
1570 
1571 #ifdef HAVE_GIO_UNIX
1572 GSocketAddress *
_tp_create_temp_unix_socket(GSocketService * service,gchar ** tmpdir,GError ** error)1573 _tp_create_temp_unix_socket (GSocketService *service,
1574     gchar **tmpdir,
1575     GError **error)
1576 {
1577   GSocketAddress *address;
1578   gchar *dir = g_dir_make_tmp ("tp-glib-socket.XXXXXX", error);
1579   gchar *name;
1580 
1581   if (dir == NULL)
1582     return NULL;
1583 
1584   if (g_chmod (dir, 0700) != 0)
1585     {
1586       int e = errno;
1587 
1588       g_set_error (error, G_IO_ERROR, g_io_error_from_errno (e),
1589           "unable to set permissions of %s to 0700: %s", dir,
1590           g_strerror (e));
1591       g_free (dir);
1592       return NULL;
1593     }
1594 
1595   name = g_build_filename (dir, "s", NULL);
1596   address = g_unix_socket_address_new (name);
1597   g_free (name);
1598 
1599   if (!g_socket_listener_add_address (G_SOCKET_LISTENER (service),
1600         address, G_SOCKET_TYPE_STREAM,
1601         G_SOCKET_PROTOCOL_DEFAULT,
1602         NULL, NULL, error))
1603     {
1604       g_object_unref (address);
1605       g_free (dir);
1606       return NULL;
1607     }
1608 
1609   if (tmpdir != NULL)
1610     *tmpdir = dir;
1611   else
1612     g_free (dir);
1613 
1614   return address;
1615 }
1616 #endif /* HAVE_GIO_UNIX */
1617 
1618 GList *
_tp_create_channel_request_list(TpSimpleClientFactory * factory,GHashTable * request_props)1619 _tp_create_channel_request_list (TpSimpleClientFactory *factory,
1620     GHashTable *request_props)
1621 {
1622   GHashTableIter iter;
1623   GList *result = NULL;
1624   gpointer key, value;
1625 
1626   g_hash_table_iter_init (&iter, request_props);
1627   while (g_hash_table_iter_next (&iter, &key, &value))
1628     {
1629       TpChannelRequest *req;
1630       const gchar *path = key;
1631       GHashTable *props = value;
1632       GError *error = NULL;
1633 
1634       req = _tp_simple_client_factory_ensure_channel_request (factory, path,
1635           props, &error);
1636       if (req == NULL)
1637         {
1638           DEBUG ("Failed to create TpChannelRequest: %s", error->message);
1639           g_error_free (error);
1640           continue;
1641         }
1642 
1643       result = g_list_prepend (result, req);
1644     }
1645 
1646   return result;
1647 }
1648 
1649 /**
1650  * tp_utf8_make_valid:
1651  * @name: string to coerce into UTF8
1652  *
1653  * Validate that the provided string is valid UTF8. If not,
1654  * replace all invalid bytes with unicode replacement
1655  * character (U+FFFD).
1656  *
1657  * This method is a verbatim copy of glib's internal
1658  * _g_utf8_make_valid<!-- -->() function, and will be deprecated as
1659  * soon as the glib one becomes public.
1660  *
1661  * Returns: (transfer full): a new valid UTF8 string
1662  *
1663  * Since: 0.13.15
1664  */
1665 gchar *
tp_utf8_make_valid(const gchar * name)1666 tp_utf8_make_valid (const gchar *name)
1667 {
1668   GString *string;
1669   const gchar *remainder, *invalid;
1670   gint remaining_bytes, valid_bytes;
1671 
1672   g_return_val_if_fail (name != NULL, NULL);
1673 
1674   string = NULL;
1675   remainder = name;
1676   remaining_bytes = strlen (name);
1677 
1678   while (remaining_bytes != 0)
1679     {
1680       if (g_utf8_validate (remainder, remaining_bytes, &invalid))
1681         break;
1682       valid_bytes = invalid - remainder;
1683 
1684       if (string == NULL)
1685         string = g_string_sized_new (remaining_bytes);
1686 
1687       g_string_append_len (string, remainder, valid_bytes);
1688       /* append U+FFFD REPLACEMENT CHARACTER */
1689       g_string_append (string, "\357\277\275");
1690 
1691       remaining_bytes -= valid_bytes + 1;
1692       remainder = invalid + 1;
1693     }
1694 
1695   if (string == NULL)
1696     return g_strdup (name);
1697 
1698   g_string_append (string, remainder);
1699 
1700   g_assert (g_utf8_validate (string->str, -1, NULL));
1701 
1702   return g_string_free (string, FALSE);
1703 }
1704 
1705 /*
1706  * _tp_enum_from_nick:
1707  * @enum_type: the GType of a subtype of GEnum
1708  * @nick: a non-%NULL string purporting to be the nickname of a value of
1709  *        @enum_type
1710  * @value: the address at which to store the value of @enum_type corresponding
1711  *         to @nick if this functions returns %TRUE; if this function returns
1712  *         %FALSE, this variable will be left untouched.
1713  *
1714  * <!-- -->
1715  *
1716  * Returns: %TRUE if @nick is a member of @enum_type, or %FALSE otherwise
1717  */
1718 gboolean
_tp_enum_from_nick(GType enum_type,const gchar * nick,gint * value)1719 _tp_enum_from_nick (
1720     GType enum_type,
1721     const gchar *nick,
1722     gint *value)
1723 {
1724   GEnumClass *klass = g_type_class_ref (enum_type);
1725   GEnumValue *enum_value;
1726 
1727   g_return_val_if_fail (klass != NULL, FALSE);
1728   g_return_val_if_fail (value != NULL, FALSE);
1729 
1730   enum_value = g_enum_get_value_by_nick (klass, nick);
1731   g_type_class_unref (klass);
1732 
1733   if (enum_value != NULL)
1734     {
1735       *value = enum_value->value;
1736       return TRUE;
1737     }
1738   else
1739     {
1740       return FALSE;
1741     }
1742 }
1743 
1744 /*
1745  * _tp_enum_to_nick:
1746  * @enum_type: the GType of a subtype of GEnum
1747  * @value: a value of @enum_type
1748  *
1749  * <!-- -->
1750  *
1751  * Returns: the nickname of @value, or %NULL if it is not, in fact, a value of
1752  * @enum_type
1753  */
1754 const gchar *
_tp_enum_to_nick(GType enum_type,gint value)1755 _tp_enum_to_nick (
1756     GType enum_type,
1757     gint value)
1758 {
1759   GEnumClass *klass = g_type_class_ref (enum_type);
1760   GEnumValue *enum_value;
1761 
1762   g_return_val_if_fail (klass != NULL, NULL);
1763 
1764   enum_value = g_enum_get_value (klass, value);
1765   g_type_class_unref (klass);
1766 
1767   if (enum_value != NULL)
1768     return enum_value->value_nick;
1769   else
1770     return NULL;
1771 }
1772 
1773 /*
1774  * _tp_enum_to_nick_nonnull:
1775  *
1776  * The same as _tp_enum_to_nick, but always returns non-NULL.
1777  */
1778 const gchar *
_tp_enum_to_nick_nonnull(GType enum_type,gint value)1779 _tp_enum_to_nick_nonnull (
1780     GType enum_type,
1781     gint value)
1782 {
1783   GEnumClass *klass = g_type_class_ref (enum_type);
1784   GEnumValue *enum_value;
1785 
1786   g_return_val_if_fail (klass != NULL, "(incorrect class)");
1787 
1788   enum_value = g_enum_get_value (klass, value);
1789   g_type_class_unref (klass);
1790 
1791   if (enum_value == NULL)
1792     return "(out-of-range value)";
1793   else if (enum_value->value_nick == NULL)
1794     return "(value with no nickname)";
1795   else
1796     return enum_value->value_nick;
1797 }
1798 
1799 gboolean
_tp_bind_connection_status_to_boolean(GBinding * binding,const GValue * src_value,GValue * dest_value,gpointer user_data)1800 _tp_bind_connection_status_to_boolean (GBinding *binding,
1801     const GValue *src_value,
1802     GValue *dest_value,
1803     gpointer user_data)
1804 {
1805   gboolean invert = GPOINTER_TO_UINT (user_data);
1806   gboolean value;
1807 
1808   g_return_val_if_fail (G_VALUE_HOLDS_UINT (src_value), FALSE);
1809   g_return_val_if_fail (G_VALUE_HOLDS_BOOLEAN (dest_value), FALSE);
1810 
1811   value = (g_value_get_uint (src_value) == TP_CONNECTION_STATUS_CONNECTED);
1812 
1813   if (invert)
1814     value = !value;
1815 
1816   g_value_set_boolean (dest_value, value);
1817 
1818   return TRUE;
1819 }
1820 
1821 /*
1822  * _tp_determine_socket_address_type:
1823  *
1824  * Determines the best available socket address type.
1825  *
1826  */
1827 static gboolean
_tp_determine_socket_address_type(GHashTable * supported_sockets,TpSocketAddressType * address_type,GError ** error)1828 _tp_determine_socket_address_type (GHashTable *supported_sockets,
1829     TpSocketAddressType *address_type,
1830     GError **error)
1831 {
1832   guint i;
1833   TpSocketAddressType types[] = {
1834 #ifdef HAVE_GIO_UNIX
1835       TP_SOCKET_ADDRESS_TYPE_UNIX,
1836 #endif /* HAVE_GIO_UNIX */
1837       TP_SOCKET_ADDRESS_TYPE_IPV4,
1838       TP_SOCKET_ADDRESS_TYPE_IPV6
1839   };
1840 
1841   for (i = 0; i < G_N_ELEMENTS (types); i++)
1842     {
1843       GArray *arr = g_hash_table_lookup (supported_sockets,
1844           GUINT_TO_POINTER (types[i]));
1845 
1846       if (arr != NULL)
1847         {
1848           *address_type = types[i];
1849           return TRUE;
1850         }
1851     }
1852 
1853   /* This should never happen */
1854   g_set_error (error, TP_ERROR,
1855       TP_ERROR_NOT_IMPLEMENTED, "No supported socket types");
1856 
1857   return FALSE;
1858 }
1859 
1860 /*
1861  * _tp_determine_access_control_type:
1862  *
1863  * Determines the best available socket access control type, falling back to
1864  * TP_SOCKET_ACCESS_CONTROL_LOCALHOST if needed.
1865  *
1866  */
1867 static gboolean
_tp_determine_access_control_type(GHashTable * supported_sockets,TpSocketAddressType address_type,TpSocketAccessControl * access_control,GError ** error)1868 _tp_determine_access_control_type (GHashTable *supported_sockets,
1869     TpSocketAddressType address_type,
1870     TpSocketAccessControl *access_control,
1871     GError **error)
1872 {
1873   gboolean support_localhost = FALSE;
1874   GArray *arr;
1875   guint i;
1876 
1877   arr = g_hash_table_lookup (supported_sockets,
1878       GUINT_TO_POINTER (address_type));
1879 
1880   switch (address_type)
1881     {
1882 #ifdef HAVE_GIO_UNIX
1883       case TP_SOCKET_ADDRESS_TYPE_UNIX:
1884       case TP_SOCKET_ADDRESS_TYPE_ABSTRACT_UNIX:
1885         {
1886           /* Preferred order: credentials, localhost */
1887           for (i = 0; i < arr->len; i++)
1888             {
1889               TpSocketAccessControl _access = g_array_index (arr,
1890                   TpSocketAccessControl, i);
1891 
1892               if (_access == TP_SOCKET_ACCESS_CONTROL_CREDENTIALS)
1893                 {
1894                   *access_control = _access;
1895                   return TRUE;
1896                 }
1897               else if (_access == TP_SOCKET_ACCESS_CONTROL_LOCALHOST)
1898                 {
1899                   support_localhost = TRUE;
1900                 }
1901             }
1902         }
1903         break;
1904 #else
1905       case TP_SOCKET_ADDRESS_TYPE_UNIX:
1906       case TP_SOCKET_ADDRESS_TYPE_ABSTRACT_UNIX:
1907         break;
1908 #endif
1909       case TP_SOCKET_ADDRESS_TYPE_IPV6:
1910       case TP_SOCKET_ADDRESS_TYPE_IPV4:
1911         {
1912           /* Preferred order: port, localhost */
1913           for (i = 0; i < arr->len; i++)
1914             {
1915               TpSocketAccessControl _access = g_array_index (arr,
1916                   TpSocketAccessControl, i);
1917 
1918               if (_access == TP_SOCKET_ACCESS_CONTROL_PORT)
1919                 {
1920                   *access_control = _access;
1921                   return TRUE;
1922                 }
1923               else if (_access == TP_SOCKET_ACCESS_CONTROL_LOCALHOST)
1924                 {
1925                   support_localhost = TRUE;
1926                 }
1927             }
1928         }
1929         break;
1930     }
1931 
1932   /* This should never happen */
1933   if (!support_localhost)
1934     {
1935       g_set_error (error, TP_ERROR,
1936           TP_ERROR_NOT_IMPLEMENTED, "No supported access control");
1937       return FALSE;
1938     }
1939 
1940   *access_control = TP_SOCKET_ACCESS_CONTROL_LOCALHOST;
1941   return TRUE;
1942 }
1943 
1944 gboolean
_tp_set_socket_address_type_and_access_control_type(GHashTable * supported_sockets,TpSocketAddressType * address_type,TpSocketAccessControl * access_control,GError ** error)1945 _tp_set_socket_address_type_and_access_control_type (
1946     GHashTable *supported_sockets,
1947     TpSocketAddressType *address_type,
1948     TpSocketAccessControl *access_control,
1949     GError **error)
1950 {
1951   g_return_val_if_fail (address_type != NULL, FALSE);
1952   g_return_val_if_fail (access_control != NULL, FALSE);
1953 
1954   if (!_tp_determine_socket_address_type (supported_sockets, address_type,
1955         error))
1956     return FALSE;
1957 
1958   return _tp_determine_access_control_type (supported_sockets,
1959       *address_type, access_control, error);
1960 }
1961 
1962 GSocket *
_tp_create_client_socket(TpSocketAddressType socket_type,GError ** error)1963 _tp_create_client_socket (TpSocketAddressType socket_type,
1964     GError **error)
1965 {
1966   GSocket *client_socket;
1967   GSocketFamily family;
1968 
1969   switch (socket_type)
1970     {
1971 #ifdef HAVE_GIO_UNIX
1972       case TP_SOCKET_ADDRESS_TYPE_UNIX:
1973         family = G_SOCKET_FAMILY_UNIX;
1974         break;
1975 #endif
1976 
1977       case TP_SOCKET_ADDRESS_TYPE_IPV4:
1978         family = G_SOCKET_FAMILY_IPV4;
1979         break;
1980 
1981       case TP_SOCKET_ADDRESS_TYPE_IPV6:
1982         family = G_SOCKET_FAMILY_IPV6;
1983         break;
1984 
1985       default:
1986         g_assert_not_reached ();
1987     }
1988 
1989   /* Create socket to connect to the CM. We use a GSocket and not a
1990    * GSocketClient because it creates the underlying socket when trying to
1991    * connect and we need to be able to get the local port (needed for
1992    * TP_SOCKET_ACCESS_CONTROL_PORT) of the socket before actually connecting. */
1993   client_socket = g_socket_new (family, G_SOCKET_TYPE_STREAM,
1994       G_SOCKET_PROTOCOL_DEFAULT, error);
1995   if (client_socket == NULL)
1996     return NULL;
1997 
1998   if (socket_type == TP_SOCKET_ADDRESS_TYPE_IPV4 ||
1999       socket_type == TP_SOCKET_ADDRESS_TYPE_IPV6)
2000     {
2001       /* Bind local address. This is needed to be able to get the local port
2002        * of the socket and pass it to the CM when using
2003        * TP_SOCKET_ACCESS_CONTROL_PORT. */
2004       GSocketAddress *local_address;
2005       GInetAddress *tmp;
2006       gboolean success;
2007 
2008       tmp = g_inet_address_new_any (family);
2009       local_address = g_inet_socket_address_new (tmp, 0);
2010 
2011       success = g_socket_bind (client_socket, local_address,
2012           TRUE, error);
2013 
2014       g_object_unref (tmp);
2015       g_object_unref (local_address);
2016 
2017       if (!success)
2018         return NULL;
2019     }
2020 
2021   return client_socket;
2022 }
2023 
2024 gboolean
_tp_contacts_to_handles(TpConnection * connection,guint n_contacts,TpContact * const * contacts,GArray ** handles)2025 _tp_contacts_to_handles (TpConnection *connection,
2026     guint n_contacts,
2027     TpContact * const *contacts,
2028     GArray **handles)
2029 {
2030     guint i;
2031 
2032     g_return_val_if_fail (handles != NULL, FALSE);
2033     g_return_val_if_fail (n_contacts > 0, FALSE);
2034 
2035     *handles = g_array_sized_new (FALSE, FALSE, sizeof (TpHandle), n_contacts);
2036 
2037     for (i = 0; i < n_contacts; i++)
2038       {
2039         TpHandle handle;
2040 
2041         if (!TP_IS_CONTACT (contacts[i]) ||
2042             tp_contact_get_connection (contacts[i]) != connection)
2043           {
2044             tp_clear_pointer (handles, g_array_unref);
2045             return FALSE;
2046           }
2047 
2048         handle = tp_contact_get_handle (contacts[i]);
2049         g_array_append_val (*handles, handle);
2050       }
2051 
2052   return TRUE;
2053 }
2054 
2055 /* table's key can be anything (usually TpHandle) but value must be a
2056  * TpContact */
2057 GPtrArray *
_tp_contacts_from_values(GHashTable * table)2058 _tp_contacts_from_values (GHashTable *table)
2059 {
2060   GPtrArray *contacts;
2061   GHashTableIter iter;
2062   gpointer value;
2063 
2064   if (table == NULL)
2065       return NULL;
2066 
2067   contacts = g_ptr_array_new_full (g_hash_table_size (table),
2068       g_object_unref);
2069 
2070   g_hash_table_iter_init (&iter, table);
2071   while (g_hash_table_iter_next (&iter, NULL, &value))
2072     {
2073       if (value == NULL)
2074         continue;
2075       g_assert (TP_IS_CONTACT (value));
2076 
2077       g_ptr_array_add (contacts, g_object_ref (value));
2078     }
2079 
2080   return contacts;
2081 }
2082 
2083 /*
2084  * @l: (transfer none) (element-type GLib.Object): a list of #GObject or
2085  *  any subclass
2086  *
2087  * Returns: (transfer full): a copy of @l
2088  */
2089 GList *
_tp_object_list_copy(GList * l)2090 _tp_object_list_copy (GList *l)
2091 {
2092   return _tp_g_list_copy_deep (l, (GCopyFunc) g_object_ref, NULL);
2093 }
2094 
2095 /*
2096  * @l: (transfer full) (element-type GLib.Object): a list of #GObject or
2097  *  any subclass
2098  *
2099  * Unref each item of @l and free the list.
2100  *
2101  * This function can be cast to #GDestroyNotify.
2102  */
2103 void
_tp_object_list_free(GList * l)2104 _tp_object_list_free (GList *l)
2105 {
2106   g_list_free_full (l, g_object_unref);
2107 }
2108 
2109 GList *
_tp_g_list_copy_deep(GList * list,GCopyFunc func,gpointer user_data)2110 _tp_g_list_copy_deep (GList *list,
2111     GCopyFunc func,
2112     gpointer user_data)
2113 {
2114   GList *ret = NULL;
2115   GList *l;
2116 
2117   ret = g_list_copy (list);
2118 
2119   if (func != NULL)
2120     {
2121       for (l = ret; l != NULL; l = l->next)
2122         l->data = func (l->data, user_data);
2123     }
2124 
2125   return ret;
2126 }
2127 
2128 /**
2129  * tp_value_array_free:
2130  * @va: a #GValueArray
2131  *
2132  * Free @va. This is exactly the same as g_value_array_free(), but does not
2133  * provoke deprecation warnings from GLib when used in conjunction with
2134  * tp_value_array_build() and tp_value_array_unpack().
2135  *
2136  * Since: 0.23.0
2137  */
2138 void
2139 (tp_value_array_free) (GValueArray *va)
2140 {
2141   _tp_value_array_free_inline (va);
2142 }
2143