Fix: lib: add NULL check for destroy_listeners in destroy_component_class
[babeltrace.git] / src / ctf-writer / stream-class.h
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright 2014 EfficiOS Inc.
5 *
6 * The Common Trace Format (CTF) Specification is available at
7 * http://www.efficios.com/ctf
8 */
9
10 #ifndef BABELTRACE_CTF_WRITER_STREAM_CLASS_INTERNAL_H
11 #define BABELTRACE_CTF_WRITER_STREAM_CLASS_INTERNAL_H
12
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>
18 #include <inttypes.h>
19
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
27 struct bt_ctf_stream_class_common {
28 struct bt_ctf_object base;
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
71 struct bt_ctf_event_class_common;
72
73 BT_HIDDEN
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);
76
77 BT_HIDDEN
78 void bt_ctf_stream_class_common_finalize(struct bt_ctf_stream_class_common *stream_class);
79
80 BT_HIDDEN
81 void bt_ctf_stream_class_common_freeze(struct bt_ctf_stream_class_common *stream_class);
82
83 static inline
84 const char *bt_ctf_stream_class_common_get_name(
85 struct bt_ctf_stream_class_common *stream_class)
86 {
87 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
88 return stream_class->name->len > 0 ? stream_class->name->str : NULL;
89 }
90
91 static inline
92 int64_t bt_ctf_stream_class_common_get_id(
93 struct bt_ctf_stream_class_common *stream_class)
94 {
95 int64_t ret;
96
97 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
98
99 if (!stream_class->id_set) {
100 BT_LOGT("Stream class's ID is not set: addr=%p, name=\"%s\"",
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
109 end:
110 return ret;
111 }
112
113 BT_HIDDEN
114 void bt_ctf_stream_class_common_set_byte_order(
115 struct bt_ctf_stream_class_common *stream_class, int byte_order);
116
117 BT_HIDDEN
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);
121
122 BT_HIDDEN
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);
127
128 BT_HIDDEN
129 int bt_ctf_stream_class_common_visit(struct bt_ctf_stream_class_common *stream_class,
130 bt_ctf_visitor visitor, void *data);
131
132 BT_HIDDEN
133 int bt_ctf_stream_class_visit(struct bt_ctf_stream_class *stream_class,
134 bt_ctf_visitor visitor, void *data);
135
136 static inline
137 struct bt_ctf_trace_common *bt_ctf_stream_class_common_borrow_trace(
138 struct bt_ctf_stream_class_common *stream_class)
139 {
140 BT_ASSERT_DBG(stream_class);
141 return (void *) bt_ctf_object_borrow_parent(&stream_class->base);
142 }
143
144 static inline
145 int 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
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));
182 end:
183 return ret;
184 }
185
186 static inline
187 void _bt_ctf_stream_class_common_set_id(
188 struct bt_ctf_stream_class_common *stream_class, int64_t id)
189 {
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));
197 }
198
199 static inline
200 int 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
207 static inline
208 int 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) {
244 BT_LOGT("Set stream class's ID: "
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 }
250 end:
251 return ret;
252 }
253
254 static inline
255 int64_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;
267 end:
268 return ret;
269 }
270
271 static inline
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)
274 {
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 ", "
278 "count=%u",
279 index, stream_class->event_classes->len);
280 return g_ptr_array_index(stream_class->event_classes, index);
281 }
282
283 static inline
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)
286 {
287 int64_t id_key = (int64_t) id;
288
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,
293 &id_key);
294 }
295
296 static inline
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)
300 {
301 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
302 return stream_class->packet_context_field_type;
303 }
304
305 static inline
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)
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
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);
352
353 end:
354 return ret;
355 }
356
357 static inline
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)
361 {
362 struct bt_ctf_field_type_common *ret = NULL;
363
364 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
365
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,
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
377 end:
378 return ret;
379 }
380
381 static inline
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)
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
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),
428 event_header_type);
429 end:
430 return ret;
431 }
432
433 static inline
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)
437 {
438 struct bt_ctf_field_type_common *ret = NULL;
439
440 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
441
442 if (!stream_class->event_context_field_type) {
443 goto end;
444 }
445
446 ret = stream_class->event_context_field_type;
447
448 end:
449 return ret;
450 }
451
452 static inline
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)
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
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),
498 event_context_type);
499 end:
500 return ret;
501 }
502
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;
507 };
508
509 struct metadata_context;
510
511 BT_HIDDEN
512 int bt_ctf_stream_class_serialize(struct bt_ctf_stream_class *stream_class,
513 struct metadata_context *context);
514
515 BT_HIDDEN
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);
520
521 #endif /* BABELTRACE_CTF_WRITER_STREAM_CLASS_INTERNAL_H */
This page took 0.049382 seconds and 4 git commands to generate.