+ assert(stream);
+
+ if (!field) {
+ /* No discarded events count field found. Not an error, skip. */
+ BT_LOGV("No field named `events_discarded` in packet context: skipping: "
+ "stream-addr=%p, stream-name=\"%s\"",
+ stream, bt_ctf_stream_get_name(stream));
+ goto end;
+ }
+
+ /*
+ * If the field is set by the user, make sure that the value is
+ * greater than or equal to the stream's current count of
+ * discarded events. We do not allow wrapping here. If it's
+ * valid, update the stream's current count.
+ */
+ if (bt_ctf_field_is_set(field)) {
+ uint64_t user_val;
+
+ ret = bt_ctf_field_unsigned_integer_get_value(field,
+ &user_val);
+ if (ret) {
+ BT_LOGW("Cannot get packet context `events_discarded` field's unsigned value: "
+ "stream-addr=%p, stream-name=\"%s\", field-addr=%p",
+ stream, bt_ctf_stream_get_name(stream), field);
+ goto end;
+ }
+
+ if (user_val < stream->discarded_events) {
+ BT_LOGW("Invalid packet context `events_discarded` field's unsigned value: "
+ "value is lesser than the stream's current discarded events count: "
+ "stream-addr=%p, stream-name=\"%s\", field-addr=%p, "
+ "value=%" PRIu64 ", "
+ "stream-discarded-events-count=%" PRIu64,
+ stream, bt_ctf_stream_get_name(stream), field,
+ user_val, stream->discarded_events);
+ goto end;
+ }
+
+ stream->discarded_events = user_val;
+ } else {
+ ret = bt_ctf_field_unsigned_integer_set_value(field,
+ stream->discarded_events);
+ if (ret) {
+ BT_LOGW("Cannot set packet context field's `events_discarded` integer field's value: "
+ "stream-addr=%p, stream-name=\"%s\", field-addr=%p, value=%" PRIu64,
+ stream, bt_ctf_stream_get_name(stream),
+ field, stream->discarded_events);
+ } else {
+ BT_LOGV("Set packet context field's `events_discarded` field's value: "
+ "stream-addr=%p, stream-name=\"%s\", field-addr=%p, value=%" PRIu64,
+ stream, bt_ctf_stream_get_name(stream),
+ field, stream->discarded_events);
+ }
+ }
+
+end:
+ bt_put(field);
+ return ret;
+}
+
+static
+int get_event_header_timestamp(struct bt_ctf_stream *stream,
+ struct bt_ctf_field *event_header, uint64_t *timestamp)
+{
+ int ret = 0;
+ struct bt_ctf_field *timestamp_field = NULL;
+ struct bt_ctf_clock_class *ts_field_mapped_clock_class = NULL;
+
+ *timestamp = 0;
+
+ if (!event_header) {
+ BT_LOGV_STR("Event header does not exist.");
+ goto end;
+ }
+
+ timestamp_field = bt_ctf_field_structure_get_field(event_header,
+ "timestamp");
+ if (!timestamp_field) {
+ BT_LOGV("Cannot get event header's `timestamp` field: "
+ "event-header-field-addr=%p", event_header);
+ goto end;
+ }
+
+ if (!bt_ctf_field_type_is_integer(timestamp_field->type)) {
+ BT_LOGV("Event header's `timestamp` field's type is not an integer field type: "
+ "event-header-field-addr=%p", event_header);
+ goto end;
+ }
+
+ ts_field_mapped_clock_class =
+ bt_ctf_field_type_integer_get_mapped_clock_class(
+ timestamp_field->type);
+ if (!ts_field_mapped_clock_class) {
+ BT_LOGV("Event header's `timestamp` field's type is not mapped to a clock class: "
+ "event-header-field-addr=%p", event_header);
+ goto end;
+ }
+
+ if (ts_field_mapped_clock_class !=
+ stream->stream_class->clock->clock_class) {
+ BT_LOGV("Event header's `timestamp` field's type is not mapped to the stream's clock's class: "
+ "event-header-field-addr=%p", event_header);
+ goto end;
+ }
+
+ ret = bt_ctf_field_unsigned_integer_get_value(timestamp_field,
+ timestamp);