#include <stdint.h>
#include <stdio.h>
#include <stddef.h>
-#include <babeltrace/ctf-ir/trace.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/ctf-ir/event.h>
+#include <babeltrace/babeltrace.h>
#include <babeltrace/babeltrace-internal.h>
+#include "../metadata/ctf-meta.h"
+
/**
* @file ctf-notif-iter.h
*
/**
* Medium operations status codes.
*/
-enum bt_ctf_notif_iter_medium_status {
+enum bt_notif_iter_medium_status {
/**
* End of file.
*
* The medium function called by the notification iterator
* function reached the end of the file.
*/
- BT_CTF_NOTIF_ITER_MEDIUM_STATUS_EOF = -4,
+ BT_NOTIF_ITER_MEDIUM_STATUS_EOF = 1,
/**
* There is no data available right now, try again later.
*/
- BT_CTF_NOTIF_ITER_MEDIUM_STATUS_AGAIN = -3,
+ BT_NOTIF_ITER_MEDIUM_STATUS_AGAIN = 11,
+
+ /** Unsupported operation. */
+ BT_NOTIF_ITER_MEDIUM_STATUS_UNSUPPORTED = -3,
/** Invalid argument. */
- BT_CTF_NOTIF_ITER_MEDIUM_STATUS_INVAL = -2,
+ BT_NOTIF_ITER_MEDIUM_STATUS_INVAL = -2,
/** General error. */
- BT_CTF_NOTIF_ITER_MEDIUM_STATUS_ERROR = -1,
+ BT_NOTIF_ITER_MEDIUM_STATUS_ERROR = -1,
/** Everything okay. */
- BT_CTF_NOTIF_ITER_MEDIUM_STATUS_OK = 0,
+ BT_NOTIF_ITER_MEDIUM_STATUS_OK = 0,
};
/**
* CTF notification iterator API status code.
*/
-enum bt_ctf_notif_iter_status {
+enum bt_notif_iter_status {
/**
* End of file.
*
* The medium function called by the notification iterator
* function reached the end of the file.
*/
- BT_CTF_NOTIF_ITER_STATUS_EOF = -4,
+ BT_NOTIF_ITER_STATUS_EOF = BT_NOTIF_ITER_MEDIUM_STATUS_EOF,
/**
* There is no data available right now, try again later.
*
* Some condition resulted in the
- * bt_ctf_notif_iter_medium_ops::request_bytes() user function not
+ * bt_notif_iter_medium_ops::request_bytes() user function not
* having access to any data now. You should retry calling the
* last called notification iterator function once the situation
* is resolved.
*/
- BT_CTF_NOTIF_ITER_STATUS_AGAIN = -3,
+ BT_NOTIF_ITER_STATUS_AGAIN = BT_NOTIF_ITER_MEDIUM_STATUS_AGAIN,
/** Invalid argument. */
- BT_CTF_NOTIF_ITER_STATUS_INVAL = -2,
+ BT_NOTIF_ITER_STATUS_INVAL = BT_NOTIF_ITER_MEDIUM_STATUS_INVAL,
+
+ /** Unsupported operation. */
+ BT_NOTIF_ITER_STATUS_UNSUPPORTED = BT_NOTIF_ITER_MEDIUM_STATUS_UNSUPPORTED,
/** General error. */
- BT_CTF_NOTIF_ITER_STATUS_ERROR = -1,
+ BT_NOTIF_ITER_STATUS_ERROR = BT_NOTIF_ITER_MEDIUM_STATUS_ERROR,
/** Everything okay. */
- BT_CTF_NOTIF_ITER_STATUS_OK = 0,
+ BT_NOTIF_ITER_STATUS_OK = 0,
+};
+
+/**
+ * CTF notification iterator seek operation directives.
+ */
+enum bt_notif_iter_seek_whence {
+ /**
+ * Set the iterator's position to an absolute offset in the underlying
+ * medium.
+ */
+ BT_NOTIF_ITER_SEEK_WHENCE_SET,
};
/**
* Those user functions are called by the notification iterator
* functions to request medium actions.
*/
-struct bt_ctf_notif_iter_medium_ops {
+struct bt_notif_iter_medium_ops {
/**
* Returns the next byte buffer to be used by the binary file
* reader to deserialize binary data.
*
* This function must return one of the following statuses:
*
- * - <b>#BT_CTF_NOTIF_ITER_MEDIUM_STATUS_OK</b>: Everything
+ * - <b>#BT_NOTIF_ITER_MEDIUM_STATUS_OK</b>: Everything
* is okay, i.e. \p buffer_sz is set to a positive value
* reflecting the number of available bytes in the buffer
* starting at the address written in \p buffer_addr.
- * - <b>#BT_CTF_NOTIF_ITER_MEDIUM_STATUS_AGAIN</b>: No data is
+ * - <b>#BT_NOTIF_ITER_MEDIUM_STATUS_AGAIN</b>: No data is
* available right now. In this case, the notification
* iterator function called by the user returns
- * #BT_CTF_NOTIF_ITER_STATUS_AGAIN, and it is the user's
+ * #BT_NOTIF_ITER_STATUS_AGAIN, and it is the user's
* responsibility to make sure enough data becomes available
* before calling the \em same notification iterator
* function again to continue the decoding process.
- * - <b>#BT_CTF_NOTIF_ITER_MEDIUM_STATUS_EOF</b>: The end of
+ * - <b>#BT_NOTIF_ITER_MEDIUM_STATUS_EOF</b>: The end of
* the file was reached, and no more data will ever be
* available for this file. In this case, the notification
* iterator function called by the user returns
- * #BT_CTF_NOTIF_ITER_STATUS_EOF. This must \em not be
+ * #BT_NOTIF_ITER_STATUS_EOF. This must \em not be
* returned when returning at least one byte of data to the
* caller, i.e. this must be returned when there's
* absolutely nothing left; should the request size be
* larger than what's left in the file, this function must
* return what's left, setting \p buffer_sz to the number of
* remaining bytes, and return
- * #BT_CTF_NOTIF_ITER_MEDIUM_STATUS_EOF on the \em following
+ * #BT_NOTIF_ITER_MEDIUM_STATUS_EOF on the \em following
* call.
- * - <b>#BT_CTF_NOTIF_ITER_MEDIUM_STATUS_ERROR</b>: A fatal
+ * - <b>#BT_NOTIF_ITER_MEDIUM_STATUS_ERROR</b>: A fatal
* error occured during this operation. In this case, the
* notification iterator function called by the user returns
- * #BT_CTF_NOTIF_ITER_STATUS_ERROR.
+ * #BT_NOTIF_ITER_STATUS_ERROR.
*
- * If #BT_CTF_NOTIF_ITER_MEDIUM_STATUS_OK is not returned, the
+ * If #BT_NOTIF_ITER_MEDIUM_STATUS_OK is not returned, the
* values of \p buffer_sz and \p buffer_addr are \em ignored by
* the caller.
*
* @param data User data
* @returns Status code (see description above)
*/
- enum bt_ctf_notif_iter_medium_status (* request_bytes)(
+ enum bt_notif_iter_medium_status (* request_bytes)(
size_t request_sz, uint8_t **buffer_addr,
size_t *buffer_sz, void *data);
+ /**
+ * Repositions the underlying stream's position.
+ *
+ * This *optional* method repositions the underlying stream
+ * to a given absolute or relative position, as indicated by
+ * the whence directive.
+ *
+ * @param whence One of #bt_notif_iter_seek_whence values
+ * @param offset Offset to use for the given directive
+ * @param data User data
+ * @returns One of #bt_notif_iter_medium_status values
+ */
+ enum bt_notif_iter_medium_status (* seek)(
+ enum bt_notif_iter_seek_whence whence,
+ off_t offset, void *data);
+
/**
* Returns a stream instance (weak reference) for the given
* stream class.
* corresponding stream class is found by the notification
* iterator.
*
- * @param stream_class Stream class associated to the stream
+ * @param stream_class Stream class of the stream to get
+ * @param stream_id Stream (instance) ID of the stream
+ * to get (-1ULL if not available)
* @param data User data
* @returns Stream instance (weak reference) or
* \c NULL on error
*/
- struct bt_ctf_stream * (* get_stream)(
- struct bt_ctf_stream_class *stream_class, void *data);
+ bt_stream * (* borrow_stream)(
+ bt_stream_class *stream_class,
+ int64_t stream_id, void *data);
};
/** CTF notification iterator. */
-struct bt_ctf_notif_iter;
-
-// TODO: Replace by the real thing
-enum bt_ctf_notif_iter_notif_type {
- BT_CTF_NOTIF_ITER_NOTIF_NEW_PACKET,
- BT_CTF_NOTIF_ITER_NOTIF_END_OF_PACKET,
- BT_CTF_NOTIF_ITER_NOTIF_EVENT,
-};
-
-struct bt_ctf_notif_iter_notif {
- enum bt_ctf_notif_iter_notif_type type;
-};
-
-struct bt_ctf_notif_iter_notif_new_packet {
- struct bt_ctf_notif_iter_notif base;
- struct bt_ctf_packet *packet;
-};
-
-struct bt_ctf_notif_iter_notif_end_of_packet {
- struct bt_ctf_notif_iter_notif base;
- struct bt_ctf_packet *packet;
-};
-
-struct bt_ctf_notif_iter_notif_event {
- struct bt_ctf_notif_iter_notif base;
- struct bt_ctf_event *event;
-};
-
-void bt_ctf_notif_iter_notif_destroy(void *notif);
+struct bt_notif_iter;
/**
* Creates a CTF notification iterator.
* @param trace Trace to read
* @param max_request_sz Maximum buffer size, in bytes, to
* request to
- * bt_ctf_notif_iter_medium_ops::request_bytes()
+ * bt_notif_iter_medium_ops::request_bytes()
* at a time
* @param medops Medium operations
* @param medops_data User data (passed to medium operations)
- * @param err_stream Error stream (can be \c NULL to disable)
* @returns New CTF notification iterator on
* success, or \c NULL on error
*/
-struct bt_ctf_notif_iter *bt_ctf_notif_iter_create(struct bt_ctf_trace *trace,
- size_t max_request_sz, struct bt_ctf_notif_iter_medium_ops medops,
- void *medops_data, FILE *err_stream);
+BT_HIDDEN
+struct bt_notif_iter *bt_notif_iter_create(struct ctf_trace_class *tc,
+ size_t max_request_sz, struct bt_notif_iter_medium_ops medops,
+ void *medops_data);
/**
* Destroys a CTF notification iterator, freeing all internal resources.
*
* @param notif_iter CTF notification iterator
*/
-void bt_ctf_notif_iter_destroy(struct bt_ctf_notif_iter *notif_iter);
-
-/**
- * Resets the internal state of a CTF notification iterator.
- *
- * This function can be used when it is desired to seek to the beginning
- * of another packet. It is expected that the next call to
- * bt_ctf_notif_iter_medium_ops::request_bytes() made by this
- * notification iterator will return the \em first bytes of a \em
- * packet.
- *
- * @param notif_iter CTF notification iterator
- */
-void bt_ctf_notif_iter_reset(struct bt_ctf_notif_iter *notif_iter);
+BT_HIDDEN
+void bt_notif_iter_destroy(struct bt_notif_iter *notif_iter);
/**
* Returns the next notification from a CTF notification iterator.
*
- * Upon successful completion, #BT_CTF_NOTIF_ITER_STATUS_OK is
+ * Upon successful completion, #BT_NOTIF_ITER_STATUS_OK is
* returned, and the next notification is written to \p notif.
* In this case, the caller is responsible for calling
* bt_notification_put() on the returned notification.
*
- * If this function returns #BT_CTF_NOTIF_ITER_STATUS_AGAIN, the caller
+ * If this function returns #BT_NOTIF_ITER_STATUS_AGAIN, the caller
* should make sure that data becomes available to its medium, and
* call this function again, until another status is returned.
*
* @param notif_iter CTF notification iterator
* @param notification Returned notification if the function's
- * return value is #BT_CTF_NOTIF_ITER_STATUS_OK
- * @returns One of #bt_ctf_notif_iter_status values
+ * return value is #BT_NOTIF_ITER_STATUS_OK
+ * @returns One of #bt_notif_iter_status values
+ */
+BT_HIDDEN
+enum bt_notif_iter_status bt_notif_iter_get_next_notification(
+ struct bt_notif_iter *notit,
+ bt_self_notification_iterator *notif_iter,
+ bt_notification **notification);
+
+/**
+ * Returns the first packet header and context fields. This function
+ * never needs to call the `borrow_stream()` medium operation because
+ * it does not create packet or event objects.
+ *
+ * @param notif_iter CTF notification iterator
+ * @param packet_header_field Packet header field (\c NULL if there's
+ * no packet header field)
+ * @param packet_context_field Packet context field (\c NULL if there's
+ * no packet context field)
+ * @returns One of #bt_notif_iter_status values
+ */
+BT_HIDDEN
+enum bt_notif_iter_status bt_notif_iter_borrow_packet_header_context_fields(
+ struct bt_notif_iter *notit,
+ bt_field **packet_header_field,
+ bt_field **packet_context_field);
+
+struct bt_notif_iter_packet_properties {
+ uint64_t exp_packet_total_size;
+ uint64_t exp_packet_content_size;
+ uint64_t stream_class_id;
+ int64_t data_stream_id;
+
+ struct {
+ uint64_t discarded_events;
+ uint64_t packets;
+ uint64_t beginning_clock;
+ uint64_t end_clock;
+ } snapshots;
+};
+
+BT_HIDDEN
+enum bt_notif_iter_status bt_notif_iter_get_packet_properties(
+ struct bt_notif_iter *notit,
+ struct bt_notif_iter_packet_properties *props);
+
+BT_HIDDEN
+void bt_notif_iter_set_medops_data(struct bt_notif_iter *notit,
+ void *medops_data);
+
+BT_HIDDEN
+enum bt_notif_iter_status bt_notif_iter_seek(
+ struct bt_notif_iter *notit, off_t offset);
+
+/*
+ * Get the current packet's offset in bytes relative to the media's initial
+ * position.
+ */
+BT_HIDDEN
+off_t bt_notif_iter_get_current_packet_offset(
+ struct bt_notif_iter *notit);
+
+/* Get the current packet's size (in bits). */
+BT_HIDDEN
+off_t bt_notif_iter_get_current_packet_size(
+ struct bt_notif_iter *notit);
+
+/*
+ * Resets the iterator so that the next requested medium bytes are
+ * assumed to be the first bytes of a new stream. The first notification
+ * which this iterator emits after calling bt_notif_iter_reset() is a
+ * BT_NOTIFICATION_TYPE_STREAM_BEGINNING one.
*/
-enum bt_ctf_notif_iter_status bt_ctf_notif_iter_get_next_notification(
- struct bt_ctf_notif_iter *notif_iter,
- struct bt_ctf_notif_iter_notif **notification);
+BT_HIDDEN
+void bt_notif_iter_reset(struct bt_notif_iter *notit);
+
+/*
+ * Notify the iterator that the trace class changed somehow (new
+ * stream/event classes).
+ */
+BT_HIDDEN
+void bt_notif_trace_class_changed(struct bt_notif_iter *notit);
+
+static inline
+const char *bt_notif_iter_medium_status_string(
+ enum bt_notif_iter_medium_status status)
+{
+ switch (status) {
+ case BT_NOTIF_ITER_MEDIUM_STATUS_EOF:
+ return "BT_NOTIF_ITER_MEDIUM_STATUS_EOF";
+ case BT_NOTIF_ITER_MEDIUM_STATUS_AGAIN:
+ return "BT_NOTIF_ITER_MEDIUM_STATUS_AGAIN";
+ case BT_NOTIF_ITER_MEDIUM_STATUS_INVAL:
+ return "BT_NOTIF_ITER_MEDIUM_STATUS_INVAL";
+ case BT_NOTIF_ITER_MEDIUM_STATUS_ERROR:
+ return "BT_NOTIF_ITER_MEDIUM_STATUS_ERROR";
+ case BT_NOTIF_ITER_MEDIUM_STATUS_OK:
+ return "BT_NOTIF_ITER_MEDIUM_STATUS_OK";
+ default:
+ return "(unknown)";
+ }
+}
+
+static inline
+const char *bt_notif_iter_status_string(
+ enum bt_notif_iter_status status)
+{
+ switch (status) {
+ case BT_NOTIF_ITER_STATUS_EOF:
+ return "BT_NOTIF_ITER_STATUS_EOF";
+ case BT_NOTIF_ITER_STATUS_AGAIN:
+ return "BT_NOTIF_ITER_STATUS_AGAIN";
+ case BT_NOTIF_ITER_STATUS_INVAL:
+ return "BT_NOTIF_ITER_STATUS_INVAL";
+ case BT_NOTIF_ITER_STATUS_ERROR:
+ return "BT_NOTIF_ITER_STATUS_ERROR";
+ case BT_NOTIF_ITER_STATUS_OK:
+ return "BT_NOTIF_ITER_STATUS_OK";
+ default:
+ return "(unknown)";
+ }
+}
#endif /* CTF_NOTIF_ITER_H */