goto end;
}
-static
-enum bt_component_status get_component_port_counts(
- struct bt_component *component, int64_t *input_count,
- int64_t *output_count)
-{
- enum bt_component_status ret;
-
- switch (bt_component_get_class_type(component)) {
- case BT_COMPONENT_CLASS_TYPE_SOURCE:
- *output_count =
- bt_component_source_get_output_port_count(component);
- if (*output_count < 0) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- break;
- case BT_COMPONENT_CLASS_TYPE_FILTER:
- *output_count =
- bt_component_filter_get_output_port_count(component);
- if (*output_count < 0) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- *input_count =
- bt_component_filter_get_input_port_count(component);
- if (*input_count < 0) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- break;
- case BT_COMPONENT_CLASS_TYPE_SINK:
- *input_count =
- bt_component_sink_get_input_port_count(component);
- if (*input_count < 0) {
- ret = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
- break;
- default:
- assert(BT_FALSE);
- break;
- }
- ret = BT_COMPONENT_STATUS_OK;
-end:
- return ret;
-}
-
-enum bt_graph_status bt_graph_add_component_as_sibling(struct bt_graph *graph,
- struct bt_component *origin,
- struct bt_component *new_component)
-{
- int64_t origin_input_port_count = 0;
- int64_t origin_output_port_count = 0;
- int64_t new_input_port_count = 0;
- int64_t new_output_port_count = 0;
- enum bt_graph_status status = BT_GRAPH_STATUS_OK;
- struct bt_graph *origin_graph = NULL;
- struct bt_graph *new_graph = NULL;
- struct bt_port *origin_port = NULL;
- struct bt_port *new_port = NULL;
- struct bt_port *upstream_port = NULL;
- struct bt_port *downstream_port = NULL;
- struct bt_connection *origin_connection = NULL;
- struct bt_connection *new_connection = NULL;
- int64_t port_index;
-
- if (!graph || !origin || !new_component) {
- status = BT_GRAPH_STATUS_INVALID;
- goto end;
- }
-
- if (graph->canceled) {
- status = BT_GRAPH_STATUS_CANCELED;
- goto end;
- }
-
- if (bt_component_get_class_type(origin) !=
- bt_component_get_class_type(new_component)) {
- status = BT_GRAPH_STATUS_INVALID;
- goto end;
- }
-
- origin_graph = bt_component_get_graph(origin);
- if (!origin_graph || (origin_graph != graph)) {
- status = BT_GRAPH_STATUS_INVALID;
- goto end;
- }
-
- new_graph = bt_component_get_graph(new_component);
- if (new_graph) {
- status = BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH;
- goto end;
- }
-
- if (get_component_port_counts(origin, &origin_input_port_count,
- &origin_output_port_count) != BT_COMPONENT_STATUS_OK) {
- status = BT_GRAPH_STATUS_INVALID;
- goto end;
- }
- if (get_component_port_counts(new_component, &new_input_port_count,
- &new_output_port_count) != BT_COMPONENT_STATUS_OK) {
- status = BT_GRAPH_STATUS_INVALID;
- goto end;
- }
-
- if (origin_input_port_count != new_input_port_count ||
- origin_output_port_count != new_output_port_count) {
- status = BT_GRAPH_STATUS_INVALID;
- goto end;
- }
-
- /* Replicate input connections. */
- for (port_index = 0; port_index< origin_input_port_count; port_index++) {
- origin_port = bt_component_get_input_port_by_index(origin,
- port_index);
- if (!origin_port) {
- status = BT_GRAPH_STATUS_ERROR;
- goto error_disconnect;
- }
-
- new_port = bt_component_get_input_port_by_index(new_component,
- port_index);
- if (!new_port) {
- status = BT_GRAPH_STATUS_ERROR;
- goto error_disconnect;
- }
-
- origin_connection = bt_port_get_connection(origin_port);
- if (origin_connection) {
- upstream_port = bt_connection_get_upstream_port(
- origin_connection);
- if (!upstream_port) {
- goto error_disconnect;
- }
-
- new_connection = bt_graph_connect_ports(graph,
- upstream_port, new_port);
- if (!new_connection) {
- goto error_disconnect;
- }
- }
-
- BT_PUT(upstream_port);
- BT_PUT(origin_connection);
- BT_PUT(new_connection);
- BT_PUT(origin_port);
- BT_PUT(new_port);
- }
-
- /* Replicate output connections. */
- for (port_index = 0; port_index < origin_output_port_count; port_index++) {
- origin_port = bt_component_get_output_port_by_index(origin,
- port_index);
- if (!origin_port) {
- status = BT_GRAPH_STATUS_ERROR;
- goto error_disconnect;
- }
- new_port = bt_component_get_output_port_by_index(new_component,
- port_index);
- if (!new_port) {
- status = BT_GRAPH_STATUS_ERROR;
- goto error_disconnect;
- }
-
- origin_connection = bt_port_get_connection(origin_port);
- if (origin_connection) {
- downstream_port = bt_connection_get_downstream_port(
- origin_connection);
- if (!downstream_port) {
- goto error_disconnect;
- }
-
- new_connection = bt_graph_connect_ports(graph,
- new_port, downstream_port);
- if (!new_connection) {
- goto error_disconnect;
- }
- }
-
- BT_PUT(downstream_port);
- BT_PUT(origin_connection);
- BT_PUT(new_connection);
- BT_PUT(origin_port);
- BT_PUT(new_port);
- }
-end:
- bt_put(origin_graph);
- bt_put(new_graph);
- bt_put(origin_port);
- bt_put(new_port);
- bt_put(upstream_port);
- bt_put(downstream_port);
- bt_put(origin_connection);
- bt_put(new_connection);
- return status;
-error_disconnect:
- /* Destroy all connections of the new component. */
- /* FIXME. */
- goto end;
-}
-
enum bt_graph_status bt_graph_consume(struct bt_graph *graph)
{
struct bt_component *sink;