List detected component classes
[babeltrace.git] / plugins / component.c
index 86e86ade9ad8f69934f2a540850e90d44313d96b..5cfbbf0e3403e9d2d7f87b4f562864a04e168c66 100644 (file)
 
 #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_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->class->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_ref_get(&component->ref);
+       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_ref_put(&component->ref);
+       return component ? bt_get(component->class) : NULL;
 }
 
-BT_HIDDEN
-enum bt_component_status bt_component_init(struct bt_component *component,
-               struct bt_component_class *class, const char *name,
-               bt_component_destroy_cb 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 || !class || !name || name[0] == '\0' || destroy) {
+       if (!component) {
                ret = BT_COMPONENT_STATUS_INVAL;
                goto end;
        }
 
-       bt_ref_init(&component->ref, bt_component_destroy);
-       bt_component_class_get(class);
-       component->class = class;
-       component->name = g_string_new(name);
-       if (!component->name) {
-               ret = BT_COMPONENT_STATUS_NOMEM;
-               goto end;
-       }
-       component->destroy = destroy;
+       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
@@ -160,28 +210,3 @@ bt_component_set_private_data(struct bt_component *component,
 end:
        return ret;
 }
-
-static
-void bt_component_destroy(struct bt_ref *ref)
-{
-       struct bt_component *component = NULL;
-
-       if (!ref) {
-               return;
-       }
-
-       component = container_of(ref, struct bt_component, ref);
-
-       /**
-        * User data is destroyed first, followed by the concrete component
-        * instance.
-        */
-       assert(!component->user_data || component->user_destroy);
-       component->user_destroy(component->user_data);
-
-       g_string_free(component->name, TRUE);
-
-       assert(component->destroy);
-       component->destroy(component);
-       bt_component_class_put(component->class);
-}
This page took 0.026343 seconds and 4 git commands to generate.