src.ctf.fs: validate parameters using param-validation
[babeltrace.git] / src / plugins / ctf / fs-src / fs.c
index 454b4aeea88eb13613b4afdd3e3ffbe9d54f050b..cb07c73d022666675897026dfa1fb23fb5aac0b9 100644 (file)
@@ -45,6 +45,7 @@
 #include "../common/metadata/ctf-meta-configure-ir-trace.h"
 #include "../common/msg-iter/msg-iter.h"
 #include "query.h"
+#include "plugins/common/param-validation/param-validation.h"
 
 struct tracer_info {
        const char *name;
@@ -248,15 +249,16 @@ void ctf_fs_iterator_finalize(bt_self_message_iterator *it)
 }
 
 BT_HIDDEN
-bt_component_class_message_iterator_init_method_status ctf_fs_iterator_init(
+bt_component_class_message_iterator_initialize_method_status ctf_fs_iterator_init(
                bt_self_message_iterator *self_msg_iter,
+               bt_self_message_iterator_configuration *config,
                bt_self_component_source *self_comp_src,
                bt_self_component_port_output *self_port)
 {
        struct ctf_fs_port_data *port_data;
        struct ctf_fs_msg_iter_data *msg_iter_data = NULL;
-       bt_component_class_message_iterator_init_method_status ret =
-               BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_OK;
+       bt_component_class_message_iterator_initialize_method_status ret =
+               BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INITIALIZE_METHOD_STATUS_OK;
        bt_logging_level log_level;
        bt_self_component *self_comp =
                bt_self_component_source_as_self_component(self_comp_src);
@@ -268,7 +270,7 @@ bt_component_class_message_iterator_init_method_status ctf_fs_iterator_init(
        log_level = port_data->ctf_fs->log_level;
        msg_iter_data = g_new0(struct ctf_fs_msg_iter_data, 1);
        if (!msg_iter_data) {
-               ret = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_MEMORY_ERROR;
+               ret = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
                goto error;
        }
 
@@ -282,22 +284,30 @@ bt_component_class_message_iterator_init_method_status ctf_fs_iterator_init(
                self_comp);
        if (!msg_iter_data->msg_iter) {
                BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Cannot create a CTF message iterator.");
-               ret = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_MEMORY_ERROR;
+               ret = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
                goto error;
        }
 
        msg_iter_data->ds_file_group = port_data->ds_file_group;
        if (ctf_fs_iterator_reset(msg_iter_data)) {
-               ret = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_ERROR;
+               ret = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INITIALIZE_METHOD_STATUS_ERROR;
                goto error;
        }
 
+       /*
+        * This iterator can seek forward if its stream class has a default
+        * clock class.
+        */
+       if (msg_iter_data->ds_file_group->sc->default_clock_class) {
+               bt_self_message_iterator_configuration_set_can_seek_forward(
+                       config, true);
+       }
+
        bt_self_message_iterator_set_data(self_msg_iter,
                msg_iter_data);
-       if (ret != BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_OK) {
+       if (ret != BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INITIALIZE_METHOD_STATUS_OK) {
                goto error;
        }
-
        msg_iter_data = NULL;
        goto end;
 
@@ -1969,6 +1979,22 @@ end:
        return ret;
 }
 
+static
+gint compare_ds_file_groups_by_first_path(gconstpointer a, gconstpointer b)
+{
+       struct ctf_fs_ds_file_group * const *ds_file_group_a = a;
+       struct ctf_fs_ds_file_group * const *ds_file_group_b = b;
+       const struct ctf_fs_ds_file_info *first_ds_file_info_a;
+       const struct ctf_fs_ds_file_info *first_ds_file_info_b;
+
+       BT_ASSERT((*ds_file_group_a)->ds_file_infos->len > 0);
+       BT_ASSERT((*ds_file_group_b)->ds_file_infos->len > 0);
+       first_ds_file_info_a = (*ds_file_group_a)->ds_file_infos->pdata[0];
+       first_ds_file_info_b = (*ds_file_group_b)->ds_file_infos->pdata[0];
+       return strcmp(first_ds_file_info_a->path->str,
+               first_ds_file_info_b->path->str);
+}
+
 int ctf_fs_component_create_ctf_fs_trace(
                struct ctf_fs_component *ctf_fs,
                const bt_value *paths_value,
@@ -2065,6 +2091,20 @@ int ctf_fs_component_create_ctf_fs_trace(
                        "Failed to fix packet index tracer bugs.");
        }
 
+       /*
+        * Sort data stream file groups by first data stream file info
+        * path to get a deterministic order. This order influences the
+        * order of the output ports. It also influences the order of
+        * the automatic stream IDs if the trace's packet headers do not
+        * contain a `stream_instance_id` field, in which case the data
+        * stream file to stream ID association is always the same,
+        * whatever the build and the system.
+        *
+        * Having a deterministic order here can help debugging and
+        * testing.
+        */
+       g_ptr_array_sort(ctf_fs->trace->ds_file_groups,
+               compare_ds_file_groups_by_first_path);
        goto end;
 error:
        ret = -1;
@@ -2175,63 +2215,26 @@ end:
        return ret;
 }
 
-/*
- * Validate the "paths" parameter passed to this component.  It must be
- * present, and it must be an array of strings.
- */
-
-static
-bool validate_inputs_parameter(struct ctf_fs_component *ctf_fs,
-               const bt_value *inputs, bt_self_component *self_comp,
-               bt_self_component_class *self_comp_class)
-{
-       bool ret;
-       bt_value_type type;
-       uint64_t i;
-       bt_logging_level log_level = ctf_fs->log_level;
-
-       if (!inputs) {
-               BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp,
-                       self_comp_class, "missing \"inputs\" parameter");
-               goto error;
-       }
-
-       type = bt_value_get_type(inputs);
-       if (type != BT_VALUE_TYPE_ARRAY) {
-               BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp,
-                       self_comp_class, "`inputs` parameter: expecting array value: type=%s",
-                       bt_common_value_type_string(type));
-               goto error;
-       }
-
-       if (bt_value_array_is_empty(inputs)) {
-               BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp,
-                       self_comp_class, "`inputs` parameter must not be empty");
-               goto error;
-       }
-
-       for (i = 0; i < bt_value_array_get_length(inputs); i++) {
-               const bt_value *elem;
+static const struct bt_param_validation_value_descr inputs_elem_descr = {
+       .type = BT_VALUE_TYPE_STRING,
+};
 
-               elem = bt_value_array_borrow_element_by_index_const(inputs, i);
-               type = bt_value_get_type(elem);
-               if (type != BT_VALUE_TYPE_STRING) {
-                       BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class,
-                               "`inputs` parameter: expecting string value: index=%" PRIu64 ", type=%s",
-                               i, bt_common_value_type_string(type));
-                       goto error;
+static const struct bt_param_validation_map_value_entry_descr fs_params_entries_descr[] = {
+       { "inputs", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, {
+               BT_VALUE_TYPE_ARRAY,
+               .array = {
+                       .min_length = 1,
+                       .max_length = BT_PARAM_VALIDATION_INFINITE,
+                       .element_type = &inputs_elem_descr,
                }
-       }
+       }},
+       { "trace-name", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, { .type = BT_VALUE_TYPE_STRING } },
+       { "clock-class-offset-s", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, { .type = BT_VALUE_TYPE_SIGNED_INTEGER } },
+       { "clock-class-offset-ns", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, { .type = BT_VALUE_TYPE_SIGNED_INTEGER } },
+       { "force-clock-class-origin-unix-epoch", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, { .type = BT_VALUE_TYPE_BOOL } },
+       BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
+};
 
