Rename <babeltrace/component/...> -> <babeltrace/graph/...>
[babeltrace.git] / plugins / ctf / fs / fs.c
index 3a60b0d5e40d4dd632658c73fed9b30f7290bcb1..9a38834a7ca56a0499d0978b8d7d06de5e78a53f 100644 (file)
  * SOFTWARE.
  */
 
-#include <babeltrace/plugin/plugin-system.h>
 #include <babeltrace/ctf-ir/packet.h>
-#include <babeltrace/ctf-ir/clock.h>
-#include <babeltrace/plugin/notification/iterator.h>
-#include <babeltrace/plugin/notification/stream.h>
-#include <babeltrace/plugin/notification/event.h>
-#include <babeltrace/plugin/notification/packet.h>
-#include <babeltrace/plugin/notification/heap.h>
+#include <babeltrace/ctf-ir/clock-class.h>
+#include <babeltrace/graph/private-component.h>
+#include <babeltrace/graph/component.h>
+#include <babeltrace/graph/notification-iterator.h>
+#include <babeltrace/graph/private-notification-iterator.h>
+#include <babeltrace/graph/notification-stream.h>
+#include <babeltrace/graph/notification-event.h>
+#include <babeltrace/graph/notification-packet.h>
+#include <babeltrace/graph/notification-heap.h>
+#include <plugins-common.h>
 #include <glib.h>
 #include <assert.h>
 #include <unistd.h>
 #define PRINT_ERR_STREAM       ctf_fs->error_fp
 #define PRINT_PREFIX           "ctf-fs"
 #include "print.h"
+#define METADATA_TEXT_SIG      "/* CTF 1.8"
 
 BT_HIDDEN
 bool ctf_fs_debug;
 
