2 * SPDX-License-Identifier: MIT
4 * Copyright 2014 EfficiOS Inc.
6 * The Common Trace Format (CTF) Specification is available at
7 * http://www.efficios.com/ctf
10 #ifndef BABELTRACE_CTF_WRITER_STREAM_CLASS_INTERNAL_H
11 #define BABELTRACE_CTF_WRITER_STREAM_CLASS_INTERNAL_H
13 #include "common/assert.h"
14 #include "common/macros.h"
15 #include "common/common.h"
16 #include <babeltrace2-ctf-writer/field-types.h>
17 #include <babeltrace2-ctf-writer/visitor.h>
21 #include "field-types.h"
23 #include "stream-class.h"
25 #include "validation.h"
27 struct bt_ctf_stream_class_common
{
28 struct bt_ctf_object base
;
31 /* Array of pointers to event class addresses */
32 GPtrArray
*event_classes
;
34 /* event class id (int64_t) to event class address */
35 GHashTable
*event_classes_ht
;
38 int64_t next_event_id
;
39 struct bt_ctf_field_type_common
*packet_context_field_type
;
40 struct bt_ctf_field_type_common
*event_header_field_type
;
41 struct bt_ctf_field_type_common
*event_context_field_type
;
46 * This flag indicates if the stream class is valid. A valid
47 * stream class is _always_ frozen.
52 * Unique clock class mapped to any field type within this
53 * stream class, including all the stream class's event class
54 * field types. This is only set if the stream class is frozen.
56 * If the stream class is frozen and this is still NULL, it is
57 * still possible that it becomes non-NULL because
58 * bt_ctf_stream_class_add_event_class() can add an event class
59 * containing a field type mapped to some clock class. In this
60 * case, this is the mapped clock class, and at this point, both
61 * the new event class and the stream class are frozen, so the
62 * next added event classes are expected to contain field types
63 * which only map to this specific clock class.
65 * If this is a CTF writer stream class, then this is the
66 * backing clock class of the `clock` member above.
68 struct bt_ctf_clock_class
*clock_class
;
71 struct bt_ctf_event_class_common
;
74 int bt_ctf_stream_class_common_initialize(struct bt_ctf_stream_class_common
*stream_class
,
75 const char *name
, bt_ctf_object_release_func release_func
);
78 void bt_ctf_stream_class_common_finalize(struct bt_ctf_stream_class_common
*stream_class
);
81 void bt_ctf_stream_class_common_freeze(struct bt_ctf_stream_class_common
*stream_class
);
84 const char *bt_ctf_stream_class_common_get_name(
85 struct bt_ctf_stream_class_common
*stream_class
)
87 BT_CTF_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
88 return stream_class
->name
->len
> 0 ? stream_class
->name
->str
: NULL
;
92 int64_t bt_ctf_stream_class_common_get_id(
93 struct bt_ctf_stream_class_common
*stream_class
)
97 BT_CTF_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
99 if (!stream_class
->id_set
) {
100 BT_LOGT("Stream class's ID is not set: addr=%p, name=\"%s\"",
102 bt_ctf_stream_class_common_get_name(stream_class
));
107 ret
= stream_class
->id
;
114 void bt_ctf_stream_class_common_set_byte_order(
115 struct bt_ctf_stream_class_common
*stream_class
, int byte_order
);
118 int bt_ctf_stream_class_common_validate_single_clock_class(
119 struct bt_ctf_stream_class_common
*stream_class
,
120 struct bt_ctf_clock_class
**expected_clock_class
);
123 int bt_ctf_stream_class_common_add_event_class(
124 struct bt_ctf_stream_class_common
*stream_class
,
125 struct bt_ctf_event_class_common
*event_class
,
126 bt_ctf_validation_flag_copy_field_type_func copy_field_type_func
);
129 int bt_ctf_stream_class_common_visit(struct bt_ctf_stream_class_common
*stream_class
,
130 bt_ctf_visitor visitor
, void *data
);
133 int bt_ctf_stream_class_visit(struct bt_ctf_stream_class
*stream_class
,
134 bt_ctf_visitor visitor
, void *data
);
137 struct bt_ctf_trace_common
*bt_ctf_stream_class_common_borrow_trace(
138 struct bt_ctf_stream_class_common
*stream_class
)
140 BT_ASSERT_DBG(stream_class
);
141 return (void *) bt_ctf_object_borrow_parent(&stream_class
->base
);
145 int bt_ctf_stream_class_common_set_name(struct bt_ctf_stream_class_common
*stream_class
,
151 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
156 if (stream_class
->frozen
) {
157 BT_LOGW("Invalid parameter: stream class is frozen: "
158 "addr=%p, name=\"%s\", id=%" PRId64
,
160 bt_ctf_stream_class_common_get_name(stream_class
),
161 bt_ctf_stream_class_common_get_id(stream_class
));
167 g_string_assign(stream_class
->name
, "");
169 if (strlen(name
) == 0) {
170 BT_LOGW("Invalid parameter: name is empty.");
175 g_string_assign(stream_class
->name
, name
);
178 BT_LOGT("Set stream class's name: "
179 "addr=%p, name=\"%s\", id=%" PRId64
,
180 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
181 bt_ctf_stream_class_common_get_id(stream_class
));
187 void _bt_ctf_stream_class_common_set_id(
188 struct bt_ctf_stream_class_common
*stream_class
, int64_t id
)
190 BT_ASSERT_DBG(stream_class
);
191 stream_class
->id
= id
;
192 stream_class
->id_set
= 1;
193 BT_LOGT("Set stream class's ID (internal): "
194 "addr=%p, name=\"%s\", id=%" PRId64
,
195 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
196 bt_ctf_stream_class_common_get_id(stream_class
));
200 int bt_ctf_stream_class_common_set_id_no_check(
201 struct bt_ctf_stream_class_common
*stream_class
, int64_t id
)
203 _bt_ctf_stream_class_common_set_id(stream_class
, id
);
208 int bt_ctf_stream_class_common_set_id(struct bt_ctf_stream_class_common
*stream_class
,
212 int64_t id
= (int64_t) id_param
;
215 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
220 if (stream_class
->frozen
) {
221 BT_LOGW("Invalid parameter: stream class is frozen: "
222 "addr=%p, name=\"%s\", id=%" PRId64
,
224 bt_ctf_stream_class_common_get_name(stream_class
),
225 bt_ctf_stream_class_common_get_id(stream_class
));
231 BT_LOGW("Invalid parameter: invalid stream class's ID: "
232 "stream-class-addr=%p, stream-class-name=\"%s\", "
233 "stream-class-id=%" PRId64
", id=%" PRIu64
,
235 bt_ctf_stream_class_common_get_name(stream_class
),
236 bt_ctf_stream_class_common_get_id(stream_class
),
242 ret
= bt_ctf_stream_class_common_set_id_no_check(stream_class
, id
);
244 BT_LOGT("Set stream class's ID: "
245 "addr=%p, name=\"%s\", id=%" PRId64
,
247 bt_ctf_stream_class_common_get_name(stream_class
),
248 bt_ctf_stream_class_common_get_id(stream_class
));
255 int64_t bt_ctf_stream_class_common_get_event_class_count(
256 struct bt_ctf_stream_class_common
*stream_class
)
261 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
266 ret
= (int64_t) stream_class
->event_classes
->len
;
272 struct bt_ctf_event_class_common
*bt_ctf_stream_class_common_borrow_event_class_by_index(
273 struct bt_ctf_stream_class_common
*stream_class
, uint64_t index
)
275 BT_CTF_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
276 BT_CTF_ASSERT_PRE(index
< stream_class
->event_classes
->len
,
277 "Index is out of bounds: index=%" PRIu64
", "
279 index
, stream_class
->event_classes
->len
);
280 return g_ptr_array_index(stream_class
->event_classes
, index
);
284 struct bt_ctf_event_class_common
*bt_ctf_stream_class_common_borrow_event_class_by_id(
285 struct bt_ctf_stream_class_common
*stream_class
, uint64_t id
)
287 int64_t id_key
= (int64_t) id
;
289 BT_CTF_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
290 BT_CTF_ASSERT_PRE(id_key
>= 0,
291 "Invalid event class ID: %" PRIu64
, id
);
292 return g_hash_table_lookup(stream_class
->event_classes_ht
,
297 struct bt_ctf_field_type_common
*
298 bt_ctf_stream_class_common_borrow_packet_context_field_type(
299 struct bt_ctf_stream_class_common
*stream_class
)
301 BT_CTF_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
302 return stream_class
->packet_context_field_type
;
306 int bt_ctf_stream_class_common_set_packet_context_field_type(
307 struct bt_ctf_stream_class_common
*stream_class
,
308 struct bt_ctf_field_type_common
*packet_context_type
)
313 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
318 if (stream_class
->frozen
) {
319 BT_LOGW("Invalid parameter: stream class is frozen: "
320 "addr=%p, name=\"%s\", id=%" PRId64
,
321 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
322 bt_ctf_stream_class_common_get_id(stream_class
));
327 if (packet_context_type
&&
328 bt_ctf_field_type_common_get_type_id(packet_context_type
) !=
329 BT_CTF_FIELD_TYPE_ID_STRUCT
) {
330 /* A packet context must be a structure. */
331 BT_LOGW("Invalid parameter: stream class's packet context field type must be a structure: "
332 "addr=%p, name=\"%s\", id=%" PRId64
", "
333 "packet-context-ft-addr=%p, packet-context-ft-id=%s",
334 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
335 bt_ctf_stream_class_common_get_id(stream_class
),
337 bt_ctf_field_type_id_string(
338 bt_ctf_field_type_common_get_type_id(packet_context_type
)));
343 bt_ctf_object_put_ref(stream_class
->packet_context_field_type
);
344 stream_class
->packet_context_field_type
= packet_context_type
;
345 bt_ctf_object_get_ref(stream_class
->packet_context_field_type
);
346 BT_LOGT("Set stream class's packet context field type: "
347 "addr=%p, name=\"%s\", id=%" PRId64
", "
348 "packet-context-ft-addr=%p",
349 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
350 bt_ctf_stream_class_common_get_id(stream_class
),
351 packet_context_type
);
358 struct bt_ctf_field_type_common
*
359 bt_ctf_stream_class_common_borrow_event_header_field_type(
360 struct bt_ctf_stream_class_common
*stream_class
)
362 struct bt_ctf_field_type_common
*ret
= NULL
;
364 BT_CTF_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
366 if (!stream_class
->event_header_field_type
) {
367 BT_LOGT("Stream class has no event header field type: "
368 "addr=%p, name=\"%s\", id=%" PRId64
,
370 bt_ctf_stream_class_common_get_name(stream_class
),
371 bt_ctf_stream_class_common_get_id(stream_class
));
375 ret
= stream_class
->event_header_field_type
;
382 int bt_ctf_stream_class_common_set_event_header_field_type(
383 struct bt_ctf_stream_class_common
*stream_class
,
384 struct bt_ctf_field_type_common
*event_header_type
)
389 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
394 if (stream_class
->frozen
) {
395 BT_LOGW("Invalid parameter: stream class is frozen: "
396 "addr=%p, name=\"%s\", id=%" PRId64
,
398 bt_ctf_stream_class_common_get_name(stream_class
),
399 bt_ctf_stream_class_common_get_id(stream_class
));
404 if (event_header_type
&&
405 bt_ctf_field_type_common_get_type_id(event_header_type
) !=
406 BT_CTF_FIELD_TYPE_ID_STRUCT
) {
407 /* An event header must be a structure. */
408 BT_LOGW("Invalid parameter: stream class's event header field type must be a structure: "
409 "addr=%p, name=\"%s\", id=%" PRId64
", "
410 "event-header-ft-addr=%p, event-header-ft-id=%s",
411 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
412 bt_ctf_stream_class_common_get_id(stream_class
),
414 bt_ctf_field_type_id_string(
415 bt_ctf_field_type_common_get_type_id(event_header_type
)));
420 bt_ctf_object_put_ref(stream_class
->event_header_field_type
);
421 stream_class
->event_header_field_type
= event_header_type
;
422 bt_ctf_object_get_ref(stream_class
->event_header_field_type
);
423 BT_LOGT("Set stream class's event header field type: "
424 "addr=%p, name=\"%s\", id=%" PRId64
", "
425 "event-header-ft-addr=%p",
426 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
427 bt_ctf_stream_class_common_get_id(stream_class
),
434 struct bt_ctf_field_type_common
*
435 bt_ctf_stream_class_common_borrow_event_context_field_type(
436 struct bt_ctf_stream_class_common
*stream_class
)
438 struct bt_ctf_field_type_common
*ret
= NULL
;
440 BT_CTF_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
442 if (!stream_class
->event_context_field_type
) {
446 ret
= stream_class
->event_context_field_type
;
453 int bt_ctf_stream_class_common_set_event_context_field_type(
454 struct bt_ctf_stream_class_common
*stream_class
,
455 struct bt_ctf_field_type_common
*event_context_type
)
460 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
465 if (stream_class
->frozen
) {
466 BT_LOGW("Invalid parameter: stream class is frozen: "
467 "addr=%p, name=\"%s\", id=%" PRId64
,
468 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
469 bt_ctf_stream_class_common_get_id(stream_class
));
474 if (event_context_type
&&
475 bt_ctf_field_type_common_get_type_id(event_context_type
) !=
476 BT_CTF_FIELD_TYPE_ID_STRUCT
) {
477 /* A packet context must be a structure. */
478 BT_LOGW("Invalid parameter: stream class's event context field type must be a structure: "
479 "addr=%p, name=\"%s\", id=%" PRId64
", "
480 "event-context-ft-addr=%p, event-context-ft-id=%s",
481 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
482 bt_ctf_stream_class_common_get_id(stream_class
),
484 bt_ctf_field_type_id_string(
485 bt_ctf_field_type_common_get_type_id(event_context_type
)));
490 bt_ctf_object_put_ref(stream_class
->event_context_field_type
);
491 stream_class
->event_context_field_type
= event_context_type
;
492 bt_ctf_object_get_ref(stream_class
->event_context_field_type
);
493 BT_LOGT("Set stream class's event context field type: "
494 "addr=%p, name=\"%s\", id=%" PRId64
", "
495 "event-context-ft-addr=%p",
496 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
497 bt_ctf_stream_class_common_get_id(stream_class
),
503 struct bt_ctf_stream_class
{
504 struct bt_ctf_stream_class_common common
;
505 struct bt_ctf_clock
*clock
;
506 int64_t next_stream_id
;
509 struct metadata_context
;
512 int bt_ctf_stream_class_serialize(struct bt_ctf_stream_class
*stream_class
,
513 struct metadata_context
*context
);
516 int bt_ctf_stream_class_map_clock_class(
517 struct bt_ctf_stream_class
*stream_class
,
518 struct bt_ctf_field_type
*packet_context_type
,
519 struct bt_ctf_field_type
*event_header_type
);
521 #endif /* BABELTRACE_CTF_WRITER_STREAM_CLASS_INTERNAL_H */