+/*
+ * seek_file_stream_by_timestamp
+ *
+ * Browse a filestream by index, if an index contains the timestamp passed in
+ * argument, seek inside the corresponding packet it until we find the event we
+ * are looking for (either the exact timestamp or the event just after the
+ * timestamp).
+ *
+ * Return 0 if the seek succeded, EOF if we didn't find any packet
+ * containing the timestamp, or a positive integer for error.
+ */
+static int seek_file_stream_by_timestamp(struct ctf_file_stream *cfs,
+ uint64_t timestamp)
+{
+ struct ctf_stream_pos *stream_pos;
+ struct packet_index *index;
+ int i, ret;
+
+ stream_pos = &cfs->pos;
+ for (i = 0; i < stream_pos->packet_index->len; i++) {
+ index = &g_array_index(stream_pos->packet_index,
+ struct packet_index, i);
+ if (index->timestamp_end < timestamp)
+ continue;
+
+ stream_pos->packet_seek(&stream_pos->parent, i, SEEK_SET);
+ do {
+ ret = stream_read_event(cfs);
+ } while (cfs->parent.timestamp < timestamp && ret == 0);
+
+ /* Can return either EOF, 0, or error (> 0). */
+ return ret;
+ }
+ /*
+ * Cannot find the timestamp within the stream packets, return
+ * EOF.
+ */
+ return EOF;
+}
+
+/*
+ * seek_ctf_trace_by_timestamp : for each file stream, seek to the event with
+ * the corresponding timestamp
+ *
+ * Return 0 on success.
+ * If the timestamp is not part of any file stream, return EOF to inform the
+ * user the timestamp is out of the scope.
+ * On other errors, return positive value.
+ */
+static int seek_ctf_trace_by_timestamp(struct ctf_trace *tin,
+ uint64_t timestamp, struct ptr_heap *stream_heap)
+{
+ int i, j, ret;
+ int found = 0;
+
+ /* for each stream_class */
+ for (i = 0; i < tin->streams->len; i++) {
+ struct ctf_stream_declaration *stream_class;
+
+ stream_class = g_ptr_array_index(tin->streams, i);
+ if (!stream_class)
+ continue;
+ /* for each file_stream */
+ for (j = 0; j < stream_class->streams->len; j++) {
+ struct ctf_stream_definition *stream;
+ struct ctf_file_stream *cfs;
+
+ stream = g_ptr_array_index(stream_class->streams, j);
+ if (!stream)
+ continue;
+ cfs = container_of(stream, struct ctf_file_stream,
+ parent);
+ ret = seek_file_stream_by_timestamp(cfs, timestamp);
+ if (ret == 0) {
+ /* Add to heap */
+ ret = heap_insert(stream_heap, cfs);
+ if (ret) {
+ /* Return positive error. */
+ return -ret;
+ }
+ found = 1;
+ } else if (ret > 0) {
+ /*
+ * Error in seek (not EOF), failure.
+ */
+ return ret;
+ }
+ /* on EOF just do not put stream into heap. */
+ }
+ }
+
+ return found ? 0 : EOF;
+}
+