ir: add bt_ctf_trace_get_stream_class_by_id()
[babeltrace.git] / formats / ctf / ir / stream-class.c
CommitLineData
11b0cdc8 1/*
3f043b05 2 * stream-class.c
11b0cdc8 3 *
d2dc44b6 4 * Babeltrace CTF IR - Stream Class
11b0cdc8 5 *
de9dd397 6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
11b0cdc8
JG
7 *
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
29#include <babeltrace/ctf-writer/clock.h>
30#include <babeltrace/ctf-ir/clock-internal.h>
31#include <babeltrace/ctf-writer/event.h>
32#include <babeltrace/ctf-ir/event-internal.h>
33#include <babeltrace/ctf-ir/event-types-internal.h>
34#include <babeltrace/ctf-ir/event-fields-internal.h>
35#include <babeltrace/ctf-writer/stream.h>
36#include <babeltrace/ctf-ir/stream-class-internal.h>
26079216 37#include <babeltrace/ctf-ir/visitor-internal.h>
11b0cdc8 38#include <babeltrace/ctf-writer/functor-internal.h>
654c1444 39#include <babeltrace/ctf-ir/utils.h>
de3dd40e
PP
40#include <babeltrace/ctf-ir/ref.h>
41#include <babeltrace/ctf-ir/common-internal.h>
11b0cdc8
JG
42#include <babeltrace/compiler.h>
43#include <babeltrace/align.h>
44
45static
de3dd40e 46void bt_ctf_stream_class_destroy(struct bt_ref *ref);
11b0cdc8 47static
662e778c 48int init_event_header(struct bt_ctf_stream_class *stream_class);
11b0cdc8 49static
662e778c 50int init_packet_context(struct bt_ctf_stream_class *stream_class);
11b0cdc8
JG
51
52struct bt_ctf_stream_class *bt_ctf_stream_class_create(const char *name)
53{
12c8a1a3 54 int ret;
11b0cdc8
JG
55 struct bt_ctf_stream_class *stream_class = NULL;
56
3ea33115 57 if (name && bt_ctf_validate_identifier(name)) {
11b0cdc8
JG
58 goto error;
59 }
60
61 stream_class = g_new0(struct bt_ctf_stream_class, 1);
62 if (!stream_class) {
63 goto error;
64 }
65
66 stream_class->name = g_string_new(name);
67 stream_class->event_classes = g_ptr_array_new_with_free_func(
68 (GDestroyNotify)bt_ctf_event_class_put);
69 if (!stream_class->event_classes) {
70 goto error_destroy;
71 }
72
662e778c
JG
73 ret = init_event_header(stream_class);
74 if (ret) {
75 goto error_destroy;
76 }
77
78 ret = init_packet_context(stream_class);
12c8a1a3
JG
79 if (ret) {
80 goto error_destroy;
81 }
82
de3dd40e 83 bt_ctf_base_init(stream_class, bt_ctf_stream_class_destroy);
11b0cdc8
JG
84 return stream_class;
85
86error_destroy:
de3dd40e 87 bt_ctf_stream_class_destroy(&stream_class->base.ref_count);
11b0cdc8
JG
88 stream_class = NULL;
89error:
90 return stream_class;
91}
92
142c5610
JG
93struct bt_ctf_trace *bt_ctf_stream_class_get_trace(
94 struct bt_ctf_stream_class *stream_class)
95{
96 struct bt_ctf_trace *trace = NULL;
97
98 if (!stream_class) {
99 goto end;
100 }
101
102 trace = stream_class->trace;
103 if (trace) {
104 bt_ctf_trace_get(trace);
105 }
106end:
107 return trace;
108}
109
69dc4535
JG
110const char *bt_ctf_stream_class_get_name(
111 struct bt_ctf_stream_class *stream_class)
112{
113 const char *name = NULL;
114
115 if (!stream_class) {
116 goto end;
117 }
118
119 name = stream_class->name->str;
120end:
121 return name;
122}
123
3ea33115
JG
124int bt_ctf_stream_class_set_name(struct bt_ctf_stream_class *stream_class,
125 const char *name)
126{
127 int ret = 0;
128
129 if (!stream_class || stream_class->frozen) {
130 ret = -1;
131 goto end;
132 }
133
134 g_string_assign(stream_class->name, name);
135end:
136 return ret;
137}
138
2f100782
JG
139struct bt_ctf_clock *bt_ctf_stream_class_get_clock(
140 struct bt_ctf_stream_class *stream_class)
141{
142 struct bt_ctf_clock *clock = NULL;
143
144 if (!stream_class || !stream_class->clock) {
145 goto end;
146 }
147
148 clock = stream_class->clock;
149 bt_ctf_clock_get(clock);
150end:
151 return clock;
152}
153
11b0cdc8
JG
154int bt_ctf_stream_class_set_clock(struct bt_ctf_stream_class *stream_class,
155 struct bt_ctf_clock *clock)
156{
157 int ret = 0;
eee752e5 158 struct bt_ctf_field_type *timestamp_field = NULL;
11b0cdc8
JG
159
160 if (!stream_class || !clock || stream_class->frozen) {
161 ret = -1;
162 goto end;
163 }
164
eee752e5
JG
165 /*
166 * Look for a "timestamp" field in the stream class' event header type
167 * and map the stream's clock to that field if no current mapping is
168 * currently set.
169 */
170 timestamp_field = bt_ctf_field_type_structure_get_field_type_by_name(
171 stream_class->event_header_type, "timestamp");
172 if (timestamp_field) {
173 struct bt_ctf_clock *mapped_clock;
174
175 mapped_clock = bt_ctf_field_type_integer_get_mapped_clock(
176 timestamp_field);
177 if (mapped_clock) {
178 bt_ctf_clock_put(mapped_clock);
179 goto end;
180 }
181
182 ret = bt_ctf_field_type_integer_set_mapped_clock(
183 timestamp_field, clock);
184 if (ret) {
185 goto end;
186 }
187 }
188
11b0cdc8
JG
189 if (stream_class->clock) {
190 bt_ctf_clock_put(stream_class->clock);
191 }
192
193 stream_class->clock = clock;
194 bt_ctf_clock_get(clock);
195end:
eee752e5
JG
196 if (timestamp_field) {
197 bt_ctf_field_type_put(timestamp_field);
198 }
11b0cdc8
JG
199 return ret;
200}
201
2f100782
JG
202int64_t bt_ctf_stream_class_get_id(struct bt_ctf_stream_class *stream_class)
203{
204 int64_t ret;
205
206 if (!stream_class || !stream_class->id_set) {
207 ret = -1;
208 goto end;
209 }
210
211 ret = (int64_t) stream_class->id;
212end:
213 return ret;
214}
215
5ca83563
JG
216BT_HIDDEN
217int _bt_ctf_stream_class_set_id(
218 struct bt_ctf_stream_class *stream_class, uint32_t id)
219{
220 stream_class->id = id;
221 stream_class->id_set = 1;
222 return 0;
223}
224
29664b2a
PP
225struct event_class_set_stream_id_data {
226 uint32_t stream_id;
227 int ret;
228};
229
230static
231void event_class_set_stream_id(gpointer event_class, gpointer data)
232{
233 struct event_class_set_stream_id_data *typed_data = data;
234
235 typed_data->ret |= bt_ctf_event_class_set_stream_id(event_class,
236 typed_data->stream_id);
237}
238
239BT_HIDDEN
240int bt_ctf_stream_class_set_id_no_check(
241 struct bt_ctf_stream_class *stream_class, uint32_t id)
2f100782
JG
242{
243 int ret = 0;
29664b2a
PP
244 struct event_class_set_stream_id_data data =
245 { .stream_id = id, .ret = 0 };
2f100782 246
29664b2a
PP
247 /*
248 * Make sure all event classes have their "stream_id" attribute
249 * set to this value.
250 */
251 g_ptr_array_foreach(stream_class->event_classes,
252 event_class_set_stream_id, &data);
253 ret = data.ret;
254 if (ret) {
2f100782
JG
255 goto end;
256 }
257
5ca83563
JG
258 ret = _bt_ctf_stream_class_set_id(stream_class, id);
259 if (ret) {
260 goto end;
261 }
2f100782
JG
262end:
263 return ret;
264}
265
29664b2a
PP
266int bt_ctf_stream_class_set_id(struct bt_ctf_stream_class *stream_class,
267 uint32_t id)
268{
269 int ret = 0;
270
271 if (!stream_class || stream_class->frozen) {
272 ret = -1;
273 goto end;
274 }
275
276 ret = bt_ctf_stream_class_set_id_no_check(stream_class, id);
277end:
278 return ret;
279}
280
0d23acbe
PP
281static
282void event_class_exists(gpointer element, gpointer query)
283{
284 struct bt_ctf_event_class *event_class_a = element;
285 struct search_query *search_query = query;
286 struct bt_ctf_event_class *event_class_b = search_query->value;
287 int64_t id_a, id_b;
288
289 if (search_query->value == element) {
290 search_query->found = 1;
291 goto end;
292 }
293
294 /*
295 * Two event classes cannot share the same name in a given
296 * stream class.
297 */
298 if (!strcmp(bt_ctf_event_class_get_name(event_class_a),
299 bt_ctf_event_class_get_name(event_class_b))) {
300 search_query->found = 1;
301 goto end;
302 }
303
304 /*
305 * Two event classes cannot share the same ID in a given
306 * stream class.
307 */
308 id_a = bt_ctf_event_class_get_id(event_class_a);
309 id_b = bt_ctf_event_class_get_id(event_class_b);
310
311 if (id_a < 0 || id_b < 0) {
312 /* at least one ID is not set: will be automatically set later */
313 goto end;
314 }
315
316 if (id_a == id_b) {
317 search_query->found = 1;
318 goto end;
319 }
320
321end:
322 return;
323}
324
11b0cdc8
JG
325int bt_ctf_stream_class_add_event_class(
326 struct bt_ctf_stream_class *stream_class,
327 struct bt_ctf_event_class *event_class)
328{
329 int ret = 0;
2f100782 330 int64_t event_id;
11b0cdc8
JG
331
332 if (!stream_class || !event_class) {
333 ret = -1;
334 goto end;
335 }
336
337 /* Check for duplicate event classes */
338 struct search_query query = { .value = event_class, .found = 0 };
0d23acbe
PP
339 g_ptr_array_foreach(stream_class->event_classes, event_class_exists,
340 &query);
11b0cdc8
JG
341 if (query.found) {
342 ret = -1;
343 goto end;
344 }
345
26079216
JG
346 /*
347 * Resolve the event's sequence length and variant tags if the
348 * stream is already associated with a trace. Otherwise, this
349 * validation will be performed once the stream is registered
350 * to a trace.
351 */
352 if (stream_class->trace) {
353 ret = bt_ctf_event_class_resolve_types(event_class,
354 stream_class->trace, stream_class);
355 if (ret) {
356 goto end;
357 }
358 }
359
2f100782
JG
360 /* Only set an event id if none was explicitly set before */
361 event_id = bt_ctf_event_class_get_id(event_class);
362 if (event_id < 0) {
363 if (bt_ctf_event_class_set_id(event_class,
364 stream_class->next_event_id++)) {
365 ret = -1;
366 goto end;
367 }
368 }
369
370 ret = bt_ctf_event_class_set_stream_class(event_class, stream_class);
371 if (ret) {
11b0cdc8
JG
372 goto end;
373 }
374
29664b2a
PP
375 ret = bt_ctf_event_class_set_stream_id(event_class, stream_class->id);
376 if (ret) {
377 goto end;
378 }
379
11b0cdc8
JG
380 bt_ctf_event_class_get(event_class);
381 g_ptr_array_add(stream_class->event_classes, event_class);
58203827 382 bt_ctf_event_class_freeze(event_class);
5ca83563
JG
383
384 if (stream_class->byte_order) {
385 /*
386 * Only set native byte order if it has been initialized
387 * when the stream class was added to a trace.
388 *
389 * If not set here, this will be set when the stream
390 * classe will be added to a trace.
391 */
392 bt_ctf_event_class_set_native_byte_order(event_class,
393 stream_class->byte_order);
394 }
11b0cdc8
JG
395end:
396 return ret;
397}
398
074ee56d 399int bt_ctf_stream_class_get_event_class_count(
69dc4535
JG
400 struct bt_ctf_stream_class *stream_class)
401{
074ee56d 402 int ret;
69dc4535
JG
403
404 if (!stream_class) {
405 ret = -1;
406 goto end;
407 }
408
074ee56d 409 ret = (int) stream_class->event_classes->len;
69dc4535
JG
410end:
411 return ret;
412}
413
414struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class(
074ee56d 415 struct bt_ctf_stream_class *stream_class, int index)
69dc4535
JG
416{
417 struct bt_ctf_event_class *event_class = NULL;
418
074ee56d
JG
419 if (!stream_class || index < 0 ||
420 index >= stream_class->event_classes->len) {
69dc4535
JG
421 goto end;
422 }
423
424 event_class = g_ptr_array_index(stream_class->event_classes, index);
425 bt_ctf_event_class_get(event_class);
426end:
427 return event_class;
428}
429
430struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_name(
431 struct bt_ctf_stream_class *stream_class, const char *name)
432{
433 size_t i;
69dc4535
JG
434 struct bt_ctf_event_class *event_class = NULL;
435
436 if (!stream_class || !name) {
437 goto end;
438 }
439
69dc4535 440 for (i = 0; i < stream_class->event_classes->len; i++) {
b8248cc0 441 struct bt_ctf_event_class *cur_event_class =
69dc4535 442 g_ptr_array_index(stream_class->event_classes, i);
b8248cc0
PP
443 const char *cur_event_class_name =
444 bt_ctf_event_class_get_name(cur_event_class);
69dc4535 445
b8248cc0
PP
446 if (!strcmp(name, cur_event_class_name)) {
447 event_class = cur_event_class;
69dc4535
JG
448 bt_ctf_event_class_get(event_class);
449 goto end;
450 }
451 }
452end:
453 return event_class;
454}
455
0863f950
PP
456struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_id(
457 struct bt_ctf_stream_class *stream_class, uint32_t id)
458{
459 size_t i;
460 struct bt_ctf_event_class *event_class = NULL;
461
462 if (!stream_class) {
463 goto end;
464 }
465
466 for (i = 0; i < stream_class->event_classes->len; i++) {
467 struct bt_ctf_event_class *current_event_class =
468 g_ptr_array_index(stream_class->event_classes, i);
469
470 if (bt_ctf_event_class_get_id(current_event_class) == id) {
471 event_class = current_event_class;
472 bt_ctf_event_class_get(event_class);
473 goto end;
474 }
475 }
476end:
477 return event_class;
478}
479
12c8a1a3
JG
480struct bt_ctf_field_type *bt_ctf_stream_class_get_packet_context_type(
481 struct bt_ctf_stream_class *stream_class)
482{
483 struct bt_ctf_field_type *ret = NULL;
484
485 if (!stream_class) {
486 goto end;
487 }
488
489 assert(stream_class->packet_context_type);
490 bt_ctf_field_type_get(stream_class->packet_context_type);
491 ret = stream_class->packet_context_type;
492end:
493 return ret;
494}
495
496int bt_ctf_stream_class_set_packet_context_type(
497 struct bt_ctf_stream_class *stream_class,
498 struct bt_ctf_field_type *packet_context_type)
499{
500 int ret = 0;
501
0a00bfa1 502 if (!stream_class || !packet_context_type || stream_class->frozen) {
12c8a1a3
JG
503 ret = -1;
504 goto end;
505 }
506
507 assert(stream_class->packet_context_type);
662e778c
JG
508 if (stream_class->packet_context_type == packet_context_type) {
509 goto end;
510 }
b34f4d90 511 if (bt_ctf_field_type_get_type_id(packet_context_type) !=
12c8a1a3
JG
512 CTF_TYPE_STRUCT) {
513 /* A packet context must be a structure */
514 ret = -1;
515 goto end;
516 }
517
518 bt_ctf_field_type_put(stream_class->packet_context_type);
519 bt_ctf_field_type_get(packet_context_type);
520 stream_class->packet_context_type = packet_context_type;
521end:
522 return ret;
523}
524
662e778c
JG
525struct bt_ctf_field_type *bt_ctf_stream_class_get_event_header_type(
526 struct bt_ctf_stream_class *stream_class)
527{
528 struct bt_ctf_field_type *ret = NULL;
529
530 if (!stream_class || !stream_class->event_header_type) {
531 goto end;
532 }
533
534 assert(stream_class->event_header_type);
535 bt_ctf_field_type_get(stream_class->event_header_type);
536 ret = stream_class->event_header_type;
537end:
538 return ret;
539}
540
541int bt_ctf_stream_class_set_event_header_type(
542 struct bt_ctf_stream_class *stream_class,
543 struct bt_ctf_field_type *event_header_type)
544{
545 int ret = 0;
546
547 if (!stream_class || !event_header_type || stream_class->frozen) {
548 ret = -1;
549 goto end;
550 }
551
552 assert(stream_class->event_header_type);
553 if (stream_class->event_header_type == event_header_type) {
554 goto end;
555 }
556 if (bt_ctf_field_type_get_type_id(event_header_type) !=
557 CTF_TYPE_STRUCT) {
558 /* An event header must be a structure */
559 ret = -1;
560 goto end;
561 }
562
563 bt_ctf_field_type_put(stream_class->event_header_type);
564 bt_ctf_field_type_get(event_header_type);
565 stream_class->event_header_type = event_header_type;
566end:
567 return ret;
568}
569
af181248
JG
570struct bt_ctf_field_type *bt_ctf_stream_class_get_event_context_type(
571 struct bt_ctf_stream_class *stream_class)
572{
573 struct bt_ctf_field_type *ret = NULL;
574
575 if (!stream_class || !stream_class->event_context_type) {
576 goto end;
577 }
578
579 assert(stream_class->event_context_type);
580 bt_ctf_field_type_get(stream_class->event_context_type);
581 ret = stream_class->event_context_type;
582end:
583 return ret;
584}
585
586int bt_ctf_stream_class_set_event_context_type(
587 struct bt_ctf_stream_class *stream_class,
588 struct bt_ctf_field_type *event_context_type)
589{
590 int ret = 0;
591
592 if (!stream_class || !event_context_type || stream_class->frozen) {
593 ret = -1;
594 goto end;
595 }
596
597 if (bt_ctf_field_type_get_type_id(event_context_type) !=
598 CTF_TYPE_STRUCT) {
599 /* A packet context must be a structure */
600 ret = -1;
601 goto end;
602 }
603
604 bt_ctf_field_type_put(stream_class->event_context_type);
605 bt_ctf_field_type_get(event_context_type);
606 stream_class->event_context_type = event_context_type;
607end:
608 return ret;
609}
610
11b0cdc8
JG
611void bt_ctf_stream_class_get(struct bt_ctf_stream_class *stream_class)
612{
de3dd40e 613 bt_ctf_get(stream_class);
11b0cdc8
JG
614}
615
616void bt_ctf_stream_class_put(struct bt_ctf_stream_class *stream_class)
617{
de3dd40e 618 bt_ctf_put(stream_class);
11b0cdc8
JG
619}
620
621BT_HIDDEN
622void bt_ctf_stream_class_freeze(struct bt_ctf_stream_class *stream_class)
623{
624 if (!stream_class) {
625 return;
626 }
627
628 stream_class->frozen = 1;
662e778c 629 bt_ctf_field_type_freeze(stream_class->event_header_type);
12c8a1a3 630 bt_ctf_field_type_freeze(stream_class->packet_context_type);
af181248 631 bt_ctf_field_type_freeze(stream_class->event_context_type);
11b0cdc8 632 bt_ctf_clock_freeze(stream_class->clock);
11b0cdc8
JG
633}
634
11b0cdc8
JG
635BT_HIDDEN
636int bt_ctf_stream_class_set_byte_order(struct bt_ctf_stream_class *stream_class,
637 enum bt_ctf_byte_order byte_order)
638{
5ca83563 639 int i, ret = 0;
c35a1669 640 int internal_byte_order;
11b0cdc8 641
c35a1669
JG
642 /* Note that "NATIVE" means the trace's endianness, not the host's. */
643 if (!stream_class || byte_order <= BT_CTF_BYTE_ORDER_UNKNOWN ||
5ca83563 644 byte_order > BT_CTF_BYTE_ORDER_NETWORK) {
c35a1669
JG
645 ret = -1;
646 goto end;
647 }
648
649 switch (byte_order) {
650 case BT_CTF_BYTE_ORDER_NETWORK:
651 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
652 internal_byte_order = BIG_ENDIAN;
653 break;
654 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
655 internal_byte_order = LITTLE_ENDIAN;
656 break;
657 default:
658 ret = -1;
11b0cdc8
JG
659 goto end;
660 }
c35a1669
JG
661
662 stream_class->byte_order = internal_byte_order;
5ca83563
JG
663
664 /* Set native byte order to little or big endian */
665 bt_ctf_field_type_set_native_byte_order(
666 stream_class->event_header_type, stream_class->byte_order);
667 bt_ctf_field_type_set_native_byte_order(
668 stream_class->packet_context_type, stream_class->byte_order);
669 bt_ctf_field_type_set_native_byte_order(
670 stream_class->event_context_type, stream_class->byte_order);
671
672 /* Set all events' native byte order */
673 for (i = 0; i < stream_class->event_classes->len; i++) {
674 bt_ctf_event_class_set_native_byte_order(
675 g_ptr_array_index(stream_class->event_classes, i),
676 stream_class->byte_order);
677 bt_ctf_event_class_freeze(
678 g_ptr_array_index(stream_class->event_classes, i));
679 }
11b0cdc8
JG
680end:
681 return ret;
682}
683
684BT_HIDDEN
685int bt_ctf_stream_class_serialize(struct bt_ctf_stream_class *stream_class,
686 struct metadata_context *context)
687{
2f100782 688 int64_t ret = 0;
11b0cdc8
JG
689 size_t i;
690
691 g_string_assign(context->field_name, "");
692 context->current_indentation_level = 1;
693 if (!stream_class->id_set) {
694 ret = -1;
695 goto end;
696 }
697
698 g_string_append_printf(context->string,
699 "stream {\n\tid = %" PRIu32 ";\n\tevent.header := ",
700 stream_class->id);
701 ret = bt_ctf_field_type_serialize(stream_class->event_header_type,
702 context);
703 if (ret) {
704 goto end;
705 }
706
707 g_string_append(context->string, ";\n\n\tpacket.context := ");
708 ret = bt_ctf_field_type_serialize(stream_class->packet_context_type,
709 context);
710 if (ret) {
711 goto end;
712 }
713
714 if (stream_class->event_context_type) {
715 g_string_append(context->string, ";\n\n\tevent.context := ");
716 ret = bt_ctf_field_type_serialize(
717 stream_class->event_context_type, context);
718 if (ret) {
719 goto end;
720 }
721 }
722
723 g_string_append(context->string, ";\n};\n\n");
11b0cdc8
JG
724 for (i = 0; i < stream_class->event_classes->len; i++) {
725 struct bt_ctf_event_class *event_class =
726 stream_class->event_classes->pdata[i];
727
11b0cdc8
JG
728 ret = bt_ctf_event_class_serialize(event_class, context);
729 if (ret) {
730 goto end;
731 }
732 }
733end:
734 context->current_indentation_level = 0;
735 return ret;
736}
737
d3814b54
JG
738BT_HIDDEN
739int bt_ctf_stream_class_set_trace(struct bt_ctf_stream_class *stream_class,
740 struct bt_ctf_trace *trace)
741{
742 int ret = 0;
743
744 if (!stream_class) {
745 ret = -1;
746 goto end;
747 }
748
749 if (stream_class->trace && trace) {
750 /* Already attached to a trace */
751 ret = -1;
752 goto end;
753 }
754
755 stream_class->trace = trace;
756end:
757 return ret;
758}
759
11b0cdc8 760static
de3dd40e 761void bt_ctf_stream_class_destroy(struct bt_ref *ref)
11b0cdc8
JG
762{
763 struct bt_ctf_stream_class *stream_class;
de3dd40e 764 struct bt_ctf_base *base;
11b0cdc8
JG
765
766 if (!ref) {
767 return;
768 }
769
de3dd40e
PP
770 base = container_of(ref, struct bt_ctf_base, ref_count);
771 stream_class = container_of(base, struct bt_ctf_stream_class, base);
11b0cdc8
JG
772 bt_ctf_clock_put(stream_class->clock);
773
774 if (stream_class->event_classes) {
2f100782
JG
775 size_t i;
776
777 /* Unregister this stream class from the event classes */
778 for (i = 0; i < stream_class->event_classes->len; i++) {
779 struct bt_ctf_event_class *event_class =
780 g_ptr_array_index(stream_class->event_classes,
781 i);
782
783 bt_ctf_event_class_set_stream_class(event_class, NULL);
784 }
785
11b0cdc8
JG
786 g_ptr_array_free(stream_class->event_classes, TRUE);
787 }
788
789 if (stream_class->name) {
790 g_string_free(stream_class->name, TRUE);
791 }
792
793 bt_ctf_field_type_put(stream_class->event_header_type);
11b0cdc8 794 bt_ctf_field_type_put(stream_class->packet_context_type);
af181248
JG
795 if (stream_class->event_context_type) {
796 bt_ctf_field_type_put(stream_class->event_context_type);
797 }
11b0cdc8
JG
798 g_free(stream_class);
799}
800
801static
662e778c 802int init_event_header(struct bt_ctf_stream_class *stream_class)
11b0cdc8
JG
803{
804 int ret = 0;
805 struct bt_ctf_field_type *event_header_type =
806 bt_ctf_field_type_structure_create();
807 struct bt_ctf_field_type *_uint32_t =
808 get_field_type(FIELD_TYPE_ALIAS_UINT32_T);
809 struct bt_ctf_field_type *_uint64_t =
810 get_field_type(FIELD_TYPE_ALIAS_UINT64_T);
811
812 if (!event_header_type) {
813 ret = -1;
814 goto end;
815 }
816
11b0cdc8
JG
817 ret = bt_ctf_field_type_structure_add_field(event_header_type,
818 _uint32_t, "id");
819 if (ret) {
820 goto end;
821 }
822
823 ret = bt_ctf_field_type_structure_add_field(event_header_type,
824 _uint64_t, "timestamp");
825 if (ret) {
826 goto end;
827 }
828
662e778c
JG
829 if (stream_class->event_header_type) {
830 bt_ctf_field_type_put(stream_class->event_header_type);
de876b7f 831 }
662e778c 832 stream_class->event_header_type = event_header_type;
11b0cdc8
JG
833end:
834 if (ret) {
835 bt_ctf_field_type_put(event_header_type);
836 }
837
838 bt_ctf_field_type_put(_uint32_t);
839 bt_ctf_field_type_put(_uint64_t);
840 return ret;
841}
842
843static
662e778c 844int init_packet_context(struct bt_ctf_stream_class *stream_class)
11b0cdc8
JG
845{
846 int ret = 0;
847 struct bt_ctf_field_type *packet_context_type =
848 bt_ctf_field_type_structure_create();
849 struct bt_ctf_field_type *_uint64_t =
850 get_field_type(FIELD_TYPE_ALIAS_UINT64_T);
851
852 if (!packet_context_type) {
853 ret = -1;
854 goto end;
855 }
856
857 /*
858 * We create a stream packet context as proposed in the CTF
859 * specification.
860 */
11b0cdc8
JG
861 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
862 _uint64_t, "timestamp_begin");
863 if (ret) {
864 goto end;
865 }
866
867 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
868 _uint64_t, "timestamp_end");
869 if (ret) {
870 goto end;
871 }
872
873 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
874 _uint64_t, "content_size");
875 if (ret) {
876 goto end;
877 }
878
879 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
880 _uint64_t, "packet_size");
881 if (ret) {
882 goto end;
883 }
884
885 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
886 _uint64_t, "events_discarded");
887 if (ret) {
888 goto end;
889 }
890
662e778c
JG
891 if (stream_class->packet_context_type) {
892 bt_ctf_field_type_put(stream_class->packet_context_type);
893 }
11b0cdc8 894 stream_class->packet_context_type = packet_context_type;
11b0cdc8
JG
895end:
896 if (ret) {
897 bt_ctf_field_type_put(packet_context_type);
898 goto end;
899 }
900
901 bt_ctf_field_type_put(_uint64_t);
902 return ret;
903}
This page took 0.064734 seconds and 4 git commands to generate.