Visibility hidden by default
[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
16ca5ff0 73int bt_ctf_stream_class_common_initialize(struct bt_ctf_stream_class_common *stream_class,
e1e02a22 74 const char *name, bt_ctf_object_release_func release_func);
16ca5ff0 75
16ca5ff0
PP
76void bt_ctf_stream_class_common_finalize(struct bt_ctf_stream_class_common *stream_class);
77
16ca5ff0
PP
78void bt_ctf_stream_class_common_freeze(struct bt_ctf_stream_class_common *stream_class);
79
80static inline
81const char *bt_ctf_stream_class_common_get_name(
82 struct bt_ctf_stream_class_common *stream_class)
83{
67d2ce02 84 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
16ca5ff0
PP
85 return stream_class->name->len > 0 ? stream_class->name->str : NULL;
86}
87
88static inline
89int64_t bt_ctf_stream_class_common_get_id(
90 struct bt_ctf_stream_class_common *stream_class)
91{
92 int64_t ret;
93
67d2ce02 94 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
16ca5ff0
PP
95
96 if (!stream_class->id_set) {
ef267d12 97 BT_LOGT("Stream class's ID is not set: addr=%p, name=\"%s\"",
16ca5ff0
PP
98 stream_class,
99 bt_ctf_stream_class_common_get_name(stream_class));
100 ret = (int64_t) -1;
101 goto end;
102 }
103
104 ret = stream_class->id;
105
106end:
107 return ret;
108}
109
16ca5ff0
PP
110void bt_ctf_stream_class_common_set_byte_order(
111 struct bt_ctf_stream_class_common *stream_class, int byte_order);
112
16ca5ff0
PP
113int 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);
116
16ca5ff0
PP
117int 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);
121
16ca5ff0
PP
122int bt_ctf_stream_class_common_visit(struct bt_ctf_stream_class_common *stream_class,
123 bt_ctf_visitor visitor, void *data);
124
16ca5ff0
PP
125int bt_ctf_stream_class_visit(struct bt_ctf_stream_class *stream_class,
126 bt_ctf_visitor visitor, void *data);
127
128static inline
129struct bt_ctf_trace_common *bt_ctf_stream_class_common_borrow_trace(
130 struct bt_ctf_stream_class_common *stream_class)
131{
98b15851 132 BT_ASSERT_DBG(stream_class);
e1e02a22 133 return (void *) bt_ctf_object_borrow_parent(&stream_class->base);
16ca5ff0
PP
134}
135
136static inline
137int bt_ctf_stream_class_common_set_name(struct bt_ctf_stream_class_common *stream_class,
138 const char *name)
139{
140 int ret = 0;
141
142 if (!stream_class) {
143 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
144 ret = -1;
145 goto end;
146 }
147
148 if (stream_class->frozen) {
149 BT_LOGW("Invalid parameter: stream class is frozen: "
150 "addr=%p, name=\"%s\", id=%" PRId64,
151 stream_class,
152 bt_ctf_stream_class_common_get_name(stream_class),
153 bt_ctf_stream_class_common_get_id(stream_class));
154 ret = -1;
155 goto end;
156 }
157
158 if (!name) {
159 g_string_assign(stream_class->name, "");
160 } else {
161 if (strlen(name) == 0) {
162 BT_LOGW("Invalid parameter: name is empty.");
163 ret = -1;
164 goto end;
165 }
166
167 g_string_assign(stream_class->name, name);
168 }
169
ef267d12 170 BT_LOGT("Set stream class's name: "
16ca5ff0
PP
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));
174end:
175 return ret;
176}
177
178static inline
179void _bt_ctf_stream_class_common_set_id(
180 struct bt_ctf_stream_class_common *stream_class, int64_t id)
181{
98b15851 182 BT_ASSERT_DBG(stream_class);
16ca5ff0
PP
183 stream_class->id = id;
184 stream_class->id_set = 1;
ef267d12 185 BT_LOGT("Set stream class's ID (internal): "
16ca5ff0
PP
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));
189}
190
191static inline
192int bt_ctf_stream_class_common_set_id_no_check(
193 struct bt_ctf_stream_class_common *stream_class, int64_t id)
194{
195 _bt_ctf_stream_class_common_set_id(stream_class, id);
196 return 0;
197}
198
199static inline
200int bt_ctf_stream_class_common_set_id(struct bt_ctf_stream_class_common *stream_class,
201 uint64_t id_param)
202{
203 int ret = 0;
204 int64_t id = (int64_t) id_param;
205
206 if (!stream_class) {
207 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
208 ret = -1;
209 goto end;
210 }
211
212 if (stream_class->frozen) {
213 BT_LOGW("Invalid parameter: stream class is frozen: "
214 "addr=%p, name=\"%s\", id=%" PRId64,
215 stream_class,
216 bt_ctf_stream_class_common_get_name(stream_class),
217 bt_ctf_stream_class_common_get_id(stream_class));
218 ret = -1;
219 goto end;
220 }
221
222 if (id < 0) {
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,
226 stream_class,
227 bt_ctf_stream_class_common_get_name(stream_class),
228 bt_ctf_stream_class_common_get_id(stream_class),
229 id_param);
230 ret = -1;
231 goto end;
232 }
233
234 ret = bt_ctf_stream_class_common_set_id_no_check(stream_class, id);
235 if (ret == 0) {
ef267d12 236 BT_LOGT("Set stream class's ID: "
16ca5ff0
PP
237 "addr=%p, name=\"%s\", id=%" PRId64,
238 stream_class,
239 bt_ctf_stream_class_common_get_name(stream_class),
240 bt_ctf_stream_class_common_get_id(stream_class));
241 }
242end:
243 return ret;
244}
245
246static inline
247int64_t bt_ctf_stream_class_common_get_event_class_count(
248 struct bt_ctf_stream_class_common *stream_class)
249{
250 int64_t ret;
251
252 if (!stream_class) {
253 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
254 ret = (int64_t) -1;
255 goto end;
256 }
257
258 ret = (int64_t) stream_class->event_classes->len;
259end:
260 return ret;
261}
262
263static inline
264struct 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)
266{
67d2ce02
MJ
267 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
268 BT_CTF_ASSERT_PRE(index < stream_class->event_classes->len,
16ca5ff0
PP
269 "Index is out of bounds: index=%" PRIu64 ", "
270 "count=%u",
271 index, stream_class->event_classes->len);
272 return g_ptr_array_index(stream_class->event_classes, index);
273}
274
275static inline
276struct 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)
278{
279 int64_t id_key = (int64_t) id;
280
67d2ce02
MJ
281 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
282 BT_CTF_ASSERT_PRE(id_key >= 0,
16ca5ff0
PP
283 "Invalid event class ID: %" PRIu64, id);
284 return g_hash_table_lookup(stream_class->event_classes_ht,
285 &id_key);
286}
287
288static inline
289struct bt_ctf_field_type_common *
290bt_ctf_stream_class_common_borrow_packet_context_field_type(
291 struct bt_ctf_stream_class_common *stream_class)
292{
67d2ce02 293 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
16ca5ff0
PP
294 return stream_class->packet_context_field_type;
295}
296
297static inline
298int 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)
301{
302 int ret = 0;
303
304 if (!stream_class) {
305 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
306 ret = -1;
307 goto end;
308 }
309
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));
315 ret = -1;
316 goto end;
317 }
318
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),
328 packet_context_type,
329 bt_ctf_field_type_id_string(
330 bt_ctf_field_type_common_get_type_id(packet_context_type)));
331 ret = -1;
332 goto end;
333 }
334
e1e02a22 335 bt_ctf_object_put_ref(stream_class->packet_context_field_type);
16ca5ff0 336 stream_class->packet_context_field_type = packet_context_type;
e1e02a22 337 bt_ctf_object_get_ref(stream_class->packet_context_field_type);
ef267d12 338 BT_LOGT("Set stream class's packet context field type: "
16ca5ff0
PP
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);
344
345end:
346 return ret;
347}
348
349static inline
350struct bt_ctf_field_type_common *
351bt_ctf_stream_class_common_borrow_event_header_field_type(
352 struct bt_ctf_stream_class_common *stream_class)
353{
354 struct bt_ctf_field_type_common *ret = NULL;
355
67d2ce02 356 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
16ca5ff0
PP
357
358 if (!stream_class->event_header_field_type) {
ef267d12 359 BT_LOGT("Stream class has no event header field type: "
16ca5ff0
PP
360 "addr=%p, name=\"%s\", id=%" PRId64,
361 stream_class,
362 bt_ctf_stream_class_common_get_name(stream_class),
363 bt_ctf_stream_class_common_get_id(stream_class));
364 goto end;
365 }
366
367 ret = stream_class->event_header_field_type;
368
369end:
370 return ret;
371}
372
373static inline
374int 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)
377{
378 int ret = 0;
379
380 if (!stream_class) {
381 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
382 ret = -1;
383 goto end;
384 }
385
386 if (stream_class->frozen) {
387 BT_LOGW("Invalid parameter: stream class is frozen: "
388 "addr=%p, name=\"%s\", id=%" PRId64,
389 stream_class,
390 bt_ctf_stream_class_common_get_name(stream_class),
391 bt_ctf_stream_class_common_get_id(stream_class));
392 ret = -1;
393 goto end;
394 }
395
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),
405 event_header_type,
406 bt_ctf_field_type_id_string(
407 bt_ctf_field_type_common_get_type_id(event_header_type)));
408 ret = -1;
409 goto end;
410 }
411
e1e02a22
PP
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);
ef267d12 415 BT_LOGT("Set stream class's event header field type: "
16ca5ff0
PP
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),
420 event_header_type);
421end:
422 return ret;
423}
424
425static inline
426struct bt_ctf_field_type_common *
427bt_ctf_stream_class_common_borrow_event_context_field_type(
428 struct bt_ctf_stream_class_common *stream_class)
429{
430 struct bt_ctf_field_type_common *ret = NULL;
431
67d2ce02 432 BT_CTF_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
16ca5ff0
PP
433
434 if (!stream_class->event_context_field_type) {
435 goto end;
436 }
437
438 ret = stream_class->event_context_field_type;
439
440end:
441 return ret;
442}
443
444static inline
445int 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)
448{
449 int ret = 0;
450
451 if (!stream_class) {
452 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
453 ret = -1;
454 goto end;
455 }
456
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));
462 ret = -1;
463 goto end;
464 }
465
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),
475 event_context_type,
476 bt_ctf_field_type_id_string(
477 bt_ctf_field_type_common_get_type_id(event_context_type)));
478 ret = -1;
479 goto end;
480 }
481
e1e02a22
PP
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);
ef267d12 485 BT_LOGT("Set stream class's event context field type: "
16ca5ff0
PP
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),
490 event_context_type);
491end:
492 return ret;
493}
3dca2276
PP
494
495struct bt_ctf_stream_class {
16ca5ff0 496 struct bt_ctf_stream_class_common common;
3dca2276
PP
497 struct bt_ctf_clock *clock;
498 int64_t next_stream_id;
499};
500
501struct metadata_context;
502
3dca2276
PP
503int bt_ctf_stream_class_serialize(struct bt_ctf_stream_class *stream_class,
504 struct metadata_context *context);
505
3dca2276
PP
506int 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);
510
511#endif /* BABELTRACE_CTF_WRITER_STREAM_CLASS_INTERNAL_H */
This page took 0.097817 seconds and 4 git commands to generate.