From fe4bef8bbc829f1a4b800254f4c784fb4bce106b Mon Sep 17 00:00:00 2001 From: Julian Bouzas <julian.bouzas@collabora.com> Date: Thu, 16 Apr 2020 13:28:55 -0400 Subject: [PATCH] spa-pod: fix constness and add get_object_type_name and get_choice_type_name --- lib/wp/spa-pod.c | 129 +++++++++++++++++++++++++++------------------ lib/wp/spa-pod.h | 20 ++++--- tests/wp/spa-pod.c | 43 +++++++++++++++ 3 files changed, 134 insertions(+), 58 deletions(-) diff --git a/lib/wp/spa-pod.c b/lib/wp/spa-pod.c index 2f54c187..a3b57a63 100644 --- a/lib/wp/spa-pod.c +++ b/lib/wp/spa-pod.c @@ -84,7 +84,7 @@ struct _WpSpaPodParser { guint32 type; struct spa_pod_parser parser; - WpSpaPod *pod; + const WpSpaPod *pod; struct spa_pod_frame frame; WpSpaTypeTable prop_table; /* Only used when parsing properties */ }; @@ -160,14 +160,11 @@ wp_spa_pod_unref (WpSpaPod *self) wp_spa_pod_free (self); } -WpSpaPod * -wp_spa_pod_new_regular_wrap (struct spa_pod *pod) +static WpSpaPod * +wp_spa_pod_new (const struct spa_pod *pod) { WpSpaPod *self = g_slice_new0 (WpSpaPod); g_ref_count_init (&self->ref); - self->flags = FLAG_NO_OWNERSHIP; - self->type = WP_SPA_POD_REGULAR; - self->pod = pod; /* Set the prop table if it is an object */ if (pod->type == SPA_TYPE_Object) { @@ -180,15 +177,22 @@ wp_spa_pod_new_regular_wrap (struct spa_pod *pod) return self; } +WpSpaPod * +wp_spa_pod_new_regular_wrap (struct spa_pod *pod) +{ + WpSpaPod *self = wp_spa_pod_new (pod); + self->flags = FLAG_NO_OWNERSHIP; + self->type = WP_SPA_POD_REGULAR; + self->pod = pod; + return self; +} + WpSpaPod * wp_spa_pod_new_property_wrap (WpSpaTypeTable table, guint32 key, guint32 flags, struct spa_pod *pod) { - WpSpaPod *self = g_slice_new0 (WpSpaPod); - g_ref_count_init (&self->ref); - self->flags = FLAG_NO_OWNERSHIP; + WpSpaPod *self = wp_spa_pod_new_regular_wrap (pod); self->type = WP_SPA_POD_PROPERTY; - self->pod = pod; self->static_pod.data_property.table = table; self->static_pod.data_property.key = key; self->static_pod.data_property.flags = flags; @@ -198,11 +202,8 @@ wp_spa_pod_new_property_wrap (WpSpaTypeTable table, guint32 key, guint32 flags, WpSpaPod * wp_spa_pod_new_control_wrap (guint32 offset, guint32 type, struct spa_pod *pod) { - WpSpaPod *self = g_slice_new0 (WpSpaPod); - g_ref_count_init (&self->ref); - self->flags = FLAG_NO_OWNERSHIP; + WpSpaPod *self = wp_spa_pod_new_regular_wrap (pod); self->type = WP_SPA_POD_CONTROL; - self->pod = pod; self->static_pod.data_control.offset = offset; self->static_pod.data_control.type = type; return self; @@ -211,22 +212,13 @@ wp_spa_pod_new_control_wrap (guint32 offset, guint32 type, struct spa_pod *pod) WpSpaPod * wp_spa_pod_new_regular_wrap_copy (const struct spa_pod *pod) { - WpSpaPod *self = g_slice_new0 (WpSpaPod); - g_ref_count_init (&self->ref); + WpSpaPod *self = wp_spa_pod_new (pod); + self->flags = 0; self->type = WP_SPA_POD_REGULAR; self->builder = wp_spa_pod_builder_new ( SPA_ROUND_UP_N (sizeof (*pod) + pod->size, 8), pod->type); self->pod = self->builder->builder.data; spa_pod_builder_primitive (&self->builder->builder, pod); - - /* Set the prop table if it is an object */ - if (pod->type == SPA_TYPE_Object) { - WpSpaTypeTable prop_table = 0; - wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_BASIC, - ((struct spa_pod_object *) pod)->body.type, NULL, NULL, &prop_table); - self->static_pod.data_property.table = prop_table; - } - return self; } @@ -253,8 +245,8 @@ wp_spa_pod_new_control_wrap_copy (guint32 offset, guint32 type, return self; } -struct spa_pod * -wp_spa_pod_get_spa_pod (WpSpaPod *self) +const struct spa_pod * +wp_spa_pod_get_spa_pod (const WpSpaPod *self) { return self->pod; } @@ -277,6 +269,30 @@ wp_spa_pod_get_type_name (const WpSpaPod *self) return nick; } +const char * +wp_spa_pod_get_choice_type_name (const WpSpaPod *self) +{ + g_return_val_if_fail (wp_spa_pod_is_choice (self), NULL); + + const char *nick = NULL; + if (!wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_CHOICE, + SPA_POD_CHOICE_TYPE (self->pod), NULL, &nick, NULL)) + g_return_val_if_reached (NULL); + return nick; +} + +const char * +wp_spa_pod_get_object_type_name (const WpSpaPod *self) +{ + g_return_val_if_fail (wp_spa_pod_is_object (self), NULL); + + const char *nick = NULL; + if (!wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_BASIC, + SPA_POD_OBJECT_TYPE (self->pod), NULL, &nick, NULL)) + g_return_val_if_reached (NULL); + return nick; +} + /** * wp_spa_pod_copy: * @other: a spa pod object @@ -1621,7 +1637,7 @@ wp_spa_pod_equal (const WpSpaPod *self, const WpSpaPod *pod) * Returns: TRUE if the object properties values were obtained, FALSE otherwise */ gboolean -wp_spa_pod_get_object (WpSpaPod *self, const char *type_name, +wp_spa_pod_get_object (const WpSpaPod *self, const char *type_name, const char **id_name, ...) { va_list args; @@ -1644,7 +1660,7 @@ wp_spa_pod_get_object (WpSpaPod *self, const char *type_name, * Returns: TRUE if the object properties values were obtained, FALSE otherwise */ gboolean -wp_spa_pod_get_object_valist (WpSpaPod *self, const char *type_name, +wp_spa_pod_get_object_valist (const WpSpaPod *self, const char *type_name, const char **id_name, va_list args) { g_return_val_if_fail (self, FALSE); @@ -1666,7 +1682,7 @@ wp_spa_pod_get_object_valist (WpSpaPod *self, const char *type_name, * Returns: TRUE if the struct values were obtained, FALSE otherwise */ gboolean -wp_spa_pod_get_struct (WpSpaPod *self, ...) +wp_spa_pod_get_struct (const WpSpaPod *self, ...) { va_list args; gboolean res; @@ -1686,7 +1702,7 @@ wp_spa_pod_get_struct (WpSpaPod *self, ...) * Returns: TRUE if the struct values were obtained, FALSE otherwise */ gboolean -wp_spa_pod_get_struct_valist (WpSpaPod *self, va_list args) +wp_spa_pod_get_struct_valist (const WpSpaPod *self, va_list args) { g_return_val_if_fail (self, FALSE); g_return_val_if_fail (wp_spa_pod_is_struct (self), FALSE); @@ -2298,7 +2314,7 @@ wp_spa_pod_parser_ref (WpSpaPodParser *self) static void wp_spa_pod_parser_free (WpSpaPodParser *self) { - g_clear_pointer (&self->pod, wp_spa_pod_unref); + self->pod = NULL; } /** @@ -2315,11 +2331,11 @@ wp_spa_pod_parser_unref (WpSpaPodParser *self) } static WpSpaPodParser * -wp_spa_pod_parser_new (WpSpaPod *pod, guint32 type) +wp_spa_pod_parser_new (const WpSpaPod *pod, guint32 type) { WpSpaPodParser *self = g_rc_box_new0 (WpSpaPodParser); self->type = type; - self->pod = wp_spa_pod_ref (pod); + self->pod = pod; spa_pod_parser_pod (&self->parser, self->pod->pod); return self; } @@ -2330,12 +2346,13 @@ wp_spa_pod_parser_new (WpSpaPod *pod, guint32 type) * @type_name: the type name of the object type * @id_name: the Id name of the object * - * Creates an object spa pod parser + * Creates an object spa pod parser. The @pod object must be valid for the + * entire life-cycle of the returned parser. * * Returns: (transfer full): The new spa pod parser */ WpSpaPodParser * -wp_spa_pod_parser_new_object (WpSpaPod *pod, const char *type_name, +wp_spa_pod_parser_new_object (const WpSpaPod *pod, const char *type_name, const char **id_name) { WpSpaPodParser *self = NULL; @@ -2358,12 +2375,13 @@ wp_spa_pod_parser_new_object (WpSpaPod *pod, const char *type_name, * wp_spa_pod_parser_new_struct: * @pod: the struct spa pod to parse * - * Creates an struct spa pod parser + * Creates an struct spa pod parser. The @pod object must be valid for the + * entire life-cycle of the returned parser. * * Returns: (transfer full): The new spa pod parser */ WpSpaPodParser * -wp_spa_pod_parser_new_struct (WpSpaPod *pod) +wp_spa_pod_parser_new_struct (const WpSpaPod *pod) { WpSpaPodParser *self = NULL; @@ -2725,7 +2743,7 @@ wp_spa_pod_parser_end (WpSpaPodParser *self) struct _WpSpaPodIterator { - WpSpaPod *pod; + const WpSpaPod *pod; union { gpointer value; /* Array and Choice */ struct spa_pod *pod; /* Struct */ @@ -2738,7 +2756,8 @@ typedef struct _WpSpaPodIterator WpSpaPodIterator; static gboolean wp_spa_pod_iterator_next_choice (WpSpaPodIterator *self, GValue *item) { - struct spa_pod_choice *pod_choice = (struct spa_pod_choice *) self->pod->pod; + const struct spa_pod_choice *pod_choice = + (const struct spa_pod_choice *) self->pod->pod; if (!self->curr.value) self->curr.value = SPA_MEMBER (&pod_choice->body, sizeof(struct spa_pod_choice_body), void); @@ -2758,7 +2777,8 @@ wp_spa_pod_iterator_next_choice (WpSpaPodIterator *self, GValue *item) static gboolean wp_spa_pod_iterator_next_array (WpSpaPodIterator *self, GValue *item) { - struct spa_pod_array *pod_arr = (struct spa_pod_array *) self->pod->pod; + const struct spa_pod_array *pod_arr = + (const struct spa_pod_array *) self->pod->pod; if (!self->curr.value) self->curr.value = SPA_MEMBER (&pod_arr->body, sizeof(struct spa_pod_array_body), void); @@ -2778,7 +2798,8 @@ wp_spa_pod_iterator_next_array (WpSpaPodIterator *self, GValue *item) static gboolean wp_spa_pod_iterator_next_object (WpSpaPodIterator *self, GValue *item) { - struct spa_pod_object *pod_obj = (struct spa_pod_object *) self->pod->pod; + const struct spa_pod_object *pod_obj = + (const struct spa_pod_object *) self->pod->pod; g_autoptr (WpSpaPod) pod = NULL; if (!self->curr.prop) @@ -2821,7 +2842,8 @@ wp_spa_pod_iterator_next_struct (WpSpaPodIterator *self, GValue *item) static gboolean wp_spa_pod_iterator_next_sequence (WpSpaPodIterator *self, GValue *item) { - struct spa_pod_sequence *pod_seq = (struct spa_pod_sequence *) self->pod->pod; + const struct spa_pod_sequence *pod_seq = + (const struct spa_pod_sequence *) self->pod->pod; g_autoptr (WpSpaPod) pod = NULL; if (!self->curr.control) @@ -2887,7 +2909,8 @@ wp_spa_pod_iterator_fold (WpIterator *iterator, WpIteratorFoldFunc func, switch (self->pod->pod->type) { case SPA_TYPE_Choice: { - struct spa_pod_choice *pod_choice = (struct spa_pod_choice *) self->pod->pod; + const struct spa_pod_choice *pod_choice = + (const struct spa_pod_choice *) self->pod->pod; gpointer p = NULL; SPA_POD_CHOICE_FOREACH (pod_choice, p) { GValue v = G_VALUE_INIT; @@ -2902,7 +2925,8 @@ wp_spa_pod_iterator_fold (WpIterator *iterator, WpIteratorFoldFunc func, } case SPA_TYPE_Array: { - struct spa_pod_array *pod_arr = (struct spa_pod_array *) self->pod->pod; + const struct spa_pod_array *pod_arr = + (const struct spa_pod_array *) self->pod->pod; gpointer p = NULL; SPA_POD_ARRAY_FOREACH (pod_arr, p) { GValue v = G_VALUE_INIT; @@ -2917,7 +2941,8 @@ wp_spa_pod_iterator_fold (WpIterator *iterator, WpIteratorFoldFunc func, } case SPA_TYPE_Object: { - struct spa_pod_object *pod_obj = (struct spa_pod_object *) self->pod->pod; + const struct spa_pod_object *pod_obj = + (const struct spa_pod_object *) self->pod->pod; struct spa_pod_prop *p = NULL; SPA_POD_OBJECT_FOREACH (pod_obj, p) { GValue v = G_VALUE_INIT; @@ -2948,7 +2973,8 @@ wp_spa_pod_iterator_fold (WpIterator *iterator, WpIteratorFoldFunc func, } case SPA_TYPE_Sequence: { - struct spa_pod_sequence *pod_seq = (struct spa_pod_sequence *) self->pod->pod; + const struct spa_pod_sequence *pod_seq = + (const struct spa_pod_sequence *) self->pod->pod; struct spa_pod_control *p = NULL; SPA_POD_SEQUENCE_FOREACH (pod_seq, p) { GValue v = G_VALUE_INIT; @@ -2973,19 +2999,20 @@ static void wp_spa_pod_iterator_finalize (WpIterator *iterator) { WpSpaPodIterator *self = wp_iterator_get_user_data (iterator); - g_clear_pointer (&self->pod, wp_spa_pod_unref); + self->pod = NULL; } /** * wp_spa_pod_iterator_new: * @pod: a spa pod object * - * Creates a new iterator for a spa pod object + * Creates a new iterator for a spa pod object. The @pod object must be valid + * for the entire life-cycle of the returned iterator. * * Returns: (transfer full): the new spa pod iterator */ WpIterator * -wp_spa_pod_iterator_new (WpSpaPod *pod) +wp_spa_pod_iterator_new (const WpSpaPod *pod) { static const WpIteratorMethods methods = { .reset = wp_spa_pod_iterator_reset, @@ -2997,7 +3024,7 @@ wp_spa_pod_iterator_new (WpSpaPod *pod) WpIterator *it = wp_iterator_new (&methods, sizeof (WpSpaPodIterator)); WpSpaPodIterator *self = wp_iterator_get_user_data (it); - self->pod = wp_spa_pod_ref (pod); + self->pod = pod; return it; } diff --git a/lib/wp/spa-pod.h b/lib/wp/spa-pod.h index 66936755..1b2d2041 100644 --- a/lib/wp/spa-pod.h +++ b/lib/wp/spa-pod.h @@ -36,6 +36,12 @@ void wp_spa_pod_unref (WpSpaPod *self); WP_API const char *wp_spa_pod_get_type_name (const WpSpaPod *self); +WP_API +const char *wp_spa_pod_get_choice_type_name (const WpSpaPod *self); + +WP_API +const char *wp_spa_pod_get_object_type_name (const WpSpaPod *self); + WP_API WpSpaPod *wp_spa_pod_copy (const WpSpaPod *other); @@ -244,19 +250,19 @@ WP_API gboolean wp_spa_pod_equal (const WpSpaPod *self, const WpSpaPod *pod); WP_API -gboolean wp_spa_pod_get_object (WpSpaPod *self, const char *type_name, +gboolean wp_spa_pod_get_object (const WpSpaPod *self, const char *type_name, const char **id_name, ...) G_GNUC_NULL_TERMINATED; WP_API -gboolean wp_spa_pod_get_object_valist (WpSpaPod *self, +gboolean wp_spa_pod_get_object_valist (const WpSpaPod *self, const char *type_name, const char **id_name, va_list args); WP_API -gboolean wp_spa_pod_get_struct (WpSpaPod *self, ...) +gboolean wp_spa_pod_get_struct (const WpSpaPod *self, ...) G_GNUC_NULL_TERMINATED; WP_API -gboolean wp_spa_pod_get_struct_valist (WpSpaPod *self, va_list args); +gboolean wp_spa_pod_get_struct_valist (const WpSpaPod *self, va_list args); WP_API gboolean wp_spa_pod_get_property (const WpSpaPod *self, const char **key, @@ -391,11 +397,11 @@ WP_API void wp_spa_pod_parser_unref (WpSpaPodParser *self); WP_API -WpSpaPodParser *wp_spa_pod_parser_new_object (WpSpaPod *pod, +WpSpaPodParser *wp_spa_pod_parser_new_object (const WpSpaPod *pod, const char *type_name, const char **id_name); WP_API -WpSpaPodParser *wp_spa_pod_parser_new_struct (WpSpaPod *pod); +WpSpaPodParser *wp_spa_pod_parser_new_struct (const WpSpaPod *pod); WP_API gboolean wp_spa_pod_parser_get_boolean (WpSpaPodParser *self, gboolean *value); @@ -455,7 +461,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (WpSpaPodParser, wp_spa_pod_parser_unref) WP_API -WpIterator *wp_spa_pod_iterator_new (WpSpaPod *pod); +WpIterator *wp_spa_pod_iterator_new (const WpSpaPod *pod); G_END_DECLS diff --git a/tests/wp/spa-pod.c b/tests/wp/spa-pod.c index 7ba96a7c..07eaa60e 100644 --- a/tests/wp/spa-pod.c +++ b/tests/wp/spa-pod.c @@ -307,6 +307,7 @@ test_spa_pod_choice (void) g_assert_nonnull (pod); g_assert_true (wp_spa_pod_is_choice (pod)); g_assert_cmpstr ("Choice", ==, wp_spa_pod_get_type_name (pod)); + g_assert_cmpstr ("Enum", ==, wp_spa_pod_get_choice_type_name (pod)); g_autoptr (WpSpaPod) child = wp_spa_pod_get_choice_child (pod); g_assert_nonnull (child); @@ -424,6 +425,7 @@ test_spa_pod_object (void) g_assert_nonnull (pod); g_assert_true (wp_spa_pod_is_object (pod)); g_assert_cmpstr ("Object", ==, wp_spa_pod_get_type_name (pod)); + g_assert_cmpstr ("Props", ==, wp_spa_pod_get_object_type_name (pod)); const char *id_name; gboolean mute = TRUE; @@ -1026,6 +1028,46 @@ test_spa_pod_unique_owner (void) wp_spa_type_deinit (); } +static void +test_spa_pod_port_config (void) +{ + wp_spa_type_init (TRUE); + + const gint rate = 48000; + const gint channels = 2; + + /* Build the format to make sure the types exist */ + g_autoptr (WpSpaPodBuilder) builder = wp_spa_pod_builder_new_object ( + "Format", "Format"); + wp_spa_pod_builder_add (builder, + "mediaType", "I", 0, + "mediaSubtype", "I", 0, + "format", "I", 0, + "rate", "i", rate, + "channels", "i", channels, + NULL); + g_autoptr (WpSpaPodBuilder) position_builder = wp_spa_pod_builder_new_array (); + for (guint i = 0; i < channels; i++) + wp_spa_pod_builder_add_id (position_builder, 0); + wp_spa_pod_builder_add_property (builder, "position"); + g_autoptr (WpSpaPod) position = wp_spa_pod_builder_end (position_builder); + wp_spa_pod_builder_add_pod (builder, position); + g_autoptr (WpSpaPod) format = wp_spa_pod_builder_end (builder); + g_assert_nonnull (format); + + /* Build the port config to make sure the types exist */ + g_autoptr (WpSpaPod) pod = wp_spa_pod_new_object ("PortConfig", "PortConfig", + "direction", "I", 0, + "mode", "I", 0, + "monitor", "b", FALSE, + "control", "b", FALSE, + "format", "P", format, + NULL); + g_assert_nonnull (pod); + + wp_spa_type_deinit (); +} + int main (int argc, char *argv[]) { @@ -1040,6 +1082,7 @@ main (int argc, char *argv[]) g_test_add_func ("/wp/spa-pod/sequence", test_spa_pod_sequence); g_test_add_func ("/wp/spa-pod/iterator", test_spa_pod_iterator); g_test_add_func ("/wp/spa-pod/unique-owner", test_spa_pod_unique_owner); + g_test_add_func ("/wp/spa-pod/port-config", test_spa_pod_port_config); return g_test_run (); } -- GitLab