From 561f8b71eee2e46b5bff332cdb39ce5f99247c14 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Mon, 18 Dec 2023 15:39:07 -0500 Subject: [PATCH] structure: Allow STRICT flag only in _serialize_full() The STRICT flag makes _serialize() nullable which is an API break for bindings. Forbid it and add _serialize_full() that accepts it and is properly annotated. Part-of: --- .../validate/tests/check/validate/utilities.c | 4 +-- .../ges/ges-command-line-formatter.c | 2 +- .../tests/examples/nvcodec/cudaipc.c | 4 +-- subprojects/gstreamer/gst/gstmeta.c | 4 +-- subprojects/gstreamer/gst/gststructure.c | 30 +++++++++++++++++-- subprojects/gstreamer/gst/gststructure.h | 5 +++- subprojects/gstreamer/gst/gstvalue.c | 3 +- .../gstreamer/tests/check/gst/gststructure.c | 6 ++-- 8 files changed, 44 insertions(+), 14 deletions(-) diff --git a/subprojects/gst-devtools/validate/tests/check/validate/utilities.c b/subprojects/gst-devtools/validate/tests/check/validate/utilities.c index 5335da2c62..095b45fb96 100644 --- a/subprojects/gst-devtools/validate/tests/check/validate/utilities.c +++ b/subprojects/gst-devtools/validate/tests/check/validate/utilities.c @@ -31,8 +31,8 @@ GST_START_TEST (test_resolve_variables) NULL); fail_unless (gst_structure_is_equal (struct_with_vars, expected), "\nReplaced: `%s`\n!=\nExpected: `%s`", - gst_structure_serialize (struct_with_vars, GST_SERIALIZE_FLAG_NONE), - gst_structure_serialize (expected, GST_SERIALIZE_FLAG_NONE)); + gst_structure_serialize_full (struct_with_vars, GST_SERIALIZE_FLAG_NONE), + gst_structure_serialize_full (expected, GST_SERIALIZE_FLAG_NONE)); gst_structure_free (variables); gst_structure_free (struct_with_vars); diff --git a/subprojects/gst-editing-services/ges/ges-command-line-formatter.c b/subprojects/gst-editing-services/ges/ges-command-line-formatter.c index 51cd06a904..70581e78e4 100644 --- a/subprojects/gst-editing-services/ges/ges-command-line-formatter.c +++ b/subprojects/gst-editing-services/ges/ges-command-line-formatter.c @@ -416,7 +416,7 @@ _cleanup_fields (const Property * field_names, GstStructure * structure, exists = TRUE; if (gst_structure_has_field (structure, field_names[i].long_name)) { - gchar *str_info = gst_structure_serialize (structure, 0); + gchar *str_info = gst_structure_serialize_full (structure, 0); *error = g_error_new (GES_ERROR, 0, diff --git a/subprojects/gst-plugins-bad/tests/examples/nvcodec/cudaipc.c b/subprojects/gst-plugins-bad/tests/examples/nvcodec/cudaipc.c index 0583ae0402..3a35e417dd 100644 --- a/subprojects/gst-plugins-bad/tests/examples/nvcodec/cudaipc.c +++ b/subprojects/gst-plugins-bad/tests/examples/nvcodec/cudaipc.c @@ -39,7 +39,7 @@ server_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data) s = gst_custom_meta_get_structure (meta); gst_structure_set (s, "foo", G_TYPE_STRING, "bar", "timestamp", G_TYPE_UINT64, GST_BUFFER_PTS (buf), NULL); - str = gst_structure_serialize (s, GST_SERIALIZE_FLAG_NONE); + str = gst_structure_serialize_full (s, GST_SERIALIZE_FLAG_NONE); gst_println ("Added custom meta %s", str); @@ -93,7 +93,7 @@ client_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data) gchar *str; s = gst_custom_meta_get_structure (meta); - str = gst_structure_serialize (s, GST_SERIALIZE_FLAG_NONE); + str = gst_structure_serialize_full (s, GST_SERIALIZE_FLAG_NONE); gst_println ("Found custom meta \"%s\"", str); g_free (str); } diff --git a/subprojects/gstreamer/gst/gstmeta.c b/subprojects/gstreamer/gst/gstmeta.c index af0a73455d..772cf38a88 100644 --- a/subprojects/gstreamer/gst/gstmeta.c +++ b/subprojects/gstreamer/gst/gstmeta.c @@ -196,8 +196,8 @@ custom_serialize_func (const GstMeta * meta, GstByteArrayInterface * data, guint8 * version) { const GstCustomMeta *cmeta = (const GstCustomMeta *) meta; - gchar *str = - gst_structure_serialize (cmeta->structure, GST_SERIALIZE_FLAG_STRICT); + gchar *str = gst_structure_serialize_full (cmeta->structure, + GST_SERIALIZE_FLAG_STRICT); if (str == NULL) return FALSE; diff --git a/subprojects/gstreamer/gst/gststructure.c b/subprojects/gstreamer/gst/gststructure.c index 9e5760930f..9055ddf439 100644 --- a/subprojects/gstreamer/gst/gststructure.c +++ b/subprojects/gstreamer/gst/gststructure.c @@ -127,7 +127,7 @@ * ``` * * > *note*: gst_structure_to_string() won't use that syntax for backward - * > compatibility reason, gst_structure_serialize() has been added for + * > compatibility reason, gst_structure_serialize_full() has been added for * > that purpose. */ @@ -2197,7 +2197,7 @@ structure_serialize (const GstStructure * structure, GstSerializeFlags flags) * * This function will lead to unexpected results when there are nested #GstCaps * / #GstStructure deeper than one level, you should user - * gst_structure_serialize() instead for those cases. + * gst_structure_serialize_full() instead for those cases. * * Free-function: g_free * @@ -2222,16 +2222,42 @@ gst_structure_to_string (const GstStructure * structure) * GStreamer prior to 1.20 unless #GST_SERIALIZE_FLAG_BACKWARD_COMPAT is passed * as @flag. * + * %GST_SERIALIZE_FLAG_STRICT flags is not allowed because it would make this + * function nullable which is an API break for bindings. + * Use gst_structure_serialize_full() instead. + * * Free-function: g_free * * Returns: (transfer full): a pointer to string allocated by g_malloc(). * g_free() after usage. * * Since: 1.20 + * Deprecated: Use gst_structure_serialize_full() instead. */ gchar * gst_structure_serialize (const GstStructure * structure, GstSerializeFlags flags) +{ + g_return_val_if_fail ((flags & GST_SERIALIZE_FLAG_STRICT) == 0, NULL); + return structure_serialize (structure, flags); +} + +/** + * gst_structure_serialize_full: + * @structure: a #GstStructure + * @flags: The flags to use to serialize structure + * + * Alias for gst_structure_serialize() but with nullable annotation because it + * can return %NULL when %GST_SERIALIZE_FLAG_STRICT flag is set. + * + * Returns: (transfer full) (nullable): a pointer to string allocated by g_malloc(). + * g_free() after usage. + * + * Since: 1.24 + */ +gchar * +gst_structure_serialize_full (const GstStructure * structure, + GstSerializeFlags flags) { return structure_serialize (structure, flags); } diff --git a/subprojects/gstreamer/gst/gststructure.h b/subprojects/gstreamer/gst/gststructure.h index f2dd81b517..d86dedcce5 100644 --- a/subprojects/gstreamer/gst/gststructure.h +++ b/subprojects/gstreamer/gst/gststructure.h @@ -364,9 +364,12 @@ gboolean gst_structure_get_flags (const GstStructure * GST_API gchar * gst_structure_to_string (const GstStructure * structure) G_GNUC_MALLOC; -GST_API +GST_DEPRECATED_FOR(gst_structure_serialize_full) gchar * gst_structure_serialize (const GstStructure * structure, GstSerializeFlags flags) G_GNUC_MALLOC; +GST_API +gchar * gst_structure_serialize_full (const GstStructure * structure, + GstSerializeFlags flags) G_GNUC_MALLOC; GST_API GstStructure * gst_structure_from_string (const gchar * string, diff --git a/subprojects/gstreamer/gst/gstvalue.c b/subprojects/gstreamer/gst/gstvalue.c index 643d44247f..315bcfb4d5 100644 --- a/subprojects/gstreamer/gst/gstvalue.c +++ b/subprojects/gstreamer/gst/gstvalue.c @@ -369,7 +369,8 @@ _priv_gst_value_serialize_any_list (const GValue * value, const gchar * begin, s_val = gst_value_serialize (v); } else { if (GST_VALUE_HOLDS_STRUCTURE (v)) - s_val = gst_structure_serialize (gst_value_get_structure (v), flags); + s_val = + gst_structure_serialize_full (gst_value_get_structure (v), flags); else if (GST_VALUE_HOLDS_CAPS (v)) s_val = gst_caps_serialize (gst_value_get_caps (v), flags); } diff --git a/subprojects/gstreamer/tests/check/gst/gststructure.c b/subprojects/gstreamer/tests/check/gst/gststructure.c index bcfba211fe..3c1a17c4b8 100644 --- a/subprojects/gstreamer/tests/check/gst/gststructure.c +++ b/subprojects/gstreamer/tests/check/gst/gststructure.c @@ -792,7 +792,7 @@ GST_START_TEST (test_serialize_nested_structures) fail_unless (gst_structure_has_field_typed (s, "main-sub1", GST_TYPE_STRUCTURE)); - str2 = gst_structure_serialize (s, GST_SERIALIZE_FLAG_NONE); + str2 = gst_structure_serialize_full (s, GST_SERIALIZE_FLAG_NONE); fail_unless (str2 != NULL); fail_unless_equals_string (str1, str2); @@ -1041,13 +1041,13 @@ GST_START_TEST (test_strict) GstElement *bin = gst_bin_new ("mybin"); s = gst_structure_new ("test-struct", "obj", GST_TYPE_BIN, bin, NULL); fail_unless (s); - fail_if (gst_structure_serialize (s, GST_SERIALIZE_FLAG_STRICT)); + fail_if (gst_structure_serialize_full (s, GST_SERIALIZE_FLAG_STRICT)); gst_structure_free (s); gst_object_unref (bin); s = gst_structure_new ("test-struct", "ptr", G_TYPE_POINTER, NULL, NULL); fail_unless (s); - fail_if (gst_structure_serialize (s, GST_SERIALIZE_FLAG_STRICT)); + fail_if (gst_structure_serialize_full (s, GST_SERIALIZE_FLAG_STRICT)); gst_structure_free (s); }