+ BT_CTF_FIELD_TYPE_ID_VARIANT;
+}
+
+static
+struct stream_class_field_path_cache *
+create_stream_class_field_path_cache_entry(
+ struct bt_ctf_notif_iter *notit,
+ struct bt_ctf_stream_class *stream_class)
+{
+ int v = -1;
+ int id = -1;
+ int timestamp_end = -1;
+ int packet_size = -1;
+ int content_size = -1;
+ struct stream_class_field_path_cache *cache_entry = g_new0(
+ struct stream_class_field_path_cache, 1);
+ struct bt_ctf_field_type *event_header = NULL, *packet_context = NULL;
+
+ if (!cache_entry) {
+ BT_LOGE_STR("Failed to allocate one stream class field path cache.");
+ goto end;
+ }
+
+ event_header = bt_ctf_stream_class_get_event_header_type(stream_class);
+ if (event_header && bt_ctf_field_type_is_structure(event_header)) {
+ int i, count;
+
+ count = bt_ctf_field_type_structure_get_field_count(
+ event_header);
+ assert(count >= 0);
+
+ for (i = 0; i < count; i++) {
+ int ret;
+ const char *name;
+
+ ret = bt_ctf_field_type_structure_get_field(
+ event_header, &name, NULL, i);
+ if (ret) {
+ BT_LOGE("Cannot get event header structure field type's field: "
+ "notit-addr=%p, stream-class-addr=%p, "
+ "stream-class-name=\"%s\", "
+ "stream-class-id=%" PRId64 ", "
+ "ft-addr=%p, index=%d",
+ notit, stream_class,
+ bt_ctf_stream_class_get_name(stream_class),
+ bt_ctf_stream_class_get_id(stream_class),
+ event_header, i);
+ goto error;
+ }
+
+ if (v != -1 && id != -1) {
+ break;
+ }
+
+ if (v == -1 && strcmp(name, "v") == 0) {
+ v = i;
+ } else if (id == -1 && !strcmp(name, "id")) {
+ id = i;
+ }
+ }
+ }
+
+ packet_context = bt_ctf_stream_class_get_packet_context_type(
+ stream_class);
+ if (packet_context && bt_ctf_field_type_is_structure(packet_context)) {
+ int i, count;
+
+ count = bt_ctf_field_type_structure_get_field_count(
+ packet_context);
+ assert(count >= 0);
+
+ for (i = 0; i < count; i++) {
+ int ret;
+ const char *name;
+ struct bt_ctf_field_type *field_type;
+
+ if (timestamp_end != -1 && packet_size != -1 &&
+ content_size != -1) {
+ break;
+ }
+
+ ret = bt_ctf_field_type_structure_get_field(
+ packet_context, &name, &field_type, i);
+ if (ret) {
+ BT_LOGE("Cannot get packet context structure field type's field: "
+ "notit-addr=%p, stream-class-addr=%p, "
+ "stream-class-name=\"%s\", "
+ "stream-class-id=%" PRId64 ", "
+ "ft-addr=%p, index=%d",
+ notit, stream_class,
+ bt_ctf_stream_class_get_name(stream_class),
+ bt_ctf_stream_class_get_id(stream_class),
+ event_header, i);
+ goto error;
+ }
+
+ if (timestamp_end == -1 &&
+ strcmp(name, "timestamp_end") == 0) {
+ struct field_cb_override *override = g_new0(
+ struct field_cb_override, 1);
+
+ if (!override) {
+ BT_PUT(field_type);
+ goto error;
+ }
+
+ override->func = btr_timestamp_end_cb;
+ override->data = notit;
+ g_hash_table_insert(notit->field_overrides,
+ bt_get(field_type), override);
+ timestamp_end = i;
+ } else if (packet_size == -1 &&
+ !strcmp(name, "packet_size")) {
+ packet_size = i;
+ } else if (content_size == -1 &&
+ !strcmp(name, "content_size")) {
+ content_size = i;
+ }
+ BT_PUT(field_type);
+ }
+ }
+
+ cache_entry->v = v;
+ cache_entry->id = id;
+ cache_entry->timestamp_end = timestamp_end;
+ cache_entry->packet_size = packet_size;
+ cache_entry->content_size = content_size;
+end:
+ BT_PUT(event_header);
+ BT_PUT(packet_context);
+ return cache_entry;
+error:
+ g_free(cache_entry);
+ cache_entry = NULL;
+ goto end;
+}
+
+static
+struct stream_class_field_path_cache *get_stream_class_field_path_cache(
+ struct bt_ctf_notif_iter *notit,
+ struct bt_ctf_stream_class *stream_class)
+{
+ bool cache_entry_found;
+ struct stream_class_field_path_cache *cache_entry;
+
+ cache_entry_found = g_hash_table_lookup_extended(
+ notit->sc_field_path_caches,
+ stream_class, NULL, (gpointer) &cache_entry);
+ if (unlikely(!cache_entry_found)) {
+ cache_entry = create_stream_class_field_path_cache_entry(notit,
+ stream_class);
+ g_hash_table_insert(notit->sc_field_path_caches,
+ bt_get(stream_class), (gpointer) cache_entry);
+ }
+
+ return cache_entry;