Branch data Line data Source code
1 : : /*
2 : : * Copyright © 2007, 2008 Ryan Lortie
3 : : * Copyright © 2010 Codethink Limited
4 : : *
5 : : * SPDX-License-Identifier: LGPL-2.1-or-later
6 : : *
7 : : * This library is free software; you can redistribute it and/or
8 : : * modify it under the terms of the GNU Lesser General Public
9 : : * License as published by the Free Software Foundation; either
10 : : * version 2.1 of the License, or (at your option) any later version.
11 : : *
12 : : * This library is distributed in the hope that it will be useful,
13 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : : * Lesser General Public License for more details.
16 : : *
17 : : * You should have received a copy of the GNU Lesser General Public
18 : : * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 : : *
20 : : * Author: Ryan Lortie <desrt@desrt.ca>
21 : : */
22 : :
23 : : /* Prologue {{{1 */
24 : :
25 : : #include "config.h"
26 : :
27 : : #include <glib/gvariant-serialiser.h>
28 : : #include "gvariant-internal.h"
29 : : #include <glib/gvariant-core.h>
30 : : #include <glib/gtestutils.h>
31 : : #include <glib/gstrfuncs.h>
32 : : #include <glib/gslice.h>
33 : : #include <glib/ghash.h>
34 : : #include <glib/gmem.h>
35 : :
36 : : #include <string.h>
37 : :
38 : : /**
39 : : * GVariant:
40 : : *
41 : : * `GVariant` is a variant datatype; it can contain one or more values
42 : : * along with information about the type of the values.
43 : : *
44 : : * A `GVariant` may contain simple types, like an integer, or a boolean value;
45 : : * or complex types, like an array of two strings, or a dictionary of key
46 : : * value pairs. A `GVariant` is also immutable: once it’s been created neither
47 : : * its type nor its content can be modified further.
48 : : *
49 : : * `GVariant` is useful whenever data needs to be serialized, for example when
50 : : * sending method parameters in D-Bus, or when saving settings using
51 : : * [`GSettings`](../gio/class.Settings.html).
52 : : *
53 : : * When creating a new `GVariant`, you pass the data you want to store in it
54 : : * along with a string representing the type of data you wish to pass to it.
55 : : *
56 : : * For instance, if you want to create a `GVariant` holding an integer value you
57 : : * can use:
58 : : *
59 : : * ```c
60 : : * GVariant *v = g_variant_new ("u", 40);
61 : : * ```
62 : : *
63 : : * The string `u` in the first argument tells `GVariant` that the data passed to
64 : : * the constructor (`40`) is going to be an unsigned integer.
65 : : *
66 : : * More advanced examples of `GVariant` in use can be found in documentation for
67 : : * [`GVariant` format strings](gvariant-format-strings.html#pointers).
68 : : *
69 : : * The range of possible values is determined by the type.
70 : : *
71 : : * The type system used by `GVariant` is [type@GLib.VariantType].
72 : : *
73 : : * `GVariant` instances always have a type and a value (which are given
74 : : * at construction time). The type and value of a `GVariant` instance
75 : : * can never change other than by the `GVariant` itself being
76 : : * destroyed. A `GVariant` cannot contain a pointer.
77 : : *
78 : : * `GVariant` is reference counted using [method@GLib.Variant.ref] and
79 : : * [method@GLib.Variant.unref]. `GVariant` also has floating reference counts —
80 : : * see [method@GLib.Variant.ref_sink].
81 : : *
82 : : * `GVariant` is completely threadsafe. A `GVariant` instance can be
83 : : * concurrently accessed in any way from any number of threads without
84 : : * problems.
85 : : *
86 : : * `GVariant` is heavily optimised for dealing with data in serialized
87 : : * form. It works particularly well with data located in memory-mapped
88 : : * files. It can perform nearly all deserialization operations in a
89 : : * small constant time, usually touching only a single memory page.
90 : : * Serialized `GVariant` data can also be sent over the network.
91 : : *
92 : : * `GVariant` is largely compatible with D-Bus. Almost all types of
93 : : * `GVariant` instances can be sent over D-Bus. See [type@GLib.VariantType] for
94 : : * exceptions. (However, `GVariant`’s serialization format is not the same
95 : : * as the serialization format of a D-Bus message body: use
96 : : * [GDBusMessage](../gio/class.DBusMessage.html), in the GIO library, for those.)
97 : : *
98 : : * For space-efficiency, the `GVariant` serialization format does not
99 : : * automatically include the variant’s length, type or endianness,
100 : : * which must either be implied from context (such as knowledge that a
101 : : * particular file format always contains a little-endian
102 : : * `G_VARIANT_TYPE_VARIANT` which occupies the whole length of the file)
103 : : * or supplied out-of-band (for instance, a length, type and/or endianness
104 : : * indicator could be placed at the beginning of a file, network message
105 : : * or network stream).
106 : : *
107 : : * A `GVariant`’s size is limited mainly by any lower level operating
108 : : * system constraints, such as the number of bits in `gsize`. For
109 : : * example, it is reasonable to have a 2GB file mapped into memory
110 : : * with [struct@GLib.MappedFile], and call [ctor@GLib.Variant.new_from_data] on
111 : : * it.
112 : : *
113 : : * For convenience to C programmers, `GVariant` features powerful
114 : : * varargs-based value construction and destruction. This feature is
115 : : * designed to be embedded in other libraries.
116 : : *
117 : : * There is a Python-inspired text language for describing `GVariant`
118 : : * values. `GVariant` includes a printer for this language and a parser
119 : : * with type inferencing.
120 : : *
121 : : * ## Memory Use
122 : : *
123 : : * `GVariant` tries to be quite efficient with respect to memory use.
124 : : * This section gives a rough idea of how much memory is used by the
125 : : * current implementation. The information here is subject to change
126 : : * in the future.
127 : : *
128 : : * The memory allocated by `GVariant` can be grouped into 4 broad
129 : : * purposes: memory for serialized data, memory for the type
130 : : * information cache, buffer management memory and memory for the
131 : : * `GVariant` structure itself.
132 : : *
133 : : * ## Serialized Data Memory
134 : : *
135 : : * This is the memory that is used for storing `GVariant` data in
136 : : * serialized form. This is what would be sent over the network or
137 : : * what would end up on disk, not counting any indicator of the
138 : : * endianness, or of the length or type of the top-level variant.
139 : : *
140 : : * The amount of memory required to store a boolean is 1 byte. 16,
141 : : * 32 and 64 bit integers and double precision floating point numbers
142 : : * use their ‘natural’ size. Strings (including object path and
143 : : * signature strings) are stored with a nul terminator, and as such
144 : : * use the length of the string plus 1 byte.
145 : : *
146 : : * ‘Maybe’ types use no space at all to represent the null value and
147 : : * use the same amount of space (sometimes plus one byte) as the
148 : : * equivalent non-maybe-typed value to represent the non-null case.
149 : : *
150 : : * Arrays use the amount of space required to store each of their
151 : : * members, concatenated. Additionally, if the items stored in an
152 : : * array are not of a fixed-size (ie: strings, other arrays, etc)
153 : : * then an additional framing offset is stored for each item. The
154 : : * size of this offset is either 1, 2 or 4 bytes depending on the
155 : : * overall size of the container. Additionally, extra padding bytes
156 : : * are added as required for alignment of child values.
157 : : *
158 : : * Tuples (including dictionary entries) use the amount of space
159 : : * required to store each of their members, concatenated, plus one
160 : : * framing offset (as per arrays) for each non-fixed-sized item in
161 : : * the tuple, except for the last one. Additionally, extra padding
162 : : * bytes are added as required for alignment of child values.
163 : : *
164 : : * Variants use the same amount of space as the item inside of the
165 : : * variant, plus 1 byte, plus the length of the type string for the
166 : : * item inside the variant.
167 : : *
168 : : * As an example, consider a dictionary mapping strings to variants.
169 : : * In the case that the dictionary is empty, 0 bytes are required for
170 : : * the serialization.
171 : : *
172 : : * If we add an item ‘width’ that maps to the int32 value of 500 then
173 : : * we will use 4 bytes to store the int32 (so 6 for the variant
174 : : * containing it) and 6 bytes for the string. The variant must be
175 : : * aligned to 8 after the 6 bytes of the string, so that’s 2 extra
176 : : * bytes. 6 (string) + 2 (padding) + 6 (variant) is 14 bytes used
177 : : * for the dictionary entry. An additional 1 byte is added to the
178 : : * array as a framing offset making a total of 15 bytes.
179 : : *
180 : : * If we add another entry, ‘title’ that maps to a nullable string
181 : : * that happens to have a value of null, then we use 0 bytes for the
182 : : * null value (and 3 bytes for the variant to contain it along with
183 : : * its type string) plus 6 bytes for the string. Again, we need 2
184 : : * padding bytes. That makes a total of 6 + 2 + 3 = 11 bytes.
185 : : *
186 : : * We now require extra padding between the two items in the array.
187 : : * After the 14 bytes of the first item, that’s 2 bytes required.
188 : : * We now require 2 framing offsets for an extra two
189 : : * bytes. 14 + 2 + 11 + 2 = 29 bytes to encode the entire two-item
190 : : * dictionary.
191 : : *
192 : : * ## Type Information Cache
193 : : *
194 : : * For each `GVariant` type that currently exists in the program a type
195 : : * information structure is kept in the type information cache. The
196 : : * type information structure is required for rapid deserialization.
197 : : *
198 : : * Continuing with the above example, if a `GVariant` exists with the
199 : : * type `a{sv}` then a type information struct will exist for
200 : : * `a{sv}`, `{sv}`, `s`, and `v`. Multiple uses of the same type
201 : : * will share the same type information. Additionally, all
202 : : * single-digit types are stored in read-only static memory and do
203 : : * not contribute to the writable memory footprint of a program using
204 : : * `GVariant`.
205 : : *
206 : : * Aside from the type information structures stored in read-only
207 : : * memory, there are two forms of type information. One is used for
208 : : * container types where there is a single element type: arrays and
209 : : * maybe types. The other is used for container types where there
210 : : * are multiple element types: tuples and dictionary entries.
211 : : *
212 : : * Array type info structures are `6 * sizeof (void *)`, plus the
213 : : * memory required to store the type string itself. This means that
214 : : * on 32-bit systems, the cache entry for `a{sv}` would require 30
215 : : * bytes of memory (plus allocation overhead).
216 : : *
217 : : * Tuple type info structures are `6 * sizeof (void *)`, plus `4 *
218 : : * sizeof (void *)` for each item in the tuple, plus the memory
219 : : * required to store the type string itself. A 2-item tuple, for
220 : : * example, would have a type information structure that consumed
221 : : * writable memory in the size of `14 * sizeof (void *)` (plus type
222 : : * string) This means that on 32-bit systems, the cache entry for
223 : : * `{sv}` would require 61 bytes of memory (plus allocation overhead).
224 : : *
225 : : * This means that in total, for our `a{sv}` example, 91 bytes of
226 : : * type information would be allocated.
227 : : *
228 : : * The type information cache, additionally, uses a [struct@GLib.HashTable] to
229 : : * store and look up the cached items and stores a pointer to this
230 : : * hash table in static storage. The hash table is freed when there
231 : : * are zero items in the type cache.
232 : : *
233 : : * Although these sizes may seem large it is important to remember
234 : : * that a program will probably only have a very small number of
235 : : * different types of values in it and that only one type information
236 : : * structure is required for many different values of the same type.
237 : : *
238 : : * ## Buffer Management Memory
239 : : *
240 : : * `GVariant` uses an internal buffer management structure to deal
241 : : * with the various different possible sources of serialized data
242 : : * that it uses. The buffer is responsible for ensuring that the
243 : : * correct call is made when the data is no longer in use by
244 : : * `GVariant`. This may involve a [func@GLib.free] or
245 : : * even [method@GLib.MappedFile.unref].
246 : : *
247 : : * One buffer management structure is used for each chunk of
248 : : * serialized data. The size of the buffer management structure
249 : : * is `4 * (void *)`. On 32-bit systems, that’s 16 bytes.
250 : : *
251 : : * ## GVariant structure
252 : : *
253 : : * The size of a `GVariant` structure is `6 * (void *)`. On 32-bit
254 : : * systems, that’s 24 bytes.
255 : : *
256 : : * `GVariant` structures only exist if they are explicitly created
257 : : * with API calls. For example, if a `GVariant` is constructed out of
258 : : * serialized data for the example given above (with the dictionary)
259 : : * then although there are 9 individual values that comprise the
260 : : * entire dictionary (two keys, two values, two variants containing
261 : : * the values, two dictionary entries, plus the dictionary itself),
262 : : * only 1 `GVariant` instance exists — the one referring to the
263 : : * dictionary.
264 : : *
265 : : * If calls are made to start accessing the other values then
266 : : * `GVariant` instances will exist for those values only for as long
267 : : * as they are in use (ie: until you call [method@GLib.Variant.unref]). The
268 : : * type information is shared. The serialized data and the buffer
269 : : * management structure for that serialized data is shared by the
270 : : * child.
271 : : *
272 : : * ## Summary
273 : : *
274 : : * To put the entire example together, for our dictionary mapping
275 : : * strings to variants (with two entries, as given above), we are
276 : : * using 91 bytes of memory for type information, 29 bytes of memory
277 : : * for the serialized data, 16 bytes for buffer management and 24
278 : : * bytes for the `GVariant` instance, or a total of 160 bytes, plus
279 : : * allocation overhead. If we were to use [method@GLib.Variant.get_child_value]
280 : : * to access the two dictionary entries, we would use an additional 48
281 : : * bytes. If we were to have other dictionaries of the same type, we
282 : : * would use more memory for the serialized data and buffer
283 : : * management for those dictionaries, but the type information would
284 : : * be shared.
285 : : *
286 : : * Since: 2.24
287 : : */
288 : :
289 : : /* definition of GVariant structure is in gvariant-core.c */
290 : :
291 : : /* this is a g_return_val_if_fail() for making
292 : : * sure a (GVariant *) has the required type.
293 : : */
294 : : #define TYPE_CHECK(value, TYPE, val) \
295 : : if G_UNLIKELY (!g_variant_is_of_type (value, TYPE)) { \
296 : : g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, \
297 : : "g_variant_is_of_type (" #value \
298 : : ", " #TYPE ")"); \
299 : : return val; \
300 : : }
301 : :
302 : : /* Numeric Type Constructor/Getters {{{1 */
303 : : /* < private >
304 : : * g_variant_new_from_trusted:
305 : : * @type: the #GVariantType
306 : : * @data: the data to use
307 : : * @size: the size of @data
308 : : *
309 : : * Constructs a new trusted #GVariant instance from the provided data.
310 : : * This is used to implement g_variant_new_* for all the basic types.
311 : : *
312 : : * Note: @data must be backed by memory that is aligned appropriately for the
313 : : * @type being loaded. Otherwise this function will internally create a copy of
314 : : * the memory (since GLib 2.60) or (in older versions) fail and exit the
315 : : * process.
316 : : *
317 : : * Returns: a new floating #GVariant
318 : : */
319 : : static GVariant *
320 : 1862497 : g_variant_new_from_trusted (const GVariantType *type,
321 : : gconstpointer data,
322 : : gsize size)
323 : : {
324 : : GVariant *value;
325 : : GBytes *bytes;
326 : :
327 : 1862497 : bytes = g_bytes_new (data, size);
328 : 1862497 : value = g_variant_new_from_bytes (type, bytes, TRUE);
329 : 1862497 : g_bytes_unref (bytes);
330 : :
331 : 1862497 : return value;
332 : : }
333 : :
334 : : /**
335 : : * g_variant_new_boolean:
336 : : * @value: a #gboolean value
337 : : *
338 : : * Creates a new boolean #GVariant instance -- either %TRUE or %FALSE.
339 : : *
340 : : * Returns: (transfer none): a floating reference to a new boolean #GVariant instance
341 : : *
342 : : * Since: 2.24
343 : : **/
344 : : GVariant *
345 : 34330 : g_variant_new_boolean (gboolean value)
346 : : {
347 : 34330 : guchar v = value;
348 : :
349 : 34330 : return g_variant_new_from_trusted (G_VARIANT_TYPE_BOOLEAN, &v, 1);
350 : : }
351 : :
352 : : /**
353 : : * g_variant_get_boolean:
354 : : * @value: a boolean #GVariant instance
355 : : *
356 : : * Returns the boolean value of @value.
357 : : *
358 : : * It is an error to call this function with a @value of any type
359 : : * other than %G_VARIANT_TYPE_BOOLEAN.
360 : : *
361 : : * Returns: %TRUE or %FALSE
362 : : *
363 : : * Since: 2.24
364 : : **/
365 : : gboolean
366 : 115243 : g_variant_get_boolean (GVariant *value)
367 : : {
368 : : const guchar *data;
369 : :
370 [ - + ]: 115243 : TYPE_CHECK (value, G_VARIANT_TYPE_BOOLEAN, FALSE);
371 : :
372 : 115243 : data = g_variant_get_data (value);
373 : :
374 [ + + + + ]: 115243 : return data != NULL ? *data != 0 : FALSE;
375 : : }
376 : :
377 : : /* the constructors and accessors for byte, int{16,32,64}, handles and
378 : : * doubles all look pretty much exactly the same, so we reduce
379 : : * copy/pasting here.
380 : : */
381 : : #define NUMERIC_TYPE(TYPE, type, ctype) \
382 : : GVariant *g_variant_new_##type (ctype value) { \
383 : : return g_variant_new_from_trusted (G_VARIANT_TYPE_##TYPE, \
384 : : &value, sizeof value); \
385 : : } \
386 : : ctype g_variant_get_##type (GVariant *value) { \
387 : : const ctype *data; \
388 : : TYPE_CHECK (value, G_VARIANT_TYPE_ ## TYPE, 0); \
389 : : data = g_variant_get_data (value); \
390 : : return data != NULL ? *data : 0; \
391 : : }
392 : :
393 : :
394 : : /**
395 : : * g_variant_new_byte:
396 : : * @value: a #guint8 value
397 : : *
398 : : * Creates a new byte #GVariant instance.
399 : : *
400 : : * Returns: (transfer none): a floating reference to a new byte #GVariant instance
401 : : *
402 : : * Since: 2.24
403 : : **/
404 : : /**
405 : : * g_variant_get_byte:
406 : : * @value: a byte #GVariant instance
407 : : *
408 : : * Returns the byte value of @value.
409 : : *
410 : : * It is an error to call this function with a @value of any type
411 : : * other than %G_VARIANT_TYPE_BYTE.
412 : : *
413 : : * Returns: a #guint8
414 : : *
415 : : * Since: 2.24
416 : : **/
417 [ - + + + ]: 498943 : NUMERIC_TYPE (BYTE, byte, guint8)
418 : :
419 : : /**
420 : : * g_variant_new_int16:
421 : : * @value: a #gint16 value
422 : : *
423 : : * Creates a new int16 #GVariant instance.
424 : : *
425 : : * Returns: (transfer none): a floating reference to a new int16 #GVariant instance
426 : : *
427 : : * Since: 2.24
428 : : **/
429 : : /**
430 : : * g_variant_get_int16:
431 : : * @value: an int16 #GVariant instance
432 : : *
433 : : * Returns the 16-bit signed integer value of @value.
434 : : *
435 : : * It is an error to call this function with a @value of any type
436 : : * other than %G_VARIANT_TYPE_INT16.
437 : : *
438 : : * Returns: a #gint16
439 : : *
440 : : * Since: 2.24
441 : : **/
442 [ - + + + ]: 197849 : NUMERIC_TYPE (INT16, int16, gint16)
443 : :
444 : : /**
445 : : * g_variant_new_uint16:
446 : : * @value: a #guint16 value
447 : : *
448 : : * Creates a new uint16 #GVariant instance.
449 : : *
450 : : * Returns: (transfer none): a floating reference to a new uint16 #GVariant instance
451 : : *
452 : : * Since: 2.24
453 : : **/
454 : : /**
455 : : * g_variant_get_uint16:
456 : : * @value: a uint16 #GVariant instance
457 : : *
458 : : * Returns the 16-bit unsigned integer value of @value.
459 : : *
460 : : * It is an error to call this function with a @value of any type
461 : : * other than %G_VARIANT_TYPE_UINT16.
462 : : *
463 : : * Returns: a #guint16
464 : : *
465 : : * Since: 2.24
466 : : **/
467 [ - + + + ]: 46074 : NUMERIC_TYPE (UINT16, uint16, guint16)
468 : :
469 : : /**
470 : : * g_variant_new_int32:
471 : : * @value: a #gint32 value
472 : : *
473 : : * Creates a new int32 #GVariant instance.
474 : : *
475 : : * Returns: (transfer none): a floating reference to a new int32 #GVariant instance
476 : : *
477 : : * Since: 2.24
478 : : **/
479 : : /**
480 : : * g_variant_get_int32:
481 : : * @value: an int32 #GVariant instance
482 : : *
483 : : * Returns the 32-bit signed integer value of @value.
484 : : *
485 : : * It is an error to call this function with a @value of any type
486 : : * other than %G_VARIANT_TYPE_INT32.
487 : : *
488 : : * Returns: a #gint32
489 : : *
490 : : * Since: 2.24
491 : : **/
492 [ - + + + ]: 21869 : NUMERIC_TYPE (INT32, int32, gint32)
493 : :
494 : : /**
495 : : * g_variant_new_uint32:
496 : : * @value: a #guint32 value
497 : : *
498 : : * Creates a new uint32 #GVariant instance.
499 : : *
500 : : * Returns: (transfer none): a floating reference to a new uint32 #GVariant instance
501 : : *
502 : : * Since: 2.24
503 : : **/
504 : : /**
505 : : * g_variant_get_uint32:
506 : : * @value: a uint32 #GVariant instance
507 : : *
508 : : * Returns the 32-bit unsigned integer value of @value.
509 : : *
510 : : * It is an error to call this function with a @value of any type
511 : : * other than %G_VARIANT_TYPE_UINT32.
512 : : *
513 : : * Returns: a #guint32
514 : : *
515 : : * Since: 2.24
516 : : **/
517 [ - + + + ]: 117770 : NUMERIC_TYPE (UINT32, uint32, guint32)
518 : :
519 : : /**
520 : : * g_variant_new_int64:
521 : : * @value: a #gint64 value
522 : : *
523 : : * Creates a new int64 #GVariant instance.
524 : : *
525 : : * Returns: (transfer none): a floating reference to a new int64 #GVariant instance
526 : : *
527 : : * Since: 2.24
528 : : **/
529 : : /**
530 : : * g_variant_get_int64:
531 : : * @value: an int64 #GVariant instance
532 : : *
533 : : * Returns the 64-bit signed integer value of @value.
534 : : *
535 : : * It is an error to call this function with a @value of any type
536 : : * other than %G_VARIANT_TYPE_INT64.
537 : : *
538 : : * Returns: a #gint64
539 : : *
540 : : * Since: 2.24
541 : : **/
542 [ - + + + ]: 54174 : NUMERIC_TYPE (INT64, int64, gint64)
543 : :
544 : : /**
545 : : * g_variant_new_uint64:
546 : : * @value: a #guint64 value
547 : : *
548 : : * Creates a new uint64 #GVariant instance.
549 : : *
550 : : * Returns: (transfer none): a floating reference to a new uint64 #GVariant instance
551 : : *
552 : : * Since: 2.24
553 : : **/
554 : : /**
555 : : * g_variant_get_uint64:
556 : : * @value: a uint64 #GVariant instance
557 : : *
558 : : * Returns the 64-bit unsigned integer value of @value.
559 : : *
560 : : * It is an error to call this function with a @value of any type
561 : : * other than %G_VARIANT_TYPE_UINT64.
562 : : *
563 : : * Returns: a #guint64
564 : : *
565 : : * Since: 2.24
566 : : **/
567 [ - + + + ]: 117302 : NUMERIC_TYPE (UINT64, uint64, guint64)
568 : :
569 : : /**
570 : : * g_variant_new_handle:
571 : : * @value: a #gint32 value
572 : : *
573 : : * Creates a new handle #GVariant instance.
574 : : *
575 : : * By convention, handles are indexes into an array of file descriptors
576 : : * that are sent alongside a D-Bus message. If you're not interacting
577 : : * with D-Bus, you probably don't need them.
578 : : *
579 : : * Returns: (transfer none): a floating reference to a new handle #GVariant instance
580 : : *
581 : : * Since: 2.24
582 : : **/
583 : : /**
584 : : * g_variant_get_handle:
585 : : * @value: a handle #GVariant instance
586 : : *
587 : : * Returns the 32-bit signed integer value of @value.
588 : : *
589 : : * It is an error to call this function with a @value of any type other
590 : : * than %G_VARIANT_TYPE_HANDLE.
591 : : *
592 : : * By convention, handles are indexes into an array of file descriptors
593 : : * that are sent alongside a D-Bus message. If you're not interacting
594 : : * with D-Bus, you probably don't need them.
595 : : *
596 : : * Returns: a #gint32
597 : : *
598 : : * Since: 2.24
599 : : **/
600 [ - + + + ]: 73370 : NUMERIC_TYPE (HANDLE, handle, gint32)
601 : :
602 : : /**
603 : : * g_variant_new_double:
604 : : * @value: a #gdouble floating point value
605 : : *
606 : : * Creates a new double #GVariant instance.
607 : : *
608 : : * Returns: (transfer none): a floating reference to a new double #GVariant instance
609 : : *
610 : : * Since: 2.24
611 : : **/
612 : : /**
613 : : * g_variant_get_double:
614 : : * @value: a double #GVariant instance
615 : : *
616 : : * Returns the double precision floating point value of @value.
617 : : *
618 : : * It is an error to call this function with a @value of any type
619 : : * other than %G_VARIANT_TYPE_DOUBLE.
620 : : *
621 : : * Returns: a #gdouble
622 : : *
623 : : * Since: 2.24
624 : : **/
625 [ - + + + ]: 34926 : NUMERIC_TYPE (DOUBLE, double, gdouble)
626 : :
627 : : /* Container type Constructor / Deconstructors {{{1 */
628 : : /**
629 : : * g_variant_new_maybe:
630 : : * @child_type: (nullable): the #GVariantType of the child, or %NULL
631 : : * @child: (nullable): the child value, or %NULL
632 : : *
633 : : * Depending on if @child is %NULL, either wraps @child inside of a
634 : : * maybe container or creates a Nothing instance for the given @type.
635 : : *
636 : : * At least one of @child_type and @child must be non-%NULL.
637 : : * If @child_type is non-%NULL then it must be a definite type.
638 : : * If they are both non-%NULL then @child_type must be the type
639 : : * of @child.
640 : : *
641 : : * If @child is a floating reference (see g_variant_ref_sink()), the new
642 : : * instance takes ownership of @child.
643 : : *
644 : : * Returns: (transfer none): a floating reference to a new #GVariant maybe instance
645 : : *
646 : : * Since: 2.24
647 : : **/
648 : : GVariant *
649 : 1981 : g_variant_new_maybe (const GVariantType *child_type,
650 : : GVariant *child)
651 : : {
652 : : GVariantType *maybe_type;
653 : : GVariant *value;
654 : :
655 : 1981 : g_return_val_if_fail (child_type == NULL || g_variant_type_is_definite
656 : : (child_type), 0);
657 : 1981 : g_return_val_if_fail (child_type != NULL || child != NULL, NULL);
658 : 1981 : g_return_val_if_fail (child_type == NULL || child == NULL ||
659 : : g_variant_is_of_type (child, child_type),
660 : : NULL);
661 : :
662 [ + + ]: 1981 : if (child_type == NULL)
663 : 352 : child_type = g_variant_get_type (child);
664 : :
665 : 1981 : maybe_type = g_variant_type_new_maybe (child_type);
666 : :
667 [ + + ]: 1981 : if (child != NULL)
668 : : {
669 : : GVariant **children;
670 : : gboolean trusted;
671 : :
672 : 665 : children = g_new (GVariant *, 1);
673 : 665 : children[0] = g_variant_ref_sink (child);
674 : 665 : trusted = g_variant_is_trusted (children[0]);
675 : :
676 : 665 : value = g_variant_new_from_children (maybe_type, children, 1, trusted);
677 : : }
678 : : else
679 : 1316 : value = g_variant_new_from_children (maybe_type, NULL, 0, TRUE);
680 : :
681 : 1981 : g_variant_type_free (maybe_type);
682 : :
683 : 1981 : return value;
684 : : }
685 : :
686 : : /**
687 : : * g_variant_get_maybe:
688 : : * @value: a maybe-typed value
689 : : *
690 : : * Given a maybe-typed #GVariant instance, extract its value. If the
691 : : * value is Nothing, then this function returns %NULL.
692 : : *
693 : : * Returns: (nullable) (transfer full): the contents of @value, or %NULL
694 : : *
695 : : * Since: 2.24
696 : : **/
697 : : GVariant *
698 : 1196 : g_variant_get_maybe (GVariant *value)
699 : : {
700 [ - + ]: 1196 : TYPE_CHECK (value, G_VARIANT_TYPE_MAYBE, NULL);
701 : :
702 [ + + ]: 1196 : if (g_variant_n_children (value))
703 : 604 : return g_variant_get_child_value (value, 0);
704 : :
705 : 592 : return NULL;
706 : : }
707 : :
708 : : /**
709 : : * g_variant_new_variant: (constructor)
710 : : * @value: a #GVariant instance
711 : : *
712 : : * Boxes @value. The result is a #GVariant instance representing a
713 : : * variant containing the original value.
714 : : *
715 : : * If @child is a floating reference (see g_variant_ref_sink()), the new
716 : : * instance takes ownership of @child.
717 : : *
718 : : * Returns: (transfer none): a floating reference to a new variant #GVariant instance
719 : : *
720 : : * Since: 2.24
721 : : **/
722 : : GVariant *
723 : 203371 : g_variant_new_variant (GVariant *value)
724 : : {
725 : 203371 : g_return_val_if_fail (value != NULL, NULL);
726 : :
727 : 203371 : g_variant_ref_sink (value);
728 : :
729 : 406742 : return g_variant_new_from_children (G_VARIANT_TYPE_VARIANT,
730 : 203371 : g_memdup2 (&value, sizeof value),
731 : : 1, g_variant_is_trusted (value));
732 : : }
733 : :
734 : : /**
735 : : * g_variant_get_variant:
736 : : * @value: a variant #GVariant instance
737 : : *
738 : : * Unboxes @value. The result is the #GVariant instance that was
739 : : * contained in @value.
740 : : *
741 : : * Returns: (transfer full): the item contained in the variant
742 : : *
743 : : * Since: 2.24
744 : : **/
745 : : GVariant *
746 : 238093 : g_variant_get_variant (GVariant *value)
747 : : {
748 [ - + ]: 238093 : TYPE_CHECK (value, G_VARIANT_TYPE_VARIANT, NULL);
749 : :
750 : 238093 : return g_variant_get_child_value (value, 0);
751 : : }
752 : :
753 : : /**
754 : : * g_variant_new_array:
755 : : * @child_type: (nullable): the element type of the new array
756 : : * @children: (nullable) (array length=n_children): an array of
757 : : * #GVariant pointers, the children
758 : : * @n_children: the length of @children
759 : : *
760 : : * Creates a new #GVariant array from @children.
761 : : *
762 : : * @child_type must be non-%NULL if @n_children is zero. Otherwise, the
763 : : * child type is determined by inspecting the first element of the
764 : : * @children array. If @child_type is non-%NULL then it must be a
765 : : * definite type.
766 : : *
767 : : * The items of the array are taken from the @children array. No entry
768 : : * in the @children array may be %NULL.
769 : : *
770 : : * All items in the array must have the same type, which must be the
771 : : * same as @child_type, if given.
772 : : *
773 : : * If the @children are floating references (see g_variant_ref_sink()), the
774 : : * new instance takes ownership of them as if via g_variant_ref_sink().
775 : : *
776 : : * Returns: (transfer none): a floating reference to a new #GVariant array
777 : : *
778 : : * Since: 2.24
779 : : **/
780 : : GVariant *
781 : 5397 : g_variant_new_array (const GVariantType *child_type,
782 : : GVariant * const *children,
783 : : gsize n_children)
784 : : {
785 : : GVariantType *array_type;
786 : : GVariant **my_children;
787 : : gboolean trusted;
788 : : GVariant *value;
789 : : gsize i;
790 : :
791 : 5397 : g_return_val_if_fail (n_children > 0 || child_type != NULL, NULL);
792 : 5397 : g_return_val_if_fail (n_children == 0 || children != NULL, NULL);
793 : 5397 : g_return_val_if_fail (child_type == NULL ||
794 : : g_variant_type_is_definite (child_type), NULL);
795 : :
796 : 5397 : my_children = g_new (GVariant *, n_children);
797 : 5397 : trusted = TRUE;
798 : :
799 [ + + ]: 5397 : if (child_type == NULL)
800 : 2591 : child_type = g_variant_get_type (children[0]);
801 : 5397 : array_type = g_variant_type_new_array (child_type);
802 : :
803 [ + + ]: 314543 : for (i = 0; i < n_children; i++)
804 : : {
805 : 309146 : gboolean is_of_child_type = g_variant_is_of_type (children[i], child_type);
806 [ - + ]: 309146 : if G_UNLIKELY (!is_of_child_type)
807 : : {
808 [ # # ]: 0 : while (i != 0)
809 : 0 : g_variant_unref (my_children[--i]);
810 : 0 : g_free (my_children);
811 : 0 : g_return_val_if_fail (is_of_child_type, NULL);
812 : : }
813 : 309146 : my_children[i] = g_variant_ref_sink (children[i]);
814 : 309146 : trusted &= g_variant_is_trusted (children[i]);
815 : : }
816 : :
817 : 5397 : value = g_variant_new_from_children (array_type, my_children,
818 : : n_children, trusted);
819 : 5397 : g_variant_type_free (array_type);
820 : :
821 : 5397 : return value;
822 : : }
823 : :
824 : : /*< private >
825 : : * g_variant_make_tuple_type:
826 : : * @children: (array length=n_children): an array of GVariant *
827 : : * @n_children: the length of @children
828 : : *
829 : : * Return the type of a tuple containing @children as its items.
830 : : **/
831 : : static GVariantType *
832 : 12168 : g_variant_make_tuple_type (GVariant * const *children,
833 : : gsize n_children)
834 : : {
835 : : const GVariantType **types;
836 : : GVariantType *type;
837 : : gsize i;
838 : :
839 : 12168 : types = g_new (const GVariantType *, n_children);
840 : :
841 [ + + ]: 46268 : for (i = 0; i < n_children; i++)
842 : 34100 : types[i] = g_variant_get_type (children[i]);
843 : :
844 : 12168 : type = g_variant_type_new_tuple (types, n_children);
845 : 12168 : g_free (types);
846 : :
847 : 12168 : return type;
848 : : }
849 : :
850 : : /**
851 : : * g_variant_new_tuple:
852 : : * @children: (array length=n_children): the items to make the tuple out of
853 : : * @n_children: the length of @children
854 : : *
855 : : * Creates a new tuple #GVariant out of the items in @children. The
856 : : * type is determined from the types of @children. No entry in the
857 : : * @children array may be %NULL.
858 : : *
859 : : * If @n_children is 0 then the unit tuple is constructed.
860 : : *
861 : : * If the @children are floating references (see g_variant_ref_sink()), the
862 : : * new instance takes ownership of them as if via g_variant_ref_sink().
863 : : *
864 : : * Returns: (transfer none): a floating reference to a new #GVariant tuple
865 : : *
866 : : * Since: 2.24
867 : : **/
868 : : GVariant *
869 : 1712 : g_variant_new_tuple (GVariant * const *children,
870 : : gsize n_children)
871 : : {
872 : : GVariantType *tuple_type;
873 : : GVariant **my_children;
874 : : gboolean trusted;
875 : : GVariant *value;
876 : : gsize i;
877 : :
878 : 1712 : g_return_val_if_fail (n_children == 0 || children != NULL, NULL);
879 : :
880 : 1712 : my_children = g_new (GVariant *, n_children);
881 : 1712 : trusted = TRUE;
882 : :
883 [ + + ]: 19066 : for (i = 0; i < n_children; i++)
884 : : {
885 : 17354 : my_children[i] = g_variant_ref_sink (children[i]);
886 : 17354 : trusted &= g_variant_is_trusted (children[i]);
887 : : }
888 : :
889 : 1712 : tuple_type = g_variant_make_tuple_type (children, n_children);
890 : 1712 : value = g_variant_new_from_children (tuple_type, my_children,
891 : : n_children, trusted);
892 : 1712 : g_variant_type_free (tuple_type);
893 : :
894 : 1712 : return value;
895 : : }
896 : :
897 : : /*< private >
898 : : * g_variant_make_dict_entry_type:
899 : : * @key: a #GVariant, the key
900 : : * @val: a #GVariant, the value
901 : : *
902 : : * Return the type of a dictionary entry containing @key and @val as its
903 : : * children.
904 : : **/
905 : : static GVariantType *
906 : 208664 : g_variant_make_dict_entry_type (GVariant *key,
907 : : GVariant *val)
908 : : {
909 : 208664 : return g_variant_type_new_dict_entry (g_variant_get_type (key),
910 : : g_variant_get_type (val));
911 : : }
912 : :
913 : : /**
914 : : * g_variant_new_dict_entry: (constructor)
915 : : * @key: a basic #GVariant, the key
916 : : * @value: a #GVariant, the value
917 : : *
918 : : * Creates a new dictionary entry #GVariant. @key and @value must be
919 : : * non-%NULL. @key must be a value of a basic type (ie: not a container).
920 : : *
921 : : * If the @key or @value are floating references (see g_variant_ref_sink()),
922 : : * the new instance takes ownership of them as if via g_variant_ref_sink().
923 : : *
924 : : * Returns: (transfer none): a floating reference to a new dictionary entry #GVariant
925 : : *
926 : : * Since: 2.24
927 : : **/
928 : : GVariant *
929 : 143055 : g_variant_new_dict_entry (GVariant *key,
930 : : GVariant *value)
931 : : {
932 : : GVariantType *dict_type;
933 : : GVariant **children;
934 : : gboolean trusted;
935 : :
936 : 143055 : g_return_val_if_fail (key != NULL && value != NULL, NULL);
937 : 143055 : g_return_val_if_fail (!g_variant_is_container (key), NULL);
938 : :
939 : 143055 : children = g_new (GVariant *, 2);
940 : 143055 : children[0] = g_variant_ref_sink (key);
941 : 143055 : children[1] = g_variant_ref_sink (value);
942 [ + - + + ]: 143055 : trusted = g_variant_is_trusted (key) && g_variant_is_trusted (value);
943 : :
944 : 143055 : dict_type = g_variant_make_dict_entry_type (key, value);
945 : 143055 : value = g_variant_new_from_children (dict_type, children, 2, trusted);
946 : 143055 : g_variant_type_free (dict_type);
947 : :
948 : 143055 : return value;
949 : : }
950 : :
951 : : /**
952 : : * g_variant_lookup: (skip)
953 : : * @dictionary: a dictionary #GVariant
954 : : * @key: the key to look up in the dictionary
955 : : * @format_string: a GVariant format string
956 : : * @...: the arguments to unpack the value into
957 : : *
958 : : * Looks up a value in a dictionary #GVariant.
959 : : *
960 : : * This function is a wrapper around g_variant_lookup_value() and
961 : : * g_variant_get(). In the case that %NULL would have been returned,
962 : : * this function returns %FALSE. Otherwise, it unpacks the returned
963 : : * value and returns %TRUE.
964 : : *
965 : : * @format_string determines the C types that are used for unpacking
966 : : * the values and also determines if the values are copied or borrowed,
967 : : * see the section on
968 : : * [`GVariant` format strings](gvariant-format-strings.html#pointers).
969 : : *
970 : : * This function is currently implemented with a linear scan. If you
971 : : * plan to do many lookups then #GVariantDict may be more efficient.
972 : : *
973 : : * Returns: %TRUE if a value was unpacked
974 : : *
975 : : * Since: 2.28
976 : : */
977 : : gboolean
978 : 22 : g_variant_lookup (GVariant *dictionary,
979 : : const gchar *key,
980 : : const gchar *format_string,
981 : : ...)
982 : : {
983 : : GVariantType *type;
984 : : GVariant *value;
985 : :
986 : : /* flatten */
987 : 22 : g_variant_get_data (dictionary);
988 : :
989 : 22 : type = g_variant_format_string_scan_type (format_string, NULL, NULL);
990 : 22 : value = g_variant_lookup_value (dictionary, key, type);
991 : 22 : g_variant_type_free (type);
992 : :
993 [ + + ]: 22 : if (value)
994 : : {
995 : : va_list ap;
996 : :
997 : 12 : va_start (ap, format_string);
998 : 12 : g_variant_get_va (value, format_string, NULL, &ap);
999 : 12 : g_variant_unref (value);
1000 : 12 : va_end (ap);
1001 : :
1002 : 12 : return TRUE;
1003 : : }
1004 : :
1005 : : else
1006 : 10 : return FALSE;
1007 : : }
1008 : :
1009 : : /**
1010 : : * g_variant_lookup_value:
1011 : : * @dictionary: a dictionary #GVariant
1012 : : * @key: the key to look up in the dictionary
1013 : : * @expected_type: (nullable): a #GVariantType, or %NULL
1014 : : *
1015 : : * Looks up a value in a dictionary #GVariant.
1016 : : *
1017 : : * This function works with dictionaries of the type a{s*} (and equally
1018 : : * well with type a{o*}, but we only further discuss the string case
1019 : : * for sake of clarity).
1020 : : *
1021 : : * In the event that @dictionary has the type a{sv}, the @expected_type
1022 : : * string specifies what type of value is expected to be inside of the
1023 : : * variant. If the value inside the variant has a different type then
1024 : : * %NULL is returned. In the event that @dictionary has a value type other
1025 : : * than v then @expected_type must directly match the value type and it is
1026 : : * used to unpack the value directly or an error occurs.
1027 : : *
1028 : : * In either case, if @key is not found in @dictionary, %NULL is returned.
1029 : : *
1030 : : * If the key is found and the value has the correct type, it is
1031 : : * returned. If @expected_type was specified then any non-%NULL return
1032 : : * value will have this type.
1033 : : *
1034 : : * This function is currently implemented with a linear scan. If you
1035 : : * plan to do many lookups then #GVariantDict may be more efficient.
1036 : : *
1037 : : * Returns: (transfer full): the value of the dictionary key, or %NULL
1038 : : *
1039 : : * Since: 2.28
1040 : : */
1041 : : GVariant *
1042 : 33 : g_variant_lookup_value (GVariant *dictionary,
1043 : : const gchar *key,
1044 : : const GVariantType *expected_type)
1045 : : {
1046 : : GVariantIter iter;
1047 : : GVariant *entry;
1048 : : GVariant *value;
1049 : :
1050 : 33 : g_return_val_if_fail (g_variant_is_of_type (dictionary,
1051 : : G_VARIANT_TYPE ("a{s*}")) ||
1052 : : g_variant_is_of_type (dictionary,
1053 : : G_VARIANT_TYPE ("a{o*}")),
1054 : : NULL);
1055 : :
1056 : 33 : g_variant_iter_init (&iter, dictionary);
1057 : :
1058 [ + + ]: 44 : while ((entry = g_variant_iter_next_value (&iter)))
1059 : : {
1060 : : GVariant *entry_key;
1061 : : gboolean matches;
1062 : :
1063 : 33 : entry_key = g_variant_get_child_value (entry, 0);
1064 : 33 : matches = strcmp (g_variant_get_string (entry_key, NULL), key) == 0;
1065 : 33 : g_variant_unref (entry_key);
1066 : :
1067 [ + + ]: 33 : if (matches)
1068 : 22 : break;
1069 : :
1070 : 11 : g_variant_unref (entry);
1071 : : }
1072 : :
1073 [ + + ]: 33 : if (entry == NULL)
1074 : 11 : return NULL;
1075 : :
1076 : 22 : value = g_variant_get_child_value (entry, 1);
1077 : 22 : g_variant_unref (entry);
1078 : :
1079 [ + + ]: 22 : if (g_variant_is_of_type (value, G_VARIANT_TYPE_VARIANT))
1080 : : {
1081 : : GVariant *tmp;
1082 : :
1083 : 20 : tmp = g_variant_get_variant (value);
1084 : 20 : g_variant_unref (value);
1085 : :
1086 [ + + + + ]: 20 : if (expected_type && !g_variant_is_of_type (tmp, expected_type))
1087 : : {
1088 : 2 : g_variant_unref (tmp);
1089 : 2 : tmp = NULL;
1090 : : }
1091 : :
1092 : 20 : value = tmp;
1093 : : }
1094 : :
1095 : 22 : g_return_val_if_fail (expected_type == NULL || value == NULL ||
1096 : : g_variant_is_of_type (value, expected_type), NULL);
1097 : :
1098 : 22 : return value;
1099 : : }
1100 : :
1101 : : /**
1102 : : * g_variant_get_fixed_array:
1103 : : * @value: a #GVariant array with fixed-sized elements
1104 : : * @n_elements: (out): a pointer to the location to store the number of items
1105 : : * @element_size: the size of each element
1106 : : *
1107 : : * Provides access to the serialized data for an array of fixed-sized
1108 : : * items.
1109 : : *
1110 : : * @value must be an array with fixed-sized elements. Numeric types are
1111 : : * fixed-size, as are tuples containing only other fixed-sized types.
1112 : : *
1113 : : * @element_size must be the size of a single element in the array,
1114 : : * as given by the section on
1115 : : * [serialized data memory](struct.Variant.html#serialized-data-memory).
1116 : : *
1117 : : * In particular, arrays of these fixed-sized types can be interpreted
1118 : : * as an array of the given C type, with @element_size set to the size
1119 : : * the appropriate type:
1120 : : * - %G_VARIANT_TYPE_INT16 (etc.): #gint16 (etc.)
1121 : : * - %G_VARIANT_TYPE_BOOLEAN: #guchar (not #gboolean!)
1122 : : * - %G_VARIANT_TYPE_BYTE: #guint8
1123 : : * - %G_VARIANT_TYPE_HANDLE: #guint32
1124 : : * - %G_VARIANT_TYPE_DOUBLE: #gdouble
1125 : : *
1126 : : * For example, if calling this function for an array of 32-bit integers,
1127 : : * you might say `sizeof(gint32)`. This value isn't used except for the purpose
1128 : : * of a double-check that the form of the serialized data matches the caller's
1129 : : * expectation.
1130 : : *
1131 : : * @n_elements, which must be non-%NULL, is set equal to the number of
1132 : : * items in the array.
1133 : : *
1134 : : * Returns: (array length=n_elements) (transfer none): a pointer to
1135 : : * the fixed array
1136 : : *
1137 : : * Since: 2.24
1138 : : **/
1139 : : gconstpointer
1140 : 28 : g_variant_get_fixed_array (GVariant *value,
1141 : : gsize *n_elements,
1142 : : gsize element_size)
1143 : : {
1144 : : GVariantTypeInfo *array_info;
1145 : : gsize array_element_size;
1146 : : gconstpointer data;
1147 : : gsize size;
1148 : :
1149 [ - + ]: 28 : TYPE_CHECK (value, G_VARIANT_TYPE_ARRAY, NULL);
1150 : :
1151 : 28 : g_return_val_if_fail (n_elements != NULL, NULL);
1152 : 28 : g_return_val_if_fail (element_size > 0, NULL);
1153 : :
1154 : 28 : array_info = g_variant_get_type_info (value);
1155 : 28 : g_variant_type_info_query_element (array_info, NULL, &array_element_size);
1156 : :
1157 : 28 : g_return_val_if_fail (array_element_size, NULL);
1158 : :
1159 [ - + ]: 28 : if G_UNLIKELY (array_element_size != element_size)
1160 : : {
1161 [ # # ]: 0 : if (array_element_size)
1162 : 0 : g_critical ("g_variant_get_fixed_array: assertion "
1163 : : "'g_variant_array_has_fixed_size (value, element_size)' "
1164 : : "failed: array size %"G_GSIZE_FORMAT" does not match "
1165 : : "given element_size %"G_GSIZE_FORMAT".",
1166 : : array_element_size, element_size);
1167 : : else
1168 : 0 : g_critical ("g_variant_get_fixed_array: assertion "
1169 : : "'g_variant_array_has_fixed_size (value, element_size)' "
1170 : : "failed: array does not have fixed size.");
1171 : : }
1172 : :
1173 : 28 : data = g_variant_get_data (value);
1174 : 28 : size = g_variant_get_size (value);
1175 : :
1176 [ - + ]: 28 : if (size % element_size)
1177 : 0 : *n_elements = 0;
1178 : : else
1179 : 28 : *n_elements = size / element_size;
1180 : :
1181 [ + - ]: 28 : if (*n_elements)
1182 : 28 : return data;
1183 : :
1184 : 0 : return NULL;
1185 : : }
1186 : :
1187 : : /**
1188 : : * g_variant_new_fixed_array:
1189 : : * @element_type: the #GVariantType of each element
1190 : : * @elements: a pointer to the fixed array of contiguous elements
1191 : : * @n_elements: the number of elements
1192 : : * @element_size: the size of each element
1193 : : *
1194 : : * Constructs a new array #GVariant instance, where the elements are
1195 : : * of @element_type type.
1196 : : *
1197 : : * @elements must be an array with fixed-sized elements. Numeric types are
1198 : : * fixed-size as are tuples containing only other fixed-sized types.
1199 : : *
1200 : : * @element_size must be the size of a single element in the array.
1201 : : * For example, if calling this function for an array of 32-bit integers,
1202 : : * you might say sizeof(gint32). This value isn't used except for the purpose
1203 : : * of a double-check that the form of the serialized data matches the caller's
1204 : : * expectation.
1205 : : *
1206 : : * @n_elements must be the length of the @elements array.
1207 : : *
1208 : : * Returns: (transfer none): a floating reference to a new array #GVariant instance
1209 : : *
1210 : : * Since: 2.32
1211 : : **/
1212 : : GVariant *
1213 : 671 : g_variant_new_fixed_array (const GVariantType *element_type,
1214 : : gconstpointer elements,
1215 : : gsize n_elements,
1216 : : gsize element_size)
1217 : : {
1218 : : GVariantType *array_type;
1219 : : gsize array_element_size;
1220 : : GVariantTypeInfo *array_info;
1221 : : GVariant *value;
1222 : : gpointer data;
1223 : :
1224 : 671 : g_return_val_if_fail (g_variant_type_is_definite (element_type), NULL);
1225 : 671 : g_return_val_if_fail (element_size > 0, NULL);
1226 : :
1227 : 671 : array_type = g_variant_type_new_array (element_type);
1228 : 671 : array_info = g_variant_type_info_get (array_type);
1229 : 671 : g_variant_type_info_query_element (array_info, NULL, &array_element_size);
1230 [ - + ]: 671 : if G_UNLIKELY (array_element_size != element_size)
1231 : : {
1232 [ # # ]: 0 : if (array_element_size)
1233 : 0 : g_critical ("g_variant_new_fixed_array: array size %" G_GSIZE_FORMAT
1234 : : " does not match given element_size %" G_GSIZE_FORMAT ".",
1235 : : array_element_size, element_size);
1236 : : else
1237 : 0 : g_critical ("g_variant_get_fixed_array: array does not have fixed size.");
1238 : 0 : return NULL;
1239 : : }
1240 : :
1241 : 671 : data = g_memdup2 (elements, n_elements * element_size);
1242 : 671 : value = g_variant_new_from_data (array_type, data,
1243 : : n_elements * element_size,
1244 : : FALSE, g_free, data);
1245 : :
1246 : 671 : g_variant_type_free (array_type);
1247 : 671 : g_variant_type_info_unref (array_info);
1248 : :
1249 : 671 : return value;
1250 : : }
1251 : :
1252 : : /* String type constructor/getters/validation {{{1 */
1253 : : /**
1254 : : * g_variant_new_string:
1255 : : * @string: a normal UTF-8 nul-terminated string
1256 : : *
1257 : : * Creates a string #GVariant with the contents of @string.
1258 : : *
1259 : : * @string must be valid UTF-8, and must not be %NULL. To encode
1260 : : * potentially-%NULL strings, use g_variant_new() with `ms` as the
1261 : : * [format string](gvariant-format-strings.html#maybe-types).
1262 : : *
1263 : : * Returns: (transfer none): a floating reference to a new string #GVariant instance
1264 : : *
1265 : : * Since: 2.24
1266 : : **/
1267 : : GVariant *
1268 : 886406 : g_variant_new_string (const gchar *string)
1269 : : {
1270 : 886406 : g_return_val_if_fail (string != NULL, NULL);
1271 : 886406 : g_return_val_if_fail (g_utf8_validate (string, -1, NULL), NULL);
1272 : :
1273 : 886406 : return g_variant_new_from_trusted (G_VARIANT_TYPE_STRING,
1274 : 886406 : string, strlen (string) + 1);
1275 : : }
1276 : :
1277 : : /**
1278 : : * g_variant_new_take_string: (skip)
1279 : : * @string: a normal UTF-8 nul-terminated string
1280 : : *
1281 : : * Creates a string #GVariant with the contents of @string.
1282 : : *
1283 : : * @string must be valid UTF-8, and must not be %NULL. To encode
1284 : : * potentially-%NULL strings, use this with g_variant_new_maybe().
1285 : : *
1286 : : * After this call, @string belongs to the #GVariant and may no longer be
1287 : : * modified by the caller. The memory of @data has to be dynamically
1288 : : * allocated and will eventually be freed with g_free().
1289 : : *
1290 : : * You must not modify or access @string in any other way after passing
1291 : : * it to this function. It is even possible that @string is immediately
1292 : : * freed.
1293 : : *
1294 : : * Returns: (transfer none): a floating reference to a new string
1295 : : * #GVariant instance
1296 : : *
1297 : : * Since: 2.38
1298 : : **/
1299 : : GVariant *
1300 : 5 : g_variant_new_take_string (gchar *string)
1301 : : {
1302 : : GVariant *value;
1303 : : GBytes *bytes;
1304 : :
1305 : 5 : g_return_val_if_fail (string != NULL, NULL);
1306 : 5 : g_return_val_if_fail (g_utf8_validate (string, -1, NULL), NULL);
1307 : :
1308 : 5 : bytes = g_bytes_new_take (string, strlen (string) + 1);
1309 : 5 : value = g_variant_new_from_bytes (G_VARIANT_TYPE_STRING, bytes, TRUE);
1310 : 5 : g_bytes_unref (bytes);
1311 : :
1312 : 5 : return value;
1313 : : }
1314 : :
1315 : : /**
1316 : : * g_variant_new_printf: (skip)
1317 : : * @format_string: a printf-style format string
1318 : : * @...: arguments for @format_string
1319 : : *
1320 : : * Creates a string-type GVariant using printf formatting.
1321 : : *
1322 : : * This is similar to calling g_strdup_printf() and then
1323 : : * g_variant_new_string() but it saves a temporary variable and an
1324 : : * unnecessary copy.
1325 : : *
1326 : : * Returns: (transfer none): a floating reference to a new string
1327 : : * #GVariant instance
1328 : : *
1329 : : * Since: 2.38
1330 : : **/
1331 : : GVariant *
1332 : 1 : g_variant_new_printf (const gchar *format_string,
1333 : : ...)
1334 : : {
1335 : : GVariant *value;
1336 : : GBytes *bytes;
1337 : : gchar *string;
1338 : : va_list ap;
1339 : :
1340 : 1 : g_return_val_if_fail (format_string != NULL, NULL);
1341 : :
1342 : 1 : va_start (ap, format_string);
1343 : 1 : string = g_strdup_vprintf (format_string, ap);
1344 : 1 : va_end (ap);
1345 : :
1346 : 1 : bytes = g_bytes_new_take (string, strlen (string) + 1);
1347 : 1 : value = g_variant_new_from_bytes (G_VARIANT_TYPE_STRING, bytes, TRUE);
1348 : 1 : g_bytes_unref (bytes);
1349 : :
1350 : 1 : return value;
1351 : : }
1352 : :
1353 : : /**
1354 : : * g_variant_new_object_path:
1355 : : * @object_path: a normal C nul-terminated string
1356 : : *
1357 : : * Creates a D-Bus object path #GVariant with the contents of @object_path.
1358 : : * @object_path must be a valid D-Bus object path. Use
1359 : : * g_variant_is_object_path() if you're not sure.
1360 : : *
1361 : : * Returns: (transfer none): a floating reference to a new object path #GVariant instance
1362 : : *
1363 : : * Since: 2.24
1364 : : **/
1365 : : GVariant *
1366 : 524613 : g_variant_new_object_path (const gchar *object_path)
1367 : : {
1368 : 524613 : g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
1369 : :
1370 : 524613 : return g_variant_new_from_trusted (G_VARIANT_TYPE_OBJECT_PATH,
1371 : 524613 : object_path, strlen (object_path) + 1);
1372 : : }
1373 : :
1374 : : /**
1375 : : * g_variant_is_object_path:
1376 : : * @string: a normal C nul-terminated string
1377 : : *
1378 : : * Determines if a given string is a valid D-Bus object path. You
1379 : : * should ensure that a string is a valid D-Bus object path before
1380 : : * passing it to g_variant_new_object_path().
1381 : : *
1382 : : * A valid object path starts with `/` followed by zero or more
1383 : : * sequences of characters separated by `/` characters. Each sequence
1384 : : * must contain only the characters `[A-Z][a-z][0-9]_`. No sequence
1385 : : * (including the one following the final `/` character) may be empty.
1386 : : *
1387 : : * Returns: %TRUE if @string is a D-Bus object path
1388 : : *
1389 : : * Since: 2.24
1390 : : **/
1391 : : gboolean
1392 : 794375 : g_variant_is_object_path (const gchar *string)
1393 : : {
1394 : 794375 : g_return_val_if_fail (string != NULL, FALSE);
1395 : :
1396 : 794375 : return g_variant_serialiser_is_object_path (string, strlen (string) + 1);
1397 : : }
1398 : :
1399 : : /**
1400 : : * g_variant_new_signature:
1401 : : * @signature: a normal C nul-terminated string
1402 : : *
1403 : : * Creates a D-Bus type signature #GVariant with the contents of
1404 : : * @string. @string must be a valid D-Bus type signature. Use
1405 : : * g_variant_is_signature() if you're not sure.
1406 : : *
1407 : : * Returns: (transfer none): a floating reference to a new signature #GVariant instance
1408 : : *
1409 : : * Since: 2.24
1410 : : **/
1411 : : GVariant *
1412 : 50239 : g_variant_new_signature (const gchar *signature)
1413 : : {
1414 : 50239 : g_return_val_if_fail (g_variant_is_signature (signature), NULL);
1415 : :
1416 : 50239 : return g_variant_new_from_trusted (G_VARIANT_TYPE_SIGNATURE,
1417 : 50239 : signature, strlen (signature) + 1);
1418 : : }
1419 : :
1420 : : /**
1421 : : * g_variant_is_signature:
1422 : : * @string: a normal C nul-terminated string
1423 : : *
1424 : : * Determines if a given string is a valid D-Bus type signature. You
1425 : : * should ensure that a string is a valid D-Bus type signature before
1426 : : * passing it to g_variant_new_signature().
1427 : : *
1428 : : * D-Bus type signatures consist of zero or more definite #GVariantType
1429 : : * strings in sequence.
1430 : : *
1431 : : * Returns: %TRUE if @string is a D-Bus type signature
1432 : : *
1433 : : * Since: 2.24
1434 : : **/
1435 : : gboolean
1436 : 260468 : g_variant_is_signature (const gchar *string)
1437 : : {
1438 : 260468 : g_return_val_if_fail (string != NULL, FALSE);
1439 : :
1440 : 260468 : return g_variant_serialiser_is_signature (string, strlen (string) + 1);
1441 : : }
1442 : :
1443 : : /**
1444 : : * g_variant_get_string:
1445 : : * @value: a string #GVariant instance
1446 : : * @length: (optional) (default 0) (out): a pointer to a #gsize,
1447 : : * to store the length
1448 : : *
1449 : : * Returns the string value of a #GVariant instance with a string
1450 : : * type. This includes the types %G_VARIANT_TYPE_STRING,
1451 : : * %G_VARIANT_TYPE_OBJECT_PATH and %G_VARIANT_TYPE_SIGNATURE.
1452 : : *
1453 : : * The string will always be UTF-8 encoded, will never be %NULL, and will never
1454 : : * contain nul bytes.
1455 : : *
1456 : : * If @length is non-%NULL then the length of the string (in bytes) is
1457 : : * returned there. For trusted values, this information is already
1458 : : * known. Untrusted values will be validated and, if valid, a strlen() will be
1459 : : * performed. If invalid, a default value will be returned — for
1460 : : * %G_VARIANT_TYPE_OBJECT_PATH, this is `"/"`, and for other types it is the
1461 : : * empty string.
1462 : : *
1463 : : * It is an error to call this function with a @value of any type
1464 : : * other than those three.
1465 : : *
1466 : : * The return value remains valid as long as @value exists.
1467 : : *
1468 : : * Returns: (transfer none): the constant string, UTF-8 encoded
1469 : : *
1470 : : * Since: 2.24
1471 : : **/
1472 : : const gchar *
1473 : 2018182 : g_variant_get_string (GVariant *value,
1474 : : gsize *length)
1475 : : {
1476 : : gconstpointer data;
1477 : : gsize size;
1478 : :
1479 : 2018182 : g_return_val_if_fail (value != NULL, NULL);
1480 : 2018182 : g_return_val_if_fail (
1481 : : g_variant_is_of_type (value, G_VARIANT_TYPE_STRING) ||
1482 : : g_variant_is_of_type (value, G_VARIANT_TYPE_OBJECT_PATH) ||
1483 : : g_variant_is_of_type (value, G_VARIANT_TYPE_SIGNATURE), NULL);
1484 : :
1485 : 2018182 : data = g_variant_get_data (value);
1486 : 2018182 : size = g_variant_get_size (value);
1487 : :
1488 [ + + ]: 2018182 : if (!g_variant_is_trusted (value))
1489 : : {
1490 [ + + + - ]: 19661 : switch (g_variant_classify (value))
1491 : : {
1492 : 7439 : case G_VARIANT_CLASS_STRING:
1493 [ + + ]: 7439 : if (g_variant_serialiser_is_string (data, size))
1494 : 7138 : break;
1495 : :
1496 : 301 : data = "";
1497 : 301 : size = 1;
1498 : 301 : break;
1499 : :
1500 : 10406 : case G_VARIANT_CLASS_OBJECT_PATH:
1501 [ + + ]: 10406 : if (g_variant_serialiser_is_object_path (data, size))
1502 : 9935 : break;
1503 : :
1504 : 471 : data = "/";
1505 : 471 : size = 2;
1506 : 471 : break;
1507 : :
1508 : 1816 : case G_VARIANT_CLASS_SIGNATURE:
1509 [ + + ]: 1816 : if (g_variant_serialiser_is_signature (data, size))
1510 : 1593 : break;
1511 : :
1512 : 223 : data = "";
1513 : 223 : size = 1;
1514 : 223 : break;
1515 : :
1516 : 0 : default:
1517 : : g_assert_not_reached ();
1518 : : }
1519 : : }
1520 : :
1521 [ + + ]: 2018182 : if (length)
1522 : 101276 : *length = size - 1;
1523 : :
1524 : 2018182 : return data;
1525 : : }
1526 : :
1527 : : /**
1528 : : * g_variant_dup_string:
1529 : : * @value: a string #GVariant instance
1530 : : * @length: (out): a pointer to a #gsize, to store the length
1531 : : *
1532 : : * Similar to g_variant_get_string() except that instead of returning
1533 : : * a constant string, the string is duplicated.
1534 : : *
1535 : : * The string will always be UTF-8 encoded.
1536 : : *
1537 : : * The return value must be freed using g_free().
1538 : : *
1539 : : * Returns: (transfer full): a newly allocated string, UTF-8 encoded
1540 : : *
1541 : : * Since: 2.24
1542 : : **/
1543 : : gchar *
1544 : 2211 : g_variant_dup_string (GVariant *value,
1545 : : gsize *length)
1546 : : {
1547 : 4422 : return g_strdup (g_variant_get_string (value, length));
1548 : : }
1549 : :
1550 : : /**
1551 : : * g_variant_new_strv:
1552 : : * @strv: (array length=length) (element-type utf8): an array of strings
1553 : : * @length: the length of @strv, or -1
1554 : : *
1555 : : * Constructs an array of strings #GVariant from the given array of
1556 : : * strings.
1557 : : *
1558 : : * If @length is -1 then @strv is %NULL-terminated.
1559 : : *
1560 : : * Returns: (transfer none): a new floating #GVariant instance
1561 : : *
1562 : : * Since: 2.24
1563 : : **/
1564 : : GVariant *
1565 : 90 : g_variant_new_strv (const gchar * const *strv,
1566 : : gssize length)
1567 : : {
1568 : : GVariant **strings;
1569 : : gsize i, length_unsigned;
1570 : :
1571 : 90 : g_return_val_if_fail (length == 0 || strv != NULL, NULL);
1572 : :
1573 [ + + ]: 90 : if (length < 0)
1574 : 86 : length = g_strv_length ((gchar **) strv);
1575 : 90 : length_unsigned = length;
1576 : :
1577 : 90 : strings = g_new (GVariant *, length_unsigned);
1578 [ + + ]: 215 : for (i = 0; i < length_unsigned; i++)
1579 : 125 : strings[i] = g_variant_ref_sink (g_variant_new_string (strv[i]));
1580 : :
1581 : 90 : return g_variant_new_from_children (G_VARIANT_TYPE_STRING_ARRAY,
1582 : : strings, length_unsigned, TRUE);
1583 : : }
1584 : :
1585 : : /**
1586 : : * g_variant_get_strv:
1587 : : * @value: an array of strings #GVariant
1588 : : * @length: (out) (optional): the length of the result, or %NULL
1589 : : *
1590 : : * Gets the contents of an array of strings #GVariant. This call
1591 : : * makes a shallow copy; the return result should be released with
1592 : : * g_free(), but the individual strings must not be modified.
1593 : : *
1594 : : * If @length is non-%NULL then the number of elements in the result
1595 : : * is stored there. In any case, the resulting array will be
1596 : : * %NULL-terminated.
1597 : : *
1598 : : * For an empty array, @length will be set to 0 and a pointer to a
1599 : : * %NULL pointer will be returned.
1600 : : *
1601 : : * Returns: (array length=length zero-terminated=1) (transfer container): an array of constant strings
1602 : : *
1603 : : * Since: 2.24
1604 : : **/
1605 : : const gchar **
1606 : 111 : g_variant_get_strv (GVariant *value,
1607 : : gsize *length)
1608 : : {
1609 : : const gchar **strv;
1610 : : gsize n;
1611 : : gsize i;
1612 : :
1613 [ - + ]: 111 : TYPE_CHECK (value, G_VARIANT_TYPE_STRING_ARRAY, NULL);
1614 : :
1615 : 111 : g_variant_get_data (value);
1616 : 111 : n = g_variant_n_children (value);
1617 : 111 : strv = g_new (const gchar *, n + 1);
1618 : :
1619 [ + + ]: 211 : for (i = 0; i < n; i++)
1620 : : {
1621 : : GVariant *string;
1622 : :
1623 : 100 : string = g_variant_get_child_value (value, i);
1624 : 100 : strv[i] = g_variant_get_string (string, NULL);
1625 : 100 : g_variant_unref (string);
1626 : : }
1627 : 111 : strv[i] = NULL;
1628 : :
1629 [ + + ]: 111 : if (length)
1630 : 9 : *length = n;
1631 : :
1632 : 111 : return strv;
1633 : : }
1634 : :
1635 : : /**
1636 : : * g_variant_dup_strv:
1637 : : * @value: an array of strings #GVariant
1638 : : * @length: (out) (optional): the length of the result, or %NULL
1639 : : *
1640 : : * Gets the contents of an array of strings #GVariant. This call
1641 : : * makes a deep copy; the return result should be released with
1642 : : * g_strfreev().
1643 : : *
1644 : : * If @length is non-%NULL then the number of elements in the result
1645 : : * is stored there. In any case, the resulting array will be
1646 : : * %NULL-terminated.
1647 : : *
1648 : : * For an empty array, @length will be set to 0 and a pointer to a
1649 : : * %NULL pointer will be returned.
1650 : : *
1651 : : * Returns: (array length=length zero-terminated=1) (transfer full): an array of strings
1652 : : *
1653 : : * Since: 2.24
1654 : : **/
1655 : : gchar **
1656 : 35 : g_variant_dup_strv (GVariant *value,
1657 : : gsize *length)
1658 : : {
1659 : : gchar **strv;
1660 : : gsize n;
1661 : : gsize i;
1662 : :
1663 [ - + ]: 35 : TYPE_CHECK (value, G_VARIANT_TYPE_STRING_ARRAY, NULL);
1664 : :
1665 : 35 : n = g_variant_n_children (value);
1666 : 35 : strv = g_new (gchar *, n + 1);
1667 : :
1668 [ + + ]: 99 : for (i = 0; i < n; i++)
1669 : : {
1670 : : GVariant *string;
1671 : :
1672 : 64 : string = g_variant_get_child_value (value, i);
1673 : 64 : strv[i] = g_variant_dup_string (string, NULL);
1674 : 64 : g_variant_unref (string);
1675 : : }
1676 : 35 : strv[i] = NULL;
1677 : :
1678 [ - + ]: 35 : if (length)
1679 : 0 : *length = n;
1680 : :
1681 : 35 : return strv;
1682 : : }
1683 : :
1684 : : /**
1685 : : * g_variant_new_objv:
1686 : : * @strv: (array length=length) (element-type utf8): an array of strings
1687 : : * @length: the length of @strv, or -1
1688 : : *
1689 : : * Constructs an array of object paths #GVariant from the given array of
1690 : : * strings.
1691 : : *
1692 : : * Each string must be a valid #GVariant object path; see
1693 : : * g_variant_is_object_path().
1694 : : *
1695 : : * If @length is -1 then @strv is %NULL-terminated.
1696 : : *
1697 : : * Returns: (transfer none): a new floating #GVariant instance
1698 : : *
1699 : : * Since: 2.30
1700 : : **/
1701 : : GVariant *
1702 : 56 : g_variant_new_objv (const gchar * const *strv,
1703 : : gssize length)
1704 : : {
1705 : : GVariant **strings;
1706 : : gsize i, length_unsigned;
1707 : :
1708 : 56 : g_return_val_if_fail (length == 0 || strv != NULL, NULL);
1709 : :
1710 [ + - ]: 56 : if (length < 0)
1711 : 56 : length = g_strv_length ((gchar **) strv);
1712 : 56 : length_unsigned = length;
1713 : :
1714 : 56 : strings = g_new (GVariant *, length_unsigned);
1715 [ + + ]: 84 : for (i = 0; i < length_unsigned; i++)
1716 : 28 : strings[i] = g_variant_ref_sink (g_variant_new_object_path (strv[i]));
1717 : :
1718 : 56 : return g_variant_new_from_children (G_VARIANT_TYPE_OBJECT_PATH_ARRAY,
1719 : : strings, length_unsigned, TRUE);
1720 : : }
1721 : :
1722 : : /**
1723 : : * g_variant_get_objv:
1724 : : * @value: an array of object paths #GVariant
1725 : : * @length: (out) (optional): the length of the result, or %NULL
1726 : : *
1727 : : * Gets the contents of an array of object paths #GVariant. This call
1728 : : * makes a shallow copy; the return result should be released with
1729 : : * g_free(), but the individual strings must not be modified.
1730 : : *
1731 : : * If @length is non-%NULL then the number of elements in the result
1732 : : * is stored there. In any case, the resulting array will be
1733 : : * %NULL-terminated.
1734 : : *
1735 : : * For an empty array, @length will be set to 0 and a pointer to a
1736 : : * %NULL pointer will be returned.
1737 : : *
1738 : : * Returns: (array length=length zero-terminated=1) (transfer container): an array of constant strings
1739 : : *
1740 : : * Since: 2.30
1741 : : **/
1742 : : const gchar **
1743 : 1 : g_variant_get_objv (GVariant *value,
1744 : : gsize *length)
1745 : : {
1746 : : const gchar **strv;
1747 : : gsize n;
1748 : : gsize i;
1749 : :
1750 [ - + ]: 1 : TYPE_CHECK (value, G_VARIANT_TYPE_OBJECT_PATH_ARRAY, NULL);
1751 : :
1752 : 1 : g_variant_get_data (value);
1753 : 1 : n = g_variant_n_children (value);
1754 : 1 : strv = g_new (const gchar *, n + 1);
1755 : :
1756 [ + + ]: 3 : for (i = 0; i < n; i++)
1757 : : {
1758 : : GVariant *string;
1759 : :
1760 : 2 : string = g_variant_get_child_value (value, i);
1761 : 2 : strv[i] = g_variant_get_string (string, NULL);
1762 : 2 : g_variant_unref (string);
1763 : : }
1764 : 1 : strv[i] = NULL;
1765 : :
1766 [ - + ]: 1 : if (length)
1767 : 0 : *length = n;
1768 : :
1769 : 1 : return strv;
1770 : : }
1771 : :
1772 : : /**
1773 : : * g_variant_dup_objv:
1774 : : * @value: an array of object paths #GVariant
1775 : : * @length: (out) (optional): the length of the result, or %NULL
1776 : : *
1777 : : * Gets the contents of an array of object paths #GVariant. This call
1778 : : * makes a deep copy; the return result should be released with
1779 : : * g_strfreev().
1780 : : *
1781 : : * If @length is non-%NULL then the number of elements in the result
1782 : : * is stored there. In any case, the resulting array will be
1783 : : * %NULL-terminated.
1784 : : *
1785 : : * For an empty array, @length will be set to 0 and a pointer to a
1786 : : * %NULL pointer will be returned.
1787 : : *
1788 : : * Returns: (array length=length zero-terminated=1) (transfer full): an array of strings
1789 : : *
1790 : : * Since: 2.30
1791 : : **/
1792 : : gchar **
1793 : 16 : g_variant_dup_objv (GVariant *value,
1794 : : gsize *length)
1795 : : {
1796 : : gchar **strv;
1797 : : gsize n;
1798 : : gsize i;
1799 : :
1800 [ - + ]: 16 : TYPE_CHECK (value, G_VARIANT_TYPE_OBJECT_PATH_ARRAY, NULL);
1801 : :
1802 : 16 : n = g_variant_n_children (value);
1803 : 16 : strv = g_new (gchar *, n + 1);
1804 : :
1805 [ + + ]: 36 : for (i = 0; i < n; i++)
1806 : : {
1807 : : GVariant *string;
1808 : :
1809 : 20 : string = g_variant_get_child_value (value, i);
1810 : 20 : strv[i] = g_variant_dup_string (string, NULL);
1811 : 20 : g_variant_unref (string);
1812 : : }
1813 : 16 : strv[i] = NULL;
1814 : :
1815 [ - + ]: 16 : if (length)
1816 : 0 : *length = n;
1817 : :
1818 : 16 : return strv;
1819 : : }
1820 : :
1821 : :
1822 : : /**
1823 : : * g_variant_new_bytestring:
1824 : : * @string: (array zero-terminated=1) (element-type guint8): a normal
1825 : : * nul-terminated string in no particular encoding
1826 : : *
1827 : : * Creates an array-of-bytes #GVariant with the contents of @string.
1828 : : * This function is just like g_variant_new_string() except that the
1829 : : * string need not be valid UTF-8.
1830 : : *
1831 : : * The nul terminator character at the end of the string is stored in
1832 : : * the array.
1833 : : *
1834 : : * Returns: (transfer none): a floating reference to a new bytestring #GVariant instance
1835 : : *
1836 : : * Since: 2.26
1837 : : **/
1838 : : GVariant *
1839 : 177 : g_variant_new_bytestring (const gchar *string)
1840 : : {
1841 : 177 : g_return_val_if_fail (string != NULL, NULL);
1842 : :
1843 : 177 : return g_variant_new_from_trusted (G_VARIANT_TYPE_BYTESTRING,
1844 : 177 : string, strlen (string) + 1);
1845 : : }
1846 : :
1847 : : /**
1848 : : * g_variant_get_bytestring:
1849 : : * @value: an array-of-bytes #GVariant instance
1850 : : *
1851 : : * Returns the string value of a #GVariant instance with an
1852 : : * array-of-bytes type. The string has no particular encoding.
1853 : : *
1854 : : * If the array does not end with a nul terminator character, the empty
1855 : : * string is returned. For this reason, you can always trust that a
1856 : : * non-%NULL nul-terminated string will be returned by this function.
1857 : : *
1858 : : * If the array contains a nul terminator character somewhere other than
1859 : : * the last byte then the returned string is the string, up to the first
1860 : : * such nul character.
1861 : : *
1862 : : * g_variant_get_fixed_array() should be used instead if the array contains
1863 : : * arbitrary data that could not be nul-terminated or could contain nul bytes.
1864 : : *
1865 : : * It is an error to call this function with a @value that is not an
1866 : : * array of bytes.
1867 : : *
1868 : : * The return value remains valid as long as @value exists.
1869 : : *
1870 : : * Returns: (transfer none) (array zero-terminated=1) (element-type guint8):
1871 : : * the constant string
1872 : : *
1873 : : * Since: 2.26
1874 : : **/
1875 : : const gchar *
1876 : 111 : g_variant_get_bytestring (GVariant *value)
1877 : : {
1878 : : const gchar *string;
1879 : : gsize size;
1880 : :
1881 [ - + ]: 111 : TYPE_CHECK (value, G_VARIANT_TYPE_BYTESTRING, NULL);
1882 : :
1883 : : /* Won't be NULL since this is an array type */
1884 : 111 : string = g_variant_get_data (value);
1885 : 111 : size = g_variant_get_size (value);
1886 : :
1887 [ + + + + ]: 111 : if (size && string[size - 1] == '\0')
1888 : 109 : return string;
1889 : : else
1890 : 2 : return "";
1891 : : }
1892 : :
1893 : : /**
1894 : : * g_variant_dup_bytestring:
1895 : : * @value: an array-of-bytes #GVariant instance
1896 : : * @length: (out) (optional) (default NULL): a pointer to a #gsize, to store
1897 : : * the length (not including the nul terminator)
1898 : : *
1899 : : * Similar to g_variant_get_bytestring() except that instead of
1900 : : * returning a constant string, the string is duplicated.
1901 : : *
1902 : : * The return value must be freed using g_free().
1903 : : *
1904 : : * Returns: (transfer full) (array zero-terminated=1 length=length) (element-type guint8):
1905 : : * a newly allocated string
1906 : : *
1907 : : * Since: 2.26
1908 : : **/
1909 : : gchar *
1910 : 60 : g_variant_dup_bytestring (GVariant *value,
1911 : : gsize *length)
1912 : : {
1913 : 60 : const gchar *original = g_variant_get_bytestring (value);
1914 : : gsize size;
1915 : :
1916 : : /* don't crash in case get_bytestring() had an assert failure */
1917 [ - + ]: 60 : if (original == NULL)
1918 : 0 : return NULL;
1919 : :
1920 : 60 : size = strlen (original);
1921 : :
1922 [ - + ]: 60 : if (length)
1923 : 0 : *length = size;
1924 : :
1925 : 60 : return g_memdup2 (original, size + 1);
1926 : : }
1927 : :
1928 : : /**
1929 : : * g_variant_new_bytestring_array:
1930 : : * @strv: (array length=length): an array of strings
1931 : : * @length: the length of @strv, or -1
1932 : : *
1933 : : * Constructs an array of bytestring #GVariant from the given array of
1934 : : * strings.
1935 : : *
1936 : : * If @length is -1 then @strv is %NULL-terminated.
1937 : : *
1938 : : * Returns: (transfer none): a new floating #GVariant instance
1939 : : *
1940 : : * Since: 2.26
1941 : : **/
1942 : : GVariant *
1943 : 44 : g_variant_new_bytestring_array (const gchar * const *strv,
1944 : : gssize length)
1945 : : {
1946 : : GVariant **strings;
1947 : : gsize i, length_unsigned;
1948 : :
1949 : 44 : g_return_val_if_fail (length == 0 || strv != NULL, NULL);
1950 : :
1951 [ + - ]: 44 : if (length < 0)
1952 : 44 : length = g_strv_length ((gchar **) strv);
1953 : 44 : length_unsigned = length;
1954 : :
1955 : 44 : strings = g_new (GVariant *, length_unsigned);
1956 [ + + ]: 92 : for (i = 0; i < length_unsigned; i++)
1957 : 48 : strings[i] = g_variant_ref_sink (g_variant_new_bytestring (strv[i]));
1958 : :
1959 : 44 : return g_variant_new_from_children (G_VARIANT_TYPE_BYTESTRING_ARRAY,
1960 : : strings, length_unsigned, TRUE);
1961 : : }
1962 : :
1963 : : /**
1964 : : * g_variant_get_bytestring_array:
1965 : : * @value: an array of array of bytes #GVariant ('aay')
1966 : : * @length: (out) (optional): the length of the result, or %NULL
1967 : : *
1968 : : * Gets the contents of an array of array of bytes #GVariant. This call
1969 : : * makes a shallow copy; the return result should be released with
1970 : : * g_free(), but the individual strings must not be modified.
1971 : : *
1972 : : * If @length is non-%NULL then the number of elements in the result is
1973 : : * stored there. In any case, the resulting array will be
1974 : : * %NULL-terminated.
1975 : : *
1976 : : * For an empty array, @length will be set to 0 and a pointer to a
1977 : : * %NULL pointer will be returned.
1978 : : *
1979 : : * Returns: (array length=length) (transfer container): an array of constant strings
1980 : : *
1981 : : * Since: 2.26
1982 : : **/
1983 : : const gchar **
1984 : 6 : g_variant_get_bytestring_array (GVariant *value,
1985 : : gsize *length)
1986 : : {
1987 : : const gchar **strv;
1988 : : gsize n;
1989 : : gsize i;
1990 : :
1991 [ - + ]: 6 : TYPE_CHECK (value, G_VARIANT_TYPE_BYTESTRING_ARRAY, NULL);
1992 : :
1993 : 6 : g_variant_get_data (value);
1994 : 6 : n = g_variant_n_children (value);
1995 : 6 : strv = g_new (const gchar *, n + 1);
1996 : :
1997 [ + + ]: 24 : for (i = 0; i < n; i++)
1998 : : {
1999 : : GVariant *string;
2000 : :
2001 : 18 : string = g_variant_get_child_value (value, i);
2002 : 18 : strv[i] = g_variant_get_bytestring (string);
2003 : 18 : g_variant_unref (string);
2004 : : }
2005 : 6 : strv[i] = NULL;
2006 : :
2007 [ - + ]: 6 : if (length)
2008 : 0 : *length = n;
2009 : :
2010 : 6 : return strv;
2011 : : }
2012 : :
2013 : : /**
2014 : : * g_variant_dup_bytestring_array:
2015 : : * @value: an array of array of bytes #GVariant ('aay')
2016 : : * @length: (out) (optional): the length of the result, or %NULL
2017 : : *
2018 : : * Gets the contents of an array of array of bytes #GVariant. This call
2019 : : * makes a deep copy; the return result should be released with
2020 : : * g_strfreev().
2021 : : *
2022 : : * If @length is non-%NULL then the number of elements in the result is
2023 : : * stored there. In any case, the resulting array will be
2024 : : * %NULL-terminated.
2025 : : *
2026 : : * For an empty array, @length will be set to 0 and a pointer to a
2027 : : * %NULL pointer will be returned.
2028 : : *
2029 : : * Returns: (array length=length) (transfer full): an array of strings
2030 : : *
2031 : : * Since: 2.26
2032 : : **/
2033 : : gchar **
2034 : 18 : g_variant_dup_bytestring_array (GVariant *value,
2035 : : gsize *length)
2036 : : {
2037 : : gchar **strv;
2038 : : gsize n;
2039 : : gsize i;
2040 : :
2041 [ - + ]: 18 : TYPE_CHECK (value, G_VARIANT_TYPE_BYTESTRING_ARRAY, NULL);
2042 : :
2043 : 18 : g_variant_get_data (value);
2044 : 18 : n = g_variant_n_children (value);
2045 : 18 : strv = g_new (gchar *, n + 1);
2046 : :
2047 [ + + ]: 64 : for (i = 0; i < n; i++)
2048 : : {
2049 : : GVariant *string;
2050 : :
2051 : 46 : string = g_variant_get_child_value (value, i);
2052 : 46 : strv[i] = g_variant_dup_bytestring (string, NULL);
2053 : 46 : g_variant_unref (string);
2054 : : }
2055 : 18 : strv[i] = NULL;
2056 : :
2057 [ + + ]: 18 : if (length)
2058 : 1 : *length = n;
2059 : :
2060 : 18 : return strv;
2061 : : }
2062 : :
2063 : : /* Type checking and querying {{{1 */
2064 : : /**
2065 : : * g_variant_get_type:
2066 : : * @value: a #GVariant
2067 : : *
2068 : : * Determines the type of @value.
2069 : : *
2070 : : * The return value is valid for the lifetime of @value and must not
2071 : : * be freed.
2072 : : *
2073 : : * Returns: a #GVariantType
2074 : : *
2075 : : * Since: 2.24
2076 : : **/
2077 : : const GVariantType *
2078 : 10320852 : g_variant_get_type (GVariant *value)
2079 : : {
2080 : : GVariantTypeInfo *type_info;
2081 : :
2082 : 10320852 : g_return_val_if_fail (value != NULL, NULL);
2083 : :
2084 : 10320852 : type_info = g_variant_get_type_info (value);
2085 : :
2086 : 10320852 : return (GVariantType *) g_variant_type_info_get_type_string (type_info);
2087 : : }
2088 : :
2089 : : /**
2090 : : * g_variant_get_type_string:
2091 : : * @value: a #GVariant
2092 : : *
2093 : : * Returns the type string of @value. Unlike the result of calling
2094 : : * g_variant_type_peek_string(), this string is nul-terminated. This
2095 : : * string belongs to #GVariant and must not be freed.
2096 : : *
2097 : : * Returns: the type string for the type of @value
2098 : : *
2099 : : * Since: 2.24
2100 : : **/
2101 : : const gchar *
2102 : 1818114 : g_variant_get_type_string (GVariant *value)
2103 : : {
2104 : : GVariantTypeInfo *type_info;
2105 : :
2106 : 1818114 : g_return_val_if_fail (value != NULL, NULL);
2107 : :
2108 : 1818114 : type_info = g_variant_get_type_info (value);
2109 : :
2110 : 1818114 : return g_variant_type_info_get_type_string (type_info);
2111 : : }
2112 : :
2113 : : /**
2114 : : * g_variant_is_of_type:
2115 : : * @value: a #GVariant instance
2116 : : * @type: a #GVariantType
2117 : : *
2118 : : * Checks if a value has a type matching the provided type.
2119 : : *
2120 : : * Returns: %TRUE if the type of @value matches @type
2121 : : *
2122 : : * Since: 2.24
2123 : : **/
2124 : : gboolean
2125 : 8471755 : g_variant_is_of_type (GVariant *value,
2126 : : const GVariantType *type)
2127 : : {
2128 : 8471755 : return g_variant_type_is_subtype_of (g_variant_get_type (value), type);
2129 : : }
2130 : :
2131 : : /**
2132 : : * g_variant_is_container:
2133 : : * @value: a #GVariant instance
2134 : : *
2135 : : * Checks if @value is a container.
2136 : : *
2137 : : * Returns: %TRUE if @value is a container
2138 : : *
2139 : : * Since: 2.24
2140 : : */
2141 : : gboolean
2142 : 453720 : g_variant_is_container (GVariant *value)
2143 : : {
2144 : 453720 : return g_variant_type_is_container (g_variant_get_type (value));
2145 : : }
2146 : :
2147 : :
2148 : : /**
2149 : : * g_variant_classify:
2150 : : * @value: a #GVariant
2151 : : *
2152 : : * Classifies @value according to its top-level type.
2153 : : *
2154 : : * Returns: the #GVariantClass of @value
2155 : : *
2156 : : * Since: 2.24
2157 : : **/
2158 : : /**
2159 : : * GVariantClass:
2160 : : * @G_VARIANT_CLASS_BOOLEAN: The #GVariant is a boolean.
2161 : : * @G_VARIANT_CLASS_BYTE: The #GVariant is a byte.
2162 : : * @G_VARIANT_CLASS_INT16: The #GVariant is a signed 16 bit integer.
2163 : : * @G_VARIANT_CLASS_UINT16: The #GVariant is an unsigned 16 bit integer.
2164 : : * @G_VARIANT_CLASS_INT32: The #GVariant is a signed 32 bit integer.
2165 : : * @G_VARIANT_CLASS_UINT32: The #GVariant is an unsigned 32 bit integer.
2166 : : * @G_VARIANT_CLASS_INT64: The #GVariant is a signed 64 bit integer.
2167 : : * @G_VARIANT_CLASS_UINT64: The #GVariant is an unsigned 64 bit integer.
2168 : : * @G_VARIANT_CLASS_HANDLE: The #GVariant is a file handle index.
2169 : : * @G_VARIANT_CLASS_DOUBLE: The #GVariant is a double precision floating
2170 : : * point value.
2171 : : * @G_VARIANT_CLASS_STRING: The #GVariant is a normal string.
2172 : : * @G_VARIANT_CLASS_OBJECT_PATH: The #GVariant is a D-Bus object path
2173 : : * string.
2174 : : * @G_VARIANT_CLASS_SIGNATURE: The #GVariant is a D-Bus signature string.
2175 : : * @G_VARIANT_CLASS_VARIANT: The #GVariant is a variant.
2176 : : * @G_VARIANT_CLASS_MAYBE: The #GVariant is a maybe-typed value.
2177 : : * @G_VARIANT_CLASS_ARRAY: The #GVariant is an array.
2178 : : * @G_VARIANT_CLASS_TUPLE: The #GVariant is a tuple.
2179 : : * @G_VARIANT_CLASS_DICT_ENTRY: The #GVariant is a dictionary entry.
2180 : : *
2181 : : * The range of possible top-level types of #GVariant instances.
2182 : : *
2183 : : * Since: 2.24
2184 : : **/
2185 : : GVariantClass
2186 : 31317 : g_variant_classify (GVariant *value)
2187 : : {
2188 : 31317 : g_return_val_if_fail (value != NULL, 0);
2189 : :
2190 : 31317 : return *g_variant_get_type_string (value);
2191 : : }
2192 : :
2193 : : /* Pretty printer {{{1 */
2194 : : /* This function is not introspectable because if @string is NULL,
2195 : : @returns is (transfer full), otherwise it is (transfer none), which
2196 : : is not supported by GObjectIntrospection */
2197 : : /**
2198 : : * g_variant_print_string: (skip)
2199 : : * @value: a #GVariant
2200 : : * @string: (nullable) (default NULL): a #GString, or %NULL
2201 : : * @type_annotate: %TRUE if type information should be included in
2202 : : * the output
2203 : : *
2204 : : * Behaves as g_variant_print(), but operates on a #GString.
2205 : : *
2206 : : * If @string is non-%NULL then it is appended to and returned. Else,
2207 : : * a new empty #GString is allocated and it is returned.
2208 : : *
2209 : : * Returns: a #GString containing the string
2210 : : *
2211 : : * Since: 2.24
2212 : : **/
2213 : : GString *
2214 : 1697976 : g_variant_print_string (GVariant *value,
2215 : : GString *string,
2216 : : gboolean type_annotate)
2217 : : {
2218 : 1697976 : const gchar *value_type_string = g_variant_get_type_string (value);
2219 : :
2220 [ + + ]: 1697976 : if G_UNLIKELY (string == NULL)
2221 : 1604 : string = g_string_new (NULL);
2222 : :
2223 [ + + + + : 1697976 : switch (value_type_string[0])
+ + + + +
+ + + + +
+ + + +
- ]
2224 : : {
2225 : 32611 : case G_VARIANT_CLASS_MAYBE:
2226 [ + + ]: 32611 : if (type_annotate)
2227 : 742 : g_string_append_printf (string, "@%s ", value_type_string);
2228 : :
2229 [ + + ]: 32611 : if (g_variant_n_children (value))
2230 : : {
2231 : : const GVariantType *base_type;
2232 : : guint i, depth;
2233 : 4150 : GVariant *element = NULL;
2234 : :
2235 : : /* Nested maybes:
2236 : : *
2237 : : * Consider the case of the type "mmi". In this case we could
2238 : : * write "just just 4", but "4" alone is totally unambiguous,
2239 : : * so we try to drop "just" where possible.
2240 : : *
2241 : : * We have to be careful not to always drop "just", though,
2242 : : * since "nothing" needs to be distinguishable from "just
2243 : : * nothing". The case where we need to ensure we keep the
2244 : : * "just" is actually exactly the case where we have a nested
2245 : : * Nothing.
2246 : : *
2247 : : * Search for the nested Nothing, to save a lot of recursion if there
2248 : : * are multiple levels of maybes.
2249 : : */
2250 : 4150 : for (depth = 0, base_type = g_variant_get_type (value);
2251 [ + + ]: 8349 : g_variant_type_is_maybe (base_type);
2252 : 4199 : depth++, base_type = g_variant_type_element (base_type));
2253 : :
2254 : 4150 : element = g_variant_ref (value);
2255 [ + + + - ]: 8349 : for (i = 0; i < depth && element != NULL; i++)
2256 : : {
2257 [ + + ]: 4199 : GVariant *new_element = g_variant_n_children (element) ? g_variant_get_child_value (element, 0) : NULL;
2258 : 4199 : g_variant_unref (element);
2259 : 4199 : element = g_steal_pointer (&new_element);
2260 : : }
2261 : :
2262 [ + + ]: 4150 : if (element == NULL)
2263 : : {
2264 : : /* One of the maybes was Nothing, so print out the right number of
2265 : : * justs. */
2266 [ + + ]: 40 : for (; i > 1; i--)
2267 [ + - ]: 40 : g_string_append (string, "just ");
2268 [ + - ]: 40 : g_string_append (string, "nothing");
2269 : : }
2270 : : else
2271 : : {
2272 : : /* There are no Nothings, so print out the child with no prefixes. */
2273 : 4130 : g_variant_print_string (element, string, FALSE);
2274 : : }
2275 : :
2276 : 4150 : g_clear_pointer (&element, g_variant_unref);
2277 : : }
2278 : : else
2279 [ + - ]: 56922 : g_string_append (string, "nothing");
2280 : :
2281 : 32611 : break;
2282 : :
2283 : 36833 : case G_VARIANT_CLASS_ARRAY:
2284 : : /* it's an array so the first character of the type string is 'a'
2285 : : *
2286 : : * if the first two characters are 'ay' then it's a bytestring.
2287 : : * under certain conditions we print those as strings.
2288 : : */
2289 [ + + ]: 36833 : if (value_type_string[1] == 'y')
2290 : : {
2291 : : const gchar *str;
2292 : : gsize size;
2293 : : gsize i;
2294 : :
2295 : : /* first determine if it is a byte string.
2296 : : * that's when there's a single nul character: at the end.
2297 : : */
2298 : 1202 : str = g_variant_get_data (value);
2299 : 1202 : size = g_variant_get_size (value);
2300 : :
2301 [ + + ]: 39206 : for (i = 0; i < size; i++)
2302 [ + + ]: 38136 : if (str[i] == '\0')
2303 : 132 : break;
2304 : :
2305 : : /* first nul byte is the last byte -> it's a byte string. */
2306 [ + + ]: 1202 : if (i == size - 1)
2307 : : {
2308 : 17 : gchar *escaped = g_strescape (str, NULL);
2309 : :
2310 : : /* use double quotes only if a ' is in the string */
2311 [ - + ]: 17 : if (strchr (str, '\''))
2312 : 0 : g_string_append_printf (string, "b\"%s\"", escaped);
2313 : : else
2314 : 17 : g_string_append_printf (string, "b'%s'", escaped);
2315 : :
2316 : 17 : g_free (escaped);
2317 : 17 : break;
2318 : : }
2319 : :
2320 : : else
2321 : : {
2322 : : /* fall through and handle normally... */
2323 : : }
2324 : : }
2325 : :
2326 : : /*
2327 : : * if the first two characters are 'a{' then it's an array of
2328 : : * dictionary entries (ie: a dictionary) so we print that
2329 : : * differently.
2330 : : */
2331 [ + + ]: 36816 : if (value_type_string[1] == '{')
2332 : : /* dictionary */
2333 : : {
2334 : 505 : const gchar *comma = "";
2335 : : gsize n, i;
2336 : :
2337 [ + + ]: 505 : if ((n = g_variant_n_children (value)) == 0)
2338 : : {
2339 [ + + ]: 17 : if (type_annotate)
2340 : 4 : g_string_append_printf (string, "@%s ", value_type_string);
2341 [ + - ]: 17 : g_string_append (string, "{}");
2342 : 17 : break;
2343 : : }
2344 : :
2345 : : g_string_append_c (string, '{');
2346 [ + + ]: 27453 : for (i = 0; i < n; i++)
2347 : : {
2348 : : GVariant *entry, *key, *val;
2349 : :
2350 : : g_string_append (string, comma);
2351 : 26965 : comma = ", ";
2352 : :
2353 : 26965 : entry = g_variant_get_child_value (value, i);
2354 : 26965 : key = g_variant_get_child_value (entry, 0);
2355 : 26965 : val = g_variant_get_child_value (entry, 1);
2356 : 26965 : g_variant_unref (entry);
2357 : :
2358 : 26965 : g_variant_print_string (key, string, type_annotate);
2359 : 26965 : g_variant_unref (key);
2360 [ + - ]: 26965 : g_string_append (string, ": ");
2361 : 26965 : g_variant_print_string (val, string, type_annotate);
2362 : 26965 : g_variant_unref (val);
2363 : 26965 : type_annotate = FALSE;
2364 : : }
2365 : : g_string_append_c (string, '}');
2366 : : }
2367 : : else
2368 : : /* normal (non-dictionary) array */
2369 : : {
2370 : 36311 : const gchar *comma = "";
2371 : : gsize n, i;
2372 : :
2373 [ + + ]: 36311 : if ((n = g_variant_n_children (value)) == 0)
2374 : : {
2375 [ + + ]: 18769 : if (type_annotate)
2376 : 91 : g_string_append_printf (string, "@%s ", value_type_string);
2377 [ + - ]: 18769 : g_string_append (string, "[]");
2378 : 18769 : break;
2379 : : }
2380 : :
2381 : : g_string_append_c (string, '[');
2382 [ + + ]: 1218230 : for (i = 0; i < n; i++)
2383 : : {
2384 : : GVariant *element;
2385 : :
2386 : : g_string_append (string, comma);
2387 : 1200688 : comma = ", ";
2388 : :
2389 : 1200688 : element = g_variant_get_child_value (value, i);
2390 : :
2391 : 1200688 : g_variant_print_string (element, string, type_annotate);
2392 : 1200688 : g_variant_unref (element);
2393 : 1200688 : type_annotate = FALSE;
2394 : : }
2395 : : g_string_append_c (string, ']');
2396 : : }
2397 : :
2398 : 18030 : break;
2399 : :
2400 : 135399 : case G_VARIANT_CLASS_TUPLE:
2401 : : {
2402 : : gsize n, i;
2403 : :
2404 : 135399 : n = g_variant_n_children (value);
2405 : :
2406 : : g_string_append_c (string, '(');
2407 [ + + ]: 442422 : for (i = 0; i < n; i++)
2408 : : {
2409 : : GVariant *element;
2410 : :
2411 : 307023 : element = g_variant_get_child_value (value, i);
2412 : 307023 : g_variant_print_string (element, string, type_annotate);
2413 [ + - ]: 307023 : g_string_append (string, ", ");
2414 : 307023 : g_variant_unref (element);
2415 : : }
2416 : :
2417 : : /* for >1 item: remove final ", "
2418 : : * for 1 item: remove final " ", but leave the ","
2419 : : * for 0 items: there is only "(", so remove nothing
2420 : : */
2421 : 135399 : g_string_truncate (string, string->len - (n > 0) - (n > 1));
2422 : : g_string_append_c (string, ')');
2423 : : }
2424 : 135399 : break;
2425 : :
2426 [ + - ]: 14655 : case G_VARIANT_CLASS_DICT_ENTRY:
2427 : : {
2428 : : GVariant *element;
2429 : :
2430 : : g_string_append_c (string, '{');
2431 : :
2432 : 14655 : element = g_variant_get_child_value (value, 0);
2433 : 14655 : g_variant_print_string (element, string, type_annotate);
2434 : 14655 : g_variant_unref (element);
2435 : :
2436 [ + - ]: 14655 : g_string_append (string, ", ");
2437 : :
2438 : 14655 : element = g_variant_get_child_value (value, 1);
2439 : 14655 : g_variant_print_string (element, string, type_annotate);
2440 : 14655 : g_variant_unref (element);
2441 : :
2442 : : g_string_append_c (string, '}');
2443 : : }
2444 : 14655 : break;
2445 : :
2446 : 101259 : case G_VARIANT_CLASS_VARIANT:
2447 : : {
2448 : 101259 : GVariant *child = g_variant_get_variant (value);
2449 : :
2450 : : /* Always annotate types in nested variants, because they are
2451 : : * (by nature) of variable type.
2452 : : */
2453 : : g_string_append_c (string, '<');
2454 : 101259 : g_variant_print_string (child, string, TRUE);
2455 : : g_string_append_c (string, '>');
2456 : :
2457 : 101259 : g_variant_unref (child);
2458 : : }
2459 : 101259 : break;
2460 : :
2461 : 91739 : case G_VARIANT_CLASS_BOOLEAN:
2462 [ + + ]: 91739 : if (g_variant_get_boolean (value))
2463 [ + - ]: 80312 : g_string_append (string, "true");
2464 : : else
2465 [ + - ]: 103166 : g_string_append (string, "false");
2466 : 91739 : break;
2467 : :
2468 : 29151 : case G_VARIANT_CLASS_STRING:
2469 : : {
2470 : 29151 : const gchar *str = g_variant_get_string (value, NULL);
2471 [ + + ]: 29151 : gunichar quote = strchr (str, '\'') ? '"' : '\'';
2472 : :
2473 [ + - ]: 29151 : g_string_append_c (string, quote);
2474 : :
2475 [ + + ]: 3005003 : while (*str)
2476 : : {
2477 : 2975852 : gunichar c = g_utf8_get_char (str);
2478 : :
2479 [ + + + + ]: 2975852 : if (c == quote || c == '\\')
2480 : : g_string_append_c (string, '\\');
2481 : :
2482 [ + + ]: 2975852 : if (g_unichar_isprint (c))
2483 : 2975777 : g_string_append_unichar (string, c);
2484 : :
2485 : : else
2486 : : {
2487 : : g_string_append_c (string, '\\');
2488 [ + + ]: 75 : if (c < 0x10000)
2489 : : switch (c)
2490 : : {
2491 [ + - ]: 3 : case '\a':
2492 : : g_string_append_c (string, 'a');
2493 : 3 : break;
2494 : :
2495 [ + - ]: 3 : case '\b':
2496 : : g_string_append_c (string, 'b');
2497 : 3 : break;
2498 : :
2499 [ + - ]: 3 : case '\f':
2500 : : g_string_append_c (string, 'f');
2501 : 3 : break;
2502 : :
2503 [ + - ]: 4 : case '\n':
2504 : : g_string_append_c (string, 'n');
2505 : 4 : break;
2506 : :
2507 [ + - ]: 3 : case '\r':
2508 : : g_string_append_c (string, 'r');
2509 : 3 : break;
2510 : :
2511 [ + - ]: 4 : case '\t':
2512 : : g_string_append_c (string, 't');
2513 : 4 : break;
2514 : :
2515 [ + - ]: 3 : case '\v':
2516 : : g_string_append_c (string, 'v');
2517 : 3 : break;
2518 : :
2519 : 51 : default:
2520 : 51 : g_string_append_printf (string, "u%04x", c);
2521 : 51 : break;
2522 : : }
2523 : : else
2524 : 1 : g_string_append_printf (string, "U%08x", c);
2525 : : }
2526 : :
2527 : 2975852 : str = g_utf8_next_char (str);
2528 : : }
2529 : :
2530 [ + - ]: 29151 : g_string_append_c (string, quote);
2531 : : }
2532 : 29151 : break;
2533 : :
2534 : 72671 : case G_VARIANT_CLASS_BYTE:
2535 [ + + ]: 72671 : if (type_annotate)
2536 [ + - ]: 2302 : g_string_append (string, "byte ");
2537 : 72671 : g_string_append_printf (string, "0x%02x",
2538 : 72671 : g_variant_get_byte (value));
2539 : 72671 : break;
2540 : :
2541 : 80813 : case G_VARIANT_CLASS_INT16:
2542 [ + + ]: 80813 : if (type_annotate)
2543 [ + - ]: 2458 : g_string_append (string, "int16 ");
2544 : 80813 : g_string_append_printf (string, "%"G_GINT16_FORMAT,
2545 : 80813 : g_variant_get_int16 (value));
2546 : 80813 : break;
2547 : :
2548 : 36474 : case G_VARIANT_CLASS_UINT16:
2549 [ + + ]: 36474 : if (type_annotate)
2550 [ + - ]: 2428 : g_string_append (string, "uint16 ");
2551 : 36474 : g_string_append_printf (string, "%"G_GUINT16_FORMAT,
2552 : 36474 : g_variant_get_uint16 (value));
2553 : 36474 : break;
2554 : :
2555 : 10907 : case G_VARIANT_CLASS_INT32:
2556 : : /* Never annotate this type because it is the default for numbers
2557 : : * (and this is a *pretty* printer)
2558 : : */
2559 : 10907 : g_string_append_printf (string, "%"G_GINT32_FORMAT,
2560 : : g_variant_get_int32 (value));
2561 : 10907 : break;
2562 : :
2563 : 52356 : case G_VARIANT_CLASS_HANDLE:
2564 [ + + ]: 52356 : if (type_annotate)
2565 [ + - ]: 2418 : g_string_append (string, "handle ");
2566 : 52356 : g_string_append_printf (string, "%"G_GINT32_FORMAT,
2567 : : g_variant_get_handle (value));
2568 : 52356 : break;
2569 : :
2570 : 33774 : case G_VARIANT_CLASS_UINT32:
2571 [ + + ]: 33774 : if (type_annotate)
2572 [ + - ]: 2530 : g_string_append (string, "uint32 ");
2573 : 33774 : g_string_append_printf (string, "%"G_GUINT32_FORMAT,
2574 : : g_variant_get_uint32 (value));
2575 : 33774 : break;
2576 : :
2577 : 39730 : case G_VARIANT_CLASS_INT64:
2578 [ + + ]: 39730 : if (type_annotate)
2579 [ + - ]: 2372 : g_string_append (string, "int64 ");
2580 : 39730 : g_string_append_printf (string, "%"G_GINT64_FORMAT,
2581 : : g_variant_get_int64 (value));
2582 : 39730 : break;
2583 : :
2584 : 107414 : case G_VARIANT_CLASS_UINT64:
2585 [ + + ]: 107414 : if (type_annotate)
2586 [ + - ]: 2254 : g_string_append (string, "uint64 ");
2587 : 107414 : g_string_append_printf (string, "%"G_GUINT64_FORMAT,
2588 : : g_variant_get_uint64 (value));
2589 : 107414 : break;
2590 : :
2591 : 25469 : case G_VARIANT_CLASS_DOUBLE:
2592 : : {
2593 : : gchar buffer[100];
2594 : : gint i;
2595 : :
2596 : 25469 : g_ascii_dtostr (buffer, sizeof buffer, g_variant_get_double (value));
2597 : :
2598 [ + + ]: 52731 : for (i = 0; buffer[i]; i++)
2599 [ + + + - ]: 42557 : if (buffer[i] == '.' || buffer[i] == 'e' ||
2600 [ + + + - ]: 27266 : buffer[i] == 'n' || buffer[i] == 'N')
2601 : : break;
2602 : :
2603 : : /* if there is no '.' or 'e' in the float then add one */
2604 [ + + ]: 25469 : if (buffer[i] == '\0')
2605 : : {
2606 : 10174 : buffer[i++] = '.';
2607 : 10174 : buffer[i++] = '0';
2608 : 10174 : buffer[i++] = '\0';
2609 : : }
2610 : :
2611 : : g_string_append (string, buffer);
2612 : : }
2613 : 25469 : break;
2614 : :
2615 : 772656 : case G_VARIANT_CLASS_OBJECT_PATH:
2616 [ + + ]: 772656 : if (type_annotate)
2617 [ + - ]: 2342 : g_string_append (string, "objectpath ");
2618 : 772656 : g_string_append_printf (string, "\'%s\'",
2619 : : g_variant_get_string (value, NULL));
2620 : 772656 : break;
2621 : :
2622 : 24065 : case G_VARIANT_CLASS_SIGNATURE:
2623 [ + + ]: 24065 : if (type_annotate)
2624 [ + - ]: 2424 : g_string_append (string, "signature ");
2625 : 24065 : g_string_append_printf (string, "\'%s\'",
2626 : : g_variant_get_string (value, NULL));
2627 : 24065 : break;
2628 : :
2629 : 0 : default:
2630 : : g_assert_not_reached ();
2631 : : }
2632 : :
2633 : 1697976 : return string;
2634 : : }
2635 : :
2636 : : /**
2637 : : * g_variant_print:
2638 : : * @value: a #GVariant
2639 : : * @type_annotate: %TRUE if type information should be included in
2640 : : * the output
2641 : : *
2642 : : * Pretty-prints @value in the format understood by g_variant_parse().
2643 : : *
2644 : : * The format is described [here](gvariant-text-format.html).
2645 : : *
2646 : : * If @type_annotate is %TRUE, then type information is included in
2647 : : * the output.
2648 : : *
2649 : : * Returns: (transfer full): a newly-allocated string holding the result.
2650 : : *
2651 : : * Since: 2.24
2652 : : */
2653 : : gchar *
2654 : 1604 : g_variant_print (GVariant *value,
2655 : : gboolean type_annotate)
2656 : : {
2657 : 1604 : return g_string_free (g_variant_print_string (value, NULL, type_annotate),
2658 : : FALSE);
2659 : : }
2660 : :
2661 : : /* Hash, Equal, Compare {{{1 */
2662 : : /**
2663 : : * g_variant_hash:
2664 : : * @value: (type GVariant): a basic #GVariant value as a #gconstpointer
2665 : : *
2666 : : * Generates a hash value for a #GVariant instance.
2667 : : *
2668 : : * The output of this function is guaranteed to be the same for a given
2669 : : * value only per-process. It may change between different processor
2670 : : * architectures or even different versions of GLib. Do not use this
2671 : : * function as a basis for building protocols or file formats.
2672 : : *
2673 : : * The type of @value is #gconstpointer only to allow use of this
2674 : : * function with #GHashTable. @value must be a #GVariant.
2675 : : *
2676 : : * Returns: a hash value corresponding to @value
2677 : : *
2678 : : * Since: 2.24
2679 : : **/
2680 : : guint
2681 : 8192 : g_variant_hash (gconstpointer value_)
2682 : : {
2683 : 8192 : GVariant *value = (GVariant *) value_;
2684 : :
2685 [ + + + + : 8192 : switch (g_variant_classify (value))
+ + - ]
2686 : : {
2687 : 2116 : case G_VARIANT_CLASS_STRING:
2688 : : case G_VARIANT_CLASS_OBJECT_PATH:
2689 : : case G_VARIANT_CLASS_SIGNATURE:
2690 : 2116 : return g_str_hash (g_variant_get_string (value, NULL));
2691 : :
2692 : 4 : case G_VARIANT_CLASS_BOOLEAN:
2693 : : /* this is a very odd thing to hash... */
2694 : 4 : return g_variant_get_boolean (value);
2695 : :
2696 : 370 : case G_VARIANT_CLASS_BYTE:
2697 : 370 : return g_variant_get_byte (value);
2698 : :
2699 : 1496 : case G_VARIANT_CLASS_INT16:
2700 : : case G_VARIANT_CLASS_UINT16:
2701 : : {
2702 : : const guint16 *ptr;
2703 : :
2704 : 1496 : ptr = g_variant_get_data (value);
2705 : :
2706 [ + - ]: 1496 : if (ptr)
2707 : 1496 : return *ptr;
2708 : : else
2709 : 0 : return 0;
2710 : : }
2711 : :
2712 : 2058 : case G_VARIANT_CLASS_INT32:
2713 : : case G_VARIANT_CLASS_UINT32:
2714 : : case G_VARIANT_CLASS_HANDLE:
2715 : : {
2716 : : const guint *ptr;
2717 : :
2718 : 2058 : ptr = g_variant_get_data (value);
2719 : :
2720 [ + - ]: 2058 : if (ptr)
2721 : 2058 : return *ptr;
2722 : : else
2723 : 0 : return 0;
2724 : : }
2725 : :
2726 : 2148 : case G_VARIANT_CLASS_INT64:
2727 : : case G_VARIANT_CLASS_UINT64:
2728 : : case G_VARIANT_CLASS_DOUBLE:
2729 : : /* need a separate case for these guys because otherwise
2730 : : * performance could be quite bad on big endian systems
2731 : : */
2732 : : {
2733 : : const guint *ptr;
2734 : :
2735 : 2148 : ptr = g_variant_get_data (value);
2736 : :
2737 [ + - ]: 2148 : if (ptr)
2738 : 2148 : return ptr[0] + ptr[1];
2739 : : else
2740 : 0 : return 0;
2741 : : }
2742 : :
2743 : 0 : default:
2744 : 0 : g_return_val_if_fail (!g_variant_is_container (value), 0);
2745 : : g_assert_not_reached ();
2746 : : }
2747 : : }
2748 : :
2749 : : /**
2750 : : * g_variant_equal:
2751 : : * @one: (type GVariant): a #GVariant instance
2752 : : * @two: (type GVariant): a #GVariant instance
2753 : : *
2754 : : * Checks if @one and @two have the same type and value.
2755 : : *
2756 : : * The types of @one and @two are #gconstpointer only to allow use of
2757 : : * this function with #GHashTable. They must each be a #GVariant.
2758 : : *
2759 : : * Returns: %TRUE if @one and @two are equal
2760 : : *
2761 : : * Since: 2.24
2762 : : **/
2763 : : gboolean
2764 : 9478239 : g_variant_equal (gconstpointer one,
2765 : : gconstpointer two)
2766 : : {
2767 : : gboolean equal;
2768 : :
2769 : 9478239 : g_return_val_if_fail (one != NULL && two != NULL, FALSE);
2770 : :
2771 [ + + ]: 18956478 : if (g_variant_get_type_info ((GVariant *) one) !=
2772 : 9478239 : g_variant_get_type_info ((GVariant *) two))
2773 : 7873055 : return FALSE;
2774 : :
2775 : : /* if both values are trusted to be in their canonical serialized form
2776 : : * then a simple memcmp() of their serialized data will answer the
2777 : : * question.
2778 : : *
2779 : : * if not, then this might generate a false negative (since it is
2780 : : * possible for two different byte sequences to represent the same
2781 : : * value). for now we solve this by pretty-printing both values and
2782 : : * comparing the result.
2783 : : */
2784 [ + + + + ]: 3210159 : if (g_variant_is_trusted ((GVariant *) one) &&
2785 : 1604975 : g_variant_is_trusted ((GVariant *) two))
2786 : 1419089 : {
2787 : : gconstpointer data_one, data_two;
2788 : : gsize size_one, size_two;
2789 : :
2790 : 1604777 : size_one = g_variant_get_size ((GVariant *) one);
2791 : 1604777 : size_two = g_variant_get_size ((GVariant *) two);
2792 : :
2793 [ + + ]: 1604777 : if (size_one != size_two)
2794 : 185688 : return FALSE;
2795 : :
2796 : 1419089 : data_one = g_variant_get_data ((GVariant *) one);
2797 : 1419089 : data_two = g_variant_get_data ((GVariant *) two);
2798 : :
2799 [ + + ]: 1419089 : if (size_one)
2800 : 1419080 : equal = memcmp (data_one, data_two, size_one) == 0;
2801 : : else
2802 : 9 : equal = TRUE;
2803 : : }
2804 : : else
2805 : : {
2806 : : gchar *strone, *strtwo;
2807 : :
2808 : 407 : strone = g_variant_print ((GVariant *) one, FALSE);
2809 : 407 : strtwo = g_variant_print ((GVariant *) two, FALSE);
2810 : 407 : equal = strcmp (strone, strtwo) == 0;
2811 : 407 : g_free (strone);
2812 : 407 : g_free (strtwo);
2813 : : }
2814 : :
2815 : 1419496 : return equal;
2816 : : }
2817 : :
2818 : : /**
2819 : : * g_variant_compare:
2820 : : * @one: (type GVariant): a basic-typed #GVariant instance
2821 : : * @two: (type GVariant): a #GVariant instance of the same type
2822 : : *
2823 : : * Compares @one and @two.
2824 : : *
2825 : : * The types of @one and @two are #gconstpointer only to allow use of
2826 : : * this function with #GTree, #GPtrArray, etc. They must each be a
2827 : : * #GVariant.
2828 : : *
2829 : : * Comparison is only defined for basic types (ie: booleans, numbers,
2830 : : * strings). For booleans, %FALSE is less than %TRUE. Numbers are
2831 : : * ordered in the usual way. Strings are in ASCII lexographical order.
2832 : : *
2833 : : * It is a programmer error to attempt to compare container values or
2834 : : * two values that have types that are not exactly equal. For example,
2835 : : * you cannot compare a 32-bit signed integer with a 32-bit unsigned
2836 : : * integer. Also note that this function is not particularly
2837 : : * well-behaved when it comes to comparison of doubles; in particular,
2838 : : * the handling of incomparable values (ie: NaN) is undefined.
2839 : : *
2840 : : * If you only require an equality comparison, g_variant_equal() is more
2841 : : * general.
2842 : : *
2843 : : * Returns: negative value if a < b;
2844 : : * zero if a = b;
2845 : : * positive value if a > b.
2846 : : *
2847 : : * Since: 2.26
2848 : : **/
2849 : : gint
2850 : 124 : g_variant_compare (gconstpointer one,
2851 : : gconstpointer two)
2852 : : {
2853 : 124 : GVariant *a = (GVariant *) one;
2854 : 124 : GVariant *b = (GVariant *) two;
2855 : :
2856 : 124 : g_return_val_if_fail (g_variant_classify (a) == g_variant_classify (b), 0);
2857 : :
2858 [ + + + + : 124 : switch (g_variant_classify (a))
+ + + + +
+ - ]
2859 : : {
2860 : 1 : case G_VARIANT_CLASS_BOOLEAN:
2861 : 2 : return g_variant_get_boolean (a) -
2862 : 1 : g_variant_get_boolean (b);
2863 : :
2864 : 7 : case G_VARIANT_CLASS_BYTE:
2865 : 7 : return ((gint) g_variant_get_byte (a)) -
2866 : 7 : ((gint) g_variant_get_byte (b));
2867 : :
2868 : 7 : case G_VARIANT_CLASS_INT16:
2869 : 7 : return ((gint) g_variant_get_int16 (a)) -
2870 : 7 : ((gint) g_variant_get_int16 (b));
2871 : :
2872 : 7 : case G_VARIANT_CLASS_UINT16:
2873 : 7 : return ((gint) g_variant_get_uint16 (a)) -
2874 : 7 : ((gint) g_variant_get_uint16 (b));
2875 : :
2876 : 59 : case G_VARIANT_CLASS_INT32:
2877 : : {
2878 : 59 : gint32 a_val = g_variant_get_int32 (a);
2879 : 59 : gint32 b_val = g_variant_get_int32 (b);
2880 : :
2881 [ + + + + ]: 59 : return (a_val == b_val) ? 0 : (a_val > b_val) ? 1 : -1;
2882 : : }
2883 : :
2884 : 19 : case G_VARIANT_CLASS_UINT32:
2885 : : {
2886 : 19 : guint32 a_val = g_variant_get_uint32 (a);
2887 : 19 : guint32 b_val = g_variant_get_uint32 (b);
2888 : :
2889 [ + + + + ]: 19 : return (a_val == b_val) ? 0 : (a_val > b_val) ? 1 : -1;
2890 : : }
2891 : :
2892 : 7 : case G_VARIANT_CLASS_INT64:
2893 : : {
2894 : 7 : gint64 a_val = g_variant_get_int64 (a);
2895 : 7 : gint64 b_val = g_variant_get_int64 (b);
2896 : :
2897 [ + + + + ]: 7 : return (a_val == b_val) ? 0 : (a_val > b_val) ? 1 : -1;
2898 : : }
2899 : :
2900 : 7 : case G_VARIANT_CLASS_UINT64:
2901 : : {
2902 : 7 : guint64 a_val = g_variant_get_uint64 (a);
2903 : 7 : guint64 b_val = g_variant_get_uint64 (b);
2904 : :
2905 [ + + - + ]: 7 : return (a_val == b_val) ? 0 : (a_val > b_val) ? 1 : -1;
2906 : : }
2907 : :
2908 : 7 : case G_VARIANT_CLASS_DOUBLE:
2909 : : {
2910 : 7 : gdouble a_val = g_variant_get_double (a);
2911 : 7 : gdouble b_val = g_variant_get_double (b);
2912 : :
2913 [ + + + + ]: 7 : return (a_val == b_val) ? 0 : (a_val > b_val) ? 1 : -1;
2914 : : }
2915 : :
2916 : 3 : case G_VARIANT_CLASS_STRING:
2917 : : case G_VARIANT_CLASS_OBJECT_PATH:
2918 : : case G_VARIANT_CLASS_SIGNATURE:
2919 : 3 : return strcmp (g_variant_get_string (a, NULL),
2920 : 3 : g_variant_get_string (b, NULL));
2921 : :
2922 : 0 : default:
2923 : 0 : g_return_val_if_fail (!g_variant_is_container (a), 0);
2924 : : g_assert_not_reached ();
2925 : : }
2926 : : }
2927 : :
2928 : : /* GVariantIter {{{1 */
2929 : : /**
2930 : : * GVariantIter: (skip)
2931 : : *
2932 : : * #GVariantIter is an opaque data structure and can only be accessed
2933 : : * using the following functions.
2934 : : **/
2935 : : struct stack_iter
2936 : : {
2937 : : GVariant *value;
2938 : : gssize n, i;
2939 : :
2940 : : const gchar *loop_format;
2941 : :
2942 : : gsize padding[3];
2943 : : gsize magic;
2944 : : };
2945 : :
2946 : : G_STATIC_ASSERT (sizeof (struct stack_iter) <= sizeof (GVariantIter));
2947 : :
2948 : : struct heap_iter
2949 : : {
2950 : : struct stack_iter iter;
2951 : :
2952 : : GVariant *value_ref;
2953 : : gsize magic;
2954 : : };
2955 : :
2956 : : G_STATIC_ASSERT (sizeof (struct heap_iter) <= sizeof (GVariantIter));
2957 : :
2958 : : #define GVSI(i) ((struct stack_iter *) (i))
2959 : : #define GVHI(i) ((struct heap_iter *) (i))
2960 : : #define GVSI_MAGIC ((gsize) 3579507750u)
2961 : : #define GVHI_MAGIC ((gsize) 1450270775u)
2962 : : #define is_valid_iter(i) (i != NULL && \
2963 : : GVSI(i)->magic == GVSI_MAGIC)
2964 : : #define is_valid_heap_iter(i) (is_valid_iter(i) && \
2965 : : GVHI(i)->magic == GVHI_MAGIC)
2966 : :
2967 : : /**
2968 : : * g_variant_iter_new:
2969 : : * @value: a container #GVariant
2970 : : *
2971 : : * Creates a heap-allocated #GVariantIter for iterating over the items
2972 : : * in @value.
2973 : : *
2974 : : * Use g_variant_iter_free() to free the return value when you no longer
2975 : : * need it.
2976 : : *
2977 : : * A reference is taken to @value and will be released only when
2978 : : * g_variant_iter_free() is called.
2979 : : *
2980 : : * Returns: (transfer full): a new heap-allocated #GVariantIter
2981 : : *
2982 : : * Since: 2.24
2983 : : **/
2984 : : GVariantIter *
2985 : 14926 : g_variant_iter_new (GVariant *value)
2986 : : {
2987 : : GVariantIter *iter;
2988 : :
2989 : 14926 : iter = (GVariantIter *) g_slice_new (struct heap_iter);
2990 : 14926 : GVHI(iter)->value_ref = g_variant_ref (value);
2991 : 14926 : GVHI(iter)->magic = GVHI_MAGIC;
2992 : :
2993 : 14926 : g_variant_iter_init (iter, value);
2994 : :
2995 : 14926 : return iter;
2996 : : }
2997 : :
2998 : : /**
2999 : : * g_variant_iter_init: (skip)
3000 : : * @iter: a pointer to a #GVariantIter
3001 : : * @value: a container #GVariant
3002 : : *
3003 : : * Initialises (without allocating) a #GVariantIter. @iter may be
3004 : : * completely uninitialised prior to this call; its old value is
3005 : : * ignored.
3006 : : *
3007 : : * The iterator remains valid for as long as @value exists, and need not
3008 : : * be freed in any way.
3009 : : *
3010 : : * Returns: the number of items in @value
3011 : : *
3012 : : * Since: 2.24
3013 : : **/
3014 : : gsize
3015 : 138809 : g_variant_iter_init (GVariantIter *iter,
3016 : : GVariant *value)
3017 : : {
3018 : 138809 : GVSI(iter)->magic = GVSI_MAGIC;
3019 : 138809 : GVSI(iter)->value = value;
3020 : 138809 : GVSI(iter)->n = g_variant_n_children (value);
3021 : 138809 : GVSI(iter)->i = -1;
3022 : 138809 : GVSI(iter)->loop_format = NULL;
3023 : :
3024 : 138809 : return GVSI(iter)->n;
3025 : : }
3026 : :
3027 : : /**
3028 : : * g_variant_iter_copy:
3029 : : * @iter: a #GVariantIter
3030 : : *
3031 : : * Creates a new heap-allocated #GVariantIter to iterate over the
3032 : : * container that was being iterated over by @iter. Iteration begins on
3033 : : * the new iterator from the current position of the old iterator but
3034 : : * the two copies are independent past that point.
3035 : : *
3036 : : * Use g_variant_iter_free() to free the return value when you no longer
3037 : : * need it.
3038 : : *
3039 : : * A reference is taken to the container that @iter is iterating over
3040 : : * and will be related only when g_variant_iter_free() is called.
3041 : : *
3042 : : * Returns: (transfer full): a new heap-allocated #GVariantIter
3043 : : *
3044 : : * Since: 2.24
3045 : : **/
3046 : : GVariantIter *
3047 : 1 : g_variant_iter_copy (GVariantIter *iter)
3048 : : {
3049 : : GVariantIter *copy;
3050 : :
3051 : 1 : g_return_val_if_fail (is_valid_iter (iter), 0);
3052 : :
3053 : 1 : copy = g_variant_iter_new (GVSI(iter)->value);
3054 : 1 : GVSI(copy)->i = GVSI(iter)->i;
3055 : :
3056 : 1 : return copy;
3057 : : }
3058 : :
3059 : : /**
3060 : : * g_variant_iter_n_children:
3061 : : * @iter: a #GVariantIter
3062 : : *
3063 : : * Queries the number of child items in the container that we are
3064 : : * iterating over. This is the total number of items -- not the number
3065 : : * of items remaining.
3066 : : *
3067 : : * This function might be useful for preallocation of arrays.
3068 : : *
3069 : : * Returns: the number of children in the container
3070 : : *
3071 : : * Since: 2.24
3072 : : **/
3073 : : gsize
3074 : 13940 : g_variant_iter_n_children (GVariantIter *iter)
3075 : : {
3076 : 13940 : g_return_val_if_fail (is_valid_iter (iter), 0);
3077 : :
3078 : 13940 : return GVSI(iter)->n;
3079 : : }
3080 : :
3081 : : /**
3082 : : * g_variant_iter_free:
3083 : : * @iter: (transfer full): a heap-allocated #GVariantIter
3084 : : *
3085 : : * Frees a heap-allocated #GVariantIter. Only call this function on
3086 : : * iterators that were returned by g_variant_iter_new() or
3087 : : * g_variant_iter_copy().
3088 : : *
3089 : : * Since: 2.24
3090 : : **/
3091 : : void
3092 : 14926 : g_variant_iter_free (GVariantIter *iter)
3093 : : {
3094 : 14926 : g_return_if_fail (is_valid_heap_iter (iter));
3095 : :
3096 : 14926 : g_variant_unref (GVHI(iter)->value_ref);
3097 : 14926 : GVHI(iter)->magic = 0;
3098 : :
3099 : 14926 : g_slice_free (struct heap_iter, GVHI(iter));
3100 : : }
3101 : :
3102 : : /**
3103 : : * g_variant_iter_next_value:
3104 : : * @iter: a #GVariantIter
3105 : : *
3106 : : * Gets the next item in the container. If no more items remain then
3107 : : * %NULL is returned.
3108 : : *
3109 : : * Use g_variant_unref() to drop your reference on the return value when
3110 : : * you no longer need it.
3111 : : *
3112 : : * Here is an example for iterating with g_variant_iter_next_value():
3113 : : * |[<!-- language="C" -->
3114 : : * // recursively iterate a container
3115 : : * void
3116 : : * iterate_container_recursive (GVariant *container)
3117 : : * {
3118 : : * GVariantIter iter;
3119 : : * GVariant *child;
3120 : : *
3121 : : * g_variant_iter_init (&iter, container);
3122 : : * while ((child = g_variant_iter_next_value (&iter)))
3123 : : * {
3124 : : * g_print ("type '%s'\n", g_variant_get_type_string (child));
3125 : : *
3126 : : * if (g_variant_is_container (child))
3127 : : * iterate_container_recursive (child);
3128 : : *
3129 : : * g_variant_unref (child);
3130 : : * }
3131 : : * }
3132 : : * ]|
3133 : : *
3134 : : * Returns: (nullable) (transfer full): a #GVariant, or %NULL
3135 : : *
3136 : : * Since: 2.24
3137 : : **/
3138 : : GVariant *
3139 : 804402 : g_variant_iter_next_value (GVariantIter *iter)
3140 : : {
3141 : 804402 : g_return_val_if_fail (is_valid_iter (iter), FALSE);
3142 : :
3143 [ + + ]: 804402 : if G_UNLIKELY (GVSI(iter)->i >= GVSI(iter)->n)
3144 : : {
3145 : 1 : g_critical ("g_variant_iter_next_value: must not be called again "
3146 : : "after NULL has already been returned.");
3147 : 1 : return NULL;
3148 : : }
3149 : :
3150 : 804401 : GVSI(iter)->i++;
3151 : :
3152 [ + + ]: 804401 : if (GVSI(iter)->i < GVSI(iter)->n)
3153 : 665636 : return g_variant_get_child_value (GVSI(iter)->value, GVSI(iter)->i);
3154 : :
3155 : 138765 : return NULL;
3156 : : }
3157 : :
3158 : : /* GVariantBuilder {{{1 */
3159 : : /**
3160 : : * GVariantBuilder:
3161 : : *
3162 : : * A utility type for constructing container-type #GVariant instances.
3163 : : *
3164 : : * This is an opaque structure and may only be accessed using the
3165 : : * following functions.
3166 : : *
3167 : : * #GVariantBuilder is not threadsafe in any way. Do not attempt to
3168 : : * access it from more than one thread.
3169 : : **/
3170 : :
3171 : : struct stack_builder
3172 : : {
3173 : : GVariantBuilder *parent;
3174 : : GVariantType *type;
3175 : :
3176 : : /* type constraint explicitly specified by 'type'.
3177 : : * for tuple types, this moves along as we add more items.
3178 : : */
3179 : : const GVariantType *expected_type;
3180 : :
3181 : : /* type constraint implied by previous array item.
3182 : : */
3183 : : const GVariantType *prev_item_type;
3184 : :
3185 : : /* constraints on the number of children. max = -1 for unlimited. */
3186 : : gsize min_items;
3187 : : gsize max_items;
3188 : :
3189 : : /* dynamically-growing pointer array */
3190 : : GVariant **children;
3191 : : gsize allocated_children;
3192 : : gsize offset;
3193 : :
3194 : : /* set to '1' if all items in the container will have the same type
3195 : : * (ie: maybe, array, variant) '0' if not (ie: tuple, dict entry)
3196 : : */
3197 : : guint uniform_item_types : 1;
3198 : :
3199 : : /* set to '1' initially and changed to '0' if an untrusted value is
3200 : : * added
3201 : : */
3202 : : guint trusted : 1;
3203 : :
3204 : : gsize magic;
3205 : : };
3206 : :
3207 : : G_STATIC_ASSERT (sizeof (struct stack_builder) <= sizeof (GVariantBuilder));
3208 : :
3209 : : struct heap_builder
3210 : : {
3211 : : GVariantBuilder builder;
3212 : : gsize magic;
3213 : :
3214 : : gint ref_count;
3215 : : };
3216 : :
3217 : : #define GVSB(b) ((struct stack_builder *) (b))
3218 : : #define GVHB(b) ((struct heap_builder *) (b))
3219 : : #define GVSB_MAGIC ((gsize) 1033660112u)
3220 : : #define GVSB_MAGIC_PARTIAL ((gsize) 2942751021u)
3221 : : #define GVHB_MAGIC ((gsize) 3087242682u)
3222 : : #define is_valid_builder(b) (GVSB(b)->magic == GVSB_MAGIC)
3223 : : #define is_valid_heap_builder(b) (GVHB(b)->magic == GVHB_MAGIC)
3224 : :
3225 : : /* Just to make sure that by adding a union to GVariantBuilder, we
3226 : : * didn't accidentally change ABI. */
3227 : : G_STATIC_ASSERT (sizeof (GVariantBuilder) == sizeof (guintptr[16]));
3228 : :
3229 : : static gboolean
3230 : 1247219 : ensure_valid_builder (GVariantBuilder *builder)
3231 : : {
3232 [ - + ]: 1247219 : if (builder == NULL)
3233 : 0 : return FALSE;
3234 [ + + ]: 1247219 : else if (is_valid_builder (builder))
3235 : 1247215 : return TRUE;
3236 [ + - ]: 4 : if (builder->u.s.partial_magic == GVSB_MAGIC_PARTIAL)
3237 : : {
3238 : : static GVariantBuilder cleared_builder;
3239 : :
3240 : : /* Make sure that only first two fields were set and the rest is
3241 : : * zeroed to avoid messing up the builder that had parent
3242 : : * address equal to GVSB_MAGIC_PARTIAL. */
3243 [ - + ]: 4 : if (memcmp (cleared_builder.u.s.y, builder->u.s.y, sizeof cleared_builder.u.s.y))
3244 : 0 : return FALSE;
3245 : :
3246 : 4 : g_variant_builder_init (builder, builder->u.s.type);
3247 : : }
3248 : 4 : return is_valid_builder (builder);
3249 : : }
3250 : :
3251 : : /* return_if_invalid_builder (b) is like
3252 : : * g_return_if_fail (ensure_valid_builder (b)), except that
3253 : : * the side effects of ensure_valid_builder are evaluated
3254 : : * regardless of whether G_DISABLE_CHECKS is defined or not. */
3255 : : #define return_if_invalid_builder(b) G_STMT_START { \
3256 : : gboolean valid_builder G_GNUC_UNUSED = ensure_valid_builder (b); \
3257 : : g_return_if_fail (valid_builder); \
3258 : : } G_STMT_END
3259 : :
3260 : : /* return_val_if_invalid_builder (b, val) is like
3261 : : * g_return_val_if_fail (ensure_valid_builder (b), val), except that
3262 : : * the side effects of ensure_valid_builder are evaluated
3263 : : * regardless of whether G_DISABLE_CHECKS is defined or not. */
3264 : : #define return_val_if_invalid_builder(b, val) G_STMT_START { \
3265 : : gboolean valid_builder G_GNUC_UNUSED = ensure_valid_builder (b); \
3266 : : g_return_val_if_fail (valid_builder, val); \
3267 : : } G_STMT_END
3268 : :
3269 : : /**
3270 : : * g_variant_builder_new:
3271 : : * @type: a container type
3272 : : *
3273 : : * Allocates and initialises a new #GVariantBuilder.
3274 : : *
3275 : : * You should call g_variant_builder_unref() on the return value when it
3276 : : * is no longer needed. The memory will not be automatically freed by
3277 : : * any other call.
3278 : : *
3279 : : * In most cases it is easier to place a #GVariantBuilder directly on
3280 : : * the stack of the calling function and initialise it with
3281 : : * g_variant_builder_init().
3282 : : *
3283 : : * Returns: (transfer full): a #GVariantBuilder
3284 : : *
3285 : : * Since: 2.24
3286 : : **/
3287 : : GVariantBuilder *
3288 : 6 : g_variant_builder_new (const GVariantType *type)
3289 : : {
3290 : : GVariantBuilder *builder;
3291 : :
3292 : 6 : builder = (GVariantBuilder *) g_slice_new (struct heap_builder);
3293 : 6 : g_variant_builder_init (builder, type);
3294 : 6 : GVHB(builder)->magic = GVHB_MAGIC;
3295 : 6 : GVHB(builder)->ref_count = 1;
3296 : :
3297 : 6 : return builder;
3298 : : }
3299 : :
3300 : : /**
3301 : : * g_variant_builder_unref:
3302 : : * @builder: (transfer full): a #GVariantBuilder allocated by g_variant_builder_new()
3303 : : *
3304 : : * Decreases the reference count on @builder.
3305 : : *
3306 : : * In the event that there are no more references, releases all memory
3307 : : * associated with the #GVariantBuilder.
3308 : : *
3309 : : * Don't call this on stack-allocated #GVariantBuilder instances or bad
3310 : : * things will happen.
3311 : : *
3312 : : * Since: 2.24
3313 : : **/
3314 : : void
3315 : 8 : g_variant_builder_unref (GVariantBuilder *builder)
3316 : : {
3317 : 8 : g_return_if_fail (is_valid_heap_builder (builder));
3318 : :
3319 [ + + ]: 8 : if (--GVHB(builder)->ref_count)
3320 : 2 : return;
3321 : :
3322 : 6 : g_variant_builder_clear (builder);
3323 : 6 : GVHB(builder)->magic = 0;
3324 : :
3325 : 6 : g_slice_free (struct heap_builder, GVHB(builder));
3326 : : }
3327 : :
3328 : : /**
3329 : : * g_variant_builder_ref:
3330 : : * @builder: a #GVariantBuilder allocated by g_variant_builder_new()
3331 : : *
3332 : : * Increases the reference count on @builder.
3333 : : *
3334 : : * Don't call this on stack-allocated #GVariantBuilder instances or bad
3335 : : * things will happen.
3336 : : *
3337 : : * Returns: (transfer full): a new reference to @builder
3338 : : *
3339 : : * Since: 2.24
3340 : : **/
3341 : : GVariantBuilder *
3342 : 2 : g_variant_builder_ref (GVariantBuilder *builder)
3343 : : {
3344 : 2 : g_return_val_if_fail (is_valid_heap_builder (builder), NULL);
3345 : :
3346 : 2 : GVHB(builder)->ref_count++;
3347 : :
3348 : 2 : return builder;
3349 : : }
3350 : :
3351 : : /**
3352 : : * g_variant_builder_clear: (skip)
3353 : : * @builder: a #GVariantBuilder
3354 : : *
3355 : : * Releases all memory associated with a #GVariantBuilder without
3356 : : * freeing the #GVariantBuilder structure itself.
3357 : : *
3358 : : * It typically only makes sense to do this on a stack-allocated
3359 : : * #GVariantBuilder if you want to abort building the value part-way
3360 : : * through. This function need not be called if you call
3361 : : * g_variant_builder_end() and it also doesn't need to be called on
3362 : : * builders allocated with g_variant_builder_new() (see
3363 : : * g_variant_builder_unref() for that).
3364 : : *
3365 : : * This function leaves the #GVariantBuilder structure set to all-zeros.
3366 : : * It is valid to call this function on either an initialised
3367 : : * #GVariantBuilder or one that is set to all-zeros but it is not valid
3368 : : * to call this function on uninitialised memory.
3369 : : *
3370 : : * Since: 2.24
3371 : : **/
3372 : : void
3373 : 171812 : g_variant_builder_clear (GVariantBuilder *builder)
3374 : : {
3375 : : gsize i;
3376 : :
3377 [ + + ]: 171812 : if (GVSB(builder)->magic == 0)
3378 : : /* all-zeros or partial case */
3379 : 2 : return;
3380 : :
3381 [ - + ]: 171810 : return_if_invalid_builder (builder);
3382 : :
3383 : 171810 : g_variant_type_free (GVSB(builder)->type);
3384 : :
3385 [ + + ]: 172155 : for (i = 0; i < GVSB(builder)->offset; i++)
3386 : 345 : g_variant_unref (GVSB(builder)->children[i]);
3387 : :
3388 : 171810 : g_free (GVSB(builder)->children);
3389 : :
3390 [ + + ]: 171810 : if (GVSB(builder)->parent)
3391 : : {
3392 : 9 : g_variant_builder_clear (GVSB(builder)->parent);
3393 : 9 : g_slice_free (GVariantBuilder, GVSB(builder)->parent);
3394 : : }
3395 : :
3396 : 171810 : memset (builder, 0, sizeof (GVariantBuilder));
3397 : : }
3398 : :
3399 : : /**
3400 : : * g_variant_builder_init: (skip)
3401 : : * @builder: a #GVariantBuilder
3402 : : * @type: a container type
3403 : : *
3404 : : * Initialises a #GVariantBuilder structure.
3405 : : *
3406 : : * @type must be non-%NULL. It specifies the type of container to
3407 : : * construct. It can be an indefinite type such as
3408 : : * %G_VARIANT_TYPE_ARRAY or a definite type such as "as" or "(ii)".
3409 : : * Maybe, array, tuple, dictionary entry and variant-typed values may be
3410 : : * constructed.
3411 : : *
3412 : : * After the builder is initialised, values are added using
3413 : : * g_variant_builder_add_value() or g_variant_builder_add().
3414 : : *
3415 : : * After all the child values are added, g_variant_builder_end() frees
3416 : : * the memory associated with the builder and returns the #GVariant that
3417 : : * was created.
3418 : : *
3419 : : * This function completely ignores the previous contents of @builder.
3420 : : * On one hand this means that it is valid to pass in completely
3421 : : * uninitialised memory. On the other hand, this means that if you are
3422 : : * initialising over top of an existing #GVariantBuilder you need to
3423 : : * first call g_variant_builder_clear() in order to avoid leaking
3424 : : * memory.
3425 : : *
3426 : : * You must not call g_variant_builder_ref() or
3427 : : * g_variant_builder_unref() on a #GVariantBuilder that was initialised
3428 : : * with this function. If you ever pass a reference to a
3429 : : * #GVariantBuilder outside of the control of your own code then you
3430 : : * should assume that the person receiving that reference may try to use
3431 : : * reference counting; you should use g_variant_builder_new() instead of
3432 : : * this function.
3433 : : *
3434 : : * Since: 2.24
3435 : : **/
3436 : : void
3437 : 171810 : g_variant_builder_init (GVariantBuilder *builder,
3438 : : const GVariantType *type)
3439 : : {
3440 : 171810 : g_return_if_fail (type != NULL);
3441 : 171810 : g_return_if_fail (g_variant_type_is_container (type));
3442 : :
3443 : 171810 : memset (builder, 0, sizeof (GVariantBuilder));
3444 : :
3445 : 171810 : GVSB(builder)->type = g_variant_type_copy (type);
3446 : 171810 : GVSB(builder)->magic = GVSB_MAGIC;
3447 : 171810 : GVSB(builder)->trusted = TRUE;
3448 : :
3449 [ + + + + : 171810 : switch (*(const gchar *) type)
+ + - ]
3450 : : {
3451 : 987 : case G_VARIANT_CLASS_VARIANT:
3452 : 987 : GVSB(builder)->uniform_item_types = TRUE;
3453 : 987 : GVSB(builder)->allocated_children = 1;
3454 : 987 : GVSB(builder)->expected_type = NULL;
3455 : 987 : GVSB(builder)->min_items = 1;
3456 : 987 : GVSB(builder)->max_items = 1;
3457 : 987 : break;
3458 : :
3459 : 54396 : case G_VARIANT_CLASS_ARRAY:
3460 : 54396 : GVSB(builder)->uniform_item_types = TRUE;
3461 : 54396 : GVSB(builder)->allocated_children = 8;
3462 : 54396 : GVSB(builder)->expected_type =
3463 : 54396 : g_variant_type_element (GVSB(builder)->type);
3464 : 54396 : GVSB(builder)->min_items = 0;
3465 : 54396 : GVSB(builder)->max_items = -1;
3466 : 54396 : break;
3467 : :
3468 : 608 : case G_VARIANT_CLASS_MAYBE:
3469 : 608 : GVSB(builder)->uniform_item_types = TRUE;
3470 : 608 : GVSB(builder)->allocated_children = 1;
3471 : 608 : GVSB(builder)->expected_type =
3472 : 608 : g_variant_type_element (GVSB(builder)->type);
3473 : 608 : GVSB(builder)->min_items = 0;
3474 : 608 : GVSB(builder)->max_items = 1;
3475 : 608 : break;
3476 : :
3477 : 74484 : case G_VARIANT_CLASS_DICT_ENTRY:
3478 : 74484 : GVSB(builder)->uniform_item_types = FALSE;
3479 : 74484 : GVSB(builder)->allocated_children = 2;
3480 : 74484 : GVSB(builder)->expected_type =
3481 : 74484 : g_variant_type_key (GVSB(builder)->type);
3482 : 74484 : GVSB(builder)->min_items = 2;
3483 : 74484 : GVSB(builder)->max_items = 2;
3484 : 74484 : break;
3485 : :
3486 : 10456 : case 'r': /* G_VARIANT_TYPE_TUPLE was given */
3487 : 10456 : GVSB(builder)->uniform_item_types = FALSE;
3488 : 10456 : GVSB(builder)->allocated_children = 8;
3489 : 10456 : GVSB(builder)->expected_type = NULL;
3490 : 10456 : GVSB(builder)->min_items = 0;
3491 : 10456 : GVSB(builder)->max_items = -1;
3492 : 10456 : break;
3493 : :
3494 : 30879 : case G_VARIANT_CLASS_TUPLE: /* a definite tuple type was given */
3495 : 30879 : GVSB(builder)->allocated_children = g_variant_type_n_items (type);
3496 : 30879 : GVSB(builder)->expected_type =
3497 : 30879 : g_variant_type_first (GVSB(builder)->type);
3498 : 30879 : GVSB(builder)->min_items = GVSB(builder)->allocated_children;
3499 : 30879 : GVSB(builder)->max_items = GVSB(builder)->allocated_children;
3500 : 30879 : GVSB(builder)->uniform_item_types = FALSE;
3501 : 30879 : break;
3502 : :
3503 : 0 : default:
3504 : : g_assert_not_reached ();
3505 : : }
3506 : :
3507 : : #ifdef G_ANALYZER_ANALYZING
3508 : : /* Static analysers can’t couple the code in g_variant_builder_init() to the
3509 : : * code in g_variant_builder_end() by GVariantType, so end up assuming that
3510 : : * @offset and @children mismatch and that uninitialised memory is accessed
3511 : : * from @children. At runtime, this is caught by the preconditions at the top
3512 : : * of g_variant_builder_end(). Help the analyser by zero-initialising the
3513 : : * memory to avoid a false positive. */
3514 : 171810 : GVSB(builder)->children = g_new0 (GVariant *,
3515 : : GVSB(builder)->allocated_children);
3516 : : #else
3517 : : GVSB(builder)->children = g_new (GVariant *,
3518 : : GVSB(builder)->allocated_children);
3519 : : #endif
3520 : : }
3521 : :
3522 : : static void
3523 : 872228 : g_variant_builder_make_room (struct stack_builder *builder)
3524 : : {
3525 [ + + ]: 872228 : if (builder->offset == builder->allocated_children)
3526 : : {
3527 : 16561 : builder->allocated_children *= 2;
3528 : 16561 : builder->children = g_renew (GVariant *, builder->children,
3529 : : builder->allocated_children);
3530 : : }
3531 : 872228 : }
3532 : :
3533 : : /**
3534 : : * g_variant_builder_add_value:
3535 : : * @builder: a #GVariantBuilder
3536 : : * @value: a #GVariant
3537 : : *
3538 : : * Adds @value to @builder.
3539 : : *
3540 : : * It is an error to call this function in any way that would create an
3541 : : * inconsistent value to be constructed. Some examples of this are
3542 : : * putting different types of items into an array, putting the wrong
3543 : : * types or number of items in a tuple, putting more than one value into
3544 : : * a variant, etc.
3545 : : *
3546 : : * If @value is a floating reference (see g_variant_ref_sink()),
3547 : : * the @builder instance takes ownership of @value.
3548 : : *
3549 : : * Since: 2.24
3550 : : **/
3551 : : void
3552 : 872228 : g_variant_builder_add_value (GVariantBuilder *builder,
3553 : : GVariant *value)
3554 : : {
3555 [ - + ]: 872228 : return_if_invalid_builder (builder);
3556 : 872228 : g_return_if_fail (GVSB(builder)->offset < GVSB(builder)->max_items);
3557 : 872228 : g_return_if_fail (!GVSB(builder)->expected_type ||
3558 : : g_variant_is_of_type (value,
3559 : : GVSB(builder)->expected_type));
3560 : 872228 : g_return_if_fail (!GVSB(builder)->prev_item_type ||
3561 : : g_variant_is_of_type (value,
3562 : : GVSB(builder)->prev_item_type));
3563 : :
3564 : 872228 : GVSB(builder)->trusted &= g_variant_is_trusted (value);
3565 : :
3566 [ + + ]: 872228 : if (!GVSB(builder)->uniform_item_types)
3567 : : {
3568 : : /* advance our expected type pointers */
3569 [ + + ]: 234694 : if (GVSB(builder)->expected_type)
3570 : 217948 : GVSB(builder)->expected_type =
3571 : 217948 : g_variant_type_next (GVSB(builder)->expected_type);
3572 : :
3573 [ + + ]: 234694 : if (GVSB(builder)->prev_item_type)
3574 : 26129 : GVSB(builder)->prev_item_type =
3575 : 26129 : g_variant_type_next (GVSB(builder)->prev_item_type);
3576 : : }
3577 : : else
3578 : 637534 : GVSB(builder)->prev_item_type = g_variant_get_type (value);
3579 : :
3580 : 872228 : g_variant_builder_make_room (GVSB(builder));
3581 : :
3582 : 872228 : GVSB(builder)->children[GVSB(builder)->offset++] =
3583 : 872228 : g_variant_ref_sink (value);
3584 : : }
3585 : :
3586 : : /**
3587 : : * g_variant_builder_open:
3588 : : * @builder: a #GVariantBuilder
3589 : : * @type: the #GVariantType of the container
3590 : : *
3591 : : * Opens a subcontainer inside the given @builder. When done adding
3592 : : * items to the subcontainer, g_variant_builder_close() must be called. @type
3593 : : * is the type of the container: so to build a tuple of several values, @type
3594 : : * must include the tuple itself.
3595 : : *
3596 : : * It is an error to call this function in any way that would cause an
3597 : : * inconsistent value to be constructed (ie: adding too many values or
3598 : : * a value of an incorrect type).
3599 : : *
3600 : : * Example of building a nested variant:
3601 : : * |[<!-- language="C" -->
3602 : : * GVariantBuilder builder;
3603 : : * guint32 some_number = get_number ();
3604 : : * g_autoptr (GHashTable) some_dict = get_dict ();
3605 : : * GHashTableIter iter;
3606 : : * const gchar *key;
3607 : : * const GVariant *value;
3608 : : * g_autoptr (GVariant) output = NULL;
3609 : : *
3610 : : * g_variant_builder_init (&builder, G_VARIANT_TYPE ("(ua{sv})"));
3611 : : * g_variant_builder_add (&builder, "u", some_number);
3612 : : * g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{sv}"));
3613 : : *
3614 : : * g_hash_table_iter_init (&iter, some_dict);
3615 : : * while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value))
3616 : : * {
3617 : : * g_variant_builder_open (&builder, G_VARIANT_TYPE ("{sv}"));
3618 : : * g_variant_builder_add (&builder, "s", key);
3619 : : * g_variant_builder_add (&builder, "v", value);
3620 : : * g_variant_builder_close (&builder);
3621 : : * }
3622 : : *
3623 : : * g_variant_builder_close (&builder);
3624 : : *
3625 : : * output = g_variant_builder_end (&builder);
3626 : : * ]|
3627 : : *
3628 : : * Since: 2.24
3629 : : **/
3630 : : void
3631 : 15784 : g_variant_builder_open (GVariantBuilder *builder,
3632 : : const GVariantType *type)
3633 : : {
3634 : : GVariantBuilder *parent;
3635 : :
3636 [ - + ]: 15784 : return_if_invalid_builder (builder);
3637 : 15784 : g_return_if_fail (GVSB(builder)->offset < GVSB(builder)->max_items);
3638 : 15784 : g_return_if_fail (!GVSB(builder)->expected_type ||
3639 : : g_variant_type_is_subtype_of (type,
3640 : : GVSB(builder)->expected_type));
3641 : 15784 : g_return_if_fail (!GVSB(builder)->prev_item_type ||
3642 : : g_variant_type_is_subtype_of (GVSB(builder)->prev_item_type,
3643 : : type));
3644 : :
3645 : 15784 : parent = g_slice_dup (GVariantBuilder, builder);
3646 : 15784 : g_variant_builder_init (builder, type);
3647 : 15784 : GVSB(builder)->parent = parent;
3648 : :
3649 : : /* push the prev_item_type down into the subcontainer */
3650 [ + + ]: 15784 : if (GVSB(parent)->prev_item_type)
3651 : : {
3652 [ + + ]: 14044 : if (!GVSB(builder)->uniform_item_types)
3653 : : /* tuples and dict entries */
3654 : 8682 : GVSB(builder)->prev_item_type =
3655 : 8682 : g_variant_type_first (GVSB(parent)->prev_item_type);
3656 : :
3657 [ + + ]: 5362 : else if (!g_variant_type_is_variant (GVSB(builder)->type))
3658 : : /* maybes and arrays */
3659 : 4750 : GVSB(builder)->prev_item_type =
3660 : 4750 : g_variant_type_element (GVSB(parent)->prev_item_type);
3661 : : }
3662 : : }
3663 : :
3664 : : /**
3665 : : * g_variant_builder_close:
3666 : : * @builder: a #GVariantBuilder
3667 : : *
3668 : : * Closes the subcontainer inside the given @builder that was opened by
3669 : : * the most recent call to g_variant_builder_open().
3670 : : *
3671 : : * It is an error to call this function in any way that would create an
3672 : : * inconsistent value to be constructed (ie: too few values added to the
3673 : : * subcontainer).
3674 : : *
3675 : : * Since: 2.24
3676 : : **/
3677 : : void
3678 : 15775 : g_variant_builder_close (GVariantBuilder *builder)
3679 : : {
3680 : : GVariantBuilder *parent;
3681 : :
3682 [ - + ]: 15775 : return_if_invalid_builder (builder);
3683 : 15775 : g_return_if_fail (GVSB(builder)->parent != NULL);
3684 : :
3685 : 15775 : parent = GVSB(builder)->parent;
3686 : 15775 : GVSB(builder)->parent = NULL;
3687 : :
3688 : 15775 : g_variant_builder_add_value (parent, g_variant_builder_end (builder));
3689 : 15775 : *builder = *parent;
3690 : :
3691 : 15775 : g_slice_free (GVariantBuilder, parent);
3692 : : }
3693 : :
3694 : : /*< private >
3695 : : * g_variant_make_maybe_type:
3696 : : * @element: a #GVariant
3697 : : *
3698 : : * Return the type of a maybe containing @element.
3699 : : */
3700 : : static GVariantType *
3701 : 49 : g_variant_make_maybe_type (GVariant *element)
3702 : : {
3703 : 49 : return g_variant_type_new_maybe (g_variant_get_type (element));
3704 : : }
3705 : :
3706 : : /*< private >
3707 : : * g_variant_make_array_type:
3708 : : * @element: a #GVariant
3709 : : *
3710 : : * Return the type of an array containing @element.
3711 : : */
3712 : : static GVariantType *
3713 : 515 : g_variant_make_array_type (GVariant *element)
3714 : : {
3715 : 515 : return g_variant_type_new_array (g_variant_get_type (element));
3716 : : }
3717 : :
3718 : : /**
3719 : : * g_variant_builder_end:
3720 : : * @builder: a #GVariantBuilder
3721 : : *
3722 : : * Ends the builder process and returns the constructed value.
3723 : : *
3724 : : * It is not permissible to use @builder in any way after this call
3725 : : * except for reference counting operations (in the case of a
3726 : : * heap-allocated #GVariantBuilder) or by reinitialising it with
3727 : : * g_variant_builder_init() (in the case of stack-allocated). This
3728 : : * means that for the stack-allocated builders there is no need to
3729 : : * call g_variant_builder_clear() after the call to
3730 : : * g_variant_builder_end().
3731 : : *
3732 : : * It is an error to call this function in any way that would create an
3733 : : * inconsistent value to be constructed (ie: insufficient number of
3734 : : * items added to a container with a specific number of children
3735 : : * required). It is also an error to call this function if the builder
3736 : : * was created with an indefinite array or maybe type and no children
3737 : : * have been added; in this case it is impossible to infer the type of
3738 : : * the empty array.
3739 : : *
3740 : : * Returns: (transfer none): a new, floating, #GVariant
3741 : : *
3742 : : * Since: 2.24
3743 : : **/
3744 : : GVariant *
3745 : 171622 : g_variant_builder_end (GVariantBuilder *builder)
3746 : : {
3747 : : GVariantType *my_type;
3748 : : GVariant *value;
3749 : :
3750 [ - + ]: 171622 : return_val_if_invalid_builder (builder, NULL);
3751 : 171622 : g_return_val_if_fail (GVSB(builder)->offset >= GVSB(builder)->min_items,
3752 : : NULL);
3753 : 171622 : g_return_val_if_fail (!GVSB(builder)->uniform_item_types ||
3754 : : GVSB(builder)->prev_item_type != NULL ||
3755 : : g_variant_type_is_definite (GVSB(builder)->type),
3756 : : NULL);
3757 : :
3758 [ + + ]: 171622 : if (g_variant_type_is_definite (GVSB(builder)->type))
3759 : 94993 : my_type = g_variant_type_copy (GVSB(builder)->type);
3760 : :
3761 [ + + ]: 76629 : else if (g_variant_type_is_maybe (GVSB(builder)->type))
3762 : 49 : my_type = g_variant_make_maybe_type (GVSB(builder)->children[0]);
3763 : :
3764 [ + + ]: 76580 : else if (g_variant_type_is_array (GVSB(builder)->type))
3765 : 515 : my_type = g_variant_make_array_type (GVSB(builder)->children[0]);
3766 : :
3767 [ + + ]: 76065 : else if (g_variant_type_is_tuple (GVSB(builder)->type))
3768 : 10456 : my_type = g_variant_make_tuple_type (GVSB(builder)->children,
3769 : : GVSB(builder)->offset);
3770 : :
3771 [ + - ]: 65609 : else if (g_variant_type_is_dict_entry (GVSB(builder)->type))
3772 : 65609 : my_type = g_variant_make_dict_entry_type (GVSB(builder)->children[0],
3773 : 65609 : GVSB(builder)->children[1]);
3774 : : else
3775 : : g_assert_not_reached ();
3776 : :
3777 : 171622 : value = g_variant_new_from_children (my_type,
3778 : 171622 : g_renew (GVariant *,
3779 : : GVSB(builder)->children,
3780 : : GVSB(builder)->offset),
3781 : : GVSB(builder)->offset,
3782 : 171622 : GVSB(builder)->trusted);
3783 : 171622 : GVSB(builder)->children = NULL;
3784 : 171622 : GVSB(builder)->offset = 0;
3785 : :
3786 : 171622 : g_variant_builder_clear (builder);
3787 : 171622 : g_variant_type_free (my_type);
3788 : :
3789 : 171622 : return value;
3790 : : }
3791 : :
3792 : : /* GVariantDict {{{1 */
3793 : :
3794 : : /**
3795 : : * GVariantDict:
3796 : : *
3797 : : * #GVariantDict is a mutable interface to #GVariant dictionaries.
3798 : : *
3799 : : * It can be used for doing a sequence of dictionary lookups in an
3800 : : * efficient way on an existing #GVariant dictionary or it can be used
3801 : : * to construct new dictionaries with a hashtable-like interface. It
3802 : : * can also be used for taking existing dictionaries and modifying them
3803 : : * in order to create new ones.
3804 : : *
3805 : : * #GVariantDict can only be used with %G_VARIANT_TYPE_VARDICT
3806 : : * dictionaries.
3807 : : *
3808 : : * It is possible to use #GVariantDict allocated on the stack or on the
3809 : : * heap. When using a stack-allocated #GVariantDict, you begin with a
3810 : : * call to g_variant_dict_init() and free the resources with a call to
3811 : : * g_variant_dict_clear().
3812 : : *
3813 : : * Heap-allocated #GVariantDict follows normal refcounting rules: you
3814 : : * allocate it with g_variant_dict_new() and use g_variant_dict_ref()
3815 : : * and g_variant_dict_unref().
3816 : : *
3817 : : * g_variant_dict_end() is used to convert the #GVariantDict back into a
3818 : : * dictionary-type #GVariant. When used with stack-allocated instances,
3819 : : * this also implicitly frees all associated memory, but for
3820 : : * heap-allocated instances, you must still call g_variant_dict_unref()
3821 : : * afterwards.
3822 : : *
3823 : : * You will typically want to use a heap-allocated #GVariantDict when
3824 : : * you expose it as part of an API. For most other uses, the
3825 : : * stack-allocated form will be more convenient.
3826 : : *
3827 : : * Consider the following two examples that do the same thing in each
3828 : : * style: take an existing dictionary and look up the "count" uint32
3829 : : * key, adding 1 to it if it is found, or returning an error if the
3830 : : * key is not found. Each returns the new dictionary as a floating
3831 : : * #GVariant.
3832 : : *
3833 : : * ## Using a stack-allocated GVariantDict
3834 : : *
3835 : : * |[<!-- language="C" -->
3836 : : * GVariant *
3837 : : * add_to_count (GVariant *orig,
3838 : : * GError **error)
3839 : : * {
3840 : : * GVariantDict dict;
3841 : : * guint32 count;
3842 : : *
3843 : : * g_variant_dict_init (&dict, orig);
3844 : : * if (!g_variant_dict_lookup (&dict, "count", "u", &count))
3845 : : * {
3846 : : * g_set_error (...);
3847 : : * g_variant_dict_clear (&dict);
3848 : : * return NULL;
3849 : : * }
3850 : : *
3851 : : * g_variant_dict_insert (&dict, "count", "u", count + 1);
3852 : : *
3853 : : * return g_variant_dict_end (&dict);
3854 : : * }
3855 : : * ]|
3856 : : *
3857 : : * ## Using heap-allocated GVariantDict
3858 : : *
3859 : : * |[<!-- language="C" -->
3860 : : * GVariant *
3861 : : * add_to_count (GVariant *orig,
3862 : : * GError **error)
3863 : : * {
3864 : : * GVariantDict *dict;
3865 : : * GVariant *result;
3866 : : * guint32 count;
3867 : : *
3868 : : * dict = g_variant_dict_new (orig);
3869 : : *
3870 : : * if (g_variant_dict_lookup (dict, "count", "u", &count))
3871 : : * {
3872 : : * g_variant_dict_insert (dict, "count", "u", count + 1);
3873 : : * result = g_variant_dict_end (dict);
3874 : : * }
3875 : : * else
3876 : : * {
3877 : : * g_set_error (...);
3878 : : * result = NULL;
3879 : : * }
3880 : : *
3881 : : * g_variant_dict_unref (dict);
3882 : : *
3883 : : * return result;
3884 : : * }
3885 : : * ]|
3886 : : *
3887 : : * Since: 2.40
3888 : : **/
3889 : : struct stack_dict
3890 : : {
3891 : : GHashTable *values;
3892 : : gsize magic;
3893 : : };
3894 : :
3895 : : G_STATIC_ASSERT (sizeof (struct stack_dict) <= sizeof (GVariantDict));
3896 : :
3897 : : struct heap_dict
3898 : : {
3899 : : struct stack_dict dict;
3900 : : gint ref_count;
3901 : : gsize magic;
3902 : : };
3903 : :
3904 : : #define GVSD(d) ((struct stack_dict *) (d))
3905 : : #define GVHD(d) ((struct heap_dict *) (d))
3906 : : #define GVSD_MAGIC ((gsize) 2579507750u)
3907 : : #define GVSD_MAGIC_PARTIAL ((gsize) 3488698669u)
3908 : : #define GVHD_MAGIC ((gsize) 2450270775u)
3909 : : #define is_valid_dict(d) (GVSD(d)->magic == GVSD_MAGIC)
3910 : : #define is_valid_heap_dict(d) (GVHD(d)->magic == GVHD_MAGIC)
3911 : :
3912 : : /* Just to make sure that by adding a union to GVariantDict, we didn't
3913 : : * accidentally change ABI. */
3914 : : G_STATIC_ASSERT (sizeof (GVariantDict) == sizeof (guintptr[16]));
3915 : :
3916 : : static gboolean
3917 : 89 : ensure_valid_dict (GVariantDict *dict)
3918 : : {
3919 [ - + ]: 89 : if (dict == NULL)
3920 : 0 : return FALSE;
3921 [ + + ]: 89 : else if (is_valid_dict (dict))
3922 : 88 : return TRUE;
3923 [ + - ]: 1 : if (dict->u.s.partial_magic == GVSD_MAGIC_PARTIAL)
3924 : : {
3925 : : static GVariantDict cleared_dict;
3926 : :
3927 : : /* Make sure that only first two fields were set and the rest is
3928 : : * zeroed to avoid messing up the builder that had parent
3929 : : * address equal to GVSB_MAGIC_PARTIAL. */
3930 [ - + ]: 1 : if (memcmp (cleared_dict.u.s.y, dict->u.s.y, sizeof cleared_dict.u.s.y))
3931 : 0 : return FALSE;
3932 : :
3933 : 1 : g_variant_dict_init (dict, dict->u.s.asv);
3934 : : }
3935 : 1 : return is_valid_dict (dict);
3936 : : }
3937 : :
3938 : : /* return_if_invalid_dict (d) is like
3939 : : * g_return_if_fail (ensure_valid_dict (d)), except that
3940 : : * the side effects of ensure_valid_dict are evaluated
3941 : : * regardless of whether G_DISABLE_CHECKS is defined or not. */
3942 : : #define return_if_invalid_dict(d) G_STMT_START { \
3943 : : gboolean valid_dict G_GNUC_UNUSED = ensure_valid_dict (d); \
3944 : : g_return_if_fail (valid_dict); \
3945 : : } G_STMT_END
3946 : :
3947 : : /* return_val_if_invalid_dict (d, val) is like
3948 : : * g_return_val_if_fail (ensure_valid_dict (d), val), except that
3949 : : * the side effects of ensure_valid_dict are evaluated
3950 : : * regardless of whether G_DISABLE_CHECKS is defined or not. */
3951 : : #define return_val_if_invalid_dict(d, val) G_STMT_START { \
3952 : : gboolean valid_dict G_GNUC_UNUSED = ensure_valid_dict (d); \
3953 : : g_return_val_if_fail (valid_dict, val); \
3954 : : } G_STMT_END
3955 : :
3956 : : /**
3957 : : * g_variant_dict_new:
3958 : : * @from_asv: (nullable): the #GVariant with which to initialise the
3959 : : * dictionary
3960 : : *
3961 : : * Allocates and initialises a new #GVariantDict.
3962 : : *
3963 : : * You should call g_variant_dict_unref() on the return value when it
3964 : : * is no longer needed. The memory will not be automatically freed by
3965 : : * any other call.
3966 : : *
3967 : : * In some cases it may be easier to place a #GVariantDict directly on
3968 : : * the stack of the calling function and initialise it with
3969 : : * g_variant_dict_init(). This is particularly useful when you are
3970 : : * using #GVariantDict to construct a #GVariant.
3971 : : *
3972 : : * Returns: (transfer full): a #GVariantDict
3973 : : *
3974 : : * Since: 2.40
3975 : : **/
3976 : : GVariantDict *
3977 : 38 : g_variant_dict_new (GVariant *from_asv)
3978 : : {
3979 : : GVariantDict *dict;
3980 : :
3981 : : /* We actually want to treat the allocation as a `struct heap_dict`, but the
3982 : : * compiler will warn if it’s not at least as big as `struct GVariantDict`. */
3983 : : G_STATIC_ASSERT (sizeof (GVariantDict) >= sizeof (struct heap_dict));
3984 : :
3985 : 38 : dict = g_malloc (sizeof (GVariantDict));
3986 : 38 : g_variant_dict_init (dict, from_asv);
3987 : 38 : GVHD(dict)->magic = GVHD_MAGIC;
3988 : 38 : GVHD(dict)->ref_count = 1;
3989 : :
3990 : 38 : return dict;
3991 : : }
3992 : :
3993 : : /**
3994 : : * g_variant_dict_init: (skip)
3995 : : * @dict: a #GVariantDict
3996 : : * @from_asv: (nullable): the initial value for @dict
3997 : : *
3998 : : * Initialises a #GVariantDict structure.
3999 : : *
4000 : : * If @from_asv is given, it is used to initialise the dictionary.
4001 : : *
4002 : : * This function completely ignores the previous contents of @dict. On
4003 : : * one hand this means that it is valid to pass in completely
4004 : : * uninitialised memory. On the other hand, this means that if you are
4005 : : * initialising over top of an existing #GVariantDict you need to first
4006 : : * call g_variant_dict_clear() in order to avoid leaking memory.
4007 : : *
4008 : : * You must not call g_variant_dict_ref() or g_variant_dict_unref() on a
4009 : : * #GVariantDict that was initialised with this function. If you ever
4010 : : * pass a reference to a #GVariantDict outside of the control of your
4011 : : * own code then you should assume that the person receiving that
4012 : : * reference may try to use reference counting; you should use
4013 : : * g_variant_dict_new() instead of this function.
4014 : : *
4015 : : * Since: 2.40
4016 : : **/
4017 : : void
4018 : 52 : g_variant_dict_init (GVariantDict *dict,
4019 : : GVariant *from_asv)
4020 : : {
4021 : : GVariantIter iter;
4022 : : gchar *key;
4023 : : GVariant *value;
4024 : :
4025 : 52 : GVSD(dict)->values = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);
4026 : 52 : GVSD(dict)->magic = GVSD_MAGIC;
4027 : :
4028 [ + + ]: 52 : if (from_asv)
4029 : : {
4030 : 17 : g_variant_iter_init (&iter, from_asv);
4031 [ + + ]: 33 : while (g_variant_iter_next (&iter, "{sv}", &key, &value))
4032 : 16 : g_hash_table_insert (GVSD(dict)->values, key, value);
4033 : : }
4034 : 52 : }
4035 : :
4036 : : /**
4037 : : * g_variant_dict_lookup:
4038 : : * @dict: a #GVariantDict
4039 : : * @key: the key to look up in the dictionary
4040 : : * @format_string: a GVariant format string
4041 : : * @...: the arguments to unpack the value into
4042 : : *
4043 : : * Looks up a value in a #GVariantDict.
4044 : : *
4045 : : * This function is a wrapper around g_variant_dict_lookup_value() and
4046 : : * g_variant_get(). In the case that %NULL would have been returned,
4047 : : * this function returns %FALSE and does not modify the values of the arguments
4048 : : * passed in to @.... Otherwise, it unpacks the returned
4049 : : * value and returns %TRUE.
4050 : : *
4051 : : * @format_string determines the C types that are used for unpacking the
4052 : : * values and also determines if the values are copied or borrowed, see the
4053 : : * section on [`GVariant` format strings](gvariant-format-strings.html#pointers).
4054 : : *
4055 : : * Returns: %TRUE if a value was unpacked
4056 : : *
4057 : : * Since: 2.40
4058 : : **/
4059 : : gboolean
4060 : 16 : g_variant_dict_lookup (GVariantDict *dict,
4061 : : const gchar *key,
4062 : : const gchar *format_string,
4063 : : ...)
4064 : : {
4065 : : GVariant *value;
4066 : : va_list ap;
4067 : :
4068 [ - + ]: 16 : return_val_if_invalid_dict (dict, FALSE);
4069 : 16 : g_return_val_if_fail (key != NULL, FALSE);
4070 : 16 : g_return_val_if_fail (format_string != NULL, FALSE);
4071 : :
4072 : 16 : value = g_hash_table_lookup (GVSD(dict)->values, key);
4073 : :
4074 [ + + - + ]: 16 : if (value == NULL || !g_variant_check_format_string (value, format_string, FALSE))
4075 : 5 : return FALSE;
4076 : :
4077 : 11 : va_start (ap, format_string);
4078 : 11 : g_variant_get_va (value, format_string, NULL, &ap);
4079 : 11 : va_end (ap);
4080 : :
4081 : 11 : return TRUE;
4082 : : }
4083 : :
4084 : : /**
4085 : : * g_variant_dict_lookup_value:
4086 : : * @dict: a #GVariantDict
4087 : : * @key: the key to look up in the dictionary
4088 : : * @expected_type: (nullable): a #GVariantType, or %NULL
4089 : : *
4090 : : * Looks up a value in a #GVariantDict.
4091 : : *
4092 : : * If @key is not found in @dictionary, %NULL is returned.
4093 : : *
4094 : : * The @expected_type string specifies what type of value is expected.
4095 : : * If the value associated with @key has a different type then %NULL is
4096 : : * returned.
4097 : : *
4098 : : * If the key is found and the value has the correct type, it is
4099 : : * returned. If @expected_type was specified then any non-%NULL return
4100 : : * value will have this type.
4101 : : *
4102 : : * Returns: (transfer full) (nullable): the value of the dictionary key, or %NULL
4103 : : *
4104 : : * Since: 2.40
4105 : : **/
4106 : : GVariant *
4107 : 0 : g_variant_dict_lookup_value (GVariantDict *dict,
4108 : : const gchar *key,
4109 : : const GVariantType *expected_type)
4110 : : {
4111 : : GVariant *result;
4112 : :
4113 [ # # ]: 0 : return_val_if_invalid_dict (dict, NULL);
4114 : 0 : g_return_val_if_fail (key != NULL, NULL);
4115 : :
4116 : 0 : result = g_hash_table_lookup (GVSD(dict)->values, key);
4117 : :
4118 [ # # # # : 0 : if (result && (!expected_type || g_variant_is_of_type (result, expected_type)))
# # ]
4119 : 0 : return g_variant_ref (result);
4120 : :
4121 : 0 : return NULL;
4122 : : }
4123 : :
4124 : : /**
4125 : : * g_variant_dict_contains:
4126 : : * @dict: a #GVariantDict
4127 : : * @key: the key to look up in the dictionary
4128 : : *
4129 : : * Checks if @key exists in @dict.
4130 : : *
4131 : : * Returns: %TRUE if @key is in @dict
4132 : : *
4133 : : * Since: 2.40
4134 : : **/
4135 : : gboolean
4136 : 9 : g_variant_dict_contains (GVariantDict *dict,
4137 : : const gchar *key)
4138 : : {
4139 [ - + ]: 9 : return_val_if_invalid_dict (dict, FALSE);
4140 : 9 : g_return_val_if_fail (key != NULL, FALSE);
4141 : :
4142 : 9 : return g_hash_table_contains (GVSD(dict)->values, key);
4143 : : }
4144 : :
4145 : : /**
4146 : : * g_variant_dict_insert:
4147 : : * @dict: a #GVariantDict
4148 : : * @key: the key to insert a value for
4149 : : * @format_string: a #GVariant varargs format string
4150 : : * @...: arguments, as per @format_string
4151 : : *
4152 : : * Inserts a value into a #GVariantDict.
4153 : : *
4154 : : * This call is a convenience wrapper that is exactly equivalent to
4155 : : * calling g_variant_new() followed by g_variant_dict_insert_value().
4156 : : *
4157 : : * Since: 2.40
4158 : : **/
4159 : : void
4160 : 0 : g_variant_dict_insert (GVariantDict *dict,
4161 : : const gchar *key,
4162 : : const gchar *format_string,
4163 : : ...)
4164 : : {
4165 : : va_list ap;
4166 : :
4167 [ # # ]: 0 : return_if_invalid_dict (dict);
4168 : 0 : g_return_if_fail (key != NULL);
4169 : 0 : g_return_if_fail (format_string != NULL);
4170 : :
4171 : 0 : va_start (ap, format_string);
4172 : 0 : g_variant_dict_insert_value (dict, key, g_variant_new_va (format_string, NULL, &ap));
4173 : 0 : va_end (ap);
4174 : : }
4175 : :
4176 : : /**
4177 : : * g_variant_dict_insert_value:
4178 : : * @dict: a #GVariantDict
4179 : : * @key: the key to insert a value for
4180 : : * @value: the value to insert
4181 : : *
4182 : : * Inserts (or replaces) a key in a #GVariantDict.
4183 : : *
4184 : : * @value is consumed if it is floating.
4185 : : *
4186 : : * Since: 2.40
4187 : : **/
4188 : : void
4189 : 5 : g_variant_dict_insert_value (GVariantDict *dict,
4190 : : const gchar *key,
4191 : : GVariant *value)
4192 : : {
4193 [ - + ]: 5 : return_if_invalid_dict (dict);
4194 : 5 : g_return_if_fail (key != NULL);
4195 : 5 : g_return_if_fail (value != NULL);
4196 : :
4197 : 10 : g_hash_table_insert (GVSD(dict)->values, g_strdup (key), g_variant_ref_sink (value));
4198 : : }
4199 : :
4200 : : /**
4201 : : * g_variant_dict_remove:
4202 : : * @dict: a #GVariantDict
4203 : : * @key: the key to remove
4204 : : *
4205 : : * Removes a key and its associated value from a #GVariantDict.
4206 : : *
4207 : : * Returns: %TRUE if the key was found and removed
4208 : : *
4209 : : * Since: 2.40
4210 : : **/
4211 : : gboolean
4212 : 0 : g_variant_dict_remove (GVariantDict *dict,
4213 : : const gchar *key)
4214 : : {
4215 [ # # ]: 0 : return_val_if_invalid_dict (dict, FALSE);
4216 : 0 : g_return_val_if_fail (key != NULL, FALSE);
4217 : :
4218 : 0 : return g_hash_table_remove (GVSD(dict)->values, key);
4219 : : }
4220 : :
4221 : : /**
4222 : : * g_variant_dict_clear:
4223 : : * @dict: a #GVariantDict
4224 : : *
4225 : : * Releases all memory associated with a #GVariantDict without freeing
4226 : : * the #GVariantDict structure itself.
4227 : : *
4228 : : * It typically only makes sense to do this on a stack-allocated
4229 : : * #GVariantDict if you want to abort building the value part-way
4230 : : * through. This function need not be called if you call
4231 : : * g_variant_dict_end() and it also doesn't need to be called on dicts
4232 : : * allocated with g_variant_dict_new (see g_variant_dict_unref() for
4233 : : * that).
4234 : : *
4235 : : * It is valid to call this function on either an initialised
4236 : : * #GVariantDict or one that was previously cleared by an earlier call
4237 : : * to g_variant_dict_clear() but it is not valid to call this function
4238 : : * on uninitialised memory.
4239 : : *
4240 : : * Since: 2.40
4241 : : **/
4242 : : void
4243 : 58 : g_variant_dict_clear (GVariantDict *dict)
4244 : : {
4245 [ + + ]: 58 : if (GVSD(dict)->magic == 0)
4246 : : /* all-zeros case */
4247 : 6 : return;
4248 : :
4249 [ - + ]: 52 : return_if_invalid_dict (dict);
4250 : :
4251 : 52 : g_hash_table_unref (GVSD(dict)->values);
4252 : 52 : GVSD(dict)->values = NULL;
4253 : :
4254 : 52 : GVSD(dict)->magic = 0;
4255 : : }
4256 : :
4257 : : /**
4258 : : * g_variant_dict_end:
4259 : : * @dict: a #GVariantDict
4260 : : *
4261 : : * Returns the current value of @dict as a #GVariant of type
4262 : : * %G_VARIANT_TYPE_VARDICT, clearing it in the process.
4263 : : *
4264 : : * It is not permissible to use @dict in any way after this call except
4265 : : * for reference counting operations (in the case of a heap-allocated
4266 : : * #GVariantDict) or by reinitialising it with g_variant_dict_init() (in
4267 : : * the case of stack-allocated).
4268 : : *
4269 : : * Returns: (transfer none): a new, floating, #GVariant
4270 : : *
4271 : : * Since: 2.40
4272 : : **/
4273 : : GVariant *
4274 : 7 : g_variant_dict_end (GVariantDict *dict)
4275 : : {
4276 : : GVariantBuilder builder;
4277 : : GHashTableIter iter;
4278 : : gpointer key, value;
4279 : :
4280 [ - + ]: 7 : return_val_if_invalid_dict (dict, NULL);
4281 : :
4282 : 7 : g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
4283 : :
4284 : 7 : g_hash_table_iter_init (&iter, GVSD(dict)->values);
4285 [ + + ]: 12 : while (g_hash_table_iter_next (&iter, &key, &value))
4286 : 5 : g_variant_builder_add (&builder, "{sv}", (const gchar *) key, (GVariant *) value);
4287 : :
4288 : 7 : g_variant_dict_clear (dict);
4289 : :
4290 : 7 : return g_variant_builder_end (&builder);
4291 : : }
4292 : :
4293 : : /**
4294 : : * g_variant_dict_ref:
4295 : : * @dict: a heap-allocated #GVariantDict
4296 : : *
4297 : : * Increases the reference count on @dict.
4298 : : *
4299 : : * Don't call this on stack-allocated #GVariantDict instances or bad
4300 : : * things will happen.
4301 : : *
4302 : : * Returns: (transfer full): a new reference to @dict
4303 : : *
4304 : : * Since: 2.40
4305 : : **/
4306 : : GVariantDict *
4307 : 34 : g_variant_dict_ref (GVariantDict *dict)
4308 : : {
4309 : 34 : g_return_val_if_fail (is_valid_heap_dict (dict), NULL);
4310 : :
4311 : 34 : GVHD(dict)->ref_count++;
4312 : :
4313 : 34 : return dict;
4314 : : }
4315 : :
4316 : : /**
4317 : : * g_variant_dict_unref:
4318 : : * @dict: (transfer full): a heap-allocated #GVariantDict
4319 : : *
4320 : : * Decreases the reference count on @dict.
4321 : : *
4322 : : * In the event that there are no more references, releases all memory
4323 : : * associated with the #GVariantDict.
4324 : : *
4325 : : * Don't call this on stack-allocated #GVariantDict instances or bad
4326 : : * things will happen.
4327 : : *
4328 : : * Since: 2.40
4329 : : **/
4330 : : void
4331 : 72 : g_variant_dict_unref (GVariantDict *dict)
4332 : : {
4333 : 72 : g_return_if_fail (is_valid_heap_dict (dict));
4334 : :
4335 [ + + ]: 72 : if (--GVHD(dict)->ref_count == 0)
4336 : : {
4337 : 38 : g_variant_dict_clear (dict);
4338 : 38 : g_free_sized (dict, sizeof (GVariantDict));
4339 : : }
4340 : : }
4341 : :
4342 : :
4343 : : /* Format strings {{{1 */
4344 : : /*< private >
4345 : : * g_variant_format_string_scan:
4346 : : * @string: a string that may be prefixed with a format string
4347 : : * @limit: (nullable) (default NULL): a pointer to the end of @string,
4348 : : * or %NULL
4349 : : * @endptr: (nullable) (default NULL): location to store the end pointer,
4350 : : * or %NULL
4351 : : *
4352 : : * Checks the string pointed to by @string for starting with a properly
4353 : : * formed #GVariant varargs format string. If no valid format string is
4354 : : * found then %FALSE is returned.
4355 : : *
4356 : : * If @string does start with a valid format string then %TRUE is
4357 : : * returned. If @endptr is non-%NULL then it is updated to point to the
4358 : : * first character after the format string.
4359 : : *
4360 : : * If @limit is non-%NULL then @limit (and any character after it) will
4361 : : * not be accessed and the effect is otherwise equivalent to if the
4362 : : * character at @limit were nul.
4363 : : *
4364 : : * See the section on [GVariant format strings](gvariant-format-strings.html).
4365 : : *
4366 : : * Returns: %TRUE if there was a valid format string
4367 : : *
4368 : : * Since: 2.24
4369 : : */
4370 : : gboolean
4371 : 875649 : g_variant_format_string_scan (const gchar *string,
4372 : : const gchar *limit,
4373 : : const gchar **endptr)
4374 : : {
4375 : : #define next_char() (string == limit ? '\0' : *(string++))
4376 : : #define peek_char() (string == limit ? '\0' : *string)
4377 : : char c;
4378 : :
4379 [ + - + + : 875649 : switch (next_char())
+ + + + +
+ ]
4380 : : {
4381 : 387605 : case 'b': case 'y': case 'n': case 'q': case 'i': case 'u':
4382 : : case 'x': case 't': case 'h': case 'd': case 's': case 'o':
4383 : : case 'g': case 'v': case '*': case '?': case 'r':
4384 : 387605 : break;
4385 : :
4386 : 351 : case 'm':
4387 : 351 : return g_variant_format_string_scan (string, limit, endptr);
4388 : :
4389 : 5412 : case 'a':
4390 : : case '@':
4391 : 5412 : return g_variant_type_string_scan (string, limit, endptr);
4392 : :
4393 : 60518 : case '(':
4394 [ - + + + ]: 189282 : while (peek_char() != ')')
4395 [ + + ]: 128768 : if (!g_variant_format_string_scan (string, limit, &string))
4396 : 4 : return FALSE;
4397 : :
4398 [ + - ]: 60514 : next_char(); /* consume ')' */
4399 : 60514 : break;
4400 : :
4401 : 332317 : case '{':
4402 [ + - ]: 332317 : c = next_char();
4403 : :
4404 [ + + ]: 332317 : if (c == '&')
4405 : : {
4406 [ + - ]: 2347 : c = next_char ();
4407 : :
4408 [ + + + + : 2347 : if (c != 's' && c != 'o' && c != 'g')
+ - ]
4409 : 2 : return FALSE;
4410 : : }
4411 : : else
4412 : : {
4413 [ + + ]: 329970 : if (c == '@')
4414 [ + - ]: 4 : c = next_char ();
4415 : :
4416 : : /* ISO/IEC 9899:1999 (C99) §7.21.5.2:
4417 : : * The terminating null character is considered to be
4418 : : * part of the string.
4419 : : */
4420 [ + - + + ]: 329970 : if (c != '\0' && strchr ("bynqiuxthdsog?", c) == NULL)
4421 : 4 : return FALSE;
4422 : : }
4423 : :
4424 [ + + ]: 332311 : if (!g_variant_format_string_scan (string, limit, &string))
4425 : 2 : return FALSE;
4426 : :
4427 [ + - + + ]: 332309 : if (next_char() != '}')
4428 : 1 : return FALSE;
4429 : :
4430 : 332308 : break;
4431 : :
4432 : 396 : case '^':
4433 [ + - + + ]: 396 : if ((c = next_char()) == 'a')
4434 : : {
4435 [ + - + + ]: 387 : if ((c = next_char()) == '&')
4436 : : {
4437 [ + - + + ]: 206 : if ((c = next_char()) == 'a')
4438 : : {
4439 [ + - + - ]: 11 : if ((c = next_char()) == 'y')
4440 : 11 : break; /* '^a&ay' */
4441 : : }
4442 : :
4443 [ + + + + ]: 195 : else if (c == 's' || c == 'o')
4444 : : break; /* '^a&s', '^a&o' */
4445 : : }
4446 : :
4447 [ + + ]: 181 : else if (c == 'a')
4448 : : {
4449 [ + - + - ]: 38 : if ((c = next_char()) == 'y')
4450 : 38 : break; /* '^aay' */
4451 : : }
4452 : :
4453 [ + + + + ]: 143 : else if (c == 's' || c == 'o')
4454 : : break; /* '^as', '^ao' */
4455 : :
4456 [ + + ]: 57 : else if (c == 'y')
4457 : 56 : break; /* '^ay' */
4458 : : }
4459 [ + + ]: 9 : else if (c == '&')
4460 : : {
4461 [ + - + - ]: 8 : if ((c = next_char()) == 'a')
4462 : : {
4463 [ + - + - ]: 8 : if ((c = next_char()) == 'y')
4464 : 8 : break; /* '^&ay' */
4465 : : }
4466 : : }
4467 : :
4468 : 3 : return FALSE;
4469 : :
4470 : 89046 : case '&':
4471 [ + - ]: 89046 : c = next_char();
4472 : :
4473 [ + + + + : 89046 : if (c != 's' && c != 'o' && c != 'g')
+ + ]
4474 : 1 : return FALSE;
4475 : :
4476 : 89045 : break;
4477 : :
4478 : 4 : default:
4479 : 4 : return FALSE;
4480 : : }
4481 : :
4482 [ + - ]: 869865 : if (endptr != NULL)
4483 : 869865 : *endptr = string;
4484 : :
4485 : : #undef next_char
4486 : : #undef peek_char
4487 : :
4488 : 869865 : return TRUE;
4489 : : }
4490 : :
4491 : : /**
4492 : : * g_variant_check_format_string:
4493 : : * @value: a #GVariant
4494 : : * @format_string: a valid #GVariant format string
4495 : : * @copy_only: %TRUE to ensure the format string makes deep copies
4496 : : *
4497 : : * Checks if calling g_variant_get() with @format_string on @value would
4498 : : * be valid from a type-compatibility standpoint. @format_string is
4499 : : * assumed to be a valid format string (from a syntactic standpoint).
4500 : : *
4501 : : * If @copy_only is %TRUE then this function additionally checks that it
4502 : : * would be safe to call g_variant_unref() on @value immediately after
4503 : : * the call to g_variant_get() without invalidating the result. This is
4504 : : * only possible if deep copies are made (ie: there are no pointers to
4505 : : * the data inside of the soon-to-be-freed #GVariant instance). If this
4506 : : * check fails then a g_critical() is printed and %FALSE is returned.
4507 : : *
4508 : : * This function is meant to be used by functions that wish to provide
4509 : : * varargs accessors to #GVariant values of uncertain values (eg:
4510 : : * g_variant_lookup() or g_menu_model_get_item_attribute()).
4511 : : *
4512 : : * Returns: %TRUE if @format_string is safe to use
4513 : : *
4514 : : * Since: 2.34
4515 : : */
4516 : : gboolean
4517 : 35 : g_variant_check_format_string (GVariant *value,
4518 : : const gchar *format_string,
4519 : : gboolean copy_only)
4520 : : {
4521 : 35 : const gchar *original_format = format_string;
4522 : : const gchar *type_string;
4523 : :
4524 : : /* Interesting factoid: assuming a format string is valid, it can be
4525 : : * converted to a type string by removing all '@' '&' and '^'
4526 : : * characters.
4527 : : *
4528 : : * Instead of doing that, we can just skip those characters when
4529 : : * comparing it to the type string of @value.
4530 : : *
4531 : : * For the copy-only case we can just drop the '&' from the list of
4532 : : * characters to skip over. A '&' will never appear in a type string
4533 : : * so we know that it won't be possible to return %TRUE if it is in a
4534 : : * format string.
4535 : : */
4536 : 35 : type_string = g_variant_get_type_string (value);
4537 : :
4538 [ + + - + ]: 142 : while (*type_string || *format_string)
4539 : : {
4540 : 115 : gchar format = *format_string++;
4541 : :
4542 [ + + + + : 115 : switch (format)
+ + ]
4543 : : {
4544 : 16 : case '&':
4545 [ + + ]: 16 : if G_UNLIKELY (copy_only)
4546 : : {
4547 : : /* for the love of all that is good, please don't mark this string for translation... */
4548 : 4 : g_critical ("g_variant_check_format_string() is being called by a function with a GVariant varargs "
4549 : : "interface to validate the passed format string for type safety. The passed format "
4550 : : "(%s) contains a '&' character which would result in a pointer being returned to the "
4551 : : "data inside of a GVariant instance that may no longer exist by the time the function "
4552 : : "returns. Modify your code to use a format string without '&'.", original_format);
4553 : 4 : return FALSE;
4554 : : }
4555 : :
4556 : : G_GNUC_FALLTHROUGH;
4557 : : case '^':
4558 : : case '@':
4559 : : /* ignore these 2 (or 3) */
4560 : 20 : continue;
4561 : :
4562 : 2 : case '?':
4563 : : /* attempt to consume one of 'bynqiuxthdsog' */
4564 : : {
4565 : 2 : char s = *type_string++;
4566 : :
4567 [ + - - + ]: 2 : if (s == '\0' || strchr ("bynqiuxthdsog", s) == NULL)
4568 : 0 : return FALSE;
4569 : : }
4570 : 2 : continue;
4571 : :
4572 : 1 : case 'r':
4573 : : /* ensure it's a tuple */
4574 [ - + ]: 1 : if (*type_string != '(')
4575 : 0 : return FALSE;
4576 : :
4577 : : G_GNUC_FALLTHROUGH;
4578 : : case '*':
4579 : : /* consume a full type string for the '*' or 'r' */
4580 [ - + ]: 7 : if (!g_variant_type_string_scan (type_string, NULL, &type_string))
4581 : 0 : return FALSE;
4582 : :
4583 : 7 : continue;
4584 : :
4585 : 82 : default:
4586 : : /* attempt to consume exactly one character equal to the format */
4587 [ + + ]: 82 : if (format != *type_string++)
4588 : 4 : return FALSE;
4589 : : }
4590 : : }
4591 : :
4592 : 27 : return TRUE;
4593 : : }
4594 : :
4595 : : /*< private >
4596 : : * g_variant_format_string_scan_type:
4597 : : * @string: a string that may be prefixed with a format string
4598 : : * @limit: (nullable) (default NULL): a pointer to the end of @string,
4599 : : * or %NULL
4600 : : * @endptr: (nullable) (default NULL): location to store the end pointer,
4601 : : * or %NULL
4602 : : *
4603 : : * If @string starts with a valid format string then this function will
4604 : : * return the type that the format string corresponds to. Otherwise
4605 : : * this function returns %NULL.
4606 : : *
4607 : : * Use g_variant_type_free() to free the return value when you no longer
4608 : : * need it.
4609 : : *
4610 : : * This function is otherwise exactly like
4611 : : * g_variant_format_string_scan().
4612 : : *
4613 : : * Returns: (nullable): a #GVariantType if there was a valid format string
4614 : : *
4615 : : * Since: 2.24
4616 : : */
4617 : : GVariantType *
4618 : 397685 : g_variant_format_string_scan_type (const gchar *string,
4619 : : const gchar *limit,
4620 : : const gchar **endptr)
4621 : : {
4622 : : const gchar *my_end;
4623 : : gchar *dest;
4624 : : gchar *new;
4625 : :
4626 [ + + ]: 397685 : if (endptr == NULL)
4627 : 87 : endptr = &my_end;
4628 : :
4629 [ + + ]: 397685 : if (!g_variant_format_string_scan (string, limit, endptr))
4630 : 3 : return NULL;
4631 : :
4632 : 397682 : dest = new = g_malloc (*endptr - string + 1);
4633 [ + + ]: 2087289 : while (string != *endptr)
4634 : : {
4635 [ + + + + : 1689607 : if (*string != '@' && *string != '&' && *string != '^')
+ + ]
4636 : 1608988 : *dest++ = *string;
4637 : 1689607 : string++;
4638 : : }
4639 : 397682 : *dest = '\0';
4640 : :
4641 : 397682 : return (GVariantType *) G_VARIANT_TYPE (new);
4642 : : }
4643 : :
4644 : : static gboolean
4645 : 397594 : valid_format_string (const gchar *format_string,
4646 : : gboolean single,
4647 : : GVariant *value)
4648 : : {
4649 : : const gchar *endptr;
4650 : : GVariantType *type;
4651 : :
4652 : 397594 : type = g_variant_format_string_scan_type (format_string, NULL, &endptr);
4653 : :
4654 [ + + + + : 397594 : if G_UNLIKELY (type == NULL || (single && *endptr != '\0'))
- + ]
4655 : : {
4656 [ + + ]: 2 : if (single)
4657 : 1 : g_critical ("'%s' is not a valid GVariant format string",
4658 : : format_string);
4659 : : else
4660 : 1 : g_critical ("'%s' does not have a valid GVariant format "
4661 : : "string as a prefix", format_string);
4662 : :
4663 [ - + ]: 2 : if (type != NULL)
4664 : 0 : g_variant_type_free (type);
4665 : :
4666 : 2 : return FALSE;
4667 : : }
4668 : :
4669 [ + + + + ]: 397592 : if G_UNLIKELY (value && !g_variant_is_of_type (value, type))
4670 : : {
4671 : : gchar *fragment;
4672 : : gchar *typestr;
4673 : :
4674 : 2 : fragment = g_strndup (format_string, endptr - format_string);
4675 : 2 : typestr = g_variant_type_dup_string (type);
4676 : :
4677 : 2 : g_critical ("the GVariant format string '%s' has a type of "
4678 : : "'%s' but the given value has a type of '%s'",
4679 : : fragment, typestr, g_variant_get_type_string (value));
4680 : :
4681 : 2 : g_variant_type_free (type);
4682 : 2 : g_free (fragment);
4683 : 2 : g_free (typestr);
4684 : :
4685 : 2 : return FALSE;
4686 : : }
4687 : :
4688 : 397590 : g_variant_type_free (type);
4689 : :
4690 : 397590 : return TRUE;
4691 : : }
4692 : :
4693 : : /* Variable Arguments {{{1 */
4694 : : /* We consider 2 main classes of format strings:
4695 : : *
4696 : : * - recursive format strings
4697 : : * these are ones that result in recursion and the collection of
4698 : : * possibly more than one argument. Maybe types, tuples,
4699 : : * dictionary entries.
4700 : : *
4701 : : * - leaf format string
4702 : : * these result in the collection of a single argument.
4703 : : *
4704 : : * Leaf format strings are further subdivided into two categories:
4705 : : *
4706 : : * - single non-null pointer ("nnp")
4707 : : * these either collect or return a single non-null pointer.
4708 : : *
4709 : : * - other
4710 : : * these collect or return something else (bool, number, etc).
4711 : : *
4712 : : * Based on the above, the varargs handling code is split into 4 main parts:
4713 : : *
4714 : : * - nnp handling code
4715 : : * - leaf handling code (which may invoke nnp code)
4716 : : * - generic handling code (may be recursive, may invoke leaf code)
4717 : : * - user-facing API (which invokes the generic code)
4718 : : *
4719 : : * Each section implements some of the following functions:
4720 : : *
4721 : : * - skip:
4722 : : * collect the arguments for the format string as if
4723 : : * g_variant_new() had been called, but do nothing with them. used
4724 : : * for skipping over arguments when constructing a Nothing maybe
4725 : : * type.
4726 : : *
4727 : : * - new:
4728 : : * create a GVariant *
4729 : : *
4730 : : * - get:
4731 : : * unpack a GVariant *
4732 : : *
4733 : : * - free (nnp only):
4734 : : * free a previously allocated item
4735 : : */
4736 : :
4737 : : static gboolean
4738 : 711429 : g_variant_format_string_is_leaf (const gchar *str)
4739 : : {
4740 [ + + + + : 711429 : return str[0] != 'm' && str[0] != '(' && str[0] != '{';
+ + ]
4741 : : }
4742 : :
4743 : : static gboolean
4744 : 466001 : g_variant_format_string_is_nnp (const gchar *str)
4745 : : {
4746 [ + + + + : 464915 : return str[0] == 'a' || str[0] == 's' || str[0] == 'o' || str[0] == 'g' ||
+ + ]
4747 [ + + + + : 450510 : str[0] == '^' || str[0] == '@' || str[0] == '*' || str[0] == '?' ||
+ + + + ]
4748 [ + + + + : 930916 : str[0] == 'r' || str[0] == 'v' || str[0] == '&';
+ + + + ]
4749 : : }
4750 : :
4751 : : /* Single non-null pointer ("nnp") {{{2 */
4752 : : static void
4753 : 5823 : g_variant_valist_free_nnp (const gchar *str,
4754 : : gpointer ptr)
4755 : : {
4756 [ + + + + : 5823 : switch (*str)
+ - ]
4757 : : {
4758 : 3 : case 'a':
4759 : 3 : g_variant_iter_free (ptr);
4760 : 3 : break;
4761 : :
4762 : 18 : case '^':
4763 [ + - - + : 18 : if (g_str_has_suffix (str, "y"))
+ - + + ]
4764 : : {
4765 [ + + ]: 12 : if (str[2] != 'a') /* '^a&ay', '^ay' */
4766 : 6 : g_free (ptr);
4767 [ + + ]: 6 : else if (str[1] == 'a') /* '^aay' */
4768 : 3 : g_strfreev (ptr);
4769 : 12 : break; /* '^&ay' */
4770 : : }
4771 [ + + ]: 6 : else if (str[2] != '&') /* '^as', '^ao' */
4772 : 3 : g_strfreev (ptr);
4773 : : else /* '^a&s', '^a&o' */
4774 : 3 : g_free (ptr);
4775 : 6 : break;
4776 : :
4777 : 124 : case 's':
4778 : : case 'o':
4779 : : case 'g':
4780 : 124 : g_free (ptr);
4781 : 124 : break;
4782 : :
4783 : 3889 : case '@':
4784 : : case '*':
4785 : : case '?':
4786 : : case 'v':
4787 : 3889 : g_variant_unref (ptr);
4788 : 3889 : break;
4789 : :
4790 : 1789 : case '&':
4791 : 1789 : break;
4792 : :
4793 : 0 : default:
4794 : : g_assert_not_reached ();
4795 : : }
4796 : 5823 : }
4797 : :
4798 : : static gchar
4799 : 220 : g_variant_scan_convenience (const gchar **str,
4800 : : gboolean *constant,
4801 : : guint *arrays)
4802 : : {
4803 : 220 : *constant = FALSE;
4804 : 220 : *arrays = 0;
4805 : :
4806 : : for (;;)
4807 : 364 : {
4808 : 584 : char c = *(*str)++;
4809 : :
4810 [ + + ]: 584 : if (c == '&')
4811 : 113 : *constant = TRUE;
4812 : :
4813 [ + + ]: 471 : else if (c == 'a')
4814 : 251 : (*arrays)++;
4815 : :
4816 : : else
4817 : 220 : return c;
4818 : : }
4819 : : }
4820 : :
4821 : : static GVariant *
4822 : 78518 : g_variant_valist_new_nnp (const gchar **str,
4823 : : gpointer ptr)
4824 : : {
4825 [ + + ]: 78518 : if (**str == '&')
4826 : 8 : (*str)++;
4827 : :
4828 [ + + + + : 78518 : switch (*(*str)++)
+ + + + +
+ - ]
4829 : : {
4830 : 372 : case 'a':
4831 [ + + ]: 372 : if (ptr != NULL)
4832 : : {
4833 : : const GVariantType *type;
4834 : : GVariant *value;
4835 : :
4836 : 319 : value = g_variant_builder_end (ptr);
4837 : 319 : type = g_variant_get_type (value);
4838 : :
4839 [ - + ]: 319 : if G_UNLIKELY (!g_variant_type_is_array (type))
4840 : 0 : g_error ("g_variant_new: expected array GVariantBuilder but "
4841 : : "the built value has type '%s'",
4842 : : g_variant_get_type_string (value));
4843 : :
4844 : 319 : type = g_variant_type_element (type);
4845 : :
4846 [ - + ]: 319 : if G_UNLIKELY (!g_variant_type_is_subtype_of (type, (GVariantType *) *str))
4847 : : {
4848 : 0 : gchar *type_string = g_variant_type_dup_string ((GVariantType *) *str);
4849 : 0 : g_error ("g_variant_new: expected GVariantBuilder array element "
4850 : : "type '%s' but the built value has element type '%s'",
4851 : : type_string, g_variant_get_type_string (value) + 1);
4852 : : g_free (type_string);
4853 : : }
4854 : :
4855 : 319 : g_variant_type_string_scan (*str, NULL, str);
4856 : :
4857 : 319 : return value;
4858 : : }
4859 : : else
4860 : :
4861 : : /* special case: NULL pointer for empty array */
4862 : : {
4863 : 53 : const GVariantType *type = (GVariantType *) *str;
4864 : :
4865 : 53 : g_variant_type_string_scan (*str, NULL, str);
4866 : :
4867 [ - + ]: 53 : if G_UNLIKELY (!g_variant_type_is_definite (type))
4868 : 0 : g_error ("g_variant_new: NULL pointer given with indefinite "
4869 : : "array type; unable to determine which type of empty "
4870 : : "array to construct.");
4871 : :
4872 : 53 : return g_variant_new_array (type, NULL, 0);
4873 : : }
4874 : :
4875 : 12176 : case 's':
4876 : : {
4877 : : GVariant *value;
4878 : :
4879 : 12176 : value = g_variant_new_string (ptr);
4880 : :
4881 [ - + ]: 12176 : if (value == NULL)
4882 : 0 : value = g_variant_new_string ("[Invalid UTF-8]");
4883 : :
4884 : 12176 : return value;
4885 : : }
4886 : :
4887 : 103 : case 'o':
4888 : 103 : return g_variant_new_object_path (ptr);
4889 : :
4890 : 22 : case 'g':
4891 : 22 : return g_variant_new_signature (ptr);
4892 : :
4893 : 78 : case '^':
4894 : : {
4895 : : gboolean constant;
4896 : : guint arrays;
4897 : : gchar type;
4898 : :
4899 : 78 : type = g_variant_scan_convenience (str, &constant, &arrays);
4900 : :
4901 [ + + ]: 78 : if (type == 's')
4902 : 29 : return g_variant_new_strv (ptr, -1);
4903 : :
4904 [ + + ]: 49 : if (type == 'o')
4905 : 8 : return g_variant_new_objv (ptr, -1);
4906 : :
4907 [ + + ]: 41 : if (arrays > 1)
4908 : 16 : return g_variant_new_bytestring_array (ptr, -1);
4909 : :
4910 : 25 : return g_variant_new_bytestring (ptr);
4911 : : }
4912 : :
4913 : 186 : case '@':
4914 [ - + ]: 186 : if G_UNLIKELY (!g_variant_is_of_type (ptr, (GVariantType *) *str))
4915 : : {
4916 : 0 : gchar *type_string = g_variant_type_dup_string ((GVariantType *) *str);
4917 : 0 : g_error ("g_variant_new: expected GVariant of type '%s' but "
4918 : : "received value has type '%s'",
4919 : : type_string, g_variant_get_type_string (ptr));
4920 : : g_free (type_string);
4921 : : }
4922 : :
4923 : 186 : g_variant_type_string_scan (*str, NULL, str);
4924 : :
4925 : 186 : return ptr;
4926 : :
4927 : 7 : case '*':
4928 : 7 : return ptr;
4929 : :
4930 : 1 : case '?':
4931 [ - + ]: 1 : if G_UNLIKELY (!g_variant_type_is_basic (g_variant_get_type (ptr)))
4932 : 0 : g_error ("g_variant_new: format string '?' expects basic-typed "
4933 : : "GVariant, but received value has type '%s'",
4934 : : g_variant_get_type_string (ptr));
4935 : :
4936 : 1 : return ptr;
4937 : :
4938 : 1 : case 'r':
4939 [ - + ]: 1 : if G_UNLIKELY (!g_variant_type_is_tuple (g_variant_get_type (ptr)))
4940 : 0 : g_error ("g_variant_new: format string 'r' expects tuple-typed "
4941 : : "GVariant, but received value has type '%s'",
4942 : : g_variant_get_type_string (ptr));
4943 : :
4944 : 1 : return ptr;
4945 : :
4946 : 65572 : case 'v':
4947 : 65572 : return g_variant_new_variant (ptr);
4948 : :
4949 : 0 : default:
4950 : : g_assert_not_reached ();
4951 : : }
4952 : : }
4953 : :
4954 : : static gpointer
4955 : 168729 : g_variant_valist_get_nnp (const gchar **str,
4956 : : GVariant *value)
4957 : : {
4958 [ + + + + : 168729 : switch (*(*str)++)
+ + + - ]
4959 : : {
4960 : 710 : case 'a':
4961 : 710 : g_variant_type_string_scan (*str, NULL, str);
4962 : 710 : return g_variant_iter_new (value);
4963 : :
4964 : 28351 : case '&':
4965 : 28351 : (*str)++;
4966 : 28351 : return (gchar *) g_variant_get_string (value, NULL);
4967 : :
4968 : 2106 : case 's':
4969 : : case 'o':
4970 : : case 'g':
4971 : 2106 : return g_variant_dup_string (value, NULL);
4972 : :
4973 : 142 : case '^':
4974 : : {
4975 : : gboolean constant;
4976 : : guint arrays;
4977 : : gchar type;
4978 : :
4979 : 142 : type = g_variant_scan_convenience (str, &constant, &arrays);
4980 : :
4981 [ + + ]: 142 : if (type == 's')
4982 : : {
4983 [ + + ]: 104 : if (constant)
4984 : 96 : return g_variant_get_strv (value, NULL);
4985 : : else
4986 : 8 : return g_variant_dup_strv (value, NULL);
4987 : : }
4988 : :
4989 [ + + ]: 38 : else if (type == 'o')
4990 : : {
4991 [ + + ]: 5 : if (constant)
4992 : 1 : return g_variant_get_objv (value, NULL);
4993 : : else
4994 : 4 : return g_variant_dup_objv (value, NULL);
4995 : : }
4996 : :
4997 [ + + ]: 33 : else if (arrays > 1)
4998 : : {
4999 [ + + ]: 15 : if (constant)
5000 : 6 : return g_variant_get_bytestring_array (value, NULL);
5001 : : else
5002 : 9 : return g_variant_dup_bytestring_array (value, NULL);
5003 : : }
5004 : :
5005 : : else
5006 : : {
5007 [ + + ]: 18 : if (constant)
5008 : 5 : return (gchar *) g_variant_get_bytestring (value);
5009 : : else
5010 : 13 : return g_variant_dup_bytestring (value, NULL);
5011 : : }
5012 : : }
5013 : :
5014 : 2412 : case '@':
5015 : 2412 : g_variant_type_string_scan (*str, NULL, str);
5016 : : G_GNUC_FALLTHROUGH;
5017 : :
5018 : 2588 : case '*':
5019 : : case '?':
5020 : : case 'r':
5021 : 2588 : return g_variant_ref (value);
5022 : :
5023 : 134832 : case 'v':
5024 : 134832 : return g_variant_get_variant (value);
5025 : :
5026 : 0 : default:
5027 : : g_assert_not_reached ();
5028 : : }
5029 : : }
5030 : :
5031 : : /* Leaves {{{2 */
5032 : : static void
5033 : 64 : g_variant_valist_skip_leaf (const gchar **str,
5034 : : va_list *app)
5035 : : {
5036 [ + + ]: 64 : if (g_variant_format_string_is_nnp (*str))
5037 : : {
5038 : 1 : g_variant_format_string_scan (*str, NULL, str);
5039 : 1 : va_arg (*app, gpointer);
5040 : 1 : return;
5041 : : }
5042 : :
5043 [ + + + - ]: 63 : switch (*(*str)++)
5044 : : {
5045 : 60 : case 'b':
5046 : : case 'y':
5047 : : case 'n':
5048 : : case 'q':
5049 : : case 'i':
5050 : : case 'u':
5051 : : case 'h':
5052 : 60 : va_arg (*app, int);
5053 : 60 : return;
5054 : :
5055 : 2 : case 'x':
5056 : : case 't':
5057 : 2 : va_arg (*app, guint64);
5058 : 2 : return;
5059 : :
5060 : 1 : case 'd':
5061 : 1 : va_arg (*app, gdouble);
5062 : 1 : return;
5063 : :
5064 : 0 : default:
5065 : : g_assert_not_reached ();
5066 : : }
5067 : : }
5068 : :
5069 : : static GVariant *
5070 : 147952 : g_variant_valist_new_leaf (const gchar **str,
5071 : : va_list *app)
5072 : : {
5073 [ + + ]: 147952 : if (g_variant_format_string_is_nnp (*str))
5074 : 78516 : return g_variant_valist_new_nnp (str, va_arg (*app, gpointer));
5075 : :
5076 [ + + + + : 69436 : switch (*(*str)++)
+ + + + +
+ - ]
5077 : : {
5078 : 47 : case 'b':
5079 : 47 : return g_variant_new_boolean (va_arg (*app, gboolean));
5080 : :
5081 : 62362 : case 'y':
5082 : 62362 : return g_variant_new_byte (va_arg (*app, guint));
5083 : :
5084 : 13 : case 'n':
5085 : 13 : return g_variant_new_int16 (va_arg (*app, gint));
5086 : :
5087 : 17 : case 'q':
5088 : 17 : return g_variant_new_uint16 (va_arg (*app, guint));
5089 : :
5090 : 206 : case 'i':
5091 : 206 : return g_variant_new_int32 (va_arg (*app, gint));
5092 : :
5093 : 6323 : case 'u':
5094 : 6323 : return g_variant_new_uint32 (va_arg (*app, guint));
5095 : :
5096 : 425 : case 'x':
5097 : 425 : return g_variant_new_int64 (va_arg (*app, gint64));
5098 : :
5099 : 13 : case 't':
5100 : 13 : return g_variant_new_uint64 (va_arg (*app, guint64));
5101 : :
5102 : 9 : case 'h':
5103 : 9 : return g_variant_new_handle (va_arg (*app, gint));
5104 : :
5105 : 21 : case 'd':
5106 : 21 : return g_variant_new_double (va_arg (*app, gdouble));
5107 : :
5108 : 0 : default:
5109 : : g_assert_not_reached ();
5110 : : }
5111 : : }
5112 : :
5113 : : /* The code below assumes this */
5114 : : G_STATIC_ASSERT (sizeof (gboolean) == sizeof (guint32));
5115 : : G_STATIC_ASSERT (sizeof (gdouble) == sizeof (guint64));
5116 : :
5117 : : static void
5118 : 329918 : g_variant_valist_get_leaf (const gchar **str,
5119 : : GVariant *value,
5120 : : gboolean free,
5121 : : va_list *app)
5122 : : {
5123 : 329918 : gpointer ptr = va_arg (*app, gpointer);
5124 : :
5125 [ + + ]: 329918 : if (ptr == NULL)
5126 : : {
5127 : 12357 : g_variant_format_string_scan (*str, NULL, str);
5128 : 12357 : return;
5129 : : }
5130 : :
5131 [ + + ]: 317561 : if (g_variant_format_string_is_nnp (*str))
5132 : : {
5133 : 172878 : gpointer *nnp = (gpointer *) ptr;
5134 : :
5135 [ + + + - ]: 172878 : if (free && *nnp != NULL)
5136 : 5823 : g_variant_valist_free_nnp (*str, *nnp);
5137 : :
5138 : 172878 : *nnp = NULL;
5139 : :
5140 [ + + ]: 172878 : if (value != NULL)
5141 : 168729 : *nnp = g_variant_valist_get_nnp (str, value);
5142 : : else
5143 : 4149 : g_variant_format_string_scan (*str, NULL, str);
5144 : :
5145 : 172878 : return;
5146 : : }
5147 : :
5148 [ + + ]: 144683 : if (value != NULL)
5149 : : {
5150 [ + + + + : 142771 : switch (*(*str)++)
+ + + + +
+ - ]
5151 : : {
5152 : 24 : case 'b':
5153 : 24 : *(gboolean *) ptr = g_variant_get_boolean (value);
5154 : 24 : return;
5155 : :
5156 : 131982 : case 'y':
5157 : 131982 : *(guint8 *) ptr = g_variant_get_byte (value);
5158 : 131982 : return;
5159 : :
5160 : 9 : case 'n':
5161 : 9 : *(gint16 *) ptr = g_variant_get_int16 (value);
5162 : 9 : return;
5163 : :
5164 : 8 : case 'q':
5165 : 8 : *(guint16 *) ptr = g_variant_get_uint16 (value);
5166 : 8 : return;
5167 : :
5168 : 221 : case 'i':
5169 : 221 : *(gint32 *) ptr = g_variant_get_int32 (value);
5170 : 221 : return;
5171 : :
5172 : 10479 : case 'u':
5173 : 10479 : *(guint32 *) ptr = g_variant_get_uint32 (value);
5174 : 10479 : return;
5175 : :
5176 : 27 : case 'x':
5177 : 27 : *(gint64 *) ptr = g_variant_get_int64 (value);
5178 : 27 : return;
5179 : :
5180 : 8 : case 't':
5181 : 8 : *(guint64 *) ptr = g_variant_get_uint64 (value);
5182 : 8 : return;
5183 : :
5184 : 5 : case 'h':
5185 : 5 : *(gint32 *) ptr = g_variant_get_handle (value);
5186 : 5 : return;
5187 : :
5188 : 8 : case 'd':
5189 : 8 : *(gdouble *) ptr = g_variant_get_double (value);
5190 : 8 : return;
5191 : : }
5192 : : }
5193 : : else
5194 : : {
5195 [ + + + + : 1912 : switch (*(*str)++)
- ]
5196 : : {
5197 : 2 : case 'y':
5198 : 2 : *(guint8 *) ptr = 0;
5199 : 2 : return;
5200 : :
5201 : 4 : case 'n':
5202 : : case 'q':
5203 : 4 : *(guint16 *) ptr = 0;
5204 : 4 : return;
5205 : :
5206 : 1900 : case 'i':
5207 : : case 'u':
5208 : : case 'h':
5209 : : case 'b':
5210 : 1900 : *(guint32 *) ptr = 0;
5211 : 1900 : return;
5212 : :
5213 : 6 : case 'x':
5214 : : case 't':
5215 : : case 'd':
5216 : 6 : *(guint64 *) ptr = 0;
5217 : 6 : return;
5218 : : }
5219 : : }
5220 : :
5221 : : g_assert_not_reached ();
5222 : : }
5223 : :
5224 : : /* Generic (recursive) {{{2 */
5225 : : static void
5226 : 66 : g_variant_valist_skip (const gchar **str,
5227 : : va_list *app)
5228 : : {
5229 [ + + ]: 66 : if (g_variant_format_string_is_leaf (*str))
5230 : 64 : g_variant_valist_skip_leaf (str, app);
5231 : :
5232 [ + + ]: 2 : else if (**str == 'm') /* maybe */
5233 : : {
5234 : 1 : (*str)++;
5235 : :
5236 [ + - ]: 1 : if (!g_variant_format_string_is_nnp (*str))
5237 : 1 : va_arg (*app, gboolean);
5238 : :
5239 : 1 : g_variant_valist_skip (str, app);
5240 : : }
5241 : : else /* tuple, dictionary entry */
5242 : : {
5243 : 1 : g_assert (**str == '(' || **str == '{');
5244 : 1 : (*str)++;
5245 [ + + + - ]: 2 : while (**str != ')' && **str != '}')
5246 : 1 : g_variant_valist_skip (str, app);
5247 : 1 : (*str)++;
5248 : : }
5249 : 66 : }
5250 : :
5251 : : static GVariant *
5252 : 223561 : g_variant_valist_new (const gchar **str,
5253 : : va_list *app)
5254 : : {
5255 [ + + ]: 223561 : if (g_variant_format_string_is_leaf (*str))
5256 : 147952 : return g_variant_valist_new_leaf (str, app);
5257 : :
5258 [ + + ]: 75609 : if (**str == 'm') /* maybe */
5259 : : {
5260 : 133 : GVariantType *type = NULL;
5261 : 133 : GVariant *value = NULL;
5262 : :
5263 : 133 : (*str)++;
5264 : :
5265 [ + + ]: 133 : if (g_variant_format_string_is_nnp (*str))
5266 : : {
5267 : 5 : gpointer nnp = va_arg (*app, gpointer);
5268 : :
5269 [ + + ]: 5 : if (nnp != NULL)
5270 : 2 : value = g_variant_valist_new_nnp (str, nnp);
5271 : : else
5272 : 3 : type = g_variant_format_string_scan_type (*str, NULL, str);
5273 : : }
5274 : : else
5275 : : {
5276 : 128 : gboolean just = va_arg (*app, gboolean);
5277 : :
5278 [ + + ]: 128 : if (just)
5279 : 64 : value = g_variant_valist_new (str, app);
5280 : : else
5281 : : {
5282 : 64 : type = g_variant_format_string_scan_type (*str, NULL, NULL);
5283 : 64 : g_variant_valist_skip (str, app);
5284 : : }
5285 : : }
5286 : :
5287 : 133 : value = g_variant_new_maybe (type, value);
5288 : :
5289 [ + + ]: 133 : if (type != NULL)
5290 : 67 : g_variant_type_free (type);
5291 : :
5292 : 133 : return value;
5293 : : }
5294 : : else /* tuple, dictionary entry */
5295 : : {
5296 : : GVariantBuilder b;
5297 : :
5298 [ + + ]: 75476 : if (**str == '(')
5299 : 9910 : g_variant_builder_init (&b, G_VARIANT_TYPE_TUPLE);
5300 : : else
5301 : : {
5302 : 65566 : g_assert (**str == '{');
5303 : 65566 : g_variant_builder_init (&b, G_VARIANT_TYPE_DICT_ENTRY);
5304 : : }
5305 : :
5306 : 75476 : (*str)++; /* '(' */
5307 [ + + + + ]: 220691 : while (**str != ')' && **str != '}')
5308 : 145215 : g_variant_builder_add_value (&b, g_variant_valist_new (str, app));
5309 : 75476 : (*str)++; /* ')' */
5310 : :
5311 : 75476 : return g_variant_builder_end (&b);
5312 : : }
5313 : : }
5314 : :
5315 : : static void
5316 : 487802 : g_variant_valist_get (const gchar **str,
5317 : : GVariant *value,
5318 : : gboolean free,
5319 : : va_list *app)
5320 : : {
5321 [ + + ]: 487802 : if (g_variant_format_string_is_leaf (*str))
5322 : 329918 : g_variant_valist_get_leaf (str, value, free, app);
5323 : :
5324 [ + + ]: 157884 : else if (**str == 'm')
5325 : : {
5326 : 290 : (*str)++;
5327 : :
5328 [ + + ]: 290 : if (value != NULL)
5329 : 288 : value = g_variant_get_maybe (value);
5330 : :
5331 [ + + ]: 290 : if (!g_variant_format_string_is_nnp (*str))
5332 : : {
5333 : 282 : gboolean *ptr = va_arg (*app, gboolean *);
5334 : :
5335 [ + + ]: 282 : if (ptr != NULL)
5336 : 141 : *ptr = value != NULL;
5337 : : }
5338 : :
5339 : 290 : g_variant_valist_get (str, value, free, app);
5340 : :
5341 [ + + ]: 290 : if (value != NULL)
5342 : 144 : g_variant_unref (value);
5343 : : }
5344 : :
5345 : : else /* tuple, dictionary entry */
5346 : : {
5347 : 157594 : gint index = 0;
5348 : :
5349 : 157594 : g_assert (**str == '(' || **str == '{');
5350 : :
5351 : 157594 : (*str)++;
5352 [ + + + + ]: 484341 : while (**str != ')' && **str != '}')
5353 : : {
5354 [ + + ]: 326747 : if (value != NULL)
5355 : : {
5356 : 321436 : GVariant *child = g_variant_get_child_value (value, index++);
5357 : 321436 : g_variant_valist_get (str, child, free, app);
5358 : 321436 : g_variant_unref (child);
5359 : : }
5360 : : else
5361 : 5311 : g_variant_valist_get (str, NULL, free, app);
5362 : : }
5363 : 157594 : (*str)++;
5364 : : }
5365 : 487802 : }
5366 : :
5367 : : /* User-facing API {{{2 */
5368 : : /**
5369 : : * g_variant_new: (skip)
5370 : : * @format_string: a #GVariant format string
5371 : : * @...: arguments, as per @format_string
5372 : : *
5373 : : * Creates a new #GVariant instance.
5374 : : *
5375 : : * Think of this function as an analogue to g_strdup_printf().
5376 : : *
5377 : : * The type of the created instance and the arguments that are expected
5378 : : * by this function are determined by @format_string. See the section on
5379 : : * [GVariant format strings](gvariant-format-strings.html). Please note that
5380 : : * the syntax of the format string is very likely to be extended in the
5381 : : * future.
5382 : : *
5383 : : * The first character of the format string must not be '*' '?' '@' or
5384 : : * 'r'; in essence, a new #GVariant must always be constructed by this
5385 : : * function (and not merely passed through it unmodified).
5386 : : *
5387 : : * Note that the arguments must be of the correct width for their types
5388 : : * specified in @format_string. This can be achieved by casting them. See
5389 : : * the [GVariant varargs documentation](gvariant-format-strings.html#varargs).
5390 : : *
5391 : : * |[<!-- language="C" -->
5392 : : * MyFlags some_flags = FLAG_ONE | FLAG_TWO;
5393 : : * const gchar *some_strings[] = { "a", "b", "c", NULL };
5394 : : * GVariant *new_variant;
5395 : : *
5396 : : * new_variant = g_variant_new ("(t^as)",
5397 : : * // This cast is required.
5398 : : * (guint64) some_flags,
5399 : : * some_strings);
5400 : : * ]|
5401 : : *
5402 : : * Returns: a new floating #GVariant instance
5403 : : *
5404 : : * Since: 2.24
5405 : : **/
5406 : : GVariant *
5407 : 9909 : g_variant_new (const gchar *format_string,
5408 : : ...)
5409 : : {
5410 : : GVariant *value;
5411 : : va_list ap;
5412 : :
5413 : 9909 : g_return_val_if_fail (valid_format_string (format_string, TRUE, NULL) &&
5414 : : format_string[0] != '?' && format_string[0] != '@' &&
5415 : : format_string[0] != '*' && format_string[0] != 'r',
5416 : : NULL);
5417 : :
5418 : 9908 : va_start (ap, format_string);
5419 : 9908 : value = g_variant_new_va (format_string, NULL, &ap);
5420 : 9908 : va_end (ap);
5421 : :
5422 : 9908 : return value;
5423 : : }
5424 : :
5425 : : /**
5426 : : * g_variant_new_va: (skip)
5427 : : * @format_string: a string that is prefixed with a format string
5428 : : * @endptr: (nullable) (default NULL): location to store the end pointer,
5429 : : * or %NULL
5430 : : * @app: a pointer to a #va_list
5431 : : *
5432 : : * This function is intended to be used by libraries based on
5433 : : * #GVariant that want to provide g_variant_new()-like functionality
5434 : : * to their users.
5435 : : *
5436 : : * The API is more general than g_variant_new() to allow a wider range
5437 : : * of possible uses.
5438 : : *
5439 : : * @format_string must still point to a valid format string, but it only
5440 : : * needs to be nul-terminated if @endptr is %NULL. If @endptr is
5441 : : * non-%NULL then it is updated to point to the first character past the
5442 : : * end of the format string.
5443 : : *
5444 : : * @app is a pointer to a #va_list. The arguments, according to
5445 : : * @format_string, are collected from this #va_list and the list is left
5446 : : * pointing to the argument following the last.
5447 : : *
5448 : : * Note that the arguments in @app must be of the correct width for their
5449 : : * types specified in @format_string when collected into the #va_list.
5450 : : * See the [GVariant varargs documentation](gvariant-format-strings.html#varargs).
5451 : : *
5452 : : * These two generalisations allow mixing of multiple calls to
5453 : : * g_variant_new_va() and g_variant_get_va() within a single actual
5454 : : * varargs call by the user.
5455 : : *
5456 : : * The return value will be floating if it was a newly created GVariant
5457 : : * instance (for example, if the format string was "(ii)"). In the case
5458 : : * that the format_string was '*', '?', 'r', or a format starting with
5459 : : * '@' then the collected #GVariant pointer will be returned unmodified,
5460 : : * without adding any additional references.
5461 : : *
5462 : : * In order to behave correctly in all cases it is necessary for the
5463 : : * calling function to g_variant_ref_sink() the return result before
5464 : : * returning control to the user that originally provided the pointer.
5465 : : * At this point, the caller will have their own full reference to the
5466 : : * result. This can also be done by adding the result to a container,
5467 : : * or by passing it to another g_variant_new() call.
5468 : : *
5469 : : * Returns: a new, usually floating, #GVariant
5470 : : *
5471 : : * Since: 2.24
5472 : : **/
5473 : : GVariant *
5474 : 78283 : g_variant_new_va (const gchar *format_string,
5475 : : const gchar **endptr,
5476 : : va_list *app)
5477 : : {
5478 : : GVariant *value;
5479 : :
5480 : 78283 : g_return_val_if_fail (valid_format_string (format_string, !endptr, NULL),
5481 : : NULL);
5482 : 78282 : g_return_val_if_fail (app != NULL, NULL);
5483 : :
5484 : 78282 : value = g_variant_valist_new (&format_string, app);
5485 : :
5486 [ + + ]: 78282 : if (endptr != NULL)
5487 : 401 : *endptr = format_string;
5488 : :
5489 : 78282 : return value;
5490 : : }
5491 : :
5492 : : /**
5493 : : * g_variant_get: (skip)
5494 : : * @value: a #GVariant instance
5495 : : * @format_string: a #GVariant format string
5496 : : * @...: arguments, as per @format_string
5497 : : *
5498 : : * Deconstructs a #GVariant instance.
5499 : : *
5500 : : * Think of this function as an analogue to scanf().
5501 : : *
5502 : : * The arguments that are expected by this function are entirely
5503 : : * determined by @format_string. @format_string also restricts the
5504 : : * permissible types of @value. It is an error to give a value with
5505 : : * an incompatible type. See the section on
5506 : : * [GVariant format strings](gvariant-format-strings.html).
5507 : : * Please note that the syntax of the format string is very likely to be
5508 : : * extended in the future.
5509 : : *
5510 : : * @format_string determines the C types that are used for unpacking
5511 : : * the values and also determines if the values are copied or borrowed,
5512 : : * see the section on
5513 : : * [`GVariant` format strings](gvariant-format-strings.html#pointers).
5514 : : *
5515 : : * Since: 2.24
5516 : : **/
5517 : : void
5518 : 151770 : g_variant_get (GVariant *value,
5519 : : const gchar *format_string,
5520 : : ...)
5521 : : {
5522 : : va_list ap;
5523 : :
5524 : 151771 : g_return_if_fail (value != NULL);
5525 : 151770 : g_return_if_fail (valid_format_string (format_string, TRUE, value));
5526 : :
5527 : : /* if any direct-pointer-access formats are in use, flatten first */
5528 [ + + ]: 151769 : if (strchr (format_string, '&'))
5529 : 13699 : g_variant_get_data (value);
5530 : :
5531 : 151769 : va_start (ap, format_string);
5532 : 151769 : g_variant_get_va (value, format_string, NULL, &ap);
5533 : 151769 : va_end (ap);
5534 : : }
5535 : :
5536 : : /**
5537 : : * g_variant_get_va: (skip)
5538 : : * @value: a #GVariant
5539 : : * @format_string: a string that is prefixed with a format string
5540 : : * @endptr: (nullable) (default NULL): location to store the end pointer,
5541 : : * or %NULL
5542 : : * @app: a pointer to a #va_list
5543 : : *
5544 : : * This function is intended to be used by libraries based on #GVariant
5545 : : * that want to provide g_variant_get()-like functionality to their
5546 : : * users.
5547 : : *
5548 : : * The API is more general than g_variant_get() to allow a wider range
5549 : : * of possible uses.
5550 : : *
5551 : : * @format_string must still point to a valid format string, but it only
5552 : : * need to be nul-terminated if @endptr is %NULL. If @endptr is
5553 : : * non-%NULL then it is updated to point to the first character past the
5554 : : * end of the format string.
5555 : : *
5556 : : * @app is a pointer to a #va_list. The arguments, according to
5557 : : * @format_string, are collected from this #va_list and the list is left
5558 : : * pointing to the argument following the last.
5559 : : *
5560 : : * These two generalisations allow mixing of multiple calls to
5561 : : * g_variant_new_va() and g_variant_get_va() within a single actual
5562 : : * varargs call by the user.
5563 : : *
5564 : : * @format_string determines the C types that are used for unpacking
5565 : : * the values and also determines if the values are copied or borrowed,
5566 : : * see the section on
5567 : : * [`GVariant` format strings](gvariant-format-strings.html#pointers).
5568 : : *
5569 : : * Since: 2.24
5570 : : **/
5571 : : void
5572 : 152033 : g_variant_get_va (GVariant *value,
5573 : : const gchar *format_string,
5574 : : const gchar **endptr,
5575 : : va_list *app)
5576 : : {
5577 : 152033 : g_return_if_fail (valid_format_string (format_string, !endptr, value));
5578 : 152032 : g_return_if_fail (value != NULL);
5579 : 152032 : g_return_if_fail (app != NULL);
5580 : :
5581 : : /* if any direct-pointer-access formats are in use, flatten first */
5582 [ + + ]: 152032 : if (strchr (format_string, '&'))
5583 : 13793 : g_variant_get_data (value);
5584 : :
5585 : 152032 : g_variant_valist_get (&format_string, value, FALSE, app);
5586 : :
5587 [ + + ]: 152032 : if (endptr != NULL)
5588 : 1 : *endptr = format_string;
5589 : : }
5590 : :
5591 : : /* Varargs-enabled Utility Functions {{{1 */
5592 : :
5593 : : /**
5594 : : * g_variant_builder_add: (skip)
5595 : : * @builder: a #GVariantBuilder
5596 : : * @format_string: a #GVariant varargs format string
5597 : : * @...: arguments, as per @format_string
5598 : : *
5599 : : * Adds to a #GVariantBuilder.
5600 : : *
5601 : : * This call is a convenience wrapper that is exactly equivalent to
5602 : : * calling g_variant_new() followed by g_variant_builder_add_value().
5603 : : *
5604 : : * Note that the arguments must be of the correct width for their types
5605 : : * specified in @format_string. This can be achieved by casting them. See
5606 : : * the [GVariant varargs documentation](gvariant-format-strings.html#varargs).
5607 : : *
5608 : : * This function might be used as follows:
5609 : : *
5610 : : * |[<!-- language="C" -->
5611 : : * GVariant *
5612 : : * make_pointless_dictionary (void)
5613 : : * {
5614 : : * GVariantBuilder builder;
5615 : : * int i;
5616 : : *
5617 : : * g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
5618 : : * for (i = 0; i < 16; i++)
5619 : : * {
5620 : : * gchar buf[3];
5621 : : *
5622 : : * sprintf (buf, "%d", i);
5623 : : * g_variant_builder_add (&builder, "{is}", i, buf);
5624 : : * }
5625 : : *
5626 : : * return g_variant_builder_end (&builder);
5627 : : * }
5628 : : * ]|
5629 : : *
5630 : : * Since: 2.24
5631 : : */
5632 : : void
5633 : 67881 : g_variant_builder_add (GVariantBuilder *builder,
5634 : : const gchar *format_string,
5635 : : ...)
5636 : : {
5637 : : GVariant *variant;
5638 : : va_list ap;
5639 : :
5640 : 67881 : va_start (ap, format_string);
5641 : 67881 : variant = g_variant_new_va (format_string, NULL, &ap);
5642 : 67881 : va_end (ap);
5643 : :
5644 : 67881 : g_variant_builder_add_value (builder, variant);
5645 : 67881 : }
5646 : :
5647 : : /**
5648 : : * g_variant_get_child: (skip)
5649 : : * @value: a container #GVariant
5650 : : * @index_: the index of the child to deconstruct
5651 : : * @format_string: a #GVariant format string
5652 : : * @...: arguments, as per @format_string
5653 : : *
5654 : : * Reads a child item out of a container #GVariant instance and
5655 : : * deconstructs it according to @format_string. This call is
5656 : : * essentially a combination of g_variant_get_child_value() and
5657 : : * g_variant_get().
5658 : : *
5659 : : * @format_string determines the C types that are used for unpacking
5660 : : * the values and also determines if the values are copied or borrowed,
5661 : : * see the section on
5662 : : * [`GVariant` format strings](gvariant-format-strings.html#pointers).
5663 : : *
5664 : : * Since: 2.24
5665 : : **/
5666 : : void
5667 : 165 : g_variant_get_child (GVariant *value,
5668 : : gsize index_,
5669 : : const gchar *format_string,
5670 : : ...)
5671 : : {
5672 : : GVariant *child;
5673 : : va_list ap;
5674 : :
5675 : : /* if any direct-pointer-access formats are in use, flatten first */
5676 [ + + ]: 165 : if (strchr (format_string, '&'))
5677 : 76 : g_variant_get_data (value);
5678 : :
5679 : 165 : child = g_variant_get_child_value (value, index_);
5680 : 165 : g_return_if_fail (valid_format_string (format_string, TRUE, child));
5681 : :
5682 : 165 : va_start (ap, format_string);
5683 : 165 : g_variant_get_va (child, format_string, NULL, &ap);
5684 : 165 : va_end (ap);
5685 : :
5686 : 165 : g_variant_unref (child);
5687 : : }
5688 : :
5689 : : /**
5690 : : * g_variant_iter_next: (skip)
5691 : : * @iter: a #GVariantIter
5692 : : * @format_string: a GVariant format string
5693 : : * @...: the arguments to unpack the value into
5694 : : *
5695 : : * Gets the next item in the container and unpacks it into the variable
5696 : : * argument list according to @format_string, returning %TRUE.
5697 : : *
5698 : : * If no more items remain then %FALSE is returned.
5699 : : *
5700 : : * All of the pointers given on the variable arguments list of this
5701 : : * function are assumed to point at uninitialised memory. It is the
5702 : : * responsibility of the caller to free all of the values returned by
5703 : : * the unpacking process.
5704 : : *
5705 : : * Here is an example for memory management with g_variant_iter_next():
5706 : : * |[<!-- language="C" -->
5707 : : * // Iterates a dictionary of type 'a{sv}'
5708 : : * void
5709 : : * iterate_dictionary (GVariant *dictionary)
5710 : : * {
5711 : : * GVariantIter iter;
5712 : : * GVariant *value;
5713 : : * gchar *key;
5714 : : *
5715 : : * g_variant_iter_init (&iter, dictionary);
5716 : : * while (g_variant_iter_next (&iter, "{sv}", &key, &value))
5717 : : * {
5718 : : * g_print ("Item '%s' has type '%s'\n", key,
5719 : : * g_variant_get_type_string (value));
5720 : : *
5721 : : * // must free data for ourselves
5722 : : * g_variant_unref (value);
5723 : : * g_free (key);
5724 : : * }
5725 : : * }
5726 : : * ]|
5727 : : *
5728 : : * For a solution that is likely to be more convenient to C programmers
5729 : : * when dealing with loops, see g_variant_iter_loop().
5730 : : *
5731 : : * @format_string determines the C types that are used for unpacking
5732 : : * the values and also determines if the values are copied or borrowed.
5733 : : *
5734 : : * See the section on
5735 : : * [`GVariant` format strings](gvariant-format-strings.html#pointers).
5736 : : *
5737 : : * Returns: %TRUE if a value was unpacked, or %FALSE if there as no value
5738 : : *
5739 : : * Since: 2.24
5740 : : **/
5741 : : gboolean
5742 : 2777 : g_variant_iter_next (GVariantIter *iter,
5743 : : const gchar *format_string,
5744 : : ...)
5745 : : {
5746 : : GVariant *value;
5747 : :
5748 : 2777 : value = g_variant_iter_next_value (iter);
5749 : :
5750 : 2777 : g_return_val_if_fail (valid_format_string (format_string, TRUE, value),
5751 : : FALSE);
5752 : :
5753 [ + + ]: 2777 : if (value != NULL)
5754 : : {
5755 : : va_list ap;
5756 : :
5757 : 1836 : va_start (ap, format_string);
5758 : 1836 : g_variant_valist_get (&format_string, value, FALSE, &ap);
5759 : 1836 : va_end (ap);
5760 : :
5761 : 1836 : g_variant_unref (value);
5762 : : }
5763 : :
5764 : 2777 : return value != NULL;
5765 : : }
5766 : :
5767 : : /**
5768 : : * g_variant_iter_loop: (skip)
5769 : : * @iter: a #GVariantIter
5770 : : * @format_string: a GVariant format string
5771 : : * @...: the arguments to unpack the value into
5772 : : *
5773 : : * Gets the next item in the container and unpacks it into the variable
5774 : : * argument list according to @format_string, returning %TRUE.
5775 : : *
5776 : : * If no more items remain then %FALSE is returned.
5777 : : *
5778 : : * On the first call to this function, the pointers appearing on the
5779 : : * variable argument list are assumed to point at uninitialised memory.
5780 : : * On the second and later calls, it is assumed that the same pointers
5781 : : * will be given and that they will point to the memory as set by the
5782 : : * previous call to this function. This allows the previous values to
5783 : : * be freed, as appropriate.
5784 : : *
5785 : : * This function is intended to be used with a while loop as
5786 : : * demonstrated in the following example. This function can only be
5787 : : * used when iterating over an array. It is only valid to call this
5788 : : * function with a string constant for the format string and the same
5789 : : * string constant must be used each time. Mixing calls to this
5790 : : * function and g_variant_iter_next() or g_variant_iter_next_value() on
5791 : : * the same iterator causes undefined behavior.
5792 : : *
5793 : : * If you break out of a such a while loop using g_variant_iter_loop() then
5794 : : * you must free or unreference all the unpacked values as you would with
5795 : : * g_variant_get(). Failure to do so will cause a memory leak.
5796 : : *
5797 : : * Here is an example for memory management with g_variant_iter_loop():
5798 : : * |[<!-- language="C" -->
5799 : : * // Iterates a dictionary of type 'a{sv}'
5800 : : * void
5801 : : * iterate_dictionary (GVariant *dictionary)
5802 : : * {
5803 : : * GVariantIter iter;
5804 : : * GVariant *value;
5805 : : * gchar *key;
5806 : : *
5807 : : * g_variant_iter_init (&iter, dictionary);
5808 : : * while (g_variant_iter_loop (&iter, "{sv}", &key, &value))
5809 : : * {
5810 : : * g_print ("Item '%s' has type '%s'\n", key,
5811 : : * g_variant_get_type_string (value));
5812 : : *
5813 : : * // no need to free 'key' and 'value' here
5814 : : * // unless breaking out of this loop
5815 : : * }
5816 : : * }
5817 : : * ]|
5818 : : *
5819 : : * For most cases you should use g_variant_iter_next().
5820 : : *
5821 : : * This function is really only useful when unpacking into #GVariant or
5822 : : * #GVariantIter in order to allow you to skip the call to
5823 : : * g_variant_unref() or g_variant_iter_free().
5824 : : *
5825 : : * For example, if you are only looping over simple integer and string
5826 : : * types, g_variant_iter_next() is definitely preferred. For string
5827 : : * types, use the '&' prefix to avoid allocating any memory at all (and
5828 : : * thereby avoiding the need to free anything as well).
5829 : : *
5830 : : * @format_string determines the C types that are used for unpacking
5831 : : * the values and also determines if the values are copied or borrowed.
5832 : : *
5833 : : * See the section on
5834 : : * [`GVariant` format strings](gvariant-format-strings.html#pointers).
5835 : : *
5836 : : * Returns: %TRUE if a value was unpacked, or %FALSE if there was no
5837 : : * value
5838 : : *
5839 : : * Since: 2.24
5840 : : **/
5841 : : gboolean
5842 : 6897 : g_variant_iter_loop (GVariantIter *iter,
5843 : : const gchar *format_string,
5844 : : ...)
5845 : : {
5846 : 6897 : gboolean first_time = GVSI(iter)->loop_format == NULL;
5847 : : GVariant *value;
5848 : : va_list ap;
5849 : :
5850 : 6897 : g_return_val_if_fail (first_time ||
5851 : : format_string == GVSI(iter)->loop_format,
5852 : : FALSE);
5853 : :
5854 [ + + ]: 6897 : if (first_time)
5855 : : {
5856 [ - + ]: 2657 : TYPE_CHECK (GVSI(iter)->value, G_VARIANT_TYPE_ARRAY, FALSE);
5857 : 2657 : GVSI(iter)->loop_format = format_string;
5858 : :
5859 [ + + ]: 2657 : if (strchr (format_string, '&'))
5860 : 1497 : g_variant_get_data (GVSI(iter)->value);
5861 : : }
5862 : :
5863 : 6897 : value = g_variant_iter_next_value (iter);
5864 : :
5865 : 6897 : g_return_val_if_fail (!first_time ||
5866 : : valid_format_string (format_string, TRUE, value),
5867 : : FALSE);
5868 : :
5869 : 6897 : va_start (ap, format_string);
5870 : 6897 : g_variant_valist_get (&format_string, value, !first_time, &ap);
5871 : 6897 : va_end (ap);
5872 : :
5873 [ + + ]: 6897 : if (value != NULL)
5874 : 4240 : g_variant_unref (value);
5875 : :
5876 : 6897 : return value != NULL;
5877 : : }
5878 : :
5879 : : /* Serialized data {{{1 */
5880 : : static GVariant *
5881 : 2838 : g_variant_deep_copy (GVariant *value,
5882 : : gboolean byteswap)
5883 : : {
5884 [ + + + + : 2838 : switch (g_variant_classify (value))
+ + + + +
+ + + + +
+ - ]
5885 : : {
5886 : 871 : case G_VARIANT_CLASS_MAYBE:
5887 : : case G_VARIANT_CLASS_TUPLE:
5888 : : case G_VARIANT_CLASS_DICT_ENTRY:
5889 : : case G_VARIANT_CLASS_VARIANT:
5890 : : {
5891 : : GVariantBuilder builder;
5892 : : gsize i, n_children;
5893 : :
5894 : 871 : g_variant_builder_init (&builder, g_variant_get_type (value));
5895 : :
5896 [ + + ]: 3369 : for (i = 0, n_children = g_variant_n_children (value); i < n_children; i++)
5897 : : {
5898 : 2498 : GVariant *child = g_variant_get_child_value (value, i);
5899 : 2498 : g_variant_builder_add_value (&builder, g_variant_deep_copy (child, byteswap));
5900 : 2498 : g_variant_unref (child);
5901 : : }
5902 : :
5903 : 871 : return g_variant_builder_end (&builder);
5904 : : }
5905 : :
5906 : 415 : case G_VARIANT_CLASS_ARRAY:
5907 : : {
5908 : : GVariantBuilder builder;
5909 : : gsize i, n_children;
5910 : 415 : GVariant *first_invalid_child_deep_copy = NULL;
5911 : :
5912 : : /* Arrays are in theory treated the same as maybes, tuples, dict entries
5913 : : * and variants, and could be another case in the above block of code.
5914 : : *
5915 : : * However, they have the property that when dealing with non-normal
5916 : : * data (which is the only time g_variant_deep_copy() is currently
5917 : : * called) in a variable-sized array, the code above can easily end up
5918 : : * creating many default child values in order to return an array which
5919 : : * is of the right length and type, but without containing non-normal
5920 : : * data. This can happen if the offset table for the array is malformed.
5921 : : *
5922 : : * In this case, the code above would end up allocating the same default
5923 : : * value for each one of the child indexes beyond the first malformed
5924 : : * entry in the offset table. This can end up being a lot of identical
5925 : : * allocations of default values, particularly if the non-normal array
5926 : : * is crafted maliciously.
5927 : : *
5928 : : * Avoid that problem by returning a new reference to the same default
5929 : : * value for every child after the first invalid one. This results in
5930 : : * returning an equivalent array, in normal form and trusted — but with
5931 : : * significantly fewer memory allocations.
5932 : : *
5933 : : * See https://gitlab.gnome.org/GNOME/glib/-/issues/2540 */
5934 : :
5935 : 415 : g_variant_builder_init (&builder, g_variant_get_type (value));
5936 : :
5937 [ + + ]: 95505 : for (i = 0, n_children = g_variant_n_children (value); i < n_children; i++)
5938 : : {
5939 : : /* Try maybe_get_child_value() first; if it returns NULL, this child
5940 : : * is non-normal. get_child_value() would have constructed and
5941 : : * returned a default value in that case. */
5942 : 95090 : GVariant *child = g_variant_maybe_get_child_value (value, i);
5943 : :
5944 [ + + ]: 95090 : if (child != NULL)
5945 : : {
5946 : : /* Non-normal children may not always be contiguous, as they may
5947 : : * be non-normal for reasons other than invalid offset table
5948 : : * entries. As they are all the same type, they will all have
5949 : : * the same default value though, so keep that around. */
5950 : 49 : g_variant_builder_add_value (&builder, g_variant_deep_copy (child, byteswap));
5951 : : }
5952 [ + - + + ]: 95041 : else if (child == NULL && first_invalid_child_deep_copy != NULL)
5953 : : {
5954 : 95016 : g_variant_builder_add_value (&builder, first_invalid_child_deep_copy);
5955 : : }
5956 [ + - ]: 25 : else if (child == NULL)
5957 : : {
5958 : 25 : child = g_variant_get_child_value (value, i);
5959 : 25 : first_invalid_child_deep_copy = g_variant_ref_sink (g_variant_deep_copy (child, byteswap));
5960 : 25 : g_variant_builder_add_value (&builder, first_invalid_child_deep_copy);
5961 : : }
5962 : :
5963 : 95090 : g_clear_pointer (&child, g_variant_unref);
5964 : : }
5965 : :
5966 : 415 : g_clear_pointer (&first_invalid_child_deep_copy, g_variant_unref);
5967 : :
5968 : 415 : return g_variant_builder_end (&builder);
5969 : : }
5970 : :
5971 : 115 : case G_VARIANT_CLASS_BOOLEAN:
5972 : 115 : return g_variant_new_boolean (g_variant_get_boolean (value));
5973 : :
5974 : 141 : case G_VARIANT_CLASS_BYTE:
5975 : 141 : return g_variant_new_byte (g_variant_get_byte (value));
5976 : :
5977 : 86 : case G_VARIANT_CLASS_INT16:
5978 [ + - ]: 86 : if (byteswap)
5979 : 86 : return g_variant_new_int16 (GUINT16_SWAP_LE_BE (g_variant_get_int16 (value)));
5980 : : else
5981 : 0 : return g_variant_new_int16 (g_variant_get_int16 (value));
5982 : :
5983 : 104 : case G_VARIANT_CLASS_UINT16:
5984 [ + - ]: 104 : if (byteswap)
5985 : 104 : return g_variant_new_uint16 (GUINT16_SWAP_LE_BE (g_variant_get_uint16 (value)));
5986 : : else
5987 : 0 : return g_variant_new_uint16 (g_variant_get_uint16 (value));
5988 : :
5989 : 137 : case G_VARIANT_CLASS_INT32:
5990 [ + + ]: 137 : if (byteswap)
5991 : 90 : return g_variant_new_int32 (GUINT32_SWAP_LE_BE (g_variant_get_int32 (value)));
5992 : : else
5993 : 47 : return g_variant_new_int32 (g_variant_get_int32 (value));
5994 : :
5995 : 85 : case G_VARIANT_CLASS_UINT32:
5996 [ + - ]: 85 : if (byteswap)
5997 : 85 : return g_variant_new_uint32 (GUINT32_SWAP_LE_BE (g_variant_get_uint32 (value)));
5998 : : else
5999 : 0 : return g_variant_new_uint32 (g_variant_get_uint32 (value));
6000 : :
6001 : 116 : case G_VARIANT_CLASS_INT64:
6002 [ + - ]: 116 : if (byteswap)
6003 : 116 : return g_variant_new_int64 (GUINT64_SWAP_LE_BE (g_variant_get_int64 (value)));
6004 : : else
6005 : 0 : return g_variant_new_int64 (g_variant_get_int64 (value));
6006 : :
6007 : 99 : case G_VARIANT_CLASS_UINT64:
6008 [ + - ]: 99 : if (byteswap)
6009 : 99 : return g_variant_new_uint64 (GUINT64_SWAP_LE_BE (g_variant_get_uint64 (value)));
6010 : : else
6011 : 0 : return g_variant_new_uint64 (g_variant_get_uint64 (value));
6012 : :
6013 : 103 : case G_VARIANT_CLASS_HANDLE:
6014 [ + + ]: 103 : if (byteswap)
6015 : 102 : return g_variant_new_handle (GUINT32_SWAP_LE_BE (g_variant_get_handle (value)));
6016 : : else
6017 : 1 : return g_variant_new_handle (g_variant_get_handle (value));
6018 : :
6019 : 130 : case G_VARIANT_CLASS_DOUBLE:
6020 [ + + ]: 130 : if (byteswap)
6021 : : {
6022 : : /* We have to convert the double to a uint64 here using a union,
6023 : : * because a cast will round it numerically. */
6024 : : union
6025 : : {
6026 : : guint64 u64;
6027 : : gdouble dbl;
6028 : : } u1, u2;
6029 : 109 : u1.dbl = g_variant_get_double (value);
6030 : 109 : u2.u64 = GUINT64_SWAP_LE_BE (u1.u64);
6031 : 109 : return g_variant_new_double (u2.dbl);
6032 : : }
6033 : : else
6034 : 21 : return g_variant_new_double (g_variant_get_double (value));
6035 : :
6036 : 168 : case G_VARIANT_CLASS_STRING:
6037 : 168 : return g_variant_new_string (g_variant_get_string (value, NULL));
6038 : :
6039 : 146 : case G_VARIANT_CLASS_OBJECT_PATH:
6040 : 146 : return g_variant_new_object_path (g_variant_get_string (value, NULL));
6041 : :
6042 : 122 : case G_VARIANT_CLASS_SIGNATURE:
6043 : 122 : return g_variant_new_signature (g_variant_get_string (value, NULL));
6044 : : }
6045 : :
6046 : : g_assert_not_reached ();
6047 : : }
6048 : :
6049 : : /**
6050 : : * g_variant_get_normal_form:
6051 : : * @value: a #GVariant
6052 : : *
6053 : : * Gets a #GVariant instance that has the same value as @value and is
6054 : : * trusted to be in normal form.
6055 : : *
6056 : : * If @value is already trusted to be in normal form then a new
6057 : : * reference to @value is returned.
6058 : : *
6059 : : * If @value is not already trusted, then it is scanned to check if it
6060 : : * is in normal form. If it is found to be in normal form then it is
6061 : : * marked as trusted and a new reference to it is returned.
6062 : : *
6063 : : * If @value is found not to be in normal form then a new trusted
6064 : : * #GVariant is created with the same value as @value. The non-normal parts of
6065 : : * @value will be replaced with default values which are guaranteed to be in
6066 : : * normal form.
6067 : : *
6068 : : * It makes sense to call this function if you've received #GVariant
6069 : : * data from untrusted sources and you want to ensure your serialized
6070 : : * output is definitely in normal form.
6071 : : *
6072 : : * If @value is already in normal form, a new reference will be returned
6073 : : * (which will be floating if @value is floating). If it is not in normal form,
6074 : : * the newly created #GVariant will be returned with a single non-floating
6075 : : * reference. Typically, g_variant_take_ref() should be called on the return
6076 : : * value from this function to guarantee ownership of a single non-floating
6077 : : * reference to it.
6078 : : *
6079 : : * Returns: (transfer full): a trusted #GVariant
6080 : : *
6081 : : * Since: 2.24
6082 : : **/
6083 : : GVariant *
6084 : 315 : g_variant_get_normal_form (GVariant *value)
6085 : : {
6086 : : GVariant *trusted;
6087 : :
6088 [ + + ]: 315 : if (g_variant_is_normal_form (value))
6089 : 209 : return g_variant_ref (value);
6090 : :
6091 : 106 : trusted = g_variant_deep_copy (value, FALSE);
6092 : 106 : g_assert (g_variant_is_trusted (trusted));
6093 : :
6094 : 106 : return g_variant_ref_sink (trusted);
6095 : : }
6096 : :
6097 : : /**
6098 : : * g_variant_byteswap:
6099 : : * @value: a #GVariant
6100 : : *
6101 : : * Performs a byteswapping operation on the contents of @value. The
6102 : : * result is that all multi-byte numeric data contained in @value is
6103 : : * byteswapped. That includes 16, 32, and 64bit signed and unsigned
6104 : : * integers as well as file handles and double precision floating point
6105 : : * values.
6106 : : *
6107 : : * This function is an identity mapping on any value that does not
6108 : : * contain multi-byte numeric data. That include strings, booleans,
6109 : : * bytes and containers containing only these things (recursively).
6110 : : *
6111 : : * While this function can safely handle untrusted, non-normal data, it is
6112 : : * recommended to check whether the input is in normal form beforehand, using
6113 : : * g_variant_is_normal_form(), and to reject non-normal inputs if your
6114 : : * application can be strict about what inputs it rejects.
6115 : : *
6116 : : * The returned value is always in normal form and is marked as trusted.
6117 : : * A full, not floating, reference is returned.
6118 : : *
6119 : : * Returns: (transfer full): the byteswapped form of @value
6120 : : *
6121 : : * Since: 2.24
6122 : : **/
6123 : : GVariant *
6124 : 412 : g_variant_byteswap (GVariant *value)
6125 : : {
6126 : : GVariantTypeInfo *type_info;
6127 : : guint alignment;
6128 : : GVariant *new;
6129 : :
6130 : 412 : type_info = g_variant_get_type_info (value);
6131 : :
6132 : 412 : g_variant_type_info_query (type_info, &alignment, NULL);
6133 : :
6134 [ + + + + ]: 412 : if (alignment && g_variant_is_normal_form (value))
6135 : 173 : {
6136 : : /* (potentially) contains multi-byte numeric data, but is also already in
6137 : : * normal form so we can use a faster byteswapping codepath on the
6138 : : * serialised data */
6139 : 173 : GVariantSerialised serialised = { 0, };
6140 : : GBytes *bytes;
6141 : :
6142 : 173 : serialised.type_info = g_variant_get_type_info (value);
6143 : 173 : serialised.size = g_variant_get_size (value);
6144 : 173 : serialised.data = g_malloc (serialised.size);
6145 : 173 : serialised.depth = g_variant_get_depth (value);
6146 : 173 : serialised.ordered_offsets_up_to = G_MAXSIZE; /* operating on the normal form */
6147 : 173 : serialised.checked_offsets_up_to = G_MAXSIZE;
6148 : 173 : g_variant_store (value, serialised.data);
6149 : :
6150 : 173 : g_variant_serialised_byteswap (serialised);
6151 : :
6152 : 173 : bytes = g_bytes_new_take (serialised.data, serialised.size);
6153 : 173 : new = g_variant_ref_sink (g_variant_new_from_bytes (g_variant_get_type (value), bytes, TRUE));
6154 : 173 : g_bytes_unref (bytes);
6155 : : }
6156 [ + + ]: 239 : else if (alignment)
6157 : : /* (potentially) contains multi-byte numeric data */
6158 : 160 : new = g_variant_ref_sink (g_variant_deep_copy (value, TRUE));
6159 : : else
6160 : : /* contains no multi-byte data */
6161 : 79 : new = g_variant_get_normal_form (value);
6162 : :
6163 : 412 : g_assert (g_variant_is_trusted (new));
6164 : :
6165 : 412 : return g_steal_pointer (&new);
6166 : : }
6167 : :
6168 : : /**
6169 : : * g_variant_new_from_data:
6170 : : * @type: a definite #GVariantType
6171 : : * @data: (array length=size) (element-type guint8): the serialized data
6172 : : * @size: the size of @data
6173 : : * @trusted: %TRUE if @data is definitely in normal form
6174 : : * @notify: (scope async): function to call when @data is no longer needed
6175 : : * @user_data: data for @notify
6176 : : *
6177 : : * Creates a new #GVariant instance from serialized data.
6178 : : *
6179 : : * @type is the type of #GVariant instance that will be constructed.
6180 : : * The interpretation of @data depends on knowing the type.
6181 : : *
6182 : : * @data is not modified by this function and must remain valid with an
6183 : : * unchanging value until such a time as @notify is called with
6184 : : * @user_data. If the contents of @data change before that time then
6185 : : * the result is undefined.
6186 : : *
6187 : : * If @data is trusted to be serialized data in normal form then
6188 : : * @trusted should be %TRUE. This applies to serialized data created
6189 : : * within this process or read from a trusted location on the disk (such
6190 : : * as a file installed in /usr/lib alongside your application). You
6191 : : * should set trusted to %FALSE if @data is read from the network, a
6192 : : * file in the user's home directory, etc.
6193 : : *
6194 : : * If @data was not stored in this machine's native endianness, any multi-byte
6195 : : * numeric values in the returned variant will also be in non-native
6196 : : * endianness. g_variant_byteswap() can be used to recover the original values.
6197 : : *
6198 : : * @notify will be called with @user_data when @data is no longer
6199 : : * needed. The exact time of this call is unspecified and might even be
6200 : : * before this function returns.
6201 : : *
6202 : : * Note: @data must be backed by memory that is aligned appropriately for the
6203 : : * @type being loaded. Otherwise this function will internally create a copy of
6204 : : * the memory (since GLib 2.60) or (in older versions) fail and exit the
6205 : : * process.
6206 : : *
6207 : : * Returns: (transfer none): a new floating #GVariant of type @type
6208 : : *
6209 : : * Since: 2.24
6210 : : **/
6211 : : GVariant *
6212 : 1441 : g_variant_new_from_data (const GVariantType *type,
6213 : : gconstpointer data,
6214 : : gsize size,
6215 : : gboolean trusted,
6216 : : GDestroyNotify notify,
6217 : : gpointer user_data)
6218 : : {
6219 : : GVariant *value;
6220 : : GBytes *bytes;
6221 : :
6222 : 1441 : g_return_val_if_fail (g_variant_type_is_definite (type), NULL);
6223 : 1441 : g_return_val_if_fail (data != NULL || size == 0, NULL);
6224 : :
6225 [ + + ]: 1441 : if (notify)
6226 : 693 : bytes = g_bytes_new_with_free_func (data, size, notify, user_data);
6227 : : else
6228 : 748 : bytes = g_bytes_new_static (data, size);
6229 : :
6230 : 1441 : value = g_variant_new_from_bytes (type, bytes, trusted);
6231 : 1441 : g_bytes_unref (bytes);
6232 : :
6233 : 1441 : return value;
6234 : : }
6235 : :
6236 : : /* Epilogue {{{1 */
6237 : : /* vim:set foldmethod=marker: */
|