-static
-enum bt_notification_iterator_status ctf_fs_iterator_next(
-               struct bt_notification_iterator *iterator);
-
-static
-struct bt_notification *ctf_fs_iterator_get(
-               struct bt_notification_iterator *iterator)
-{
-       struct ctf_fs_iterator *ctf_it =
-                       bt_notification_iterator_get_private_data(iterator);
-
-       if (!ctf_it->current_notification) {
-               (void) ctf_fs_iterator_next(iterator);
-       }
-
-       return bt_get(ctf_it->current_notification);
-}
+struct bt_notification_iterator_next_return ctf_fs_iterator_next(
+               struct bt_private_notification_iterator *iterator);
 
 static
 enum bt_notification_iterator_status ctf_fs_iterator_get_next_notification(
@@ -144,11 +133,11 @@ struct bt_ctf_stream *internal_bt_notification_get_stream(
                bt_put(event);
                break;
        }
-       case BT_NOTIFICATION_TYPE_PACKET_START:
+       case BT_NOTIFICATION_TYPE_PACKET_BEGIN:
        {
                struct bt_ctf_packet *packet;
 
-               packet = bt_notification_packet_start_get_packet(notification);
+               packet = bt_notification_packet_begin_get_packet(notification);
                stream = bt_ctf_packet_get_stream(packet);
                bt_put(packet);
                break;
@@ -246,47 +235,49 @@ end:
        return ret;
 }
 
-static
-enum bt_notification_iterator_status ctf_fs_iterator_next(
-               struct bt_notification_iterator *iterator)
+struct bt_notification_iterator_next_return ctf_fs_iterator_next(
+               struct bt_private_notification_iterator *iterator)
 {
        int heap_ret;
        struct bt_ctf_stream *stream = NULL;
        struct ctf_fs_stream *fs_stream;
-       struct bt_notification *notification;
        struct bt_notification *next_stream_notification;
-       enum bt_notification_iterator_status ret =
-                       BT_NOTIFICATION_ITERATOR_STATUS_OK;
        struct ctf_fs_iterator *ctf_it =
-                       bt_notification_iterator_get_private_data(iterator);
+                       bt_private_notification_iterator_get_user_data(
+                               iterator);
+       struct bt_notification_iterator_next_return ret = {
+               .status = BT_NOTIFICATION_ITERATOR_STATUS_OK,
+               .notification = NULL,
+       };
 
-       notification = bt_notification_heap_pop(ctf_it->pending_notifications);
-       if (!notification && !ctf_it->pending_streams) {
-               ret = BT_NOTIFICATION_ITERATOR_STATUS_END;
+       ret.notification =
+               bt_notification_heap_pop(ctf_it->pending_notifications);
+       if (!ret.notification && !ctf_it->pending_streams) {
+               ret.status = BT_NOTIFICATION_ITERATOR_STATUS_END;
                goto end;
        }
 
-       if (!notification && ctf_it->pending_streams) {
+       if (!ret.notification && ctf_it->pending_streams) {
                /*
                 * Insert at one notification per stream in the heap and pop
                 * one.
                 */
-               ret = populate_heap(ctf_it);
-               if (ret) {
+               ret.status = populate_heap(ctf_it);
+               if (ret.status) {
                        goto end;
                }
 
-               notification = bt_notification_heap_pop(
+               ret.notification = bt_notification_heap_pop(
                                ctf_it->pending_notifications);
-               if (!notification) {
-                       ret = BT_NOTIFICATION_ITERATOR_STATUS_END;
+               if (!ret.notification) {
+                       ret.status = BT_NOTIFICATION_ITERATOR_STATUS_END;
                        goto end;
                }
        }
 
        /* notification is set from here. */
 
-       stream = internal_bt_notification_get_stream(notification);
+       stream = internal_bt_notification_get_stream(ret.notification);
        if (!stream) {
                /*
                 * The current notification is not associated to a particular
@@ -302,11 +293,12 @@ enum bt_notification_iterator_status ctf_fs_iterator_next(
                goto end;
        }
 
-       ret = ctf_fs_iterator_get_next_notification(ctf_it, fs_stream,
+       ret.status = ctf_fs_iterator_get_next_notification(ctf_it, fs_stream,
                        &next_stream_notification);
-       if ((ret && ret != BT_NOTIFICATION_ITERATOR_STATUS_END)) {
+       if ((ret.status && ret.status != BT_NOTIFICATION_ITERATOR_STATUS_END)) {
                heap_ret = bt_notification_heap_insert(
-                               ctf_it->pending_notifications, notification);
+                               ctf_it->pending_notifications,
+                               ret.notification);
 
                assert(!next_stream_notification);
                if (heap_ret) {
@@ -314,19 +306,19 @@ enum bt_notification_iterator_status ctf_fs_iterator_next(
                         * We're dropping the most recent notification, but at
                         * this point, something is seriously wrong...
                         */
-                       ret = BT_NOTIFICATION_ITERATOR_STATUS_NOMEM;
+                       ret.status = BT_NOTIFICATION_ITERATOR_STATUS_NOMEM;
                }
-               BT_PUT(notification);
+               BT_PUT(ret.notification);
                goto end;
        }
 
-       if (ret == BT_NOTIFICATION_ITERATOR_STATUS_END) {
+       if (ret.status == BT_NOTIFICATION_ITERATOR_STATUS_END) {
                gboolean success;
 
                /* Remove stream. */
                success = g_hash_table_remove(ctf_it->stream_ht, stream);
                assert(success);
-               ret = BT_NOTIFICATION_ITERATOR_STATUS_OK;
+               ret.status = BT_NOTIFICATION_ITERATOR_STATUS_OK;
        } else {
                heap_ret = bt_notification_heap_insert(ctf_it->pending_notifications,
                                                       next_stream_notification);
@@ -335,7 +327,7 @@ enum bt_notification_iterator_status ctf_fs_iterator_next(
                        /*
                         * We're dropping the most recent notification...
                         */
-                       ret = BT_NOTIFICATION_ITERATOR_STATUS_NOMEM;
+                       ret.status = BT_NOTIFICATION_ITERATOR_STATUS_NOMEM;
                }
        }
 
@@ -345,7 +337,6 @@ enum bt_notification_iterator_status ctf_fs_iterator_next(
         * notification.
         */
 end:
-       BT_MOVE(ctf_it->current_notification, notification);
        bt_put(stream);
        return ret;
 }
@@ -353,7 +344,9 @@ end:
 static
 void ctf_fs_iterator_destroy_data(struct ctf_fs_iterator *ctf_it)
 {
-       bt_put(ctf_it->current_notification);
+       if (!ctf_it) {
+               return;
+       }
        bt_put(ctf_it->pending_notifications);
        if (ctf_it->pending_streams) {
                g_ptr_array_free(ctf_it->pending_streams, TRUE);
@@ -364,10 +357,9 @@ void ctf_fs_iterator_destroy_data(struct ctf_fs_iterator *ctf_it)
        g_free(ctf_it);
 }
 
-static
-void ctf_fs_iterator_destroy(struct bt_notification_iterator *it)
+void ctf_fs_iterator_finalize(struct bt_private_notification_iterator *it)
 {
-       void *data = bt_notification_iterator_get_private_data(it);
+       void *data = bt_private_notification_iterator_get_user_data(it);
 
        ctf_fs_iterator_destroy_data(data);
 }
@@ -377,7 +369,7 @@ bool compare_event_notifications(struct bt_notification *a,
                struct bt_notification *b)
 {
        int ret;
-       struct bt_ctf_clock *clock;
+       struct bt_ctf_clock_class *clock_class;
        struct bt_ctf_clock_value *a_clock_value, *b_clock_value;
        struct bt_ctf_stream_class *a_stream_class;
        struct bt_ctf_stream *a_stream;
@@ -398,9 +390,9 @@ bool compare_event_notifications(struct bt_notification *a,
        trace = bt_ctf_stream_class_get_trace(a_stream_class);
        assert(trace);
 
-       clock = bt_ctf_trace_get_clock(trace, 0);
-       a_clock_value = bt_ctf_event_get_clock_value(a_event, clock);
-       b_clock_value = bt_ctf_event_get_clock_value(b_event, clock);
+       clock_class = bt_ctf_trace_get_clock_class(trace, 0);
+       a_clock_value = bt_ctf_event_get_clock_value(a_event, clock_class);
+       b_clock_value = bt_ctf_event_get_clock_value(b_event, clock_class);
        assert(a_clock_value);
        assert(b_clock_value);
 
@@ -415,7 +407,7 @@ bool compare_event_notifications(struct bt_notification *a,
        bt_put(b_clock_value);
        bt_put(a_stream);
        bt_put(a_stream_class);
-       bt_put(clock);
+       bt_put(clock_class);
        bt_put(trace);
        return a_ts < b_ts;
 }
@@ -428,7 +420,7 @@ bool compare_notifications(struct bt_notification *a, struct bt_notification *b,
                [BT_NOTIFICATION_TYPE_NEW_TRACE] = 0,
                [BT_NOTIFICATION_TYPE_NEW_STREAM_CLASS] = 1,
                [BT_NOTIFICATION_TYPE_NEW_EVENT_CLASS] = 2,
-               [BT_NOTIFICATION_TYPE_PACKET_START] = 3,
+               [BT_NOTIFICATION_TYPE_PACKET_BEGIN] = 3,
                [BT_NOTIFICATION_TYPE_PACKET_END] = 4,
                [BT_NOTIFICATION_TYPE_EVENT] = 5,
                [BT_NOTIFICATION_TYPE_END_OF_TRACE] = 6,
@@ -457,7 +449,7 @@ bool compare_notifications(struct bt_notification *a, struct bt_notification *b,
 
        /* Notification types are equal, but not of type "event". */
        switch (a_type) {
-       case BT_NOTIFICATION_TYPE_PACKET_START:
+       case BT_NOTIFICATION_TYPE_PACKET_BEGIN:
        case BT_NOTIFICATION_TYPE_PACKET_END:
        case BT_NOTIFICATION_TYPE_STREAM_END:
        {
@@ -554,6 +546,12 @@ int open_trace_streams(struct ctf_fs_component *ctf_fs,
                        goto error;
                }
 
+               if (file->size == 0) {
+                       /* Skip empty stream. */
+                       ctf_fs_file_destroy(file);
+                       continue;
+               }
+
                /* Create a private stream; file ownership is passed to it. */
                stream = ctf_fs_stream_create(ctf_fs, file);
                if (!stream) {
@@ -578,25 +576,27 @@ end:
        return ret;
 }
 
-static
-enum bt_component_status ctf_fs_iterator_init(struct bt_component *source,
-               struct bt_notification_iterator *it)
+enum bt_notification_iterator_status ctf_fs_iterator_init(
+               struct bt_private_notification_iterator *it,
+               struct bt_private_port *port)
 {
        struct ctf_fs_iterator *ctf_it;
        struct ctf_fs_component *ctf_fs;
-       enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+       struct bt_private_component *source =
+               bt_private_notification_iterator_get_private_component(it);
+       enum bt_notification_iterator_status ret = BT_NOTIFICATION_ITERATOR_STATUS_OK;
 
        assert(source && it);
 
-       ctf_fs = bt_component_get_private_data(source);
+       ctf_fs = bt_private_component_get_user_data(source);
        if (!ctf_fs) {
-               ret = BT_COMPONENT_STATUS_INVALID;
+               ret = BT_NOTIFICATION_ITERATOR_STATUS_INVAL;
                goto end;
        }
 
        ctf_it = g_new0(struct ctf_fs_iterator, 1);
        if (!ctf_it) {
-               ret = BT_COMPONENT_STATUS_NOMEM;
+               ret = BT_NOTIFICATION_ITERATOR_STATUS_NOMEM;
                goto end;
        }
 
@@ -621,38 +621,28 @@ enum bt_component_status ctf_fs_iterator_init(struct bt_component *source,
                goto error;
        }
 
-       ret = bt_notification_iterator_set_get_cb(it, ctf_fs_iterator_get);
+       ret = bt_private_notification_iterator_set_user_data(it, ctf_it);
        if (ret) {
                goto error;
        }
 
-       ret = bt_notification_iterator_set_next_cb(it, ctf_fs_iterator_next);
-       if (ret) {
-               goto error;
-       }
-
-       ret = bt_notification_iterator_set_destroy_cb(it,
-                       ctf_fs_iterator_destroy);
-       if (ret) {
-               goto error;
-       }
+       goto end;
 
-       ret = bt_notification_iterator_set_private_data(it, ctf_it);
-       if (ret) {
-               goto error;
-       }
+error:
+       (void) bt_private_notification_iterator_set_user_data(it, NULL);
+       ctf_fs_iterator_destroy_data(ctf_it);
 
 end:
+       bt_put(source);
        return ret;
-error:
-       (void) bt_notification_iterator_set_private_data(it, NULL);
-       ctf_fs_iterator_destroy_data(ctf_it);
-       goto end;
 }
 
 static
 void ctf_fs_destroy_data(struct ctf_fs_component *ctf_fs)
 {
+       if (!ctf_fs) {
+               return;
+       }
        if (ctf_fs->trace_path) {
                g_string_free(ctf_fs->trace_path, TRUE);
        }
@@ -663,10 +653,9 @@ void ctf_fs_destroy_data(struct ctf_fs_component *ctf_fs)
        g_free(ctf_fs);
 }
 
-static
-void ctf_fs_destroy(struct bt_component *component)
+void ctf_fs_finalize(struct bt_private_component *component)
 {
-       void *data = bt_component_get_private_data(component);
+       void *data = bt_private_component_get_user_data(component);
 
        ctf_fs_destroy_data(data);
 }
@@ -719,8 +708,8 @@ end:
 }
 
 BT_HIDDEN
-enum bt_component_status ctf_fs_init(struct bt_component *source,
-               struct bt_value *params)
+enum bt_component_status ctf_fs_init(struct bt_private_component *source,
+               struct bt_value *params, UNUSED_VAR void *init_method_data)
 {
        struct ctf_fs_component *ctf_fs;
        enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
@@ -733,25 +722,140 @@ enum bt_component_status ctf_fs_init(struct bt_component *source,
                goto end;
        }
 
-       ret = bt_component_set_destroy_cb(source, ctf_fs_destroy);
-       if (ret != BT_COMPONENT_STATUS_OK) {
-               goto error;
-       }
-
-       ret = bt_component_set_private_data(source, ctf_fs);
-       if (ret != BT_COMPONENT_STATUS_OK) {
-               goto error;
-       }
-
-       ret = bt_component_source_set_iterator_init_cb(source,
-                       ctf_fs_iterator_init);
+       ret = bt_private_component_set_user_data(source, ctf_fs);
        if (ret != BT_COMPONENT_STATUS_OK) {
                goto error;
        }
 end:
        return ret;
 error:
-       (void) bt_component_set_private_data(source, NULL);
+       (void) bt_private_component_set_user_data(source, NULL);
         ctf_fs_destroy_data(ctf_fs);
        return ret;
 }
+
+BT_HIDDEN
+struct bt_value *ctf_fs_query(struct bt_component_class *comp_class,
+               const char *object, struct bt_value *params)
+{
+       struct bt_value *results = NULL;
+       struct bt_value *path_value = NULL;
+       char *metadata_text = NULL;
+       FILE *metadata_fp = NULL;
+       GString *g_metadata_text = NULL;
+
+       if (strcmp(object, "metadata-info") == 0) {
+               int ret;
+               int bo;
+               const char *path;
+               bool is_packetized;
+
+               results = bt_value_map_create();
+               if (!results) {
+                       goto error;
+               }
+
+               if (!bt_value_is_map(params)) {
+                       fprintf(stderr,
+                               "Query parameters is not a map value object\n");
+                       goto error;
+               }
+
+               path_value = bt_value_map_get(params, "path");
+               ret = bt_value_string_get(path_value, &path);
+               if (ret) {
+                       fprintf(stderr,
+                               "Cannot get `path` string parameter\n");
+                       goto error;
+               }
+
+               assert(path);
+               metadata_fp = ctf_fs_metadata_open_file(path);
+               if (!metadata_fp) {
+                       fprintf(stderr,
+                               "Cannot open trace at path `%s`\n", path);
+                       goto error;
+               }
+
+               is_packetized = ctf_metadata_is_packetized(metadata_fp, &bo);
+
+               if (is_packetized) {
+                       ret = ctf_metadata_packetized_file_to_buf(NULL,
+                               metadata_fp, (uint8_t **) &metadata_text, bo);
+                       if (ret) {
+                               fprintf(stderr,
+                                       "Cannot decode packetized metadata file\n");
+                               goto error;
+                       }
+               } else {
+                       long filesize;
+
+                       fseek(metadata_fp, 0, SEEK_END);
+                       filesize = ftell(metadata_fp);
+                       rewind(metadata_fp);
+                       metadata_text = malloc(filesize + 1);
+                       if (!metadata_text) {
+                               fprintf(stderr,
+                                       "Cannot allocate buffer for metadata text\n");
+                               goto error;
+                       }
+
+                       if (fread(metadata_text, filesize, 1, metadata_fp) !=
+                                       1) {
+                               fprintf(stderr,
+                                       "Cannot read metadata file\n");
+                               goto error;
+                       }
+
+                       metadata_text[filesize] = '\0';
+               }
+
+               g_metadata_text = g_string_new(NULL);
+               if (!g_metadata_text) {
+                       goto error;
+               }
+
+               if (strncmp(metadata_text, METADATA_TEXT_SIG,
+                               sizeof(METADATA_TEXT_SIG) - 1) != 0) {
+                       g_string_assign(g_metadata_text, METADATA_TEXT_SIG);
+                       g_string_append(g_metadata_text, " */\n\n");
+               }
+
+               g_string_append(g_metadata_text, metadata_text);
+
+               ret = bt_value_map_insert_string(results, "text",
+                       g_metadata_text->str);
+               if (ret) {
+                       fprintf(stderr, "Cannot insert metadata text into results\n");
+                       goto error;
+               }
+
+               ret = bt_value_map_insert_bool(results, "is-packetized",
+                       is_packetized);
+               if (ret) {
+                       fprintf(stderr, "Cannot insert is packetized into results\n");
+                       goto error;
+               }
+       } else {
+               fprintf(stderr, "Unknown query object `%s`\n", object);
+               goto error;
+       }
+
+       goto end;
+
+error:
+       BT_PUT(results);
+
+end:
+       bt_put(path_value);
+       free(metadata_text);
+
+       if (g_metadata_text) {
+               g_string_free(g_metadata_text, TRUE);
+       }
+
+       if (metadata_fp) {
+               fclose(metadata_fp);
+       }
+       return results;
+}
This page took 0.029938 seconds and 4 git commands to generate.