* SOFTWARE.
*/
+#include <babeltrace/plugin/component.h>
#include <babeltrace/plugin/component-internal.h>
+#include <babeltrace/plugin/source-internal.h>
+#include <babeltrace/plugin/sink-internal.h>
#include <babeltrace/babeltrace-internal.h>
#include <babeltrace/compiler.h>
+#include <babeltrace/ref.h>
-static void bt_component_destroy(struct bt_ctf_ref *ref);
+static
+struct bt_component * (* const component_create_funcs[])(
+ struct bt_component_class *, struct bt_value *) = {
+ [BT_COMPONENT_TYPE_SOURCE] = bt_component_source_create,
+ [BT_COMPONENT_TYPE_SINK] = bt_component_sink_create,
+};
-const char *bt_component_get_name(struct bt_component *component)
+static
+enum bt_component_status (* const component_validation_funcs[])(
+ struct bt_component *) = {
+ [BT_COMPONENT_TYPE_SOURCE] = bt_component_source_validate,
+ [BT_COMPONENT_TYPE_SINK] = bt_component_sink_validate,
+};
+
+static
+void bt_component_destroy(struct bt_object *obj)
{
- const char *ret = NULL;
+ struct bt_component *component = NULL;
+ struct bt_component_class *component_class = NULL;
- if (!component) {
- goto end;
+ if (!obj) {
+ return;
}
- ret = component->name->str;
-end:
- return ret;
+ component = container_of(obj, struct bt_component, base);
+
+ assert(component->destroy);
+ component_class = component->class;
+
+ /*
+ * User data is destroyed first, followed by the concrete component
+ * instance.
+ */
+ if (component->user_destroy) {
+ component->user_destroy(component->user_data);
+ }
+
+ component->destroy(component);
+ g_string_free(component->name, TRUE);
+ bt_put(component_class);
+ g_free(component);
}
-enum bt_component_status bt_component_set_name(struct bt_component *component,
- const char *name)
+BT_HIDDEN
+enum bt_component_status bt_component_init(struct bt_component *component,
+ bt_component_destroy_cb destroy)
{
enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- if (!component || !name || name[0] == '\0') {
+ if (!component || !destroy) {
ret = BT_COMPONENT_STATUS_INVAL;
goto end;
}
- g_string_assign(component->name, name);
+ component->destroy = destroy;
end:
return ret;
}
+BT_HIDDEN
enum bt_component_type bt_component_get_type(struct bt_component *component)
{
- enum bt_component_type type = BT_COMPONENT_TYPE_UNKNOWN;
+ return component ? component->class->type : BT_COMPONENT_TYPE_UNKNOWN;
+}
+
+struct bt_component *bt_component_create(
+ struct bt_component_class *component_class, const char *name,
+ struct bt_value *params)
+{
+ int ret;
+ struct bt_component *component = NULL;
+ enum bt_component_type type;
+
+ if (!component_class) {
+ goto end;
+ }
+
+ type = bt_component_class_get_type(component_class);
+ if (type <= BT_COMPONENT_TYPE_UNKNOWN ||
+ type >= BT_COMPONENT_TYPE_FILTER) {
+ /* Filter components are not supported yet. */
+ goto end;
+ }
+ component = component_create_funcs[type](component_class, params);
if (!component) {
goto end;
}
- type = component->type;
+ bt_object_init(component, bt_component_destroy);
+ component->class = bt_get(component_class);
+ component->name = g_string_new(name);
+ if (component->name) {
+ BT_PUT(component);
+ goto end;
+ }
+
+ component_class->init(component, params);
+ ret = component_validation_funcs[type](component);
+ if (ret) {
+ BT_PUT(component);
+ goto end;
+ }
end:
- return type;
+ return component;
}
-enum bt_component_status bt_component_set_error_stream(
- struct bt_component *component, FILE *stream)
+const char *bt_component_get_name(struct bt_component *component)
{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ const char *ret = NULL;
if (!component) {
- ret = BT_COMPONENT_STATUS_INVAL;
goto end;
}
- component->error_stream = stream;
+ ret = component->name->str;
end:
return ret;
}
-void bt_component_get(struct bt_component *component)
+enum bt_component_status bt_component_set_name(struct bt_component *component,
+ const char *name)
{
- if (!component) {
- return;
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+
+ if (!component || !name || name[0] == '\0') {
+ ret = BT_COMPONENT_STATUS_INVAL;
+ goto end;
}
- bt_ctf_ref_get(&component->ref_count);
+ g_string_assign(component->name, name);
+end:
+ return ret;
}
-void bt_component_put(struct bt_component *component)
+struct bt_component_class *bt_component_get_class(
+ struct bt_component *component)
{
- if (!component) {
- return;
- }
-
- bt_ctf_ref_put(&component->ref_count, bt_component_destroy);
+ return component ? bt_get(component->class) : NULL;
}
-BT_HIDDEN
-enum bt_component_status bt_component_init(struct bt_component *component, const char *name,
- void *user_data, bt_component_destroy_cb user_destroy_func,
- enum bt_component_type component_type,
- bt_component_destroy_cb component_destroy)
+enum bt_component_status bt_component_set_error_stream(
+ struct bt_component *component, FILE *stream)
{
enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
- if (!component || !name || name[0] == '\0' ||
- !user_destroy_func || !user_data || !component_destroy) {
+ if (!component) {
ret = BT_COMPONENT_STATUS_INVAL;
goto end;
}
- bt_ctf_ref_init(&component->ref_count);
- component->type = component_type;
- component->user_data = user_data;
- component->user_data_destroy = user_destroy_func;
- component->destroy = component_destroy;
-
- component->name = g_string_new(name);
- if (!component->name) {
- ret = BT_COMPONENT_STATUS_NOMEM;
- goto end;
- }
+ component->error_stream = stream;
end:
return ret;
}
void *bt_component_get_private_data(struct bt_component *component)
{
- void *ret = NULL;
-
- if (!component) {
- goto end;
- }
-
- ret = component->user_data;
-end:
- return ret;
+ return component ? component->user_data : NULL;
}
enum bt_component_status
end:
return ret;
}
-
-static
-void bt_component_destroy(struct bt_ctf_ref *ref)
-{
- struct bt_component *component = NULL;
-
- if (!ref) {
- return;
- }
-
- component = container_of(ref, struct bt_component, ref_count);
-
- /**
- * User data is destroyed first, followed by the concrete component
- * instance.
- */
- assert(!component->user_data || component->user_data_destroy);
- component->user_data_destroy(component->user_data);
-
- g_string_free(component->name, TRUE);
-
- assert(component->destroy);
- component->destroy(component);
-}