-       ret = true;
-       goto end;
-
-error:
-       ret = false;
-
-end:
-       return ret;
-}
 
 bool read_src_fs_parameters(const bt_value *params,
                const bt_value **inputs,
@@ -2242,22 +2245,25 @@ bool read_src_fs_parameters(const bt_value *params,
        bool ret;
        const bt_value *value;
        bt_logging_level log_level = ctf_fs->log_level;
+       enum bt_param_validation_status validate_value_status;
+       gchar *error = NULL;
+
+       validate_value_status = bt_param_validation_validate(params,
+               fs_params_entries_descr, &error);
+       if (validate_value_status != BT_PARAM_VALIDATION_STATUS_OK) {
+               BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class,
+                       "%s", error);
+               ret = false;
+               goto end;
+       }
 
        /* inputs parameter */
        *inputs = bt_value_map_borrow_entry_value_const(params, "inputs");
-       if (!validate_inputs_parameter(ctf_fs, *inputs, self_comp, self_comp_class)) {
-               goto error;
-       }
 
        /* clock-class-offset-s parameter */
        value = bt_value_map_borrow_entry_value_const(params,
                "clock-class-offset-s");
        if (value) {
-               if (!bt_value_is_signed_integer(value)) {
-                       BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class,
-                               "clock-class-offset-s must be an integer");
-                       goto error;
-               }
                ctf_fs->metadata_config.clock_class_offset_s =
                        bt_value_integer_signed_get(value);
        }
@@ -2266,32 +2272,25 @@ bool read_src_fs_parameters(const bt_value *params,
        value = bt_value_map_borrow_entry_value_const(params,
                "clock-class-offset-ns");
        if (value) {
-               if (!bt_value_is_signed_integer(value)) {
-                       BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class,
-                               "clock-class-offset-ns must be an integer");
-                       goto error;
-               }
                ctf_fs->metadata_config.clock_class_offset_ns =
                        bt_value_integer_signed_get(value);
        }
 
+       /* force-clock-class-origin-unix-epoch parameter */
+       value = bt_value_map_borrow_entry_value_const(params,
+               "force-clock-class-origin-unix-epoch");
+       if (value) {
+               ctf_fs->metadata_config.force_clock_class_origin_unix_epoch =
+                       bt_value_bool_get(value);
+       }
+
        /* trace-name parameter */
        *trace_name = bt_value_map_borrow_entry_value_const(params, "trace-name");
-       if (*trace_name) {
-               if (!bt_value_is_string(*trace_name)) {
-                       BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class,
-                               "trace-name must be a string");
-                       goto error;
-               }
-       }
 
        ret = true;
-       goto end;
-
-error:
-       ret = false;
 
 end:
+       g_free(error);
        return ret;
 }
 
@@ -2345,17 +2344,18 @@ end:
 }
 
 BT_HIDDEN
-bt_component_class_init_method_status ctf_fs_init(
+bt_component_class_initialize_method_status ctf_fs_init(
                bt_self_component_source *self_comp_src,
+               bt_self_component_source_configuration *config,
                const bt_value *params, __attribute__((unused)) void *init_method_data)
 {
        struct ctf_fs_component *ctf_fs;
-       bt_component_class_init_method_status ret =
-               BT_COMPONENT_CLASS_INIT_METHOD_STATUS_OK;
+       bt_component_class_initialize_method_status ret =
+               BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
 
        ctf_fs = ctf_fs_create(params, self_comp_src, NULL);
        if (!ctf_fs) {
-               ret = BT_COMPONENT_CLASS_INIT_METHOD_STATUS_ERROR;
+               ret = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
        }
 
        return ret;
This page took 0.026934 seconds and 4 git commands to generate.