diff options
author | Philip Withnall <pwithnall@endlessos.org> | 2022-10-25 13:03:22 +0100 |
---|---|---|
committer | Michael Catanzaro <mcatanzaro@redhat.com> | 2023-03-24 08:56:02 -0500 |
commit | 81567d2bd81f303061b93be34da96ef2e2b11693 (patch) | |
tree | a85f6a7d39ec7e8a288108c69d22dc93182b5e65 | |
parent | 2f3b16d3439e4843718428c21aaedd1ecba868d7 (diff) | |
download | glib-81567d2bd81f303061b93be34da96ef2e2b11693.tar.gz |
gvariant: Add internal g_variant_maybe_get_child_value()
This will be used in a following commit.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #2540
-rw-r--r-- | glib/gvariant-core.c | 68 | ||||
-rw-r--r-- | glib/gvariant-core.h | 3 |
2 files changed, 71 insertions, 0 deletions
diff --git a/glib/gvariant-core.c b/glib/gvariant-core.c index 1efcf200f..dbcf60f69 100644 --- a/glib/gvariant-core.c +++ b/glib/gvariant-core.c @@ -1205,6 +1205,74 @@ g_variant_get_child_value (GVariant *value, } /** + * g_variant_maybe_get_child_value: + * @value: a container #GVariant + * @index_: the index of the child to fetch + * + * Reads a child item out of a container #GVariant instance, if it is in normal + * form. If it is not in normal form, return %NULL. + * + * This function behaves the same as g_variant_get_child_value(), except that it + * returns %NULL if the child is not in normal form. g_variant_get_child_value() + * would instead return a new default value of the correct type. + * + * This is intended to be used internally to avoid unnecessary #GVariant + * allocations. + * + * The returned value is never floating. You should free it with + * g_variant_unref() when you're done with it. + * + * This function is O(1). + * + * Returns: (transfer full): the child at the specified index + * + * Since: 2.74 + */ +GVariant * +g_variant_maybe_get_child_value (GVariant *value, + gsize index_) +{ + g_return_val_if_fail (index_ < g_variant_n_children (value), NULL); + g_return_val_if_fail (value->depth < G_MAXSIZE, NULL); + + if (~g_atomic_int_get (&value->state) & STATE_SERIALISED) + { + g_variant_lock (value); + + if (~value->state & STATE_SERIALISED) + { + GVariant *child; + + child = g_variant_ref (value->contents.tree.children[index_]); + g_variant_unlock (value); + + return child; + } + + g_variant_unlock (value); + } + + { + GVariantSerialised serialised = g_variant_to_serialised (value); + GVariantSerialised s_child; + + /* get the serializer to extract the serialized data for the child + * from the serialized data for the container + */ + s_child = g_variant_serialised_get_child (serialised, index_); + + if (!(value->state & STATE_TRUSTED) && s_child.data == NULL) + { + g_variant_type_info_unref (s_child.type_info); + return NULL; + } + + g_variant_type_info_unref (s_child.type_info); + return g_variant_get_child_value (value, index_); + } +} + +/** * g_variant_store: * @value: the #GVariant to store * @data: (not nullable): the location to store the serialised data at diff --git a/glib/gvariant-core.h b/glib/gvariant-core.h index fc04711ac..947a98ca0 100644 --- a/glib/gvariant-core.h +++ b/glib/gvariant-core.h @@ -36,4 +36,7 @@ GVariantTypeInfo * g_variant_get_type_info (GVarian gsize g_variant_get_depth (GVariant *value); +GVariant * g_variant_maybe_get_child_value (GVariant *value, + gsize index_); + #endif /* __G_VARIANT_CORE_H__ */ |