From 366e034f3d491ee6774a2aeb864067582e0da557 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Fri, 17 Feb 2017 15:08:38 -0500 Subject: [PATCH] Add ports to the source, filter and sink component interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérémie Galarneau --- .../component/component-filter-internal.h | 3 +- .../babeltrace/component/component-filter.h | 34 +- .../babeltrace/component/component-internal.h | 32 ++ .../component/component-sink-internal.h | 3 +- include/babeltrace/component/component-sink.h | 45 +-- .../component/component-source-internal.h | 1 + .../babeltrace/component/component-source.h | 25 +- lib/component/component.c | 178 ++++++++++ lib/component/filter.c | 323 ++++++++++++------ lib/component/sink.c | 174 +++------- lib/component/source.c | 132 ++++++- 11 files changed, 648 insertions(+), 302 deletions(-) diff --git a/include/babeltrace/component/component-filter-internal.h b/include/babeltrace/component/component-filter-internal.h index 9bedec53..1d4cc9a7 100644 --- a/include/babeltrace/component/component-filter-internal.h +++ b/include/babeltrace/component/component-filter-internal.h @@ -30,13 +30,12 @@ #include #include #include -#include struct bt_value; struct bt_component_filter { struct bt_component parent; - struct component_input input; + GPtrArray *input_ports, *output_ports; }; /** diff --git a/include/babeltrace/component/component-filter.h b/include/babeltrace/component/component-filter.h index cba61f68..32863b9f 100644 --- a/include/babeltrace/component/component-filter.h +++ b/include/babeltrace/component/component-filter.h @@ -34,6 +34,7 @@ extern "C" { #endif +struct bt_port; struct bt_component; struct bt_notification_iterator; @@ -63,24 +64,23 @@ extern struct bt_notification_iterator *bt_component_filter_create_notification_iterator_with_init_method_data( struct bt_component *component, void *init_method_data); -/* Defaults to 1. */ -extern enum bt_component_status -bt_component_filter_set_minimum_input_count(struct bt_component *filter, - unsigned int minimum); - -/* Defaults to 1. */ -extern enum bt_component_status -bt_component_filter_set_maximum_input_count(struct bt_component *filter, - unsigned int maximum); - -extern enum bt_component_status -bt_component_filter_get_input_count(struct bt_component *filter, - unsigned int *count); +extern int bt_component_filter_get_input_port_count( + struct bt_component *component); +extern struct bt_port *bt_component_filter_get_input_port( + struct bt_component *component, const char *name); +extern struct bt_port *bt_component_filter_get_input_port_at_index( + struct bt_component *component, int index); +extern struct bt_port *bt_component_filter_get_default_input_port( + struct bt_component *component); -/* May return NULL after an interator has reached its end. */ -extern enum bt_component_status -bt_component_filter_get_input_iterator(struct bt_component *filter, - unsigned int input, struct bt_notification_iterator **iterator); +extern int bt_component_filter_get_output_port_count( + struct bt_component *component); +extern struct bt_port *bt_component_filter_get_output_port( + struct bt_component *component, const char *name); +extern struct bt_port *bt_component_filter_get_output_port_at_index( + struct bt_component *component, int index); +extern struct bt_port *bt_component_filter_get_default_output_port( + struct bt_component *component); #ifdef __cplusplus } diff --git a/include/babeltrace/component/component-internal.h b/include/babeltrace/component/component-internal.h index 5d466c21..bc876c12 100644 --- a/include/babeltrace/component/component-internal.h +++ b/include/babeltrace/component/component-internal.h @@ -30,10 +30,14 @@ #include #include #include +#include #include #include #include +#define DEFAULT_INPUT_PORT_NAME "default" +#define DEFAULT_OUTPUT_PORT_NAME "default" + struct bt_component { struct bt_object base; struct bt_component_class *class; @@ -63,4 +67,32 @@ BT_HIDDEN struct bt_notification_iterator *bt_component_create_iterator( struct bt_component *component, void *init_method_data); +BT_HIDDEN +enum bt_component_status bt_component_set_graph(struct bt_component *component, + struct bt_graph *graph); + +BT_HIDDEN +int bt_component_init_input_ports(struct bt_component *component, + GPtrArray **input_ports); + +BT_HIDDEN +int bt_component_init_output_ports(struct bt_component *component, + GPtrArray **output_ports); + +BT_HIDDEN +struct bt_port *bt_component_get_port(GPtrArray *ports, const char *name); + +BT_HIDDEN +struct bt_port *bt_component_get_port_at_index(GPtrArray *ports, int index); + +BT_HIDDEN +struct bt_port *bt_component_add_port( + struct bt_component *component,GPtrArray *ports, + enum bt_port_type port_type, const char *name); + +BT_HIDDEN +enum bt_component_status bt_component_remove_port( + struct bt_component *component, GPtrArray *ports, + const char *name); + #endif /* BABELTRACE_COMPONENT_COMPONENT_INTERNAL_H */ diff --git a/include/babeltrace/component/component-sink-internal.h b/include/babeltrace/component/component-sink-internal.h index a8e0eb78..81833e66 100644 --- a/include/babeltrace/component/component-sink-internal.h +++ b/include/babeltrace/component/component-sink-internal.h @@ -30,7 +30,6 @@ #include #include #include -#include struct bt_value; @@ -38,7 +37,7 @@ struct bt_value; struct bt_component_sink { struct bt_component parent; - struct component_input input; + GPtrArray *input_ports; /* notification_mask_t registered_notifications_mask;*/ }; diff --git a/include/babeltrace/component/component-sink.h b/include/babeltrace/component/component-sink.h index a37221d5..659bce5b 100644 --- a/include/babeltrace/component/component-sink.h +++ b/include/babeltrace/component/component-sink.h @@ -4,7 +4,7 @@ /* * BabelTrace - Sink Component Interface * - * Copyright 2015 Jérémie Galarneau + * Copyright 2017 Jérémie Galarneau * * Author: Jérémie Galarneau * @@ -36,18 +36,6 @@ extern "C" { struct bt_component; struct bt_notification; -/** - * Add a notification iterator to a sink component. - * - * @param component Component instance - * @param iterator Notification iterator to add - * @returns One of #bt_component_status values - */ -extern -enum bt_component_status bt_component_sink_add_iterator( - struct bt_component *component, - struct bt_notification_iterator *iterator); - /** * Process one event, consuming from sources as needed. * @@ -58,24 +46,21 @@ extern enum bt_component_status bt_component_sink_consume( struct bt_component *component); -/* Defaults to 1. */ -extern enum bt_component_status -bt_component_sink_set_minimum_input_count(struct bt_component *sink, - unsigned int minimum); - -/* Defaults to 1. */ -extern enum bt_component_status -bt_component_sink_set_maximum_input_count(struct bt_component *sink, - unsigned int maximum); - -extern enum bt_component_status -bt_component_sink_get_input_count(struct bt_component *sink, - unsigned int *count); +extern int bt_component_sink_get_input_port_count( + struct bt_component *component); +extern struct bt_port *bt_component_sink_get_input_port( + struct bt_component *component, const char *name); +extern struct bt_port *bt_component_sink_get_input_port_at_index( + struct bt_component *component, int index); -/* May return NULL after an interator has reached its end. */ -extern enum bt_component_status -bt_component_sink_get_input_iterator(struct bt_component *sink, - unsigned int input, struct bt_notification_iterator **iterator); +/* Only allowed during the sink's initialization. */ +extern struct bt_port *bt_component_sink_add_input_port( + struct bt_component *component, const char *name); +/* Only allowed during the sink's initialization. */ +extern enum bt_component_status bt_component_sink_remove_input_port( + struct bt_component *component, const char *name); +extern struct bt_port *bt_component_sink_get_default_input_port( + struct bt_component *component); #ifdef __cplusplus } diff --git a/include/babeltrace/component/component-source-internal.h b/include/babeltrace/component/component-source-internal.h index fcf646de..99b0f5bf 100644 --- a/include/babeltrace/component/component-source-internal.h +++ b/include/babeltrace/component/component-source-internal.h @@ -35,6 +35,7 @@ struct bt_value; struct bt_component_source { struct bt_component parent; + GPtrArray *output_ports; }; /** diff --git a/include/babeltrace/component/component-source.h b/include/babeltrace/component/component-source.h index 662fe39d..7bea78da 100644 --- a/include/babeltrace/component/component-source.h +++ b/include/babeltrace/component/component-source.h @@ -37,19 +37,22 @@ extern "C" { struct bt_component; struct bt_notification_iterator; -/** - * Create an iterator on a component instance. - * - * @param component Component instance - * @returns Notification iterator instance - */ -extern -struct bt_notification_iterator *bt_component_source_create_notification_iterator( +/* FIXME should return a bt_component_status, same applies for filter and sink. Use uint64_t. */ +extern int bt_component_source_get_output_port_count( + struct bt_component *component); +extern struct bt_port *bt_component_source_get_output_port( + struct bt_component *component, const char *name); +extern struct bt_port *bt_component_source_get_output_port_at_index( + struct bt_component *component, int index); +extern struct bt_port *bt_component_source_get_default_output_port( struct bt_component *component); -extern -struct bt_notification_iterator *bt_component_source_create_notification_iterator_with_init_method_data( - struct bt_component *component, void *init_method_data); +/* Only allowed during the source's initialization. */ +extern struct bt_port *bt_component_source_add_output_port( + struct bt_component *component, const char *name); +/* Only allowed during the source's initialization. */ +extern enum bt_component_status bt_component_source_remove_output_port( + struct bt_component *component, const char *name); #ifdef __cplusplus } diff --git a/lib/component/component.c b/lib/component/component.c index c2290a86..31aad81b 100644 --- a/lib/component/component.c +++ b/lib/component/component.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -295,3 +296,180 @@ bt_component_set_private_data(struct bt_component *component, end: return ret; } + +BT_HIDDEN +enum bt_component_status bt_component_set_graph(struct bt_component *component, + struct bt_graph *graph) +{ + bt_object_set_parent(component, &graph->base); + return BT_COMPONENT_STATUS_OK; +} + +struct bt_graph *bt_component_get_graph( + struct bt_component *component) +{ + return (struct bt_graph *) bt_object_get_parent(&component->base); +} + +BT_HIDDEN +int bt_component_init_input_ports(struct bt_component *component, + GPtrArray **input_ports) +{ + int ret = 0; + struct bt_port *default_port; + + *input_ports = g_ptr_array_new_with_free_func(bt_object_release); + if (*input_ports) { + ret = -1; + goto end; + } + + default_port = bt_port_create(component, BT_PORT_TYPE_INPUT, + DEFAULT_INPUT_PORT_NAME); + if (!default_port) { + ret = -1; + goto end; + } + + g_ptr_array_add(*input_ports, default_port); +end: + return ret; +} + +BT_HIDDEN +int bt_component_init_output_ports(struct bt_component *component, + GPtrArray **output_ports) +{ + int ret = 0; + struct bt_port *default_port; + + *output_ports = g_ptr_array_new_with_free_func(bt_object_release); + if (*output_ports) { + ret = -1; + goto end; + } + + default_port = bt_port_create(component, BT_PORT_TYPE_OUTPUT, + DEFAULT_OUTPUT_PORT_NAME); + if (!default_port) { + ret = -1; + goto end; + } + + g_ptr_array_add(*output_ports, default_port); +end: + return ret; +} + +BT_HIDDEN +struct bt_port *bt_component_get_port(GPtrArray *ports, const char *name) +{ + size_t i; + struct bt_port *ret_port = NULL; + + for (i = 0; i < ports->len; i++) { + struct bt_port *port = g_ptr_array_index(ports, i); + const char *port_name = bt_port_get_name(port); + + if (!port_name) { + continue; + } + + if (!strcmp(name, port_name)) { + ret_port = bt_get(port); + break; + } + } + + return ret_port; +} + +BT_HIDDEN +struct bt_port *bt_component_get_port_at_index(GPtrArray *ports, int index) +{ + struct bt_port *port = NULL; + + if (index < 0 || index >= ports->len) { + goto end; + } + + port = bt_get(g_ptr_array_index(ports, index)); +end: + return port; +} + +BT_HIDDEN +struct bt_port *bt_component_add_port( + struct bt_component *component,GPtrArray *ports, + enum bt_port_type port_type, const char *name) +{ + size_t i; + struct bt_port *new_port; + + if (!component->initializing || !name || *name == '\0') { + new_port = NULL; + goto end; + } + + new_port = bt_port_create(component, port_type, name); + if (!new_port) { + goto end; + } + + /* Look for a port having the same name. */ + for (i = 0; i < ports->len; i++) { + const char *port_name; + struct bt_port *port = g_ptr_array_index( + ports, i); + + port_name = bt_port_get_name(port); + if (!port_name) { + continue; + } + + if (!strcmp(name, port_name)) { + /* Port name clash, abort. */ + goto error; + } + } + + /* No name clash, add the port. */ + g_ptr_array_add(ports, bt_get(new_port)); +end: + return new_port; +error: + BT_PUT(new_port); + goto end; +} + +BT_HIDDEN +enum bt_component_status bt_component_remove_port( + struct bt_component *component, GPtrArray *ports, + const char *name) +{ + size_t i; + enum bt_component_status status = BT_COMPONENT_STATUS_OK; + + if (!component->initializing || !name) { + status = BT_COMPONENT_STATUS_INVALID; + goto end; + } + + for (i = 0; i < ports->len; i++) { + const char *port_name; + struct bt_port *port = g_ptr_array_index(ports, i); + + port_name = bt_port_get_name(port); + if (!port_name) { + continue; + } + + if (!strcmp(name, port_name)) { + g_ptr_array_remove_index(ports, i); + goto end; + } + } + status = BT_COMPONENT_STATUS_NOT_FOUND; +end: + return status; +} diff --git a/lib/component/filter.c b/lib/component/filter.c index 153e38f2..23190709 100644 --- a/lib/component/filter.c +++ b/lib/component/filter.c @@ -28,21 +28,20 @@ #include #include -#include #include #include #include #include #include -enum bt_component_status bt_component_filter_set_minimum_input_count( +enum bt_component_status bt_component_filter_add_iterator( struct bt_component *component, - unsigned int minimum) + struct bt_notification_iterator *iterator) { - struct bt_component_filter *filter; enum bt_component_status ret = BT_COMPONENT_STATUS_OK; + struct bt_component_class_filter *filter_class; - if (!component) { + if (!component || !iterator) { ret = BT_COMPONENT_STATUS_INVALID; goto end; } @@ -52,210 +51,308 @@ enum bt_component_status bt_component_filter_set_minimum_input_count( goto end; } - if (!component->initializing) { - ret = BT_COMPONENT_STATUS_INVALID; - goto end; + /* TODO validate iterator count limits. */ + + filter_class = container_of(component->class, + struct bt_component_class_filter, parent); + if (filter_class->methods.add_iterator) { + ret = filter_class->methods.add_iterator(component, iterator); + if (ret != BT_COMPONENT_STATUS_OK) { + goto end; + } } - filter = container_of(component, struct bt_component_filter, parent); - filter->input.min_count = minimum; end: return ret; } -enum bt_component_status bt_component_filter_set_maximum_input_count( - struct bt_component *component, - unsigned int maximum) +struct bt_notification_iterator *bt_component_filter_create_notification_iterator( + struct bt_component *component) { - struct bt_component_filter *filter; - enum bt_component_status ret = BT_COMPONENT_STATUS_OK; + return bt_component_create_iterator(component, NULL); +} - if (!component) { - ret = BT_COMPONENT_STATUS_INVALID; - goto end; - } +struct bt_notification_iterator *bt_component_filter_create_notification_iterator_with_init_method_data( + struct bt_component *component, void *init_method_data) +{ + return bt_component_create_iterator(component, init_method_data); +} - if (bt_component_get_class_type(component) != BT_COMPONENT_CLASS_TYPE_FILTER) { - ret = BT_COMPONENT_STATUS_UNSUPPORTED; - goto end; - } +static +void bt_component_filter_destroy(struct bt_component *component) +{ + struct bt_component_filter *filter = container_of(component, + struct bt_component_filter, parent); - if (!component->initializing) { - ret = BT_COMPONENT_STATUS_INVALID; - goto end; + if (filter->input_ports) { + g_ptr_array_free(filter->input_ports, TRUE); } - filter = container_of(component, struct bt_component_filter, parent); - filter->input.max_count = maximum; -end: - return ret; + if (filter->output_ports) { + g_ptr_array_free(filter->output_ports, TRUE); + } } -enum bt_component_status -bt_component_filter_get_input_count(struct bt_component *component, - unsigned int *count) +BT_HIDDEN +struct bt_component *bt_component_filter_create( + struct bt_component_class *class, struct bt_value *params) { - struct bt_component_filter *filter; - enum bt_component_status ret = BT_COMPONENT_STATUS_OK; + int ret; + struct bt_component_filter *filter = NULL; + enum bt_component_status status; - if (!component || !count) { - ret = BT_COMPONENT_STATUS_INVALID; + filter = g_new0(struct bt_component_filter, 1); + if (!filter) { goto end; } - if (bt_component_get_class_type(component) != BT_COMPONENT_CLASS_TYPE_FILTER) { - ret = BT_COMPONENT_STATUS_UNSUPPORTED; - goto end; + filter->parent.class = bt_get(class); + status = bt_component_init(&filter->parent, bt_component_filter_destroy); + if (status != BT_COMPONENT_STATUS_OK) { + goto error; + } + + ret = bt_component_init_input_ports(&filter->parent, + &filter->input_ports); + if (ret) { + goto error; + } + + ret = bt_component_init_output_ports(&filter->parent, + &filter->output_ports); + if (ret) { + goto error; } - filter = container_of(component, struct bt_component_filter, parent); - *count = (unsigned int) filter->input.iterators->len; end: - return ret; + return filter ? &filter->parent : NULL; +error: + BT_PUT(filter); + goto end; } -enum bt_component_status -bt_component_filter_get_input_iterator(struct bt_component *component, - unsigned int input, struct bt_notification_iterator **iterator) +BT_HIDDEN +enum bt_component_status bt_component_filter_validate( + struct bt_component *component) { - struct bt_component_filter *filter; enum bt_component_status ret = BT_COMPONENT_STATUS_OK; - if (!component || !iterator) { + if (!component) { ret = BT_COMPONENT_STATUS_INVALID; goto end; } - if (bt_component_get_class_type(component) != BT_COMPONENT_CLASS_TYPE_FILTER) { - ret = BT_COMPONENT_STATUS_UNSUPPORTED; + if (!component->class) { + ret = BT_COMPONENT_STATUS_INVALID; goto end; } - filter = container_of(component, struct bt_component_filter, parent); - if (input >= (unsigned int) filter->input.iterators->len) { + if (component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) { ret = BT_COMPONENT_STATUS_INVALID; goto end; } - *iterator = bt_get(g_ptr_array_index(filter->input.iterators, input)); + /* Enforce iterator limits. */ end: return ret; } -enum bt_component_status bt_component_filter_add_iterator( - struct bt_component *component, - struct bt_notification_iterator *iterator) +int bt_component_filter_get_input_port_count(struct bt_component *component) { + int ret; struct bt_component_filter *filter; - enum bt_component_status ret = BT_COMPONENT_STATUS_OK; - struct bt_component_class_filter *filter_class; - if (!component || !iterator) { - ret = BT_COMPONENT_STATUS_INVALID; + if (!component) { + ret = -1; goto end; } - if (bt_component_get_class_type(component) != BT_COMPONENT_CLASS_TYPE_FILTER) { - ret = BT_COMPONENT_STATUS_UNSUPPORTED; + if (component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) { + ret = -1; goto end; } filter = container_of(component, struct bt_component_filter, parent); - if (filter->input.iterators->len == filter->input.max_count) { - ret = BT_COMPONENT_STATUS_UNSUPPORTED; + ret = filter->input_ports->len; +end: + return ret; +} + +struct bt_port *bt_component_filter_get_input_port( + struct bt_component *component, const char *name) +{ + struct bt_component_filter *filter; + struct bt_port *ret_port = NULL; + + if (!component || !name || + component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) { goto end; } - filter_class = container_of(component->class, struct bt_component_class_filter, parent); + filter = container_of(component, struct bt_component_filter, parent); + ret_port = bt_component_get_port(filter->input_ports, name); +end: + return ret_port; +} - if (filter_class->methods.add_iterator) { - ret = filter_class->methods.add_iterator(component, iterator); - if (ret != BT_COMPONENT_STATUS_OK) { - goto end; - } +struct bt_port *bt_component_filter_get_input_port_at_index( + struct bt_component *component, int index) +{ + struct bt_port *port = NULL; + struct bt_component_filter *filter; + + if (!component || + component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) { + goto end; } - g_ptr_array_add(filter->input.iterators, bt_get(iterator)); + filter = container_of(component, struct bt_component_filter, parent); + port = bt_component_get_port_at_index(filter->input_ports, index); end: - return ret; + return port; } -struct bt_notification_iterator *bt_component_filter_create_notification_iterator( +struct bt_port *bt_component_filter_get_default_input_port( struct bt_component *component) { - return bt_component_create_iterator(component, NULL); + return bt_component_filter_get_input_port(component, + DEFAULT_INPUT_PORT_NAME); } -struct bt_notification_iterator *bt_component_filter_create_notification_iterator_with_init_method_data( - struct bt_component *component, void *init_method_data) +struct bt_port *bt_component_filter_add_input_port( + struct bt_component *component, const char *name) { - return bt_component_create_iterator(component, init_method_data); + struct bt_port *port; + struct bt_component_filter *filter; + + if (!component || + component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) { + port = NULL; + goto end; + } + + filter = container_of(component, struct bt_component_filter, parent); + port = bt_component_add_port(component, filter->input_ports, + BT_PORT_TYPE_INPUT, name); +end: + return port; } -static -void bt_component_filter_destroy(struct bt_component *component) +enum bt_component_status bt_component_filter_remove_input_port( + struct bt_component *component, const char *name) { - struct bt_component_filter *filter = container_of(component, - struct bt_component_filter, parent); + enum bt_component_status status; + struct bt_component_filter *filter; - component_input_fini(&filter->input); + if (!component || + component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) { + status = BT_COMPONENT_STATUS_INVALID; + goto end; + } + + filter = container_of(component, struct bt_component_filter, parent); + status = bt_component_remove_port(component, filter->input_ports, + name); +end: + return status; } -BT_HIDDEN -struct bt_component *bt_component_filter_create( - struct bt_component_class *class, struct bt_value *params) +int bt_component_filter_get_output_port_count(struct bt_component *component) { - struct bt_component_filter *filter = NULL; - enum bt_component_status ret; + int ret; + struct bt_component_filter *filter; - filter = g_new0(struct bt_component_filter, 1); - if (!filter) { + if (!component) { + ret = -1; goto end; } - filter->parent.class = bt_get(class); - ret = bt_component_init(&filter->parent, bt_component_filter_destroy); - if (ret != BT_COMPONENT_STATUS_OK) { - goto error; + if (component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) { + ret = -1; + goto end; } - if (component_input_init(&filter->input)) { - goto error; - } + filter = container_of(component, struct bt_component_filter, parent); + ret = filter->output_ports->len; end: - return filter ? &filter->parent : NULL; -error: - BT_PUT(filter); - goto end; + return ret; } -BT_HIDDEN -enum bt_component_status bt_component_filter_validate( - struct bt_component *component) +struct bt_port *bt_component_filter_get_output_port( + struct bt_component *component, const char *name) { - enum bt_component_status ret = BT_COMPONENT_STATUS_OK; struct bt_component_filter *filter; + struct bt_port *ret_port = NULL; - if (!component) { - ret = BT_COMPONENT_STATUS_INVALID; + if (!component || !name || + component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) { goto end; } - if (!component->class) { - ret = BT_COMPONENT_STATUS_INVALID; + filter = container_of(component, struct bt_component_filter, parent); + ret_port = bt_component_get_port(filter->output_ports, name); +end: + return ret_port; +} + +struct bt_port *bt_component_filter_get_output_port_at_index( + struct bt_component *component, int index) +{ + struct bt_port *port = NULL; + struct bt_component_filter *filter; + + if (!component || + component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) { goto end; } - if (component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) { - ret = BT_COMPONENT_STATUS_INVALID; + filter = container_of(component, struct bt_component_filter, parent); + port = bt_component_get_port_at_index(filter->output_ports, index); +end: + return port; +} + +struct bt_port *bt_component_filter_get_default_output_port( + struct bt_component *component) +{ + return bt_component_filter_get_output_port(component, + DEFAULT_OUTPUT_PORT_NAME); +} + +struct bt_port *bt_component_filter_add_output_port( + struct bt_component *component, const char *name) +{ + struct bt_port *port; + struct bt_component_filter *filter; + + if (!component || + component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) { + port = NULL; goto end; } filter = container_of(component, struct bt_component_filter, parent); - ret = component_input_validate(&filter->input); - if (ret) { + port = bt_component_add_port(component, filter->output_ports, + BT_PORT_TYPE_OUTPUT, name); +end: + return port; +} + +enum bt_component_status bt_component_filter_remove_output_port( + struct bt_component *component, const char *name) +{ + enum bt_component_status status; + struct bt_component_filter *filter; + + if (!component || + component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) { + status = BT_COMPONENT_STATUS_INVALID; goto end; } + + filter = container_of(component, struct bt_component_filter, parent); + status = bt_component_remove_port(component, filter->output_ports, + name); end: - return ret; + return status; } diff --git a/lib/component/sink.c b/lib/component/sink.c index 954e758a..43f56807 100644 --- a/lib/component/sink.c +++ b/lib/component/sink.c @@ -37,7 +37,6 @@ enum bt_component_status bt_component_sink_validate( struct bt_component *component) { enum bt_component_status ret = BT_COMPONENT_STATUS_OK; - struct bt_component_sink *sink; if (!component) { ret = BT_COMPONENT_STATUS_INVALID; @@ -53,12 +52,6 @@ enum bt_component_status bt_component_sink_validate( ret = BT_COMPONENT_STATUS_INVALID; goto end; } - - sink = container_of(component, struct bt_component_sink, parent); - ret = component_input_validate(&sink->input); - if (ret) { - goto end; - } end: return ret; } @@ -69,7 +62,9 @@ void bt_component_sink_destroy(struct bt_component *component) struct bt_component_sink *sink = container_of(component, struct bt_component_sink, parent); - component_input_fini(&sink->input); + if (sink->input_ports) { + g_ptr_array_free(sink->input_ports, TRUE); + } } BT_HIDDEN @@ -97,9 +92,12 @@ struct bt_component *bt_component_sink_create( goto error; } */ - if (component_input_init(&sink->input)) { + ret = bt_component_init_input_ports(&sink->parent, + &sink->input_ports); + if (ret) { goto error; } + end: return sink ? &sink->parent : NULL; error: @@ -107,24 +105,10 @@ error: return NULL; } -static -enum bt_component_status validate_inputs(struct bt_component_sink *sink) -{ - size_t array_size = sink->input.iterators->len; - - if (array_size < sink->input.min_count || - array_size > sink->input.max_count) { - return BT_COMPONENT_STATUS_INVALID; - } - - return BT_COMPONENT_STATUS_OK; -} - enum bt_component_status bt_component_sink_consume( struct bt_component *component) { enum bt_component_status ret = BT_COMPONENT_STATUS_OK; - struct bt_component_sink *sink = NULL; struct bt_component_class_sink *sink_class = NULL; if (!component) { @@ -137,15 +121,6 @@ enum bt_component_status bt_component_sink_consume( goto end; } - sink = container_of(component, struct bt_component_sink, parent); - if (!sink->input.validated) { - ret = validate_inputs(sink); - if (ret != BT_COMPONENT_STATUS_OK) { - goto end; - } - sink->input.validated = true; - } - sink_class = container_of(component->class, struct bt_component_class_sink, parent); assert(sink_class->methods.consume); ret = sink_class->methods.consume(component); @@ -187,147 +162,102 @@ end: } */ -enum bt_component_status bt_component_sink_set_minimum_input_count( - struct bt_component *component, - unsigned int minimum) +int bt_component_sink_get_input_port_count(struct bt_component *component) { + int ret; struct bt_component_sink *sink; - enum bt_component_status ret = BT_COMPONENT_STATUS_OK; if (!component) { - ret = BT_COMPONENT_STATUS_INVALID; - goto end; - } - - if (bt_component_get_class_type(component) != BT_COMPONENT_CLASS_TYPE_SINK) { - ret = BT_COMPONENT_STATUS_UNSUPPORTED; + ret = -1; goto end; } - if (!component->initializing) { - ret = BT_COMPONENT_STATUS_INVALID; + if (component->class->type != BT_COMPONENT_CLASS_TYPE_SINK) { + ret = -1; goto end; } sink = container_of(component, struct bt_component_sink, parent); - sink->input.min_count = minimum; + ret = sink->input_ports->len; end: return ret; } -enum bt_component_status bt_component_sink_set_maximum_input_count( - struct bt_component *component, - unsigned int maximum) +struct bt_port *bt_component_sink_get_input_port( + struct bt_component *component, const char *name) { struct bt_component_sink *sink; - enum bt_component_status ret = BT_COMPONENT_STATUS_OK; - - if (!component) { - ret = BT_COMPONENT_STATUS_INVALID; - goto end; - } - - if (bt_component_get_class_type(component) != BT_COMPONENT_CLASS_TYPE_SINK) { - ret = BT_COMPONENT_STATUS_UNSUPPORTED; - goto end; - } + struct bt_port *ret_port = NULL; - if (!component->initializing) { - ret = BT_COMPONENT_STATUS_INVALID; + if (!component || !name || + component->class->type != BT_COMPONENT_CLASS_TYPE_SINK) { goto end; } sink = container_of(component, struct bt_component_sink, parent); - sink->input.max_count = maximum; + ret_port = bt_component_get_port(sink->input_ports, name); end: - return ret; + return ret_port; } -enum bt_component_status -bt_component_sink_get_input_count(struct bt_component *component, - unsigned int *count) +struct bt_port *bt_component_sink_get_input_port_at_index( + struct bt_component *component, int index) { + struct bt_port *port = NULL; struct bt_component_sink *sink; - enum bt_component_status ret = BT_COMPONENT_STATUS_OK; - if (!component || !count) { - ret = BT_COMPONENT_STATUS_INVALID; - goto end; - } - - if (bt_component_get_class_type(component) != BT_COMPONENT_CLASS_TYPE_SINK) { - ret = BT_COMPONENT_STATUS_UNSUPPORTED; + if (!component || + component->class->type != BT_COMPONENT_CLASS_TYPE_SINK) { goto end; } sink = container_of(component, struct bt_component_sink, parent); - *count = (unsigned int) sink->input.iterators->len; + port = bt_component_get_port_at_index(sink->input_ports, index); end: - return ret; + return port; } -enum bt_component_status -bt_component_sink_get_input_iterator(struct bt_component *component, - unsigned int input, struct bt_notification_iterator **iterator) +struct bt_port *bt_component_sink_get_default_input_port( + struct bt_component *component) { - struct bt_component_sink *sink; - enum bt_component_status ret = BT_COMPONENT_STATUS_OK; + return bt_component_sink_get_input_port(component, + DEFAULT_INPUT_PORT_NAME); +} - if (!component || !iterator) { - ret = BT_COMPONENT_STATUS_INVALID; - goto end; - } +struct bt_port *bt_component_sink_add_input_port( + struct bt_component *component, const char *name) +{ + struct bt_port *port; + struct bt_component_sink *sink; - if (bt_component_get_class_type(component) != BT_COMPONENT_CLASS_TYPE_SINK) { - ret = BT_COMPONENT_STATUS_UNSUPPORTED; + if (!component || + component->class->type != BT_COMPONENT_CLASS_TYPE_SINK) { + port = NULL; goto end; } sink = container_of(component, struct bt_component_sink, parent); - if (input >= (unsigned int) sink->input.iterators->len) { - ret = BT_COMPONENT_STATUS_INVALID; - goto end; - } - - *iterator = bt_get(g_ptr_array_index(sink->input.iterators, input)); + port = bt_component_add_port(component, sink->input_ports, + BT_PORT_TYPE_INPUT, name); end: - return ret; + return port; } -enum bt_component_status -bt_component_sink_add_iterator(struct bt_component *component, - struct bt_notification_iterator *iterator) +enum bt_component_status bt_component_sink_remove_input_port( + struct bt_component *component, const char *name) { + enum bt_component_status status; struct bt_component_sink *sink; - enum bt_component_status ret = BT_COMPONENT_STATUS_OK; - struct bt_component_class_sink *sink_class; - if (!component || !iterator) { - ret = BT_COMPONENT_STATUS_INVALID; - goto end; - } - - if (bt_component_get_class_type(component) != BT_COMPONENT_CLASS_TYPE_SINK) { - ret = BT_COMPONENT_STATUS_UNSUPPORTED; + if (!component || + component->class->type != BT_COMPONENT_CLASS_TYPE_SINK) { + status = BT_COMPONENT_STATUS_INVALID; goto end; } sink = container_of(component, struct bt_component_sink, parent); - if (sink->input.iterators->len == sink->input.max_count) { - ret = BT_COMPONENT_STATUS_UNSUPPORTED; - goto end; - } - - sink_class = container_of(component->class, struct bt_component_class_sink, parent); - - if (sink_class->methods.add_iterator) { - ret = sink_class->methods.add_iterator(component, iterator); - if (ret != BT_COMPONENT_STATUS_OK) { - goto end; - } - } - - g_ptr_array_add(sink->input.iterators, bt_get(iterator)); + status = bt_component_remove_port(component, sink->input_ports, + name); end: - return ret; + return status; } diff --git a/lib/component/source.c b/lib/component/source.c index 393b12f8..0baa3f9b 100644 --- a/lib/component/source.c +++ b/lib/component/source.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -58,12 +59,25 @@ end: return ret; } +static +void bt_component_source_destroy(struct bt_component *component) +{ + struct bt_component_source *source = container_of(component, + struct bt_component_source, parent); + + if (source->output_ports) { + g_ptr_array_free(source->output_ports, TRUE); + } +} + + BT_HIDDEN struct bt_component *bt_component_source_create( struct bt_component_class *class, struct bt_value *params) { + int ret; struct bt_component_source *source = NULL; - enum bt_component_status ret; + enum bt_component_status status; source = g_new0(struct bt_component_source, 1); if (!source) { @@ -71,13 +85,21 @@ struct bt_component *bt_component_source_create( } source->parent.class = bt_get(class); - ret = bt_component_init(&source->parent, NULL); - if (ret != BT_COMPONENT_STATUS_OK) { - BT_PUT(source); - goto end; + status = bt_component_init(&source->parent, bt_component_source_destroy); + if (status != BT_COMPONENT_STATUS_OK) { + goto error; } + + ret = bt_component_init_output_ports(&source->parent, &source->output_ports); + if (ret) { + goto error; + } + end: return source ? &source->parent : NULL; +error: + BT_PUT(source); + goto end; } struct bt_notification_iterator *bt_component_source_create_notification_iterator( @@ -91,3 +113,103 @@ struct bt_notification_iterator *bt_component_source_create_notification_iterato { return bt_component_create_iterator(component, init_method_data); } + +int bt_component_source_get_output_port_count(struct bt_component *component) +{ + int ret; + struct bt_component_source *source; + + if (!component) { + ret = -1; + goto end; + } + + if (component->class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) { + ret = -1; + goto end; + } + + source = container_of(component, struct bt_component_source, parent); + ret = source->output_ports->len; +end: + return ret; +} + +struct bt_port *bt_component_source_get_output_port( + struct bt_component *component, const char *name) +{ + struct bt_component_source *source; + struct bt_port *ret_port = NULL; + + if (!component || !name || + component->class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) { + goto end; + } + + source = container_of(component, struct bt_component_source, parent); + ret_port = bt_component_get_port(source->output_ports, name); +end: + return ret_port; +} + +struct bt_port *bt_component_source_get_output_port_at_index( + struct bt_component *component, int index) +{ + struct bt_port *port = NULL; + struct bt_component_source *source; + + if (!component || + component->class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) { + goto end; + } + + source = container_of(component, struct bt_component_source, parent); + port = bt_component_get_port_at_index(source->output_ports, index); +end: + return port; +} + +struct bt_port *bt_component_source_get_default_output_port( + struct bt_component *component) +{ + return bt_component_source_get_output_port(component, + DEFAULT_OUTPUT_PORT_NAME); +} + +struct bt_port *bt_component_source_add_output_port( + struct bt_component *component, const char *name) +{ + struct bt_port *port; + struct bt_component_source *source; + + if (!component || + component->class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) { + port = NULL; + goto end; + } + + source = container_of(component, struct bt_component_source, parent); + port = bt_component_add_port(component, source->output_ports, + BT_PORT_TYPE_OUTPUT, name); +end: + return port; +} + +enum bt_component_status bt_component_source_remove_output_port( + struct bt_component *component, const char *name) +{ + enum bt_component_status status; + struct bt_component_source *source; + + if (!component || + component->class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) { + status = BT_COMPONENT_STATUS_INVALID; + goto end; + } + + source = container_of(component, struct bt_component_source, parent); + status = bt_component_remove_port(component, source->output_ports, + name); +end: + return status; +} -- 2.34.1