Fix: lib: add NULL check for destroy_listeners in destroy_component_class
[babeltrace.git] / src / ctf-writer / stream-class.h
CommitLineData
3dca2276 1/*
0235b0db 2 * SPDX-License-Identifier: MIT
3dca2276 3 *
0235b0db 4 * Copyright 2014 EfficiOS Inc.
3dca2276
PP
5 *
6 * The Common Trace Format (CTF) Specification is available at
7 * http://www.efficios.com/ctf
8 */
9
0235b0db
MJ
10#ifndef BABELTRACE_CTF_WRITER_STREAM_CLASS_INTERNAL_H
11#define BABELTRACE_CTF_WRITER_STREAM_CLASS_INTERNAL_H
12
578e048b 13#include "common/assert.h"
91d81473 14#include "common/macros.h"
578e048b 15#include "common/common.h"
217cf9d3
PP
16#include <babeltrace2-ctf-writer/field-types.h>
17#include <babeltrace2-ctf-writer/visitor.h>
16ca5ff0
PP
18#include <inttypes.h>
19
578e048b
MJ
20#include "clock.h"
21#include "field-types.h"
22#include "object.h"
23#include "stream-class.h"
24#include "utils.h"
25#include "validation.h"
26
16ca5ff0 27struct bt_ctf_stream_class_common {
e1e02a22 28 struct bt_ctf_object base;
16ca5ff0
PP
29 GString *name;
30
31 /* Array of pointers to event class addresses */
32 GPtrArray *event_classes;
33
34 /* event class id (int64_t) to event class address */
35 GHashTable *event_classes_ht;
36 int id_set;
37 int64_t id;
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;
42 int frozen;
43 int byte_order;
44
45 /*
46 * This flag indicates if the stream class is valid. A valid
47 * stream class is _always_ frozen.
48 */
49 int valid;
50
51 /*
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.
55 *
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.
64 *
65 * If this is a CTF writer stream class, then this is the
66 * backing clock class of the `clock` member above.
67 */
68 struct bt_ctf_clock_class *clock_class;
69};
70
71struct bt_ctf_event_class_common;
72
73BT_HIDDEN
74int bt_ctf_stream_class_common_initialize(struct bt_ctf_stream_class_common *stream_class,
e1e02a22 75 const char *name, bt_ctf_object_release_func release_func);
16ca5ff0
PP
76
77BT_HIDDEN
78void bt_ctf_stream_class_common_finalize(struct bt_ctf_stream_class_common *stream_class);
79
80BT_HIDDEN
81void bt_ctf_stream_class_common_freeze(struct bt_ctf_stream_class_common *stream_class);
82
83static inline
84const char *bt_ctf_stream_class_common_get_name(
85 struct bt_ctf_stream_class_common *stream_class)
86{
67d2ce02 87 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
16ca5ff0
PP
88 return stream_class->name->len > 0 ? stream_class->name->str : NULL;
89}
90
91static inline
92int64_t bt_ctf_stream_class_common_get_id(
93 struct bt_ctf_stream_class_common *stream_class)
94{
95 int64_t ret;
96
67d2ce02 97 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
16ca5ff0
PP
98
99 if (!stream_class->id_set) {
ef267d12 100 BT_LOGT("Stream class's ID is not set: addr=%p, name=\"%s\"",
16ca5ff0
PP
101 stream_class,
102 bt_ctf_stream_class_common_get_name(stream_class));
103 ret = (int64_t) -1;
104 goto end;
105 }
106
107 ret = stream_class->id;
108
109end:
110 return ret;
111}
112
113BT_HIDDEN
114void bt_ctf_stream_class_common_set_byte_order(
115 struct bt_ctf_stream_class_common *stream_class, int byte_order);
116
117BT_HIDDEN
118int 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);
121
122BT_HIDDEN
123int 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);
127
128BT_HIDDEN
129int bt_ctf_stream_class_common_visit(struct bt_ctf_stream_class_common *stream_class,
130 bt_ctf_visitor visitor, void *data);
131
132BT_HIDDEN
133int bt_ctf_stream_class_visit(struct bt_ctf_stream_class *stream_class,
134 bt_ctf_visitor visitor, void *data);
135
136static inline
137struct bt_ctf_trace_common *bt_ctf_stream_class_common_borrow_trace(
138 struct bt_ctf_stream_class_common *stream_class)
139{
98b15851 140 BT_ASSERT_DBG(stream_class);
e1e02a22 141 return (void *) bt_ctf_object_borrow_parent(&stream_class->base);
16ca5ff0
PP
142}
143
144static inline
145int bt_ctf_stream_class_common_set_name(struct bt_ctf_stream_class_common *stream_class,
146 const char *name)
147{
148 int ret = 0;
149
150 if (!stream_class) {
151 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
152 ret = -1;
153 goto end;
154 }
155
156 if (stream_class->frozen) {
157 BT_LOGW("Invalid parameter: stream class is frozen: "
158 "addr=%p, name=\"%s\", id=%" PRId64,
159 stream_class,
160 bt_ctf_stream_class_common_get_name(stream_class),
161 bt_ctf_stream_class_common_get_id(stream_class));
162 ret = -1;
163 goto end;
164 }
165
166 if (!name) {
167 g_string_assign(stream_class->name, "");
168 } else {
169 if (strlen(name) == 0) {
170 BT_LOGW("Invalid parameter: name is empty.");
171 ret = -1;
172 goto end;
173 }
174
175 g_string_assign(stream_class->name, name);
176 }
177
ef267d12 178 BT_LOGT("Set stream class's name: "
16ca5ff0
PP
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));
182end:
183 return ret;
184}
185
186static inline
187void _bt_ctf_stream_class_common_set_id(
188 struct bt_ctf_stream_class_common *stream_class, int64_t id)
189{
98b15851 190 BT_ASSERT_DBG(stream_class);
16ca5ff0
PP
191 stream_class->id = id;
192 stream_class->id_set = 1;
ef267d12 193 BT_LOGT("Set stream class's ID (internal): "
16ca5ff0
PP
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));
197}
198
199static inline
200int bt_ctf_stream_class_common_set_id_no_check(
201 struct bt_ctf_stream_class_common *stream_class, int64_t id)
202{
203 _bt_ctf_stream_class_common_set_id(stream_class, id);
204 return 0;
205}
206
207static inline
208int bt_ctf_stream_class_common_set_id(struct bt_ctf_stream_class_common *stream_class,
209 uint64_t id_param)
210{
211 int ret = 0;
212 int64_t id = (int64_t) id_param;
213
214 if (!stream_class) {
215 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
216 ret = -1;
217 goto end;
218 }
219
220 if (stream_class->frozen) {
221 BT_LOGW("Invalid parameter: stream class is frozen: "
222 "addr=%p, name=\"%s\", id=%" PRId64,
223 stream_class,
224 bt_ctf_stream_class_common_get_name(stream_class),
225 bt_ctf_stream_class_common_get_id(stream_class));
226 ret = -1;
227 goto end;
228 }
229
230 if (id < 0) {
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,
234 stream_class,
235 bt_ctf_stream_class_common_get_name(stream_class),
236 bt_ctf_stream_class_common_get_id(stream_class),
237 id_param);
238 ret = -1;
239 goto end;
240 }
241
242 ret = bt_ctf_stream_class_common_set_id_no_check(stream_class, id);
243 if (ret == 0) {
ef267d12 244 BT_LOGT("Set stream class's ID: "
16ca5ff0
PP
245 "addr=%p, name=\"%s\", id=%" PRId64,
246 stream_class,
247 bt_ctf_stream_class_common_get_name(stream_class),
248 bt_ctf_stream_class_common_get_id(stream_class));
249 }
250end:
251 return ret;
252}
253
254static inline
255int64_t bt_ctf_stream_class_common_get_event_class_count(
256 struct bt_ctf_stream_class_common *stream_class)
257{
258 int64_t ret;
259
260 if (!stream_class) {
261 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
262 ret = (int64_t) -1;
263 goto end;
264 }
265
266 ret = (int64_t) stream_class->event_classes->len;
267end:
268 return ret;
269}
270
271static inline
272struct 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)
274{
67d2ce02
MJ
275 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
276 BT_CTF_ASSERT_PRE(index < stream_class->event_classes->len,
16ca5ff0
PP
277 "Index is out of bounds: index=%" PRIu64 ", "
278 "count=%u",
279 index, stream_class->event_classes->len);
280 return g_ptr_array_index(stream_class->event_classes, index);
281}
282
283static inline
284struct 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)
286{
287 int64_t id_key = (int64_t) id;
288
67d2ce02
MJ
289 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
290 BT_CTF_ASSERT_PRE(id_key >= 0,
16ca5ff0
PP
291 "Invalid event class ID: %" PRIu64, id);
292 return g_hash_table_lookup(stream_class->event_classes_ht,
293 &id_key);
294}
295
296static inline
297struct bt_ctf_field_type_common *
298bt_ctf_stream_class_common_borrow_packet_context_field_type(
299 struct bt_ctf_stream_class_common *stream_class)
300{
67d2ce02 301 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
16ca5ff0
PP
302 return stream_class->packet_context_field_type;
303}
304
305static inline
306int 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)
309{
310 int ret = 0;
311
312 if (!stream_class) {
313 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
314 ret = -1;
315 goto end;
316 }
317
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));
323 ret = -1;
324 goto end;
325 }
326
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),
336 packet_context_type,
337 bt_ctf_field_type_id_string(
338 bt_ctf_field_type_common_get_type_id(packet_context_type)));
339 ret = -1;
340 goto end;
341 }
342
e1e02a22 343 bt_ctf_object_put_ref(stream_class->packet_context_field_type);
16ca5ff0 344 stream_class->packet_context_field_type = packet_context_type;
e1e02a22 345 bt_ctf_object_get_ref(stream_class->packet_context_field_type);
ef267d12 346 BT_LOGT("Set stream class's packet context field type: "
16ca5ff0
PP
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);
352
353end:
354 return ret;
355}
356
357static inline
358struct bt_ctf_field_type_common *
359bt_ctf_stream_class_common_borrow_event_header_field_type(
360 struct bt_ctf_stream_class_common *stream_class)
361{
362 struct bt_ctf_field_type_common *ret = NULL;
363
67d2ce02 364 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
16ca5ff0
PP
365
366 if (!stream_class->event_header_field_type) {
ef267d12 367 BT_LOGT("Stream class has no event header field type: "
16ca5ff0
PP
368 "addr=%p, name=\"%s\", id=%" PRId64,
369 stream_class,
370 bt_ctf_stream_class_common_get_name(stream_class),
371 bt_ctf_stream_class_common_get_id(stream_class));
372 goto end;
373 }
374
375 ret = stream_class->event_header_field_type;
376
377end:
378 return ret;
379}
380
381static inline
382int 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)
385{
386 int ret = 0;
387
388 if (!stream_class) {
389 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
390 ret = -1;
391 goto end;
392 }
393
394 if (stream_class->frozen) {
395 BT_LOGW("Invalid parameter: stream class is frozen: "
396 "addr=%p, name=\"%s\", id=%" PRId64,
397 stream_class,
398 bt_ctf_stream_class_common_get_name(stream_class),
399 bt_ctf_stream_class_common_get_id(stream_class));
400 ret = -1;
401 goto end;
402 }
403
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),
413 event_header_type,
414 bt_ctf_field_type_id_string(
415 bt_ctf_field_type_common_get_type_id(event_header_type)));
416 ret = -1;
417 goto end;
418 }
419
e1e02a22
PP
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);
ef267d12 423 BT_LOGT("Set stream class's event header field type: "
16ca5ff0
PP
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),
428 event_header_type);
429end:
430 return ret;
431}
432
433static inline
434struct bt_ctf_field_type_common *
435bt_ctf_stream_class_common_borrow_event_context_field_type(
436 struct bt_ctf_stream_class_common *stream_class)
437{
438 struct bt_ctf_field_type_common *ret = NULL;
439
67d2ce02 440 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
16ca5ff0
PP
441
442 if (!stream_class->event_context_field_type) {
443 goto end;
444 }
445
446 ret = stream_class->event_context_field_type;
447
448end:
449 return ret;
450}
451
452static inline
453int 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)
456{
457 int ret = 0;
458
459 if (!stream_class) {
460 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
461 ret = -1;
462 goto end;
463 }
464
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));
470 ret = -1;
471 goto end;
472 }
473
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),
483 event_context_type,
484 bt_ctf_field_type_id_string(
485 bt_ctf_field_type_common_get_type_id(event_context_type)));
486 ret = -1;
487 goto end;
488 }
489
e1e02a22
PP
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);
ef267d12 493 BT_LOGT("Set stream class's event context field type: "
16ca5ff0
PP
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),
498 event_context_type);
499end:
500 return ret;
501}
3dca2276
PP
502
503struct bt_ctf_stream_class {
16ca5ff0 504 struct bt_ctf_stream_class_common common;
3dca2276
PP
505 struct bt_ctf_clock *clock;
506 int64_t next_stream_id;
507};
508
509struct metadata_context;
510
511BT_HIDDEN
512int bt_ctf_stream_class_serialize(struct bt_ctf_stream_class *stream_class,
513 struct metadata_context *context);
514
515BT_HIDDEN
516int 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);
520
521#endif /* BABELTRACE_CTF_WRITER_STREAM_CLASS_INTERNAL_H */
This page took 0.091255 seconds and 4 git commands to generate.