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
;
73 int bt_ctf_stream_class_common_initialize(struct bt_ctf_stream_class_common
*stream_class
,
74 const char *name
, bt_ctf_object_release_func release_func
);
76 void bt_ctf_stream_class_common_finalize(struct bt_ctf_stream_class_common
*stream_class
);
78 void bt_ctf_stream_class_common_freeze(struct bt_ctf_stream_class_common
*stream_class
);
81 const char *bt_ctf_stream_class_common_get_name(
82 struct bt_ctf_stream_class_common
*stream_class
)
84 BT_CTF_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
85 return stream_class
->name
->len
> 0 ? stream_class
->name
->str
: NULL
;
89 int64_t bt_ctf_stream_class_common_get_id(
90 struct bt_ctf_stream_class_common
*stream_class
)
94 BT_CTF_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
96 if (!stream_class
->id_set
) {
97 BT_LOGT("Stream class's ID is not set: addr=%p, name=\"%s\"",
99 bt_ctf_stream_class_common_get_name(stream_class
));
104 ret
= stream_class
->id
;
110 void bt_ctf_stream_class_common_set_byte_order(
111 struct bt_ctf_stream_class_common
*stream_class
, int byte_order
);
113 int bt_ctf_stream_class_common_validate_single_clock_class(
114 struct bt_ctf_stream_class_common
*stream_class
,
115 struct bt_ctf_clock_class
**expected_clock_class
);
117 int bt_ctf_stream_class_common_add_event_class(
118 struct bt_ctf_stream_class_common
*stream_class
,
119 struct bt_ctf_event_class_common
*event_class
,
120 bt_ctf_validation_flag_copy_field_type_func copy_field_type_func
);
122 int bt_ctf_stream_class_common_visit(struct bt_ctf_stream_class_common
*stream_class
,
123 bt_ctf_visitor visitor
, void *data
);
125 int bt_ctf_stream_class_visit(struct bt_ctf_stream_class
*stream_class
,
126 bt_ctf_visitor visitor
, void *data
);
129 struct bt_ctf_trace_common
*bt_ctf_stream_class_common_borrow_trace(
130 struct bt_ctf_stream_class_common
*stream_class
)
132 BT_ASSERT_DBG(stream_class
);
133 return (void *) bt_ctf_object_borrow_parent(&stream_class
->base
);
137 int bt_ctf_stream_class_common_set_name(struct bt_ctf_stream_class_common
*stream_class
,
143 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
148 if (stream_class
->frozen
) {
149 BT_LOGW("Invalid parameter: stream class is frozen: "
150 "addr=%p, name=\"%s\", id=%" PRId64
,
152 bt_ctf_stream_class_common_get_name(stream_class
),
153 bt_ctf_stream_class_common_get_id(stream_class
));
159 g_string_assign(stream_class
->name
, "");
161 if (strlen(name
) == 0) {
162 BT_LOGW("Invalid parameter: name is empty.");
167 g_string_assign(stream_class
->name
, name
);
170 BT_LOGT("Set stream class's name: "
171 "addr=%p, name=\"%s\", id=%" PRId64
,
172 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
173 bt_ctf_stream_class_common_get_id(stream_class
));
179 void _bt_ctf_stream_class_common_set_id(
180 struct bt_ctf_stream_class_common
*stream_class
, int64_t id
)
182 BT_ASSERT_DBG(stream_class
);
183 stream_class
->id
= id
;
184 stream_class
->id_set
= 1;
185 BT_LOGT("Set stream class's ID (internal): "
186 "addr=%p, name=\"%s\", id=%" PRId64
,
187 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
188 bt_ctf_stream_class_common_get_id(stream_class
));
192 int bt_ctf_stream_class_common_set_id_no_check(
193 struct bt_ctf_stream_class_common
*stream_class
, int64_t id
)
195 _bt_ctf_stream_class_common_set_id(stream_class
, id
);
200 int bt_ctf_stream_class_common_set_id(struct bt_ctf_stream_class_common
*stream_class
,
204 int64_t id
= (int64_t) id_param
;
207 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
212 if (stream_class
->frozen
) {
213 BT_LOGW("Invalid parameter: stream class is frozen: "
214 "addr=%p, name=\"%s\", id=%" PRId64
,
216 bt_ctf_stream_class_common_get_name(stream_class
),
217 bt_ctf_stream_class_common_get_id(stream_class
));
223 BT_LOGW("Invalid parameter: invalid stream class's ID: "
224 "stream-class-addr=%p, stream-class-name=\"%s\", "
225 "stream-class-id=%" PRId64
", id=%" PRIu64
,
227 bt_ctf_stream_class_common_get_name(stream_class
),
228 bt_ctf_stream_class_common_get_id(stream_class
),
234 ret
= bt_ctf_stream_class_common_set_id_no_check(stream_class
, id
);
236 BT_LOGT("Set stream class's ID: "
237 "addr=%p, name=\"%s\", id=%" PRId64
,
239 bt_ctf_stream_class_common_get_name(stream_class
),
240 bt_ctf_stream_class_common_get_id(stream_class
));
247 int64_t bt_ctf_stream_class_common_get_event_class_count(
248 struct bt_ctf_stream_class_common
*stream_class
)
253 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
258 ret
= (int64_t) stream_class
->event_classes
->len
;
264 struct bt_ctf_event_class_common
*bt_ctf_stream_class_common_borrow_event_class_by_index(
265 struct bt_ctf_stream_class_common
*stream_class
, uint64_t index
)
267 BT_CTF_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
268 BT_CTF_ASSERT_PRE(index
< stream_class
->event_classes
->len
,
269 "Index is out of bounds: index=%" PRIu64
", "
271 index
, stream_class
->event_classes
->len
);
272 return g_ptr_array_index(stream_class
->event_classes
, index
);
276 struct bt_ctf_event_class_common
*bt_ctf_stream_class_common_borrow_event_class_by_id(
277 struct bt_ctf_stream_class_common
*stream_class
, uint64_t id
)
279 int64_t id_key
= (int64_t) id
;
281 BT_CTF_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
282 BT_CTF_ASSERT_PRE(id_key
>= 0,
283 "Invalid event class ID: %" PRIu64
, id
);
284 return g_hash_table_lookup(stream_class
->event_classes_ht
,
289 struct bt_ctf_field_type_common
*
290 bt_ctf_stream_class_common_borrow_packet_context_field_type(
291 struct bt_ctf_stream_class_common
*stream_class
)
293 BT_CTF_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
294 return stream_class
->packet_context_field_type
;
298 int bt_ctf_stream_class_common_set_packet_context_field_type(
299 struct bt_ctf_stream_class_common
*stream_class
,
300 struct bt_ctf_field_type_common
*packet_context_type
)
305 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
310 if (stream_class
->frozen
) {
311 BT_LOGW("Invalid parameter: stream class is frozen: "
312 "addr=%p, name=\"%s\", id=%" PRId64
,
313 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
314 bt_ctf_stream_class_common_get_id(stream_class
));
319 if (packet_context_type
&&
320 bt_ctf_field_type_common_get_type_id(packet_context_type
) !=
321 BT_CTF_FIELD_TYPE_ID_STRUCT
) {
322 /* A packet context must be a structure. */
323 BT_LOGW("Invalid parameter: stream class's packet context field type must be a structure: "
324 "addr=%p, name=\"%s\", id=%" PRId64
", "
325 "packet-context-ft-addr=%p, packet-context-ft-id=%s",
326 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
327 bt_ctf_stream_class_common_get_id(stream_class
),
329 bt_ctf_field_type_id_string(
330 bt_ctf_field_type_common_get_type_id(packet_context_type
)));
335 bt_ctf_object_put_ref(stream_class
->packet_context_field_type
);
336 stream_class
->packet_context_field_type
= packet_context_type
;
337 bt_ctf_object_get_ref(stream_class
->packet_context_field_type
);
338 BT_LOGT("Set stream class's packet context field type: "
339 "addr=%p, name=\"%s\", id=%" PRId64
", "
340 "packet-context-ft-addr=%p",
341 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
342 bt_ctf_stream_class_common_get_id(stream_class
),
343 packet_context_type
);
350 struct bt_ctf_field_type_common
*
351 bt_ctf_stream_class_common_borrow_event_header_field_type(
352 struct bt_ctf_stream_class_common
*stream_class
)
354 struct bt_ctf_field_type_common
*ret
= NULL
;
356 BT_CTF_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
358 if (!stream_class
->event_header_field_type
) {
359 BT_LOGT("Stream class has no event header field type: "
360 "addr=%p, name=\"%s\", id=%" PRId64
,
362 bt_ctf_stream_class_common_get_name(stream_class
),
363 bt_ctf_stream_class_common_get_id(stream_class
));
367 ret
= stream_class
->event_header_field_type
;
374 int bt_ctf_stream_class_common_set_event_header_field_type(
375 struct bt_ctf_stream_class_common
*stream_class
,
376 struct bt_ctf_field_type_common
*event_header_type
)
381 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
386 if (stream_class
->frozen
) {
387 BT_LOGW("Invalid parameter: stream class is frozen: "
388 "addr=%p, name=\"%s\", id=%" PRId64
,
390 bt_ctf_stream_class_common_get_name(stream_class
),
391 bt_ctf_stream_class_common_get_id(stream_class
));
396 if (event_header_type
&&
397 bt_ctf_field_type_common_get_type_id(event_header_type
) !=
398 BT_CTF_FIELD_TYPE_ID_STRUCT
) {
399 /* An event header must be a structure. */
400 BT_LOGW("Invalid parameter: stream class's event header field type must be a structure: "
401 "addr=%p, name=\"%s\", id=%" PRId64
", "
402 "event-header-ft-addr=%p, event-header-ft-id=%s",
403 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
404 bt_ctf_stream_class_common_get_id(stream_class
),
406 bt_ctf_field_type_id_string(
407 bt_ctf_field_type_common_get_type_id(event_header_type
)));
412 bt_ctf_object_put_ref(stream_class
->event_header_field_type
);
413 stream_class
->event_header_field_type
= event_header_type
;
414 bt_ctf_object_get_ref(stream_class
->event_header_field_type
);
415 BT_LOGT("Set stream class's event header field type: "
416 "addr=%p, name=\"%s\", id=%" PRId64
", "
417 "event-header-ft-addr=%p",
418 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
419 bt_ctf_stream_class_common_get_id(stream_class
),
426 struct bt_ctf_field_type_common
*
427 bt_ctf_stream_class_common_borrow_event_context_field_type(
428 struct bt_ctf_stream_class_common
*stream_class
)
430 struct bt_ctf_field_type_common
*ret
= NULL
;
432 BT_CTF_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
434 if (!stream_class
->event_context_field_type
) {
438 ret
= stream_class
->event_context_field_type
;
445 int bt_ctf_stream_class_common_set_event_context_field_type(
446 struct bt_ctf_stream_class_common
*stream_class
,
447 struct bt_ctf_field_type_common
*event_context_type
)
452 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
457 if (stream_class
->frozen
) {
458 BT_LOGW("Invalid parameter: stream class is frozen: "
459 "addr=%p, name=\"%s\", id=%" PRId64
,
460 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
461 bt_ctf_stream_class_common_get_id(stream_class
));
466 if (event_context_type
&&
467 bt_ctf_field_type_common_get_type_id(event_context_type
) !=
468 BT_CTF_FIELD_TYPE_ID_STRUCT
) {
469 /* A packet context must be a structure. */
470 BT_LOGW("Invalid parameter: stream class's event context field type must be a structure: "
471 "addr=%p, name=\"%s\", id=%" PRId64
", "
472 "event-context-ft-addr=%p, event-context-ft-id=%s",
473 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
474 bt_ctf_stream_class_common_get_id(stream_class
),
476 bt_ctf_field_type_id_string(
477 bt_ctf_field_type_common_get_type_id(event_context_type
)));
482 bt_ctf_object_put_ref(stream_class
->event_context_field_type
);
483 stream_class
->event_context_field_type
= event_context_type
;
484 bt_ctf_object_get_ref(stream_class
->event_context_field_type
);
485 BT_LOGT("Set stream class's event context field type: "
486 "addr=%p, name=\"%s\", id=%" PRId64
", "
487 "event-context-ft-addr=%p",
488 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
489 bt_ctf_stream_class_common_get_id(stream_class
),
495 struct bt_ctf_stream_class
{
496 struct bt_ctf_stream_class_common common
;
497 struct bt_ctf_clock
*clock
;
498 int64_t next_stream_id
;
501 struct metadata_context
;
503 int bt_ctf_stream_class_serialize(struct bt_ctf_stream_class
*stream_class
,
504 struct metadata_context
*context
);
506 int bt_ctf_stream_class_map_clock_class(
507 struct bt_ctf_stream_class
*stream_class
,
508 struct bt_ctf_field_type
*packet_context_type
,
509 struct bt_ctf_field_type
*event_header_type
);
511 #endif /* BABELTRACE_CTF_WRITER_STREAM_CLASS_INTERNAL_H */