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